Android TV 接收器 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{ // Skip your ad ... return Tasks.forResult (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());
广告播放完毕后,您应该继续以先前的速度播放。
服务器端拼接
对于服务器端拼接,广告是嵌入的,因此服务器应提供同时包含内容和广告的单个数据流。在这种情况下,播放可以继续正常进行,因为时间轴除了包含广告内容之外,还包含广告的时长。