設定全方位服務 DAI

選取平台: HTML5 Android iOS tvOS Cast Roku

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

IMA DAI 總覽

如本指南所示,導入 IMA DAI SDK 包含兩個主要部分:

  • StreamRequest: VODStreamRequest 或 LiveStreamRequest,定義串流請求的物件。串流請求可以是隨選影片或直播。直播請求會指定素材資源金鑰,VOD 請求則會指定 CMS ID 和影片 ID。這兩種要求類型都可以選擇加入 API 金鑰 (用於存取指定串流),以及 Google Ad Manager 聯播網代碼 (用於讓 IMA SDK 按照 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 Server。

建立影片播放器

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

此外,請加入必要標記,載入 dai.css 和 dai.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';
  });
}

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

/**
 * 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 中使用指令碼標記,在 dai.js 標記前加入 IMA 架構。

<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 驗證金鑰。詳情請參閱「驗證 DAI 影片串流請求」。這個範例中的串流皆未使用 DAI 驗證金鑰保護,因此不會使用 apiKey。

剖析串流中繼資料

您也需要新增處理常式,監聽定時中繼資料事件,並將事件轉送至 StreamManager 類別,讓 IMA 在廣告插播期間發出廣告事件:

/**
 * Set up metadata listeners to pass metadata to the StreamManager.
 */
function listenForMetadata() {
  // 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() 函式,處理 LOADED、ERROR、AD_BREAK_STARTED 和 AD_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 上的範例。