광고 시점

개요

웹 수신기 SDK는 지정된 미디어 스트림 내에서 광고 시점 및 컴패니언 광고를 기본적으로 지원합니다. 수신기에 광고 시점을 통합하는 방법에는 광고 시점과 광고 시점 클립을 사용하는 클라이언트 측과 서버 측 병합을 제공하는 두 가지 방법이 있습니다.

광고 시점 개발을 시작하기 전에 맞춤 웹 수신기 설정을 숙지합니다. Cast SDK Ad Breaks API를 사용하면 광고가 재생의 일부인 경우 모든 Cast 지원 기기에서 사용자에게 일관된 환경을 제공할 수 있습니다.

이 가이드에서 광고 시점은 하나 이상의 광고 또는 범퍼가 포함된 재생 간격을 의미하며 각 광고 또는 범퍼는 광고 시점 클립이라고 합니다.

이 다이어그램은 광고 시점 두 개를 보여줍니다. 각 광고에는 두 개의 광고가 포함되어 있습니다.

이벤트

다음 표에서는 재생 중에 중단이 발생할 때 트리거되는 이벤트를 설명합니다.

휴식 시간 설명
BREAK_시작됨 광고 시점의 첫 번째 브레이크 클립이 로드되기 시작하면 실행됩니다. 이벤트는 cast.framework.events.BreaksEvent입니다.
중단 광고 시점의 마지막 브레이크 클립이 종료되면 실행됩니다. 이벤트는 cast.framework.events.BreaksEvent입니다.
참고: 이 이벤트는 사용자가 광고 시간을 종료하기 위해 광고 시점의 마지막 광고 시간 클립을 건너뛰더라도 실행됩니다.
BREAK_CLIP_로드 중 브레이크 클립이 로드되기 시작하면 실행됩니다. 이벤트는 cast.framework.events.BreaksEvent입니다.
BREAK_CLIP_STARTED(종료됨) 브레이크 클립이 시작되면 실행됩니다. 이벤트는 cast.framework.events.BreaksEvent입니다.
BREAK_CLIP_ENDED 브레이크 클립이 끝나면 실행됩니다. 이벤트는 cast.framework.events.BreaksEvent입니다.
참고: 이 이벤트는 사용자가 브레이크 클립을 건너뛰더라도 실행됩니다. BreaksEventendedReason 속성을 확인하세요. 광고 시점 클립을 시청한 시간을 확인하려면 PlayerManagergetBreakClipCurrentTimeSecgetBreakClipDurationSec을(를) 확인하세요.

이러한 이벤트는 분석 및 광고 재생 추적에 사용할 수 있습니다. VMAP(Video Multiple Ad Playlist) 및 VAST (동영상 광고 게재 템플릿)를 사용하면 응답에 제공된 모든 표준 추적 이벤트가 SDK에 의해 자동으로 전달됩니다.

중단이 재생되는 동안 웹 수신자 SDK는 연결된 모든 발신자에게 breakStatus를 사용하여 MediaStatus를 브로드캐스트합니다. 발신자는 이 정보를 사용하여 UI를 업데이트하고 탐색 작업을 숨길 수 있습니다.

웹 수신기 SDK는 광고 시점을 클라이언트 측 연결과 서버 측 병합을 통합하는 두 가지 방법으로 제공합니다.

클라이언트 측 광고 병합

비삽입형이라고도 하는 클라이언트 측 광고 연결의 경우 미디어가 로드될 때 필요한 광고 정보를 BreakBreakClip 객체로 지정해야 합니다. 다음 스니펫은 프리롤, 미드롤, 포스트롤 나누기를 추가하는 함수의 예입니다. 여기서 third_party 및 메서드의 참조는 개발자가 앱에 포함할 수 있는 도우미 함수의 예입니다. 또한 이 스니펫은 사용자가 BREAK_CLIP_ENDED 이벤트를 수신 대기하고 endedReason 값을 확인하여 브레이크 클립을 끝까지 볼 때 추적 이벤트가 실행되는 방식을 보여줍니다.

/**
 * @param {!cast.framework.messages.MediaInformation} mediaInformation
 */
function addBreakToMedia(mediaInformation) {
  mediaInformation.breakClips = [
  {
    id: 'bc1',
    title: third_party.getBreakClipTitle('bc1'),
    contentId: third_party.getBreakClipUrl('bc1'),
    contentType: third_party.getBreakClipContentType('bc1'),
    posterUrl: third_party.getBreakClipPosterUrl('bc1')
  },
  {
    id: 'bc2'
    ...
  },
  {
    id: 'bc3'
    ...
  },
  {
    id: 'bc4'
    ...
  }];
  mediaInformation.breaks = [
  {
    id: 'b1',
    breakClipIds: ['bc1', 'bc2'],
    position: 0  //pre-roll position
  },
  {
    id: 'b2',
    breakClipIds: ['bc3'],
    position: 10*60 //ten minutes
  },{
    id: 'b3',
    breakClipIds: ['bc4'],
    position: -1  //post-roll position (-1 is only valid client stitching; for server-side ad stitching, exact position is required)
  }];
}

const context = cast.framework.CastReceiverContext.getInstance();
const playerManager = context.getPlayerManager();

playerManager.addEventListener(cast.framework.events.EventType.BREAK_CLIP_ENDED, function(event){
  if(event.endedReason === cast.framework.events.EndedReason.END_OF_STREAM){
    //call your ad tracking code here for break clip watched to completion
  }
});


playerManager.setMessageInterceptor(
    cast.framework.messages.MessageType.LOAD,
    loadRequestData => {
      addBreakToMedia(loadRequestData.media);
      return loadRequestData;
    });
context.start();

VAST 광고

웹 수신기 SDK는 IAB 표준 VAST 광고를 지원합니다. 미디어에 VAST 광고를 포함하려면 vastAdsRequest 객체를 만들어 BreakClipvastAdsRequest 속성에 할당합니다. vastAdsRequest 객체에는 adsResponse 속성 또는 adTagUrl 속성이 정의되어 있어야 합니다.

/**
 * @param {!cast.framework.messages.MediaInformation} mediaInformation
 */
function addBreakToMedia(mediaInformation) {
  mediaInformation.breakClips = [
  {
    id: 'bc1',
    vastAdsRequest:{
      adTagUrl: 'https://castsample.com/vast?rand=' + Math.floor(Math.random()* 10000)
    }
  }];
}

웹 수신자 SDK가 지정된 adTagUrl에 요청을 전송하고 XML 응답을 파싱하여 BreakClip 객체를 생성합니다. 다음은 SDK에서 생성된 BreakClip 객체의 예입니다.

{
  "id": "GENERATED:0",
  "contentId": "https://file.mp4",
  "contentType": "video/mp4",
  "title": "Preroll",
  "duration": 10,
  "clickThroughUrl": "https://click"
}

VMAP 광고

웹 수신기 SDK는 IAB VMAP 표준을 지원합니다. VMAP가 제공되면 Cast SDK가 VMAP 응답을 파싱하고 응답에서 지정된 <AdBreak> 항목에 대한 Break 객체를 생성합니다. 또한 VMAP에 제공된 각 <AdSource> 항목에 vastAdsRequest 객체를 사용하여 적절한 BreakClips를 생성합니다. VMAP를 사용하여 콘텐츠에 광고를 삽입하려면 vastAdsRequest 객체를 만들어 로드 요청의 일부로 MediaInformation 객체의 vmapAdsRequest 속성에 할당합니다.

/**
 * @param {!cast.framework.messages.MediaInformation} mediaInformation
 */
function addBreakToMedia(mediaInformation) {
  mediaInformation.vmapAdsRequest = {
    adTagUrl: 'https://castsample.com/vmap?rand=' + Math.floor(Math.random()* 10000)
  };
}

서버 측 광고 병합

광고 측 연결(삽입된 광고라고도 함)의 경우 서버는 기본 미디어와 광고가 모두 포함된 단일 스트림을 제공해야 합니다. 이 경우 개발자는 BreakClipdurationcontentType를 제공해야 합니다. contentUrl은 생략됩니다. 또한 isEmbedded를 true로 설정해야 합니다.

/**
 * @param {!cast.framework.messages.MediaInformation} mediaInformation
 */
function addBreakToMedia(mediaInformation) {
  mediaInformation.breakClips = [
  {
    id: 'bc1',
    title: third_party.getBreakClipTitle('bc1'),
    posterUrl: third_party.getBreakClipPosterUrl('bc1'),
    duration: third_party.getBreakClipDuration('bc1')
  },
  {
    id: 'bc2'
    ...
  },
  {
    id: 'bc3'
    ...
  },
  {
    id: 'bc4'
    ...
  }];
  mediaInformation.breaks = [
  {
    id: 'b1',
    breakClipIds: ['bc1', 'bc2'],
    position: 0,
    isEmbedded: true
  },
  {
    id: 'b2',
    breakClipIds: ['bc3', 'bc4'],
    position: 10*60,
    isEmbedded: true
  }];
}

const context = cast.framework.CastReceiverContext.getInstance();
const playerManager = context.getPlayerManager();
playerManager.setMessageInterceptor(
    cast.framework.messages.MessageType.LOAD,
    loadRequestData => {
      addBreakToMedia(loadRequestData.media);
      return loadRequestData;
    });
context.start();

중단 동작

기본 광고 시점 동작

  1. 광고 시점이 시작되면 isWatched로 표시됩니다. 그런 다음 사용자가 브레이크보다 먼저 스크러빙하면 콘텐츠가 정상적으로 재생되고 이전에 시청한 것으로 간주된 시점을 건너뜁니다.
  2. 사용자가 광고를 시청하지 않고 광고 시점을 스크러빙하면 콘텐츠 재생이 시작되기 전에 마지막으로 재생된 seekFromseekTo 위치 간의 광고 시점이 재생됩니다.

맞춤 광고 시점 동작

중단 및 중단 클립의 default behaviorBreakManager 객체의 setBreakClipLoadInterceptorsetBreakSeekInterceptor 메서드를 사용하여 수정할 수 있습니다.

setBreakClipLoadInterceptor 클래스의 정적 변수

setBreakClipLoadInterceptor는 광고 시점이 있기 전에 호출됩니다. 이 함수는 브레이크 클립당 한 번 호출됩니다. BreakClip 객체를 콜백 함수에 전달합니다.

예를 들어 프리롤 광고 시점이 있는 경우 재생이 시작되는 즉시 프리롤 광고 시점에 setBreakClipLoadInterceptor가 호출됩니다. 프리롤 재생이 끝나면 바로 다음 광고 시간의 setBreakClipLoadInterceptor가 호출됩니다.

null이거나 콜백 함수에서 setBreakClipLoadInterceptor에 아무것도 반환되지 않으면 브레이크 클립을 건너뜁니다. 휴식을 위한 모든 인터셉터는 즉시 호출됩니다.

setBreakClipLoadInterceptor를 사용하면 재생이 시작되기 전에 BreakClip 객체를 수정할 수 있습니다.

setBreakSeekInterceptor 클래스의 생성자

setBreakSeekInterceptor는 탐색 작업 후에 트리거되고 BreakSeekData 객체를 콜백 함수에 전달합니다. BreakSeekData 객체에는 현재 플레이헤드 시간과 탐색 대상 시간 (예: seekFromseekTo) 사이에 위치가 정의된 광고 시점 배열이 포함됩니다. 정방향 탐색 작업 후의 기본 동작은 seekTo 시간 전에 마지막으로 재생되지 않은 나누기를 재생하는 것입니다. 광고 시점 재생이 완료되면 seekTo 위치에서 콘텐츠 재생이 다시 시작됩니다.

이 인터셉터를 사용하면 각 Break의 BreakClip 객체를 수정할 수 있습니다.

동작을 맞춤설정하려면 setBreakSeekInterceptor를 구현하여 default behavior를 재정의하면 됩니다. setBreakSeekInterceptor가 구현된 경우 재생할 시점을 명시적으로 지정해야 합니다.

  • null 값이 있거나 setBreakSeekInterceptor에서 아무것도 반환되지 않으면 나누기를 건너뜁니다.
  • 콜백 함수로 전달되는 동일한 객체가 반환되면 default behavior가 재정의되고 모든 중단 시간이 재생됩니다. 또한 사용자가 이전에 스크러빙하면 이전에 해당 브레이크를 시청했더라도 중단이 표시됩니다. setBreakSeekInterceptor가 구현되지 않았다면 이미 시청한 광고를 건너뜁니다.

브레이크 클립을 건너뛸 수 있도록 설정

브레이크 클립을 건너뛸 수 있게 하려면 BreakClip 객체에서 브레이크 클립을 건너뛸 수 있을 때까지 대기하는 시간(초)을 지정합니다.

/**
 * @param {!cast.framework.messages.MediaInformation} mediaInformation
 */
function addBreakToMedia(media) {
  media.breakClips = [
  {
    id: 'bc1',
    ...
    whenSkippable: 10 //to allow user to skip break clip from sender after 10 seconds
  }];
}

광고 자동 건너뛰기

광고는 사용자의 상호작용 없이 자동으로 건너뛸 수 있습니다. 광고를 건너뛰는 두 가지 방법은 다음과 같습니다.

  1. BreakisWatched 속성을 true로 설정하면 자동으로 나누기를 건너뜁니다.
    playerManager.addEventListener(cast.framework.events.category.CORE, function(event){
      if(event.type === cast.framework.events.EventType.PLAYER_LOADING){
        let breaks = playerManager.getBreaks();
        for(let i in breaks){
          breaks[i].isWatched = true;
        }
      }
    });
  2. setBreakClipLoadInterceptor callBack에 null 값을 반환하여 BreakClip를 건너뛸 수 있습니다.
    playerManager.getBreakManager().setBreakClipLoadInterceptor(breakClip => {
      return null;
    });