設定 DAI 專用的 IMA SDK

您可以使用 IMA SDK 輕鬆將多媒體廣告整合至網站和應用程式。IMA SDK 可向任何 符合 VAST 規定的廣告伺服器要求廣告,並管理應用程式中的廣告播放作業。透過 IMA DAI SDK,應用程式會針對廣告和內容影片 (隨選影片或直播內容) 提出串流要求。接著,SDK 會傳回合併的影片串流,因此您不必在應用程式中管理廣告和內容影片之間的切換。

選取感興趣的動態廣告解決方案

全方位服務 DAI

本指南將說明如何將 IMA DAI SDK 整合至影片播放器應用程式。如要查看或參考已完成整合的範例,請從 GitHub 下載簡易範例

IMA DAI 總覽

實作 IMA DAI SDK 涉及兩個主要元件,如本指南所示:

  • StreamRequest VODStreamRequest LiveStreamRequest:定義串流要求的物件。串流要求可以是隨選影片或直播串流。直播串流要求會指定素材資源金鑰,而 VOD 要求則會指定 CMS ID 和影片 ID。這兩種要求類型可選擇加入存取指定串流所需的 API 金鑰,以及 IMA SDK 的 Google Ad Manager 聯播網代碼,以便處理 Google Ad Manager 設定中指定的廣告 ID。
  • StreamManager:處理動態廣告插播串流和與 DAI 後端互動的物件。串流管理員也會處理追蹤 ping,並將串流和廣告事件轉送給發布商。

必要條件

  • 三個空白檔案
    • dai.html
    • dai.css
    • dai.js
  • 電腦上已安裝 Python,或用於測試的網路伺服器

啟動開發伺服器

由於 IMA DAI SDK 會使用與載入頁面相同的通訊協定載入依附元件,因此您必須使用網路伺服器來測試應用程式。如要快速啟動本機開發伺服器,請使用 Python 內建的伺服器。

  1. 使用指令列,從包含 index.html 檔案的目錄執行:

    python -m http.server 8000
  2. 透過網路瀏覽器前往 http://localhost:8000/

    您也可以使用任何其他網頁伺服器,例如 Apache HTTP 伺服器

建立影片播放器

首先,請修改 dai.html,建立 HTML5 影片元素和 div,用於點閱。以下範例會匯入 IMA DAI SDK。詳情請參閱「匯入 IMA DAI SDK」。

此外,請新增必要的標記,以便載入 dai.cssdai.js 檔案,以及匯入 hls.js 影片播放器。接著修改 dai.css,指定頁面元素的大小和位置。最後,在 dai.js 中定義變數來保存串流要求資訊、在網頁載入時執行的 initPlayer() 函式,並設定播放按鈕,以便在點擊時要求串流。

<html>
<head>
  <script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
  <script src="//imasdk.googleapis.com/js/sdkloader/ima3_dai.js"></script>
  <script src="dai.js"></script>
  <link rel="stylesheet" href="dai.css">
</head>
<body onLoad="initPlayer()">
  <h2>IMA SDK DAI Demo (HLS.JS)</h2>
  <video id="video"></video>
  <div id="adUi"></div>
  <button id="play-button">Play</button>
</body>
</html>

#video,
#adUi {
  width: 640px;
  height: 360px;
  position: absolute;
  top: 35px;
  left: 0;
}

#adUi {
  cursor: pointer;
}

#play-button {
  position: absolute;
  top: 400px;
  left: 15px;
}
// This stream will be played if ad-enabled playback fails.
const BACKUP_STREAM =
    'http://storage.googleapis.com/testtopbox-public/video_content/bbb/' +
    'master.m3u8';

// Live stream asset key.
// const TEST_ASSET_KEY = 'c-rArva4ShKVIAkNfy6HUQ';

// VOD content source and video IDs.
const TEST_CONTENT_SOURCE_ID = '2548831';
const TEST_VIDEO_ID = 'tears-of-steel';

// Ad Manager network code.
const NETWORK_CODE = '21775744923';
const API_KEY = null;

// StreamManager which will be used to request ad-enabled streams.
let streamManager;

// hls.js video player
const hls = new Hls();

// Video element
let videoElement;

// Ad UI element
let adUiElement;

// The play/resume button
let playButton;

// Whether the stream is currently in an ad break.
let adBreak = false;

/**
 * Initializes the video player.
 */
function initPlayer() {
  videoElement = document.getElementById('video');
  playButton = document.getElementById('play-button');
  adUiElement = document.getElementById('adUi');
  createStreamManager();
  listenForMetadata();

  // Show the video controls when the video is paused during an ad break,
  // and hide them when ad playback resumes.
  videoElement.addEventListener('pause', () => {
    if (adBreak) {
      showVideoControls();
    }
  });
  videoElement.addEventListener('play', () => {
    if (adBreak) {
      hideVideoControls();
    }
  });

  playButton.addEventListener('click', () => {
    console.log('initiatePlayback');
    requestStream();
    // Hide this play button after the first click to request the stream.
    playButton.style.display = 'none';
  });
}

如要在暫停的廣告插播期間繼續播放,請為影片元素的 pausestart 事件設定事件監聽器,以便顯示及隱藏播放器控制項。

/**
 * Hides the video controls.
 */
function hideVideoControls() {
  videoElement.controls = false;
  adUiElement.style.display = 'block';
}

/**
 * Shows the video controls.
 */
function showVideoControls() {
  videoElement.controls = true;
  adUiElement.style.display = 'none';
}

載入 IMA DAI SDK

接著,請在 dai.html 中使用指令碼標記新增 IMA 架構,並放在 dai.js 的標記之前。

<script src="//imasdk.googleapis.com/js/sdkloader/ima3_dai.js"></script>

初始化 StreamManager

如要要求一組廣告,請建立 ima.dai.api.StreamManager,負責要求及管理 DAI 串流。建構函式會採用影片元素和廣告 UI 元素,以便處理廣告點擊。

/**
 * Create the StreamManager and listen to stream events.
 */
function createStreamManager() {
  streamManager =
      new google.ima.dai.api.StreamManager(videoElement, adUiElement);
  streamManager.addEventListener(
      google.ima.dai.api.StreamEvent.Type.LOADED, onStreamEvent);
  streamManager.addEventListener(
      google.ima.dai.api.StreamEvent.Type.ERROR, onStreamEvent);
  streamManager.addEventListener(
      google.ima.dai.api.StreamEvent.Type.AD_BREAK_STARTED, onStreamEvent);
  streamManager.addEventListener(
      google.ima.dai.api.StreamEvent.Type.AD_BREAK_ENDED, onStreamEvent);
}

提出串流要求

定義用來要求串流的函式。這個範例包含 VOD 和直播的函式,可建立 VODStreamRequest 類別和 LiveStreamRequest 類別的例項。取得 streamRequest 例項後,請使用串流要求例項呼叫 streamManager.requestStream() 方法。

/**
 * Makes a stream request and plays the stream.
 */
function requestStream() {
  requestVODStream(TEST_CONTENT_SOURCE_ID, TEST_VIDEO_ID, NETWORK_CODE, API_KEY);
  // Uncomment line below and comment one above to request a LIVE stream.
  // requestLiveStream(TEST_ASSET_KEY, NETWORK_CODE, API_KEY);
}

/**
 * Requests a Live stream with ads.
 * @param {string} assetKey
 * @param {?string} networkCode
 * @param {?string} apiKey
 */
function requestLiveStream(assetKey, networkCode, apiKey) {
  const streamRequest = new google.ima.dai.api.LiveStreamRequest();
  streamRequest.assetKey = assetKey;
  streamRequest.networkCode = networkCode;
  streamRequest.apiKey = apiKey;
  streamManager.requestStream(streamRequest);
}

/**
 * Requests a VOD stream with ads.
 * @param {string} cmsId
 * @param {string} videoId
 * @param {?string} networkCode
 * @param {?string} apiKey
 */
function requestVODStream(cmsId, videoId, networkCode, apiKey) {
  const streamRequest = new google.ima.dai.api.VODStreamRequest();
  streamRequest.contentSourceId = cmsId;
  streamRequest.videoId = videoId;
  streamRequest.networkCode = networkCode;
  streamRequest.apiKey = apiKey;
  streamManager.requestStream(streamRequest);
}

這兩種串流要求方法都會使用選用的 API 金鑰。如果您使用受保護的串流,就必須建立動態廣告插播驗證金鑰。詳情請參閱「驗證 DAI 影片串流請求」。這個範例中的兩個串流都未使用動態廣告插播驗證金鑰進行保護,因此不會使用 apiKey

剖析串流中繼資料 (僅限直播)

針對直播,您還需要新增處理常式來監聽計時中繼資料事件,並將事件轉送至 StreamManager 類別,以便 IMA 在廣告插播期間發出廣告事件:

/**
 * Set up metadata listeners to pass metadata to the StreamManager.
 */
function listenForMetadata() {
  // Only used in LIVE streams. Timed metadata is handled differently
  // by different video players, and the IMA SDK provides two ways
  // to pass in metadata, StreamManager.processMetadata() and
  // StreamManager.onTimedMetadata().
  //
  // Use StreamManager.onTimedMetadata() if your video player parses
  // the metadata itself.
  // Use StreamManager.processMetadata() if your video player provides raw
  // ID3 tags, as with hls.js.
  hls.on(Hls.Events.FRAG_PARSING_METADATA, function(event, data) {
    if (streamManager && data) {
      // For each ID3 tag in our metadata, we pass in the type - ID3, the
      // tag data (a byte array), and the presentation timestamp (PTS).
      data.samples.forEach(function(sample) {
        streamManager.processMetadata('ID3', sample.data, sample.pts);
      });
    }
  });
}

本指南使用 hls.js 播放器進行串流播放,但中繼資料實作方式取決於您使用的播放器類型。

處理串流事件

為主要影片事件實作事件監聽器。這個範例會呼叫 onStreamEvent() 函式,處理 LOADEDERRORAD_BREAK_STARTEDAD_BREAK_ENDED 事件。這個函式會處理串流載入、串流錯誤,以及在廣告播放期間停用播放器控制項,這也是 IMA SDK 所需的功能。

/**
 * Responds to a stream event.
 * @param {!google.ima.dai.api.StreamEvent} e
 */
function onStreamEvent(e) {
  switch (e.type) {
    case google.ima.dai.api.StreamEvent.Type.LOADED:
      console.log('Stream loaded');
      loadUrl(e.getStreamData().url);
      break;
    case google.ima.dai.api.StreamEvent.Type.ERROR:
      console.log('Error loading stream, playing backup stream.' + e);
      loadUrl(BACKUP_STREAM);
      break;
    case google.ima.dai.api.StreamEvent.Type.AD_BREAK_STARTED:
      console.log('Ad Break Started');
      adBreak = true;
      hideVideoControls();
      break;
    case google.ima.dai.api.StreamEvent.Type.AD_BREAK_ENDED:
      console.log('Ad Break Ended');
      adBreak = false;
      showVideoControls();
      break;
    default:
      break;
  }
}

/**
 * Loads and plays a Url.
 * @param {string} url
 */
function loadUrl(url) {
  console.log('Loading:' + url);
  hls.loadSource(url);
  hls.attachMedia(videoElement);
  hls.on(Hls.Events.MANIFEST_PARSED, function() {
    console.log('Video Play');
    videoElement.play();
  });
}

串流載入後,影片播放器會使用 loadUrl() 函式載入並播放提供的網址。

大功告成!您現在可以使用 IMA DAI SDK 請求及顯示廣告。如要進一步瞭解進階 SDK 功能,請參閱其他指南或 GitHub 上的範例