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());
광고가 끝나면 이전 재생 속도로 다시 시작해야 합니다.
서버 측 병합
서버 측 스티칭의 경우 광고가 삽입되므로 서버가 콘텐츠와 광고를 모두 포함하는 단일 스트림을 제공해야 합니다. 이 경우 타임라인에 콘텐츠 외에도 광고의 재생 시간이 포함되어 있으므로 재생이 정상적으로 계속 진행될 수 있습니다.