광고 관리자 클래스 만들기

ads_manager.js에서 스트림 요청을 하고, 광고 모음 매니페스트를 가져오고, IMA 스트림 이벤트를 수신하고, emsg 이벤트를 IMA SDK에 전달하는 IMA SDK StreamManager의 래퍼 클래스를 정의합니다.

ads_manager.js에서 IMA HbbTV 샘플 앱은 다음 메서드를 설정합니다.

  • requestStream()
  • onStreamEvent()
  • onEmsgEvent()
  • loadAdPodManifest()

광고 관리자 초기화

광고 관리자 클래스를 초기화하고 IMA 스트림 이벤트의 리스너를 설정합니다. 이 호출에서 VideoPlayer.setEmsgEventHandler() 메서드를 사용하여 emsg 이벤트 핸들러를 설정합니다.

/**
 * Wraps IMA SDK ad stream manager.
 * @param {!VideoPlayer} videoPlayer Reference an instance of the wrapper from
 * video_player.js.
 */
var AdManager = function(videoPlayer) {
  this.streamData = null;
  this.videoPlayer = videoPlayer;
  // Ad UI is not supported for HBBTV, so no 'adUiElement' is passed in the
  // StreamManager constructor.
  this.streamManager = new google.ima.dai.api.StreamManager(
      this.videoPlayer.videoElement);
  this.streamManager.addEventListener(
      [
        google.ima.dai.api.StreamEvent.Type.STREAM_INITIALIZED,
        google.ima.dai.api.StreamEvent.Type.ERROR,
        google.ima.dai.api.StreamEvent.Type.CLICK,
        google.ima.dai.api.StreamEvent.Type.STARTED,
        google.ima.dai.api.StreamEvent.Type.FIRST_QUARTILE,
        google.ima.dai.api.StreamEvent.Type.MIDPOINT,
        google.ima.dai.api.StreamEvent.Type.THIRD_QUARTILE,
        google.ima.dai.api.StreamEvent.Type.COMPLETE,
        google.ima.dai.api.StreamEvent.Type.AD_BREAK_STARTED,
        google.ima.dai.api.StreamEvent.Type.AD_BREAK_ENDED,
        google.ima.dai.api.StreamEvent.Type.AD_PROGRESS,
        google.ima.dai.api.StreamEvent.Type.PAUSED,
        google.ima.dai.api.StreamEvent.Type.RESUMED
      ],
      this.onStreamEvent.bind(this),
      false);

  this.videoPlayer.setEmsgEventHandler(this.onEmsgEvent, this);
};

광고 모음 스트림 요청

Google Ad Manager 네트워크 코드와 스트림의 맞춤 애셋 키를 사용하여 PodStreamRequest 객체를 만드는 AdManager.requestStream() 메서드를 만듭니다. 다음 스트림 매개변수를 사용하여 스트림을 제공하는 IMA 샘플 DASH 포드를 사용하여 HbbTV 앱을 테스트합니다.

  • 네트워크 코드: '21775744923'
  • 맞춤 애셋 키: 'hbbtv-dash'
/**
 * Makes a pod stream request.
 * @param {string} networkCode The network code.
 * @param {string} customAssetKey The custom asset key.
 */
AdManager.prototype.requestStream = function(networkCode, customAssetKey) {
  var streamRequest = new google.ima.dai.api.PodStreamRequest();
  streamRequest.networkCode = networkCode;
  streamRequest.customAssetKey = customAssetKey;
  streamRequest.format = 'dash';
  debugView.log('AdsManager: make PodStreamRequest');
  this.streamManager.requestStream(streamRequest);
};

광고 스트림 이벤트 수신

IMA 스트림 이벤트 STREAM_INITIALIZED, AD_BREAK_STARTED, AD_BREAK_ENDED에 대한 앱의 응답을 처리하는 AdManager.onStreamEvent() 메서드를 만듭니다.

/**
 * Handles IMA playback events.
 * @param {!Event} event The event object.
 */
AdManager.prototype.onStreamEvent = function(event) {
  switch (event.type) {
    // Once the stream response data is received, generate pod manifest url
    // for the video stream.
    case google.ima.dai.api.StreamEvent.Type.STREAM_INITIALIZED:
      debugView.log('IMA SDK: stream initialized');
      this.streamData = event.getStreamData();
      break;
    case google.ima.dai.api.StreamEvent.Type.ERROR:
      break;
    // Hide video controls while ad is playing.
    case google.ima.dai.api.StreamEvent.Type.AD_BREAK_STARTED:
      debugView.log('IMA SDK: ad break started');
      this.adPlaying = true;
      this.adBreakStarted = true;
      break;
    // Show video controls when ad ends.
    case google.ima.dai.api.StreamEvent.Type.AD_BREAK_ENDED:
      debugView.log('IMA SDK: ad break ended');
      this.adPlaying = false;
      this.adBreakStarted = false;
      break;
    // Update ad countdown timers.
    case google.ima.dai.api.StreamEvent.Type.AD_PROGRESS:
      break;
    default:
      debugView.log('IMA SDK: ' + event.type);
      break;
  }
};

광고 스트림 메타데이터 처리

emsg 이벤트 정보를 IMA에 전달하려면 StreamManager.processMetadata() 메서드를 사용하여 AdManager.onEmsgEvent() 메서드를 만듭니다. 동영상 플레이어 클래스는 VideoPlayer.setEmsgEventHandler() 메서드를 사용하여 이 메서드를 호출합니다.

/**
 * Callback on Emsg event.
 * Instructs IMA SDK to fire back VAST events accordingly.
 * @param {!Event} event The event object.
 */
AdManager.prototype.onEmsgEvent = function(event) {
  var data = event.event.messageData;
  var pts = event.event.calculatedPresentationTime;
  if ((data instanceof Uint8Array) && data.byteLength > 0) {
    this.streamManager.processMetadata('ID3', data, pts);
  }
};

광고 애드팟 매니페스트 로드

동영상 플레이어로 광고 모음 매니페스트를 미리 로드하는 AdManager.loadAdPodManifest() 메서드를 만듭니다. 방법: DASH 포드 매니페스트의 구조를 사용하여 매니페스트 URL을 구성합니다.

/**
 * Creates DAI pod url and instructs video player to load manifest.
 * @param {string} networkCode The network code.
 * @param {string} customAssetKey The custom asset key.
 * @param {number} podDuration The duration of the ad pod.
 */
AdManager.prototype.loadAdPodManifest =
    function(networkCode, customAssetKey, podDuration) {
  if (!this.streamData) {
    debugView.log('IMA SDK: No DAI pod session registered.');
    return;
  }

  var MANIFEST_BASE_URL = 'https://dai.google.com/linear/pods/v1/dash/network/';
  // Method: DASH pod manifest reference docs:
  // https://developers.google.com/ad-manager/dynamic-ad-insertion/api/pod-serving/reference/live#method_dash_pod_manifest
  var manifestUrl = MANIFEST_BASE_URL + networkCode + '/custom_asset/' +
    customAssetKey + '/stream/' + this.streamData.streamId + '/pod/' +
    this.getPodId() + '/manifest.mpd?pd=' + podDuration;
  this.videoPlayer.preload(manifestUrl);
};

HbbTV 샘플 앱은 무작위로 생성된 고유한 podId를 사용합니다. 프로덕션 앱에서 podId는 1로 시작하고 광고 시점마다 1씩 증가하는 정수입니다. podId가 광고 시청자 모두에게 동일한 값인지 확인합니다. podId를 얻으려면 EABN(Early Ad Break Notification) API를 사용하는 것이 좋습니다. 프로덕션 환경에서는 HbbTV 스트림 이벤트 AD_BREAK_ANNOUNCEpodIdpodDuration를 포함합니다.

다음으로 HbbTV 방송과 상호작용하는 HbbTV 앱의 기본 애플리케이션 클래스를 만듭니다.