Server Side Ad Insertion using FLBroadpeak
Setup
To use the Quickplay SSAI solution with Broadpeak, you must configure the Broadpeak SmartLib SDK into the application.
// Add the gradle dependency for Broadpeak SmartLib with appropriate version in build.
// application level build.gradle
repositories {
google()
mavenCentral()
maven {
url `https://delivery-platform.broadpeak.tv/android/repository/all`
allowInsecureProtocol true
}
}
// module level build.gradle
implementation 'tv.broadpeak.smartlib:smartlib-media3:06.00.02.845a8c7'
Implement QP broadpeak library in module level build.gradle
implementation com.quickplay.vstb7:fl-player-ads-broadpeak:<QP-SDK-Versions>
This version is subject to change as the Quickplay libraries are updated. Make sure that the version of Broadpeak SmartLib SDK is compatible with the Quickplay libraries that you're using.
Prerequisites
If the playback asset is eligible for SSAI, it's indicated to the application when authorizing it for playback with the Quickplay platform, using ContentAuthorizationToken.ssaiEnabled.
All SSAI related functionality must be set up only when this flag is enabled.
// obtain ContentAuthorizationToken when `ContentAuthorizer.authorizePlayback` is successful
if (contentAuthorizationToken.ssaiEnabled == true) {
// setup Broadpeak SmartLib and build Broadpeak player for SSAI playback
} else {
// build player using `PlayerBuilder.build` for normal playback
}
Playback with SSAI
Follow these steps in the mentioned order to ensure seamless integration of Broadpeak SSAI functionality into the application.
1. Initialize Broadpeak SmartLib on application startup
class PlayerApp : Application() {
override fun onCreate() {
super.onCreate()
val broadpeakInitData = BroadpeakSmartLibInitializationData(
applicationContext,
domainHostNames = BroadpeakCDN.Custom("cdn.broadpeak.com")
)
BroadpeakSessionManager.createInstance(broadpeakInitData)
registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacks {
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {}
override fun onActivityStarted(activity: Activity) {}
override fun onActivityResumed(activity: Activity) {}
override fun onActivityPaused(activity: Activity) {}
override fun onActivityStopped(activity: Activity) {}
override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {}
override fun onActivityDestroyed(activity: Activity) {
if (activity is MainActivity && activity.isFinishing) {
BroadpeakSessionManager.releaseInstance()
}
}
})
}
}
BroadpeakSmartLibInitializationData encapsulates all the information required to initialize SSAI.
| Property | Type | Default Value | Description |
|---|---|---|---|
| applicationContext | Context | - | The Android application's context. |
| analyticsHostNames | BroadpeakAnalyticsHost | BroadpeakAnalyticsHost.None | The address of the Analytics Engine or the Analytics Engines list. |
| domainHostNames | BroadpeakCDN | BroadpeakCDN.None | The domain names list used to identify Broadpeak sessions. |
| loggerLevel | Int | BroadpeakLoggerLevel.LOG_VERBOSE | The logger level for debugging. |
| uuid | UUID | null | A unique user identifier or any other information which can be used to uniquely identify a user, an account or a group of users. |
| deviceType | String | null | Overrides the default device type detected by the SmartLib. |
| userAgent | String | null | The user agent to use when firing Broadpeak analytics ad tracking beacons. |
| gdprPreferences | Int | null | The General Data Protection Regulation aka (GDPR) preference for the Broadpeak Analytics. |
| sessionKeepAliveFrequencyMs | Int | null | Overrides the default SmartLib session keep alive frequency (5000ms). The value can be within 5000ms to 10000ms. |
Possible values for BroadpeakAnalyticsHost:
None: No analytics host is configured. This is the default value.
Custom: The analytics host names list
Possible values for BroadpeakCDN:
None: Declares that none of the sessions are using Broadpeak CDN.
All: Declares that all sessions are using Broadpeak CDN.
Custom: The domain name list to use to identify url(s) using Broadpeak product.
Possible values for BroadpeakLoggerLevel:
LOG_BASIC: Sets basic logger level (initialization, sessions information, errors)
LOG_VERBOSE: Sets verbose logger level (basic logs + detailed information about the sessions, ad breaks and ads)
LOG_OFF: Disables logging.
Possible values for gdprPreferences:
GDPR_DELETE: the analytics session report will be empty.
GDPR_ENCRYPTED: decryption possible on request on analytics server.
GDPR_ANONYMIZED: no decryption possible.
GDPR_CLEAR: by default, no encryption.
The fl-player-ads-broadpeak library enables the playback of Broadpeak-curated streams with
advertisements. To build a Broadpeak player, use the BroadpeakPlayerBuilder() API with the
following optional properties:
| Property | Type | Description |
|---|---|---|
| adPlaybackPolicy | AdPlaybackPolicy | Sets the [AdPlaybackPolicy] instance that specifies the policy rules for Broadpeak ads handling. |
| playbackPolicyHandler | PlaybackPolicyHandler | Sets the [PlaybackPolicyHandler] instance that enforces the policy rules related to the content with Broadpeak ads. |
| playbackPolicyHandlerListener | PlaybackPolicyHandler.Listener | Sets the [PlaybackPolicyHandler.Listener] instance that provides the notification for ad playback policy related events. |
| palConfiguration | PALConfiguration | Sets the [PALConfiguration] instance that is used in the [PALSession] initialization. Optionally sets the permission to store user data like cookies, device IDs, and advertising IDs when using [PALSession] calls. |
| adParams | Map<String, String> | Sets the parameters used for the ad insertion. |
| customParams | Map<String, String> | Sets the custom parameters to be added to the session report. |
| pipSession | boolean | Set to true if the session needs to support Picture-in-Picture. |
Create Broadpeak player
Build a Player using BroadpeakPlayerBuilder as an extension of PlayerBuilder.
// Player Integration Component e.g. Activity, Fragment, or ViewModel
val token: ContentAuthorizationToken = getContentAuthorizationToken()
val context: Application = getApplication()
val broadpeakPlayerBuilder = BroadpeakPlayerBuilder()
val consumptionType: ConsumptionType = getConsumptionType()
broadpeakPlayerBuilder.mediaURL(contentURL)
broadpeakPlayerBuilder.mediaType(MediaType.DASH)
broadpeakPlayerBuilder.drmScheme(DRMScheme.WIDEVINE)
broadpeakPlayerBuilder.drmLicenseURL(drmLicenseURL)
val broadpeakPlayer = broadpeakPlayerBuilder.build(
context,
consumptionType
)
(broadpeakPlayer as AdComposedPlayer).registerAdListener(adListener)
player = composablePlayerWith(
broadpeakPlayer
)
player.addListener(playerListener)
player.addAuxiliaryListener(auxiliaryPlayerListener)
The PlayerBuilder build function is deprecated and MUST not be used. Only use the overloaded
build function that accepts ContentAuthorizationToken and ConsumptionType params.
Note also that you can provide additional context to playback session by setting parameters for
the ad insertion (call adParams in BroadpeakPlayerBuilder) or by setting custom parameters to
be added to the session report (call customParams in BroadpeakPlayerBuilder).
Listen to ad events
You can register an AdEventListener instance with AdComposedPlayer for listening to Ad Events. The following ad events are triggered by AdEventListener callbacks:
- Cue Point availability (available only after obtaining a response from Ad Server)
- Ad Break Start called when the first Ad, in an Ad Break, have started playing. This event may also provide
AdBreakInfometadata for the active Ad Break. - Ad Start called when an Ad has started playing. This event will also provide
AdInfometadata for the active Ad. - Ad Playback Progress called during Ad Break playback when the Ad's progress is updated. This event will also provide
AdProgressInfometadata for the active Ad Break. - Ad End called when an Ad has finished playing. This event will also provide
AdInfometadata for the active Ad. - Ad Break End called when all the Ads, in an Ad Break, have finished playing. This event may also provide
AdBreakInfometadata for the active Ad Break. - Ad Error called when an error has been encountered during Ads playback. This event will also provide
Errormetadata for the active Ad. - Ad Tracking Event called when an ad tracking event sucha as ad's first quartile, midpoint, third quartile etc. is
triggered. This event will also provide
AdTrackingEventmetadata for the active Ad Break or Ad.
val adEventListener = object : AdEventListener {
override fun onAdCuePointsAvailable(cuePoints: LongArray) {
logger.info { "cue_points_available" }
}
override fun onAdBreakStart(adBreakInfo: AdBreakInfo?) {
logger.info { "ad_break_start" }
}
override fun onAdStart(adInfo: AdInfo) {
logger.info { "ad_start" }
}
override fun onAdPlaybackProgress(adProgresInfo: AdProgressInfo) {
logger.info { "ad_progress" }
}
override fun onAdEnd(adInfo: AdInfo) {
logger.info { "ad_end" }
}
override fun onAdBreakEnd(adBreakInfo: AdBreakInfo?) {
logger.info { "ad_break_end" }
}
}
adsPlayer.registerAdListener(adEventListener)
Ad Metadata
AdInfo
Represents an advert object.
| Property | Type | Description |
|---|---|---|
| adID | string | The identifier of the advert |
| sequence | number | The sequence of the advert |
| adStartTimeOffsetMs | number | The start playhead position of the advert in milliseconds |
| durationMs | number | The duration of the advert in milliseconds |
| remainingTimeMs | number | Returns the natural playback time remaining for the advert in milliseconds |
| isSkippable | boolean | Indicates if the ad is skippable |
| skipOffsetMs | number | The value of skip offset for the advert, in milliseconds. If the VAST skip offset is not defined then this method returns -1, signifying that the advert cannot be skipped. |
| isFiller | boolean | Whether this advert represents filler content |
| adBreakInfo | AdBreakInfo | The ad break in which the advert belongs in |
| adVastProperties | AdVastProperties | Represents a VAST properties of this advert. |
AdBreakInfo
Represents an ad break object.
| Property | Type | Description |
|---|---|---|
| adBreakID | String | Unique id of the ad break |
| contentTimePosition | AdContentTimePosition | The position of the ad break, can be on of preroll, midroll or postroll |
| adSequencePosition | Int | The sequence position of the ad within the ad break. |
| adBreakStartTimeOffsetMs | Double | The content time offset at which the current ad break was scheduled |
| remainingTimeMs | Double | The natural playback time remaining for the ad break in milliseconds |
| durationMs | Double | The maximum duration of the ad break in milliseconds. |
| totalAds | Int | The total number of ads contained within this ad break. |
| adBreakIndex | Int | The index of the current ad break |
The totalAds read from AdPlayer may not be accurate when it comes from onAdStart event. This may change once ad playback starts. GoogleIMA advises to read totalAds on or after FIRST_QUARTILE ad tracking event, to get a reliable data.