Android TV Receiver SDK 原生支援指定媒體串流中的廣告插播和隨播廣告。
如要進一步瞭解廣告插播的運作方式,請參閱「網路接收器廣告插播總覽」。
使用廣告插播處理載入作業
在 Android TV 應用程式中,插播廣告會顯示在 MediaLoadRequestData
中。載入要求可以正常處理,且 AdBreakClipInfo
和 AdBreakInfo
可從 MediaInfo
擷取:
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 } } }
public class MyMediaLoadCommandCallback extends MediaLoadCommandCallback { @Override public TaskonLoad(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; }); } }
更新廣告插播時間點
廣告開始播放時,請更新 MediaStatusModifier
上的 AdBreakStatus
,以便廣播應用程式已開始播放廣告:
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)
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);
您也可以在項目載入後動態修改廣告插播點:
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})
AdBreakClipInfo breakClip1 = ... AdBreakClipInfo breakClip2 = ... AdBreakClipInfo breakClip3 = ... AdBreakInfo break1 = ... AdBreakInfo break2 = ... mediaManager.getMediaStatusModifier().getMediaInfoModifier() .setAdBreakClips({breakClip1, breakClip2, breakClip3}) .setAdBreaks({break1, break2});
啟用及處理廣告略過功能
播放廣告插播時,如果可略過目前的廣告插播短片,傳送端會顯示按鈕。如要讓使用者能夠略過廣告插播短片,請使用 MediaStatusModifier
新增 COMMAND_SKIP_AD
媒體指令:
mMediaManager.getMediaStatusModifier().setMediaCommandSupported(MediaStatus.COMMAND_SKIP_AD, true)
mMediaManager.getMediaStatusModifier().setMediaCommandSupported(MediaStatus.COMMAND_SKIP_AD, true);
如要處理 SKIP_AD
指令,請在 MediaCommandCallback
中實作 onSkipAd
回呼:
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())
public class MyMediaCommandCallback extends MediaCommandCallback { @Override public TaskonSkipAd(RequestData requestData) { // Skip your ad ... return Tasks.forResult(null); } } MediaManager mediaManager = CastReceiverContext.getInstance().getMediaManager(); mediaManager.setMediaCommandCallback(new MyMediaCommandCallback());
用戶端拼接
用戶端拼接是指廣告未嵌入串流的情況。對於 Cast Connect,除了在 MediaStatusModifier
上更新 AdBreakStatus
外,您還必須在 PlaybackStateCompat
上將播放速度設為 0,讓傳送端知道要將內容時間軸進度凍結。
// 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())
// Playback speed should be 0 if content is not playing. if (adIsPlaying) { playbackSpeed = 0.0f; } PlaybackStateCompat.Builder stateBuilder = new PlaybackStateCompat.Builder() .setActions(AVAILABLE_MEDIA_ACTIONS); stateBuilder.setState(playbackStateCompat, position, playbackSpeed); mediaSession.setPlaybackState(stateBuilder.build());
廣告播放完畢後,請恢復先前的播放速度。
伺服器端拼接
對於伺服器端拼接,廣告會內嵌,因此伺服器應提供包含內容和廣告的單一串流。在這種情況下,播放作業可以繼續正常進行,因為時間軸除了內容外,還包含廣告的時間長度。