Client Side Ad Insertion
The fl-android-ads-ima library integrates with GoogleIMA to offer Client Side Ad Insertion capability for both VOD and Live.
GoogleIMA
Supported Google IMA SDK version: 3.30.3
Create Ad Composed Player
AdComposedPlayer
manages both content and ad playback.
It basically extends the conventional Player functionality and adds Ad Rendering to it.
This section is specific to Google IMA SDK integration.
The IMA SDK will show additional views on top of the player while an ad is playing
(e.g., a ‘more info’ link and a skip button, if applicable).
Since advertisers expect a consistent experience across apps, the IMA SDK does not allow
customization of the views that it shows while an ad is playing. It is therefore not possible to
remove or reposition the skip button, change the fonts, or make other customizations to the visual
appearance of these views.
The IMA SDK may report whether ads are obscured by application provided views rendered on
top of the player. Apps that need to overlay views that are essential for controlling playback
must register them with the IMA SDK so that they can be omitted from viewability calculations.
Apps that use a custom player UI must register overlay views.
Player library provides an API to register the views that are on top of the ad view group,
but that are essential for controlling Ad playback. The AdOverlayUIScope
defines the context for
the views that are part of ad view group.
The following ad views UI scopes are defined:
Property | Description |
---|---|
PLAYBACK_CONTROLS_UI_SCOPE | UIScope for playback controls overlaying the player. |
CLOSE_AD_UI_SCOPE | UIScope for ad close buttons overlaying the player. |
OTHER_UI_SCOPE | UIScope for other overlays. |
NOT_VISIBLE_UI_SCOPE | UIScope for overlays that are not visible |
Here are the steps to initialize the playback session for IMA ads:
- Retrieve ad tag url.
val adTagUrl =
'https://pubads.g.doubleclick.net/gampad/ads?sz=640x480&' +
'iu=/124319096/external/ad_rule_samples&ciu_szs=300x250' +
'&ad_rule=1&impl=s&gdfp_req=1&env=vp&output=vast&' +
'cust_params=deployment%3Ddevsite%26sample_ar%3Dpremidpost&cmsid=496&' +
'vid=short_onecue&correlator=&unviewed_position_start=1';
- Provide the UI scope info for an overlay view shown on top of an ad view group. Below is one possible way to provide that information.
val adOverlayUIScopes = mutableListOf<AdOverlayUIScope>()
val playerControlsUIScope = AdOverlayUIScope(playerControlsView,
AdOverlayUIScope.PLAYBACK_CONTROLS_UI_SCOPE
)
adOverlayUIScopes.add(playerControlsUIScope)
val showDebugOverlayBtnUIScope = AdOverlayUIScope(showDebugOverlayBtn,
AdOverlayUIScope.OTHER_UI_SCOPE
)
adOverlayUIScopes.add(showDebugOverlayBtnUIScope)
val debugOverlayViewUIScope = AdOverlayUIScope(debugOverlayView,
AdOverlayUIScope.OTHER_UI_SCOPE
)
adOverlayUIScopes.add(debugOverlayViewUIScope)
- Create the content Player.
val contentPlayer = PlayerBuilder()
.mediaURL(contentUrl)
.mediaType(MediaType.DASH)
.build(applicationContext)
- Create IMA targeted
AdRequest
instance.
Pass a collection of AdOverlayUIScope
instances, if necessary, to initialize AdRequest
val adRequest = GoogleIMAAdRequest(adURL, adOverlayUIScopes)
- Wrap the content player with IMA targeted AdComposedPlayer.
val player = with(contentPlayer) {
IMAAdPlayerFactory.imaAdComposedPlayerWith(
applicationContext,
this,
adRequest
)
}
- Convert the AdComposedPlayer to a ComposablePlayer
val composablePlayer = composablePlayerWith(player)
- Pass the required view to the player using the attachRendererView method so that the SDK can display the ad view and content view as required, playerRoot is a FrameLayout. Although it can be done directly, we suggest to attach the view inside the Player.Listener#onPlayerViewAvailable() callback from the library.
composablePlayer.attachRendererView(
playerRoot,
FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
)
)
Listening to Ad Events
One can configure AdComposedPlayer#adEventListener property for listening to Ad Events.
The following ad events are notified via AdEventListener
callbacks:
//Called when an Ad started playing
fun onAdStart(adInfo: AdInfo)
//Called when an Ad finished playing
fun onAdEnd(adInfo: AdInfo)
// Returns an List of offsets, in milliseconds, indicating when a scheduled Ad Break will play.
fun onAdCuePointsAvailable(cuePoints: LongArray)
// Called when the first Ad, in an Ad Break, have started playing
fun onAdBreakStart(adBreakInfo: AdBreakInfo?)
// Called when all the Ads, in an Ad Break, have finished playing
fun onAdBreakEnd(adBreakInfo: AdBreakInfo?)
// Called when an error has been encountered during Ads playback
fun onAdError(error: Error)
// Called when an ad tracking event is signalled.
fun onAdTrackingEvent(adTrackingEvent: AdTrackingEvent)
Events tracked as part of AdTrackingEvent
Event | Description |
---|---|
ALL_ADS_LOADED_EVENT | Fired when the VAST response has been received. |
ALL_ADS_COMPLETED_EVENT | Fired when all the valid ads in the ads response finished playing, or when the response doesn't return any valid ads. |
AD_CUEPOINTS_CHANGED_EVENT | Fired when VOD stream cuepoints have changed. |
AD_PERIOD_STARTED_EVENT | Fired when an ad period in a stream starts. |
AD_PERIOD_ENDED_EVENT | Fired when an ad period in a stream ends. |
AD_BREAK_FETCH_ERROR_EVENT | Fired when an ad break will not play back any ads. |
AD_BREAK_READY_EVENT | Fired when an ad break is ready from VMAP or ad rule ads. |
AD_BREAK_STARTED_EVENT | Fired when an ad break in a stream starts. |
AD_BUFFERING_EVENT | Fired when playback stalls while the ad buffers. |
AD_STARTED_EVENT | Fired when an ad starts playing. |
AD_FIRST_QUARTILE_EVENT | Fired when the ad playhead crosses first quartile. |
AD_MIDPOINT_EVENT | Fired when the ad playhead crosses midpoint. |
AD_THIRD_QUARTILE_EVENT | Fired when the ad playhead crosses third quartile. |
AD_PAUSED_EVENT | Fired when an ad is paused. |
AD_RESUMED_EVENT | Fired when an ad is resumed. |
AD_ENDED_EVENT | Fired when an ad completes playing. |
AD_BREAK_ENDED_EVENT | Fired when an ad break in a stream ends. |
AD_SKIPPED_EVENT | Fired when an ad was skipped. |
AD_SKIPPABLE_STATE_CHANGED_EVENT | Fired when an ad changes its skippable state. |
AD_TAPPED_EVENT | Fired when a non-clickthrough portion of a video ad is clicked. |
AD_ICON_TAPPED_EVENT | Fired when ad icon is tapped. |
AD_ICON_FALLBACK_IMAGE_CLOSED_EVENT | Fired on closing the icon fallback image dialog. This event only fires for Connected TV devices. |
AD_CLICKED_EVENT | Fired when an ad is clicked. |
AD_AUXILIARY_DATA_EVENT | Fired to enable the SDK to communicate a message to be logged. |
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. |
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 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). |
CCPA compliance
The CCPA consent string must be sent as us_privacy
query param with ad request url. Please check Google IMA SDK Documentation¹ to read further on for CCPA compliance.
The below code shows an ad request url with the IAB parameter "1YNN".
let adTagUrl =
'https://pubads.g.doubleclick.net/gampad/ads' +
'iu=/124319096/external/single_ad_samples&output=vast&us_privacy=1YNN';