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());
広告が終了したら、前の再生速度に戻してください。
サーバーサイド スティッチング
サーバーサイド スティッチングでは、広告が埋め込まれるため、サーバーはコンテンツと広告の両方を含む単一のストリームを提供することになります。この場合、タイムラインにはコンテンツに加えて広告の再生時間も含まれているため、再生は通常どおり続行できます。