Server side ad insertion using FLMediaTailor
The fl-player-ads-mediatailor library enables the playback of AWS Elemental MediaTailor curated streams with advertisements. To build a MediaTailor player, use the MediaTailorAdsPlayerBuilder API with the following properties:
| Property | Type | Description |
|---|---|---|
| sessionURL | String | Sets the URL to create remote session with AWS Elemental MediaTailor. |
| contentURL | String | Sets the fallback URL to content playback when MediaTailor session fails. |
| drmLicenseURL | String | Sets the url for DRM keys fetch |
| drmScheme | DRMScheme | Sets content protection scheme |
| sessionConfiguration | SessionConfiguration | Session configuration parameters to create AWS MediaTailor session. |
| adPlaybackPolicy | AdPlaybackPolicy | Sets the [AdPlaybackPolicy] instance that specifies the policy rules for MediaTailor ads handling. |
| playbackPolicyHandler | PlaybackPolicyHandler | Sets the [PlaybackPolicyHandler] instance that enforces the policy rules related to the content with MediaTailor 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. |
| allowPALSessionDataStorage | Boolean | If the value is [Boolean.true] the user gives the consent to store data.The default value is [Boolean.false] - no consent. |
| httpClientConfig | HttpClientConfiguration | The Http Client configuration details for MediaTailor API calls. |
SessionConfiguration
| Parameter | Type | Description |
|---|---|---|
| playerParams | Map<String, String> | Preceding configuration used for session initialization request that defines the player variables and their aliases. |
| originParams | Map<String, String> | Custom origin parameters for the session. |
| manifestParams | Map<String, String> | Query parameters included in the parent manifest and tracking URLs in the response. |
| overlayAvails | OverlayAvailsMode | MediaTailor support for overlay ads is enabled by default. A specific SCTE-35 ad-marker type in the manifest triggers the insertion of an overlay ad. Because some players might not support client-side rendering of overlay ads, you can disable the feature at the session level. |
| availSuppression | AvailSuppression | The MediaTailor avail suppression configuration. |
| adSignaling | Boolean | To enable ad ID signaling, add an adSignaling object as a top level object, and inside, add a parameter called enabled and value of true. The default adSignaling value is disabled. |
| reportingMode | SessionReportingMode | To enable Client side ad tracking mode, set it as SessionReportingMode.Client and for MediaTailor hybrid mode use SessionReportingMode.Server. By default, Server mode is set. |
AvailSuppression
| Parameter | Type | Description |
|---|---|---|
| mode | AvailSuppressionMode | The avail suppression mode. |
| value | String | A time relative to the live edge in a live stream. |
AvailSuppressionMode
| Parameter | Description |
|---|---|
| OFF | Ad suppression is OFF |
| BEHIND_LIVE_EDGE | When set to BEHIND_LIVE_EDGE, MediaTailor doesn't fill ad breaks on or behind the aws.availSuppressionValue time |
| AFTER_LIVE_EDGE_FULL_AVAIL_ONLY | MediaTailor doesn't fill ad breaks on or behind the avail suppression period and full avail suppression policy |
| AFTER_LIVE_EDGE_PARTIAL_AVAIL | MediaTailor doesn't fill ad breaks on or behind the avail suppression period and invoke partial ad break fills when and session starts mid-break |
OverlayAvailsMode
| Parameter | Description |
|---|---|
| ON | Enabling overlaying ads. |
| OFF | Disabling overlaying ads. |
SessionReportingMode
| Parameter | Description |
|---|---|
| Server | MediaTailor supports a hybrid mode for session tracking. In this mode, the service emits playback-related ad-tracking events, but makes the complete client-side tracking payload available for the session. |
| Client | MediaTailor streams playback with Client side tracking mode. In this mode, Datazoom config ID and playerRootView is mandatory. |
SessionReportingMode.Client
| Parameter | Description |
|---|---|
| configId | The Datazoom configuration/analytics ID used to initialize the Datazoom SDK for client-side reporting. |
| playerRootView | The root view of the player ad session setup. This view is used for ad rendering and event tracking. |
PALConfiguration
| Property | Type | Description |
|---|---|---|
| willAdAutoPlay | Boolean | Defines whether the ad will be auto played without waiting for user interaction or not. |
| willAdPlayMuted | Boolean | Defines whether the ad will be played while muted or not. |
| continuousPlayback | Boolean | Defines whether the player intends to continuously play the content videos one after another similar to TV broadcast or video playlist. |
| descriptionUrl | URL | Defines the description URL of the content during which the ad will be played. |
| iconsSupported | Boolean | Defines whether VAST icons are supported by the video player. |
| nonceLengthLimit | Int | Defines the length limit of the generated nonce. |
| omidPartnerName | String | The name of the partner integrating OMID measurement. |
| omidPartnerVersion | String | The version of the partner integrating OMID measurement. |
| playerType | String | The partner provided player type. |
| playerVersion | String | The partner provided player version. |
| ppid | String | The publisher provided ID. |
| videoHeight | Int | The height of the ad video element. |
| videoWidth | Int | The width of the ad video element. |
The client application may optionally provide custom AdPlaybackPolicy and PlaybackPolicyHandler implementation, and also a PALConfiguration instance as MediaTailorAdsPlayerBuilder properties.
MediaTailor player creation use cases
The following use cases are supported by MediaTailorAdsPlayerBuilder for MediaTailorPlayer instance creation:
- The application provides session URL, content URL and PAL configuration and optionally other builder properties.
- The application provides session URL, content URL and optionally other builder properties but not PAL configuration.
- The application provides content URL and PAL configuration and optionally other builder properties but not session URL.
- The application provides content URL and optionally other builder properties but not session URL and PAL configuration.
Create MediaTailor player
Build a Player using MediaTailorAdsPlayerBuilder as an extension of PlayerBuilder (see the MediaTailor Player Creation Use Cases section). Here's a typical setup for building the player:
import com.quickplay.vstb7.player.model.MediaType
val mediaTailorAdsPlayerBuilder = MediaTailorAdsPlayerBuilder()
mediaTailorAdsPlayerBuilder.mediaType(MediaType.DASH)
mediaTailorAdsPlayerBuilder.contentURL(contentURL)
// sessionUrl is provided as part of the playback authorization's custom attribute with key `mtSessionUrl`
val sessionUrl: String? = contentAuthToken.custom?.let {
it["mtSessionUrl"] as? String
} ?: run {
null
}
mediaTailorAdsPlayerBuilder.sessionURL(sessionURL)
// if playing DRM protected content
mediaTailorAdsPlayerBuilder.drmScheme(DRMScheme.WIDEVINE)
mediaTailorAdsPlayerBuilder.drmScheme(licenseURL)
val sessionConfiguration = SessionConfiguration.Builder().apply {
playerParams(
mapOf(
"deviceType" to "androidmobile",
"uid" to "test-uid-12345",
)
) // contentAuthToken.custom.playerParams from playback Authorization
originParams(
mapOf(
"origin1" to "androidmobile",
"origin2" to "xjhhddli-9189901-uic"
)
)
manifestParams(
mapOf(
"deviceType" to "androidmobile",
"uid" to "test-uid-12345",
)
)
overlayAvails(OverlayAvailsMode.OFF)
availSuppression(
AvailSuppression(AvailSuppressionMode.AFTER_LIVE_EDGE_FULL_AVAIL_ONLY, value = "00:05:00")
)
adSignaling(false)
}.build()
mediaTailorAdsPlayerBuilder.sessionConfiguration(sessionConfiguration)
mediaTailorAdsPlayerBuilder.httpClientConfig(
HttpClientConfiguration(
connectionTimeout = 8,
readTimeout = 8,
userAgent = null,
retryOnNetworkFailure = true,
maxNetworkFailureRetryCount = 2,
baseNetworkFailureRetryDelayMs = 2000,
applicationInterceptors = emptyList()
)
)
mediaTailorAdsPlayerBuilder.playbackPolicyHandlerListener(stateObserver)
coroutineScope.launch {
when (val result: Result<MediaTailorPlayer?, Error?> =
mediaTailorAdsPlayerBuilder.buildAsync(
context
)
) {
is Result.Success -> {
val mediaTailorPlayer = result.value
mediaTailorPlayer?.let {
it.addListener(stateObserver)
it.addAuxiliaryListener(stateObserver)
it.addListener(internalPlayerListener)
it.registerAdListener(stateObserver)
player = composablePlayerWith(it as Player)
}
}
is Result.Failure -> {
// handle error
}
}
}
The PlayerBuilder build function is deprecated and MUST not be used. Only use buildAsync. This function is declared as a suspend function and MUST be called using a CoroutineScope builder function (for example, using the launch extension function).
Make sure to send the contentUrl via builder mediaTailorAdsPlayerBuilder.contentURL(contentURL) to switch to fallback content seamlessly if MediaTailor session creation fails. This provides a smooth and uninterrupted viewing experience for users.
Client side ad tracking mode
When you create a MediaTailor Player with client side ad tracking mode, you must provide DatazoomConfigId and playerRootView in addition to other parameters.
<FrameLayout
android:id="@+id/playerRoot"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/black"
android:theme="@style/ThemeOverlay.MaterialComponents.Dark"/>
val playerRootView = findViewById<FrameLayout>(R.id.playerRoot)
val mediaTailorAdsPlayerBuilder = MediaTailorAdsPlayerBuilder()
mediaTailorAdsPlayerBuilder.mediaType(MediaType.DASH)
mediaTailorAdsPlayerBuilder.contentURL(contentURL)
mediaTailorAdsPlayerBuilder.sessionURL(sessionURL)
val sessionConfiguration = SessionConfiguration.Builder().apply {
reportingMode(SessionReportingMode.Client("<DatazoomConfigId>", playerRootView))
}.build()
mediaTailorAdsPlayerBuilder.sessionConfiguration(sessionConfiguration)
Client side tracking mode dependencies
To use client side ad tracking mode, make sure to include the following dependencies in your build.gradle file:
implementation 'io.datazoom.sdk:mediatailor:0.0.16'
implementation 'io.datazoom.sdk:media3:0.0.16'
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 Error Event called when the mediaTailor session is failed to create which means playback is happening with fallback url. Please refer above note to enable fallback url.
- 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" }
}
override fun onAdError(error: Error) {
logger.info { "ad_error" }
}
override fun onAdTrackingEvent(adTrackingEvent: AdTrackingEvent) {
logger.info { "ad_tracking_event" }
}
}
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.
AdVASTProperties
Represents VAST properties of an advert.
| Property | Type | Description |
|---|---|---|
| adSystem | String | The source ad server of the advert. |
| adTitle | String | The common name of the advert. |
| adServingId | String | The identifier used to compare impression-level data across systems. |
| adId | String | The Ad identifier of the creative. |
| creativeId | String | The identifier of the creative. |
| category | String | The category of the advert content. |
| description | String | The longer description of the advert. |
| advertiser | String | The advertiser name. |
| pricing | String | The pricing element of the advert. |
| survey | String | The URI to any resource file having to do with collecting survey data. |
| expires | String | The number of seconds in which the ad is valid for execution. |
| industryIcons | List<IndustryIcon> | The list of IndustryIcon instances. |
| companionAds | List<CompanionAd> | The list of CompanionAd instances. |
| extensions | Extensions | The custom VAST extensions properties. |
| clickThroughURL | String | The click through URL for the ad. |
Handle Ad click event (Client side ad tracking mode)
To handle ad click event in Client side ad tracking mode, clickThroughURL will be provided with
ad metadata(AdInfo.adVastProperties) in onAdStart callback of AdEventListener.
When the MediaTailor Player is created with Client side ad tracking mode, the client application
must notify the MediaTailor Player when an ad is clicked by calling sendAdClick() function on MediaTailorPlayer instance.
Capturing VST parameters
Few key VST measuring metrics like licenseLoadTimeMs, ssaiStreamUrlFetchTimeMs is exposed via StreamInformation which can be accessed as below.
Please make sure to call this APIs only after player entered STARTED state.
// through API
val licenseLoadTimeMs = player?.streamInformation?.streamStartUpTimeData?.ssaiStreamUrlFetchTimeMs // A time taken to load SSAI/DAI stream URL in milliseconds.
val ssaiStreamUrlFetchTimeMs = player?.streamInformation?.streamStartUpTimeData?.licenseLoadTimeMs //A time taken to load DRM license in milliseconds.
Retrieving the MediaTailor session id for Ad Tracking
The adSessionId property provides access to the AWS MediaTailor ad session identifier for advanced tracking and diagnostics.
if (player is ComposablePlayer && player.getComposedPlayer() is AdComposedPlayer) {
val sessionId = (player.getComposedPlayer() as AdComposedPlayer)
.adSessionId
logger.info { "ad session id is $sessionId" }
}