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 VAST 2.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 adSources act as a fallback (waterfalling), meaning that if the main ad source does not provide a valid response the subsequent adSources will be utilised one after another. AdSources 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 to true.
  • 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 AdSources with different AdSourceType within an AdItem. 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