광고 관리자 클래스 만들기

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

광고 모음 스트림 요청

AdManager.requestStream() 메서드를 만들고 Google Ad Manager 네트워크 코드 및 스트림의 맞춤 애셋 키를 사용하여 PodStreamRequest 객체를 만듭니다. 다음 스트림 매개변수를 사용하여 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 앱의 기본 애플리케이션 클래스를 만듭니다.