Setting up Ads with the Android Player
Bitmovin Player is capable of serving Ads out of the box. This guide will help you get started with configuring Ads for your integration.
Prerequisites
- Basic understanding of Android development with Kotlin
- Bitmovin Player Android SDK added to your project (see Getting Started guide)
- (optional) If you want to use IMA ( i.e.
AdSourceType.Ima
) for ad handling, additional project setup is needed as shown here
Overview
The Bitmovin Player provides several ways of serving client side (linear) ads. This guide will show you how to get started and configure your ad playback.
There are three types of Ad handling in the Bitmovin Player:
- Bitmovin Advertising - Built-in VAST ad handling
- IMA - Integration of the Google IMA SDK
- Progressive - Built-in support for playing an asset as ad
All of them use the same API surface. Besides IMA, none of these require additional setup.
Supported VAST Versions
Bitmovin Advertising is designed for seamless integration with the latest VAST
4.3
standard while offering reliable backward compatibility down to VAST2.0
. At present, key VAST features are supported, providing an optimized and streamlined experience for a wide variety of advertising use cases.
The central component of advertising is the AdItem
. It represents a specific time slot within the streamed content dedicated to ads playback. An AdItem
is configured with one or more AdSource
and a position
. The first adSource
is used as the main ad. Subsequent adSource
s act as a fallback (waterfalling), meaning that if the main ad source does not provide a valid response the subsequent adSource
s will be utilised one after another. AdSource
s describe the source of an ad e.g. the VAST URL and how it should be handled by the player i.e. the AdSourceType
.
Whenever the position of an AdItem
is reached, the player pauses the main content and starts ad playback. Ads that are part of one AdItem
are accompanied by enclosing AdBreakStarted
and AdBreakFinished
events, to signal the transition. During ad playback most of the player API relates to the specific ad playback e.g. play
/pause
will pause the ad and currentTime
returns the position within the ad.
Configuration on the general ad behaviour as well as type specific handling can be found in the AdvertisingConfig
Setup
Step 1: Create an AdSource
As previously mentioned, the AdSource
represents the ad source and its handling type. It is the first thing that should be created:
// This snipped contains IMA Sample Tags from https://developers.google.com/interactive-media-ads/docs/sdks/android/tags
val skippableAdSource = AdSource(AdSourceType.Bitmovin, "https://pubads.g.doubleclick.net/gampad/ads?sz=640x480&iu=/124319096/external/single_ad_samples&ciu_szs=300x250&impl=s&gdfp_req=1&env=vp&output=vast&unviewed_position_start=1&cust_params=deployment%3Ddevsite%26sample_ct%3Dskippablelinear&correlator=")
val redirectErrorAdSource = AdSource(AdSourceType.Ima, "https://pubads.g.doubleclick.net/gampad/ads?sz=640x480&iu=/124319096/external/single_ad_samples&ciu_szs=300x250&impl=s&gdfp_req=1&env=vp&output=vast&unviewed_position_start=1&cust_params=deployment%3Ddevsite%26sample_ct%3Dredirecterror&nofb=1&correlator=")
val linearAdSource = AdSource(AdSourceType.Ima, "https://pubads.g.doubleclick.net/gampad/ads?sz=640x480&iu=/124319096/external/single_ad_samples&ciu_szs=300x250&impl=s&gdfp_req=1&env=vp&output=vast&unviewed_position_start=1&cust_params=deployment%3Ddevsite%26sample_ct%3Dlinear&correlator=")
val progressiveAdSource = AdSource(AdSourceType.Progressive, "https://bitmovin-a.akamaihd.net/content/testing/ads/testad2s.mp4")
Step 2: Create an AdItem
An AdItem
further associates AdSources, a position and potentially more configuration options:
// Example 1: Set up a pre-roll ad
val preRollAd = AdItem(skippableAdSource)
// Example 2: Set up a mid-roll ad with waterfalling at 10% of the content duration
val midRollAd = AdItem("10%", redirectErrorAdSource, linearAdSource)
// Example 3: Set up a post-roll ad
val postRollAd = AdItem("post", progressiveAdSource)
All possible values for AdItem positions can be found here, the default value is "pre"
.
The difference between pre-roll, mid-roll and post-roll ads is:
- Pre-roll Ads: These are video ads that play before the main content starts. It's the first thing a viewer sees when they click to play a video. Because of their placement, pre-roll ads typically have higher view rates.
- To prevent flashing the first frame of the main content before the pre-roll ad is played back we recommend setting
hideFirstFrame
totrue
.
- To prevent flashing the first frame of the main content before the pre-roll ad is played back we recommend setting
- Mid-roll Ads: These are video ads that play in the middle of the main content, much like traditional TV commercial breaks. The placement of mid-roll ads varies, but they're usually placed at a natural break point in the content to minimize disruption to the viewer.
- Post-roll Ads: These are video ads that play after the main content has finished. While they don't interrupt the viewing experience, they often have lower view rates because viewers might leave the page or move on to another video once the main content ends.
Mixing different AdSourceType
It is not supported to mix
AdSource
s with differentAdSourceType
within anAdItem
. If created and scheduled anyway, the player will ignore it and emit a warning.
Step 3: Scheduling Ads
There are two fundamental ways to schedule ads in the Bitmovin Player. A static config per player, or dynamic scheduling at any time.
Static Scheduling
To define a static schedule, a AdvertisingConfig
needs to be defined when creating a Player
instance and is automatically applied to the first Source
being played back after a load
call. This means that it is not intended to be used with playlists, but may be useful when reusing the Player
and playing different items using the load
call. The schedule in the AdvertisingConfig
is persisted across load
calls.
// Add the AdItems to the AdvertisingConfig
val advertisingConfig = AdvertisingConfig(preRollAd, midRollAd, postRollAd)
// Create a new PlayerConfig containing the advertising config.
val playerConfig = PlayerConfig(advertisingConfig = advertisingConfig)
val player = Player.create(context, playerConfig)
Dynamic Scheduling
It is possible to dynamically schedule AdItems
once a Source
or playlist is loaded. Those dynamic ads are discarded completely after they have been played back and either way do not persist across load
calls to the player, but may be used within playlists.
// Dynamically schedule an AdItem
player.scheduleAd(midRollAd)
Additional functionality
Our API Reference offers detailed information on all configurations and other aspects of the API. Most of additional features can be configured through the AdvertisingConfig
along with ad type specific configurations BitmovinAdvertisingConfig
and ImaConfig
.
Nevertheless, below is a curated list of particularly useful features:
Events
You can observe the lifecycle of ads using our rich Events API and subscribe to events such as AdBreakStarted
, AdBreakFinished
, AdStarted
, AdClicked
, AdScheduled
or AdError
.
You can find a full list of advertising related events here.
player.on<PlayerEvent.AdBreakStarted> { println("The Ad Break started") }
Skipping ads
Some ads can be skipped. When building custom UIs the Player.skipAd function can be used to skip the currently being played ad programmatically. However, this does not apply to IMA ads, as the IMA SDK itself provides the UI and does not allow for programatic ad skipping.
Discarding ad breaks before they start
Sometimes it might be needed to discard an ad break before it starts. For this case AdvertisingConfig.shouldPlayAdBreak
is called before an ad break starts and can be used to allow the ad break or discard it.
Conclusion
That's it!
You have now set up basic ads using the Bitmovin Android SDK 🥳
These instructions provide the basics, but the Bitmovin Android SDK API reference provides more detailed information on how to customise the ad setup to fit your specific needs.
References
Updated about 1 month ago