Ad Breaks

The Android TV Receiver SDK features native support for Ad Breaks and companion ads within a given media stream.

See the Web Receiver Ad Breaks Overview for more information on how Ad Breaks work.

Handling load with ad breaks

On your Android TV app, the breaks are included in MediaLoadRequestData . Load requests can be processed normally and the AdBreakClipInfo s and AdBreakInfo s can be retrieved from the MediaInfo :

Kotlin
 class 
  
 MyMediaLoadCommandCallback 
  
 : 
  
 MediaLoadCommandCallback 
 () 
  
 { 
  
 override 
  
 fun 
  
 onLoad 
 ( 
  
 senderId 
 : 
  
 String? 
 , 
  
 loadRequestData 
 : 
  
 MediaLoadRequestData 
  
 ): 
  
 Task 
   
 { 
  
 return 
  
 Tasks 
 . 
 call 
  
 { 
  
 // Resolve the entity into your data structure and load media. 
  
 val 
  
 mediaInfo 
  
 = 
  
 loadRequestData 
 . 
 mediaInfo 
  
 ... 
  
 myPrepareAdBreaks 
 ( 
 mediaInfo 
 . 
 adBreakClips 
 , 
  
 mediaInfo 
 . 
 adBreaks 
 ) 
  
 // Update media metadata and state (this clears all previous status 
  
 // overrides). 
  
 castReceiverContext 
 . 
 getMediaStatusModifier 
 () 
  
 . 
 setDataFromLoad 
 ( 
 mediaInfo 
 ) 
  
 // Ad breaks are set on the modifier. 
  
 castReceiverContext 
 . 
 getMediaManager 
 (). 
 broadcastMediaStatus 
 () 
  
 // Return the resolved MediaLoadRequestData to indicate load success. 
  
 return 
  
 loadRequestData 
  
 } 
  
 } 
 } 
 
Java
 public 
  
 class 
  
 MyMediaLoadCommandCallback 
  
 extends 
  
 MediaLoadCommandCallback 
  
 { 
  
 @ 
 Override 
  
 public 
  
 Task 
   
 onLoad 
 ( 
 String 
  
 senderId 
 , 
  
 MediaLoadRequestData 
  
 loadRequestData 
 ) 
  
 { 
  
 return 
  
 Tasks 
 . 
 call 
 (() 
  
 -> 
  
 { 
  
 // 
  
 Resolve 
  
 the 
  
 entity 
  
 into 
  
 your 
  
 data 
  
 structure 
  
 and 
  
 load 
  
 media 
 . 
  
 MediaInfo 
  
 mediaInfo 
  
 = 
  
 loadRequestData 
 . 
 getMediaInfo 
 (); 
  
 ... 
  
 myPrepareAdBreaks 
 ( 
 mediaInfo 
 . 
 getAdBreakClips 
 (), 
  
 mediaInfo 
 . 
 getAdBreaks 
 ()); 
  
 // 
  
 Update 
  
 media 
  
 metadata 
  
 and 
  
 state 
  
 ( 
 this 
  
 clears 
  
 all 
  
 previous 
  
 status 
  
 // 
  
 overrides 
 ) 
 . 
  
 castReceiverContext 
 . 
 getMediaStatusModifier 
 () 
  
 . 
 setDataFromLoad 
 ( 
 mediaInfo 
 ); 
  
 // 
  
 Ad 
  
 breaks 
  
 are 
  
 set 
  
 on 
  
 the 
  
 modifier 
 . 
  
 castReceiverContext 
 . 
 getMediaManager 
 () 
 . 
 broadcastMediaStatus 
 (); 
  
 // 
  
 Return 
  
 the 
  
 resolved 
  
 MediaLoadRequestData 
  
 to 
  
 indicate 
  
 load 
  
 success 
 . 
  
 return 
  
 loadRequestData 
 ; 
  
 }); 
  
 } 
 } 
 

Updating ad breaks

When ads start playing, update the AdBreakStatus on the MediaStatusModifier to broadcast that your app has started playing ads:

Kotlin
 val 
  
 breakStatus 
  
 = 
  
 AdBreakStatus 
 . 
 Builder 
 () 
  
 . 
 setBreakId 
 ( 
 "b1" 
 ) 
  
 . 
 setBreakClipId 
 ( 
 "bc1" 
 ) 
  
 . 
 setCurrentBreakClipTimeInMs 
 ( 
 breakClipProgress 
 ) 
  
 . 
 setCurrentBreakTimeInMs 
 ( 
 breakProgress 
 ) 
  
 . 
 setWhenSkippableInMs 
 ( 
 5000 
 ) 
  
 // Set this field so that the ad break clip is skippable 
  
 . 
 build 
 () 
 castReceiverContext 
 . 
 getMediaStatusModifier 
 () 
  
 . 
 setAdBreakStatus 
 ( 
 breakStatus 
 ) 
Java
 AdBreakStatus 
  
 breakStatus 
  
 = 
  
 new 
  
 AdBreakStatus 
 . 
 Builder 
 () 
  
 . 
 setBreakId 
 ( 
 "b1" 
 ) 
  
 . 
 setBreakClipId 
 ( 
 "bc1" 
 ) 
  
 . 
 setCurrentBreakClipTimeInMs 
 ( 
 breakClipProgress 
 ) 
  
 . 
 setCurrentBreakTimeInMs 
 ( 
 breakProgress 
 ) 
  
 . 
 setWhenSkippableInMs 
 ( 
 5000 
 ) 
  
 // Set this field so that the ad break clip is skippable 
  
 . 
 build 
 (); 
 castReceiverContext 
 . 
 getMediaStatusModifier 
 () 
  
 . 
 setAdBreakStatus 
 ( 
 breakStatus 
 ); 

You can also dynamically modify the ad breaks after an item is loaded:

Kotlin
 var 
  
 breakClip1 
 : 
  
 AdBreakClipInfo 
  
 = 
  
 ... 
 var 
  
 breakClip2 
 : 
  
 AdBreakClipInfo 
  
 = 
  
 ... 
 var 
  
 breakClip3 
 : 
  
 AdBreakClipInfo 
  
 = 
  
 ... 
 var 
  
 break1 
 : 
  
 AdBreakInfo 
  
 = 
  
 ... 
 var 
  
 break2 
 : 
  
 AdBreakInfo 
  
 = 
  
 ... 
 mediaManager 
 . 
 getMediaStatusModifier 
 (). 
 getMediaInfoModifier 
 () 
  
 . 
 setAdBreakClips 
 ({ 
 breakClip1 
 , 
  
 breakClip2 
 , 
  
 breakClip3 
 }) 
  
 . 
 setAdBreaks 
 ({ 
 break1 
 , 
  
 break2 
 }) 
Java
AdBreakClipInfo breakClip1 = ...
AdBreakClipInfo breakClip2 = ...
AdBreakClipInfo breakClip3 = ...

AdBreakInfo break1 = ...
AdBreakInfo break2 = ...

mediaManager.getMediaStatusModifier().getMediaInfoModifier()
    .setAdBreakClips({breakClip1, breakClip2, breakClip3})
    .setAdBreaks({break1, break2});

Enable and handle ad skipping

When an ad break is playing, the senders will show a button to skip the current ad break clip if it is skippable. To enable the ability for a user to skip an ad break clip, use the MediaStatusModifier to add the COMMAND_SKIP_AD media command:

Kotlin
 mMediaManager 
 . 
 getMediaStatusModifier 
 (). 
 setMediaCommandSupported 
 ( 
 MediaStatus 
 . 
 COMMAND_SKIP_AD 
 , 
  
 true 
 ) 
Java
mMediaManager.getMediaStatusModifier().setMediaCommandSupported(MediaStatus.COMMAND_SKIP_AD, true);

To handle the SKIP_AD command, implement the onSkipAd callback in your MediaCommandCallback s:

Kotlin
 class 
  
 MyMediaCommandCallback 
  
 : 
  
 MediaCommandCallback 
 () 
  
 { 
  
 override 
  
 fun 
  
 onSkipAd 
 ( 
 requestData 
 : 
  
 RequestData?) 
 : 
  
 Task 
 < 
 Void?> 
  
 { 
  
 // Skip your ad 
  
 ... 
  
 return 
  
 Tasks 
 . 
 forResult 
 < 
 Any? 
 > 
 ( 
 null 
 ) 
  
 } 
 } 
 val 
  
 mediaManager 
  
 = 
  
 CastReceiverContext 
 . 
 getInstance 
 (). 
 mediaManager 
 mediaManager 
 . 
 setMediaCommandCallback 
 ( 
 MyMediaCommandCallback 
 ()) 
Java
 public 
  
 class 
  
 MyMediaCommandCallback 
  
 extends 
  
 MediaCommandCallback 
  
 { 
  
 @ 
 Override 
  
 public 
  
 Task 
   
 onSkipAd 
 ( 
 RequestData 
  
 requestData 
 ) 
  
 { 
  
 // 
  
 Skip 
  
 your 
  
 ad 
  
 ... 
  
 return 
  
 Tasks 
 . 
 forResult 
 ( 
 null 
 ); 
  
 } 
 } 
 MediaManager 
  
 mediaManager 
  
 = 
  
 CastReceiverContext 
 . 
 getInstance 
 () 
 . 
 getMediaManager 
 (); 
 mediaManager 
 . 
 setMediaCommandCallback 
 ( 
 new 
  
 MyMediaCommandCallback 
 ()); 
 

Client-side stitching

Client-side stitching is where ads are not embedded in the stream. For Cast Connect, in addition to updating the AdBreakStatus on the MediaStatusModifier you mustset the playback speed to 0 on the PlaybackStateCompat so the senders know to freeze the content timeline progress.

Kotlin
 // Playback speed should be 0 if content is not playing. 
 if 
  
 ( 
 adIsPlaying 
 ) 
  
 { 
  
 playbackSpeed 
  
 = 
  
 0.0f 
 } 
 val 
  
 stateBuilder 
  
 = 
  
 PlaybackStateCompat 
 . 
 Builder 
 () 
  
 . 
 setActions 
 ( 
 AVAILABLE_MEDIA_ACTIONS 
 ) 
 stateBuilder 
 . 
 setState 
 ( 
 playbackStateCompat 
 , 
  
 position 
 , 
  
 playbackSpeed 
 ) 
 mediaSession 
 . 
 setPlaybackState 
 ( 
 stateBuilder 
 . 
 build 
 ()) 
Java
 // Playback speed should be 0 if content is not playing. 
 if 
  
 ( 
 adIsPlaying 
 ) 
  
 { 
  
 playbackSpeed 
  
 = 
  
 0.0 
 f 
 ; 
 } 
 PlaybackStateCompat 
 . 
 Builder 
  
 stateBuilder 
  
 = 
  
 new 
  
 PlaybackStateCompat 
 . 
 Builder 
 () 
  
 . 
 setActions 
 ( 
 AVAILABLE_MEDIA_ACTIONS 
 ); 
 stateBuilder 
 . 
 setState 
 ( 
 playbackStateCompat 
 , 
  
 position 
 , 
  
 playbackSpeed 
 ); 
 mediaSession 
 . 
 setPlaybackState 
 ( 
 stateBuilder 
 . 
 build 
 ()); 

Once the ad finishes, you should resume the previous playback speed.

Server-side stitching

For server-side stitching , the ads are embedded so the server is expected to provide a single stream that contains both the content and ads. In this case, playback can continue progressing normally as the timeline contains the duration of the ad in addition to the content.

Create a Mobile Website
View Site in Mobile | Classic
Share by: