Server Side Ad Insertion in Yospace player
Server Side Ad Insertion (SSAI) is the paradigm of stitching advertisements into the content directly on the server side. This allows for the same personalised ads experience with minimal complexity on the application side.
Setup
To employ the Quickplay SSAI solution using Yospace, the Yospace ad-management library must be loaded into the application.
// Add the gradle dependency for ad management library from Yospace with appropriate version in build.gradle
implementation 'com.yospace:admanagement-sdk:3.6.1'
This version is subject to change as the Quickplay libraries are updated. Please make sure that the version of Yospace ad management SDK is compatible with the Quickplay libraries that you are using.
Prerequisites
If the playback asset is eligible for SSAI, it is 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 yospace and build Yospace player for SSAI playback
} else {
// build player using `PlayerBuilder.build` for normal playback
}
Playback with SSAI
Adhering to the following steps in the mentioned order will ensure the seamless integration of SSAI functionality into the application.
1. Create YospaceSessionInitializationData
YospaceSessionInitializationData
encapsulates all the information required to initialise SSAI.
The initialization data can be created by passing the content URL from authorization response i.e.
ContentAuthorizationToken.contentURL
and the appropriate YospaceAdsSession.PlaybackMode
. It can also be used to customise other functionalities
related to SSAI.
Property | Type | Default Value | Description |
---|---|---|---|
contentURL | String | - | The url of the content to play. |
playbackMode | YospaceAdsSession.PlaybackMode | - | Indicates whether the playback is live or VOD. |
isValidationRequired | Boolean | false | The flag indicating if Session state validation is required. This flag should be set to [Boolean.true] only when performing Yospace Validation Tests. |
keepProxyAlive | Boolean | true | The property that controls if Yospace proxy session should be kept alive or not. |
connectTimeoutMs | Int | 5000 | The timeout used when establishing an HTTP connection for session initialisation and for CSM polling, in milliseconds. |
resourceTimeoutMs | Int | 5000 | The timeout used when firing analytic beacons and pre-fetching VAST resources, in milliseconds. |
userAgent | String | "" (Empty string) | The user agent to use when firing Yospace analytic tracking Beacons. |
For playbacks in Live or Restart mode, use YospaceAdsSession.PlaybackMode.Live
. For catchup and VOD playbacks,
use YospaceAdsSession.PlaybackMode.Vod
.
val yospaceSessionInitializationData = YospaceSessionInitializationData (
contentAuthorizationToken.contentURL,
yospacePlaybackMode // pass Live for live / restart playbacks, and Vod for catchup / VOD playbacks.
)
2. Create YospaceAdsSession
Using YospaceSessionInitializationData
customized in the previous step, create YospaceAdsSession
that allows the applications to open an
appropriate playback session with Yospace.
val yospaceAdsSession = YospaceAdsPlayerFactory.createYospaceAdsSession(yospaceSessionInitializationData)
3. Initialize YospaceAdsSession
Depending on the playback mode, YospaceAdsSession
offers different methods according to the type of playback to obtain the playback URL that can be
used to build the player.
Use YospaceAdsSession.initializeLiveSession
for Live / Restart playbacks and YospaceAdsSession.initializeVODSession
for Catchup / VOD playbacks.
If the Yospace session initialisation fails, the application can still use the URL obtained during authorization (that was passed to the SDK in Step 1) to continue with a normal playback without SSAI.
// use below snippet for live / restart playbacks.
yospaceAdsSession.initializeLiveSession() { sessionInitResult ->
when (sessionInitResult) {
is Result.Success -> {
val playbackURL = sessionInitResult.value
// use playbackURL to create the player
}
is Result.Failure -> {
val error = sessionInitResult.value
logger.trace { error.toString() }
// handle the error as required
// OR
// use the content URL obtained from ContentAuthorizationToken
// to continue playback without SSAI
}
}
}
// use below snippet for catchup / VOD playbacks.
yospaceAdsSession.initializeVODSession() { sessionInitResult ->
when (sessionInitResult) {
is Result.Success -> {
val playbackURL = sessionInitResult.value
// use playbackURL to create the player
}
is Result.Failure -> {
val error = sessionInitResult.value
logger.trace { error.toString() }
// handle the error as required
// OR
// use the content URL obtained from ContentAuthorizationToken
// to continue playback without SSAI
}
}
}
4. Create Player
Using the playback URL received from YospaceAdsSession
in the previous step, create a normal player using PlayerBuilder
to obtain the
Quickplay Player.
val player = PlayerBuilder()
.mediaURL(contentUrl)
.mediaType(MediaType.DASH)
.drmScheme(DRMScheme.NONE)
.drmLicenseURL("")
.build(applicationContext)
5. Create YospaceAdsPlayer
YospaceAdsPlayer
is an implementation of Player
that holds additional functionality to support SSAI.
Use YospaceAdsPlayerFactory
to create this player according to the playback type.
// create YospaceAdsPlayer for Live / Restart playbacks
val yospaceAdsPlayer = YospaceAdsPlayerFactory.createYospaceLiveSessionAdsPlayer(
player,
yospaceAdsSession
)
// create YospaceAdsPlayer for Catchup / VOD playbacks
val yospaceAdsPlayer = YospaceAdsPlayerFactory.createYospaceVODSessionAdsPlayer(
player,
yospaceAdsSession
)
Listening to Ad Events
Attach listeners
An AdEventListener
and a YospaceAdsPlayer.Listener
can be attached to the Yospace player to allow listening for all notable events.
// create listeners
val myAdEventListener = object: AdEventListener {
// implement AdEventListener to listen to ad events
}
val yospaceListener = object: YospaceAdsPlayer.Listener {
//Implement YospaceAdsPlayer.Listener to listen to yospace session related events
}
//Listening to Ad Events
yospaceAdsPlayer.adEventListener = myAdEventListener
//Listening to Yospace Session Timeout
yospaceAdsPlayer.addYospaceListener(yospaceListener)
Listening to Ad Events
The player can attach an AdEventListener
to the YospaceAdsSession
to track the state of ad playback and implement custom UIs.
//Called when cue points are available.
fun onAdCuePointsAvailable(cuePoints: LongArray)
//Called when an Ad started playing.
fun onAdStart(adInfo: AdInfo)
//Called when an Ad finished playing.
fun onAdEnd(adInfo: AdInfo)
//Called when the first Ad, in an Ad-Break, have started playing. Use this to make any corresponding UI changes, such as player controls.
fun onAdBreakStart(adBreakInfo: AdBreakInfo?)
//Called when all the Ads, in an Ad-Break, have finished playing. Use this to make any corresponding UI changes, such as player controls.
fun onAdBreakEnd(adBreakInfo: AdBreakInfo?)
//Called when an error has been encountered during Ads playback.
fun onAdError(error: Error)
Handling Yospace Session Timeout
The Yospace player can attach a YospaceAdsPlayer.Listener
to YospaceAdsPlayer
to listen when a Yospace session might have timed out.
/**
* Called when Yospace Session times out, after approximately 2 minutes,
* if the stream manifest is not requested in that time. This may happen when the client application
* streams Live SSAI enabled content and goes into background and remains in that state for at least 2 minutes.
*/
fun onLivePlaybackSessionTimeout()
When this method is triggered, the application should stop the player and re-initialise the playback session with a new player instance.
Flow of events to re-initialize the player:
- Dispose the video renderer using
Player.detachRendererView
by passing the player's parent view. - Stop the existing player.
- Reset the player controls and Ad views.
- Authorize the playback again.
- Use the new information from the new
ContentAuthorizationToken
to create a newPlayer
. - Replace the player variable with the new player.
- Attach listeners and set the player controls to the new player.
- Start the playback.
Ad Metadata
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 |
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. |
AdVASTProperties
Represents a VAST properties object.
Property | Type | Description |
---|---|---|
adSystem | string | The source ad server of the advert |
adTitle | string | The common name of the advert |
adServingId | string | An 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 | Category of the advert content |
description | string | The longer description of the advert |
advertiser | string | Advertiser name |
pricing | string | Pricing element of the advert |
survey | string | An URI to any resource file having to do with collecting survey data |
expires | string | Number of seconds in which the ad is valid for execution |
adChoicesIcons | Collection of AdChoicesIcon | The List of AdChoicesIcon instances |
AdChoicesIcon
Represents VAST response metadata related to WTA (Why This Ad?) privacy disclosures.
These disclosures are returned inside the AdChoices
element of the VAST response.
WTA related attributes are part of the relevant Icon
tag and are used to render the AdChoices icon.
Property | Type | Description |
---|---|---|
program | string | The program represented in the icon (e.g. AdChoices ). |
width | string | The pixel width of the icon asset. |
height | string | The pixel height of the icon asset. |
xPosition | string | The x-coordinate of the top, left corner of the icon asset relative to the ad display area. Values of "left" or "right" also accepted and indicate the leftmost or rightmost available position. |
yPosition | string | The y-coordinate of the top left corner of the icon asset relative to the ad display area; values of"top" or "bottom" also accepted. |
offset | string | The time of delay from when the associated linear creative begins playing to when the icon should be displayed; provided in the format HH:MM:SS.mmm or HH:MM:SS where .mmm is milliseconds (optional). |
duration | string | The duration icon should be displayed unless clicked or ad is finished playing; provided in the format HH:MM:SS.mmm or HH:MM:SS where .mmm is milliseconds (optional). |
apiFramework | string | Identifies the API needed to execute the icon resource file if applicable. |
altText | string | The alternative text for the image. In an html5 image tag this should be the text for the alt attribute. This should enable screen readers to properly read back a description of the icon for visually impaired users. |
imageURL | string | The URL of the image file for the icon (PNG is preferred). |
clickThroughURL | string | The URL of the action that occurs when a user clicks the AdChoices icon. In most cases,the user sees the Ad Settings page that the media player opens when the icon is clicked. |
fallbackImages | Collection of IconClickFallbackImage | The List of IconClickFallbackImage instances. |
IconClickFallbackImage
In cases where the WTA icon can not display the Ad Settings
page, such as when the platform does not support a browser,
WTA can show users a fallback image that contains the same disclosure information as the Ad Settings
page.
When an icon click occurs, the ad must pause and the image must be rendered above the video.
The player must provide a means for the user to close the dialogue, for example by pressing the back button.
The image must not be obstructed and should not be downloaded unless a click-action occurs.
Property | Type | Description |
---|---|---|
width | string | The pixel width of the image asset. |
height | string | The pixel height of the image asset. |
altText | string | The alternative text for the fallback image. |
imageURL | string | The URL of the image file for the fallback image (PNG is preferred). |
Open Measurement
The client can set open measurement event delegate on Ad Player to listen to events that would provide ad vertification metadata which can be used for Open Measurement integration.
The delegate only provides metadata and resources for open measurement and the client must integrate open measurement on the app. Please refer IAB Open Measurement for complete integration of Open Measurement SDK.
The following are the delegate methods
/**
* Called when the ad verification should be started.
*
* @param adVerifications The list of [AdVerification] instances.
* @param vastProperties The [VASTProperties] instance.
* @param adVideoProperties The [AdVideoProperties] instance.
*/
fun onAdVerificationStart(
adVerifications: List<AdVerification>,
vastProperties: VASTProperties,
adVideoProperties: AdVideoProperties
)
/**
* Called when the ad verification should be completed.
*/
fun onAdVerificationEnd()
/**
* Called when an ad tracking event is signalled.
*
* @param adTrackingEvent The [AdTrackingEvent] identifier.
*/
fun onAdTrackingEvent(adTrackingEvent: AdTrackingEvent)
Verification Metadata
AdVerification
Represents an ad verification object.
Property | Type | Description |
---|---|---|
vendorKey | String | The unique identifier of the verification provider |
verificationParameters | String? | The parameters which the verification provider script is expecting for the Ad Session. |
verificationResources | List<VerificationResource> | The list of VerificationResource objects. |
VerificationResource
Represents an ad verification resource object.
Property | Type | Description |
---|---|---|
name | String | The name of the node for the ad verification resource |
value | String | The value of the node for the ad verification resource |
attributes | Map<String, String> | The Map instance of attributes of the node for the ad verification resource. |
For example, lets say the ad response has the following ad verification metadata :
<AdVerifications>
<Verification vendor=“iabtechlab.com-omid”>
<JavaScriptResource apiFramework=“omid” browserOptional=“true”>
<![CDATA[https://server.com/omid-validation-verification-script-v1.js]]>
</JavaScriptResource>
<VerificationParameters>
<![CDATA[parameterstring]]>
</VerificationParameters>
</Verification>
</AdVerifications>
In the example above:
- the name of the ad verification resource is "JavaScriptResource"
- the value of the ad verification resource is: "https://server.com/omid-validation-verification-script-v1.js"
- the attributes of the ad verification resource are: apiFramework=“omid” and browserOptional=“true”