Implementing DAI Plugin for Android

This topic covers the use of the IMA DAI plugin and how it can be implemented through custom coding.

Overview

The Brightcove SDK offers a plugin to interact with the Google IMA-DAI library for multimedia ads playback in your application, and abstracts the setup and basic interaction with the Google IMA-DAI library so you can focus on requesting video streams.

Implementation

In your build.gradle file, add the new Brightcove DAI plugin as a dependency.

    implementation "com.brightcove.player:android-dai-plugin:[BRIGHTCOVE_SDK_LAST_VERSION]"

Creating An Instance Of The Brightcove DAI Plugin

Use the GoogleDAIComponent.Builder class to create a new instance:

    GoogleDAIComponent daiComponent = new GoogleDAIComponent.Builder(brightcoveVideoView, eventEmitter).build();

Through the GoogleDAIComponent.Builder you can set up the ImaSdkSettings, AdsRenderingSettings, AdLoadTimeout, and others.

Requesting Video Streams

You can request live streams or video on demand through the following interfaces:

    //For Video On Demand 
		daiComponent.requestVOD(String contentSourceID, String videoID, String apiKey);

		// For Live streams 
		daiComponent.requestLiveStream(String assetKey, String apiKey);

Configuring a fallback video

Google suggests configuring a fallback video if the DAI video stream cannot be loaded:

    daiComponent.setFallbackVideo(Video myVideo);

We recommend retrieving the fallback video through the Brightcove Catalog API:

    catalog.findVideoByID("MY_VIDEO_ID", new VideoListener() { 
		@Override 
		public void onVideo(Video video) {
				googleDAIComponent.setFallbackVideo(video);              
		  // Request a VOD 
		  googleDAIComponent.requestVOD(MY_DAI_VIDEO_CMS_ID, MY_DAI_VIDEO_ID, null); 
	} 
	});

Getting The Response From Google IMA-DAI

Use GoogleDAIComponent.Listener to get the stream response from Google IMA-DAI.

    daiComponent.addCallback(new GoogleDAIComponent.Listener() { 
		@Override public void onStreamReady(Video video) {
				 Log.d(TAG, "onStreamReady");
				 brightcoveVideoView.add(video); 
		  brightcoveVideoView.start(); 
		}
	
			 @Override public void onContentComplete() {
				 Log.d(TAG, "onContentComplete"); 
		}
	});	

The Listener notifies you when a stream is ready and when the content has completed playback.


Basic Stream Request

The complete code for a basic stream request would be the following:

    catalog.findVideoByID(getString("MY_VIDEO_ID", new VideoListener() { 
		@Override 
		public void onVideo(Video video) {
				 daiComponent.setFallbackVideo(video); 
		  daiComponent.addCallback(new GoogleDAIComponent.Listener() {
					@Override 
			public void onStreamReady(Video video) { 
				Log.d(TAG, "onStreamReady"); 
				brightcoveVideoView.add(video); 
				brightcoveVideoView.start(); 
				}
	
			@Override 
			public void onContentComplete() { 
				Log.d(TAG, "onContentComplete"); 
				} 
				}); 
		  
		  // Request a VOD video
		  googleDAIComponent.requestVOD(VOD_TEARS_OF_STEEL_CMS_ID, VOD_TEARS_OF_STEEL_VIDEO_ID, null); 
		  }
		  });		

Refer to the Brightcove DAI Sample app in our Samples repository for the complete code.

Open Measurement

The IMA SDK for Android includes the Open Measurement (OM) SDK, an industry standard developed by the Interactive Advertising Bureau (IAB) to enable third-party viewability and verification measurement. When using the IMA SDK for Android, the included OM SDK automatically parses the <AdVerifications> tag within VAST ad tags and sends viewability data to the specified measurement vendors via the OMID API. Learn more.


Registering An Obstruction

To register a friendly obstruction, create the FriendlyObstruction object as follows:

		// Create your UI object
			myPlayButton = (ImageButton) rootView.findViewById(R.id.playButton);
			
			// Create the FriendlyObstruction object
			playButtonObstruction = ImaSdkFactory.createFriendlyObstruction(
			  myPlayButton, // The UI Object
			  FriendlyObstructionPurpose.VIDEO_CONTROLS, // The pupose
			  "This is my Play button" // A detailed reason
			);
			
			brightcoveDAIComponent.getStreamDisplayContainer().registerFriendlyObstruction(playButtonObstruction);
				
	

Unregistering An Obstruction

To unregister an obstruction, use the unregisterAllFriendlyObstructions() method:

		brightcoveDAIComponent.getStreamDisplayContainer().unregisterAllFriendlyObstructions();
	

Localization

The Google IMA-DAI library supports multiple languages applied to the ads and the UI controls. This is configurable through the ImaSDKSettings object from the Google IMA-DAI library, and after the locale is set, the ImaSDKSettings object can be passed to the Brightcove DAI plugin:

		ImaSdkSettings imaSdkSettings = ImaSdkFactory.getInstance().createImaSdkSettings();
			imaSdkSettings.setLanguage("fr");
			
	GoogleDAIComponent.Builder daiBuilder = new GoogleDAIComponent.Builder(brightcoveVideoView, eventEmitter)
				   .setImaSdkSettings(imaSdkSettings)
				   
	GoogleDAIComponent googleDAIComponent = daiBuilder.build();
	
Supported Country codes.

Privacy

The Brightcove DAI plugin allows the end user to consent to the usage of their data to offer personalized ads.

This can be set by passing a Map with the parameters for each consent and their value into the GoogleDAIComponent.Builder class:

		Map<String, String> adTagParameters = new HashMap<String, String>;
			adTagParameters.put(BaseIMAComponent.TAG_NON_PERSONALIZED_ADS, “1”);
			
	ImaSdkSettings imaSdkSettings = ImaSdkFactory.getInstance().createImaSdkSettings();
	GoogleDAIComponent.Builder daiBuilder = new GoogleDAIComponent.Builder(brightcoveVideoView, eventEmitter)
					.setImaSdkSettings(imaSdkSettings)
					.setAdTagParameters(adTagParameters);
	

The supported consents are the following:

  • Non-Personalized Ads.
  • Users under the Age of Consent in Europe.
  • California Consumer Privacy Act.
    • Google’s RDP (Restricted Data Processing).
    • IAB’s RDP.
  • Limited Ads.

Non-personalized ads

To force non-personalized ads follow the next snippet:

		adTagParameters.put(BaseIMAComponent.TAG_NON_PERSONALIZED_ADS, “1”);
	

Users under age

To tag users as under the age of consent follow the next snippet:

		adTagParameters.put(BaseIMAComponent.TAG_FOR_USERS_UNDER_AGE, “1”);
	

RDP

To notify that RDP should be enabled using Google’s signal follow the next snippet:

		adTagParameters.put(BaseIMAComponent.TAG_GOOGLE_RDP_SIGNAL, “1”);
	

IAB signal

The value for this has to align with the IAB specification:

		adTagParameters.put(BaseIMAComponent.TAG_IAB_RDP_SIGNAL, “1YYN”);
	

Limit ads

To limit ads follow the next snippet:

		adTagParameters.put(BaseIMAComponent.TAG_LIMITED_ADS, “1”);
	

Limitations

  • Manifest Expiration

    Brightcove VOD manifest URLs are not static and are designed to expire after a certain time.

    A stream being ingested by Google and re-streamed as a DAI stream will stop working after the manifest URL expires. Google does not yet offer a mechanism to refresh the expired URL.

  • Stream Preconditioning

    Google IMA-DAI requires streams to be preconditioned using #EXT-X-PLACEMENT-OPPORTUNITY tags in the source HLS manifest, or through multiple periods in a DASH manifest, to signal where ad breaks should appear.

    Brightcove VOD delivery does not include this non-standard HLS tag today.

  • HLSe Not Supported

    Google IMA-DAI does not currently offer support for HLSe.

Known Issues

  • Ad Events Notifications

    The Google IMA-DAI library only notifies ad events once per ad. If users replay an ad, the Brightcove DAI plugin will not receive ad notifications of that second ad playback. This is by design by the Google IMA team.

  • Livestreams Return Null Ad Info

    The Google IMA-DAI library provides null information about ad events when the user joins a livestream in the middle of an ad. This behavior is by design in the Google IMA-DAI library, and it limits the Brightcove DAI plugin in knowing if an ad is being played and acting accordingly(notifying the user, blocking playback controls, sending the right video and analytics data to the Brightcove backend, etc.).

  • Manual-start Playback

    The Google IMA-DAI library controls the playback controls, which means that we cannot control playback while an ad is being played. This affects the stream when it has pre-rolls by not allowing it to start playback manually.