광고 시점

Android TV Receiver SDK는 특정 미디어 스트림 내에서 광고 시점과 컴패니언 광고를 기본적으로 지원합니다.

광고 시점의 작동 방식에 대한 자세한 내용은 Web Receiver 광고 시점 개요를 참고하세요.

광고 시점을 사용한 로드 처리

Android TV 앱에서 광고 시점은 MediaLoadRequestData에 포함됩니다. 로드 요청은 정상적으로 처리할 수 있으며 AdBreakClipInfoAdBreakInfoMediaInfo에서 가져올 수 있습니다.

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;
    });
    }
}

광고 시점 업데이트

광고 재생이 시작되면 MediaStatusModifier에서 AdBreakStatus를 업데이트하여 앱에서 광고 재생을 시작했음을 브로드캐스트합니다.

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);

항목이 로드된 후 광고 시점을 동적으로 수정할 수도 있습니다.

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});

광고 건너뛰기 사용 설정 및 처리

광고가 재생되는 동안 보낸 사람은 건너뛸 수 있는 경우 현재 광고 클립을 건너뛸 수 있는 버튼을 표시합니다. 사용자가 광고 시점 클립을 건너뛸 수 있도록 하려면 MediaStatusModifier를 사용하여 COMMAND_SKIP_AD 미디어 명령어를 추가합니다.

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

SKIP_AD 명령어를 처리하려면 MediaCommandCallback에서 onSkipAd 콜백을 구현합니다.

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());

클라이언트 측 스티칭

클라이언트 측 스티칭은 광고가 스트림에 삽입되지 않는 경우입니다. Cast Connect의 경우 MediaStatusModifier에서 AdBreakStatus를 업데이트하는 것 외에도 PlaybackStateCompat에서 재생 속도를 0으로 설정해야 합니다. 그래야 발신자가 콘텐츠 타임라인 진행 상황을 고정할 수 있습니다.

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.0f;
}
PlaybackStateCompat.Builder stateBuilder = new PlaybackStateCompat.Builder()
    .setActions(AVAILABLE_MEDIA_ACTIONS);
stateBuilder.setState(playbackStateCompat, position, playbackSpeed);
mediaSession.setPlaybackState(stateBuilder.build());

광고가 끝나면 이전 재생 속도로 다시 시작해야 합니다.

서버 측 병합

서버 측 스티칭의 경우 광고가 삽입되므로 서버는 콘텐츠와 광고가 모두 포함된 단일 스트림을 제공해야 합니다. 이 경우 타임라인에 콘텐츠 외에 광고 재생 시간이 포함되어 있으므로 재생이 정상적으로 계속 진행될 수 있습니다.