开始使用 IMA DAI SDK

借助 IMA SDK,您可以轻松地将多媒体广告集成到您的网站和应用中。IMA SDK 可以从任何 符合 VAST 标准的广告服务器请求广告,并在您的应用中管理广告播放。借助 IMA DAI SDK,应用可针对广告和内容视频(无论是 VOD 还是直播内容)发出流请求。然后,SDK 会返回一个组合的视频流,这样您就不必在应用内管理广告和内容视频之间的切换了。

选择您感兴趣的 DAI 解决方案

全服务 DAI

本指南演示了如何将 IMA SDK 集成到简单的视频播放器应用中。如果您想查看或遵循已完成的示例集成,请从 GitHub 下载简单示例

IMA DAI 概览

实现 IMA DAI 涉及两个主要 SDK 组件,如本指南所示:

  • StreamRequest - VODStreamRequest LiveStreamRequest:用于定义流请求的对象。流请求可以针对视频点播或直播。请求会指定内容 ID,以及 API 密钥或身份验证令牌和其他参数。
  • StreamManager:用于处理动态广告插播流以及与 DAI 后端的互动的对象。视频流管理器还会处理跟踪 ping,并将视频流和广告事件转发给发布商。

前提条件

  • 三个空文件
    • dai.html
    • dai.css
    • dai.js
  • 要用于测试的计算机或网络服务器上安装的 Python

启动开发服务器

由于 IMA SDK 加载依赖项所用的协议与加载依赖项的页面相同,因此您需要使用网络服务器来测试您的应用。启动本地开发服务器的最简单方法是使用 Python 的内置服务器。

  1. 从包含 index.html 文件的目录中,使用命令行运行以下命令:

    python -m http.server 8000
    
  2. 在网络浏览器中,前往 http://localhost:8000/

    您也可以使用任何其他网络服务器,例如 Apache HTTP Server

创建简单的视频播放器

首先,修改 dai.html,以创建一个简单的 HTML5 视频元素和一个用于点击后到达网址的 div。另外,添加必要的标记来加载 dai.cssdai.js 文件,以及导入 hls.js 视频播放器。然后,修改 dai.css 以指定页面元素的大小和位置。最后,在 dai.js 中,定义用于保存流请求信息的变量以及要在网页加载时运行的 initPlayer() 函数。

dai.html

<html>
<head>
  <script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
  <script src="dai.js"></script>
  <link rel="stylesheet" href="dai.css" type="text/css">
</head>
<body onLoad="initPlayer()">
  <h2>IMA SDK DAI Demo (HLS.JS)</h2>
    <video id="video"></video>
    <div id="ad-ui"></div>
</body>
</html>

dai.css

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

#ad-ui {
  cursor: pointer;
}

dai.js

var BACKUP_STREAM =
    'https://storage.googleapis.com/interactive-media-ads/media/bbb.m3u8'

// Livestream asset key.
var TEST_ASSET_KEY = "sN_IYUG8STe1ZzhIIE_ksA";

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

var hls = new Hls(); // hls.js video player
var videoElement;
var adUiElement;
var isAdBreak;

function initPlayer() {
  videoElement = document.getElementById('video');
  adUiElement = document.getElementById('adUi');
}

加载 IMA SDK

接下来,使用 dai.html 中的脚本标记(位于 dai.js 标记之前)添加 IMA 框架。

dai.html

<html>
<head>
  <script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
  <script type="text/javascript" src="//imasdk.googleapis.com/js/sdkloader/ima3_dai.js"></script>
  <script src="dai.js"></script>
  <link rel="stylesheet" href="dai.css" type="text/css">
</head>

初始化 StreamManager 并发出流请求

为了请求一组广告,请创建一个 ima.dai.api.StreamManager,它负责请求和管理 DAI 流。构造函数采用视频元素,生成的实例采用广告界面元素来处理广告点击。

然后,定义请求流的函数。此示例包含用于 VOD 和直播的函数,这些函数分别创建 VODStreamRequestLiveStreamRequest 的实例,然后使用 streamRequest 参数调用 streamManager.requestStream()。对于直播,您还需要添加一个处理程序来监听定时元数据事件并将事件转发到 StreamManager。您可以根据自己的用例,对代码添加注释或取消注释。两种方法均采用可选的 API 密钥。如果您使用的是受保护的视频流,则需要创建 DAI 身份验证密钥

此示例中的两个视频流都未受保护,因此未使用 apiKey

dai.js

function initPlayer() {
  videoElement = document.getElementById('video');
  adUiElement = document.getElementById('adUi');
  streamManager = new google.ima.dai.api.StreamManager(videoElement, adUiElement)

  // Timed metadata is only used for LIVE streams.
  hls.on(Hls.Events.FRAG_PARSING_METADATA, function(event, data) {
    if (streamManager && data) {
      // For each ID3 tag in the metadata, 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);
      });
    }
  });

  requestVODStream(TEST_CONTENT_SOURCE_ID, TEST_VIDEO_ID, null);
  // Uncomment the line below and comment out the one above to request a
  // LIVE stream instead of a VOD stream.
  //requestLiveStream(TEST_ASSET_KEY, null);
}

function requestVODStream(cmsId, videoId, apiKey) {
  var streamRequest = new google.ima.dai.api.VODStreamRequest();
  streamRequest.contentSourceId = cmsId;
  streamRequest.videoId = videoId;
  streamRequest.apiKey = apiKey;
  streamManager.requestStream(streamRequest);
}

function requestLiveStream(assetKey, apiKey) {
  var streamRequest = new google.ima.dai.api.LiveStreamRequest();
  streamRequest.assetKey = assetKey;
  streamRequest.apiKey = apiKey;
  streamManager.requestStream(streamRequest);
}

处理数据流事件

最后,您需要为重大视频事件实现事件监听器。这个简单示例通过调用 onStreamEvent() 函数来处理 LOADEDERRORAD_BREAK_STARTEDAD_BREAK_ENDED 事件。此函数可以处理数据流加载和错误,以及在广告播放时停用播放器控件(SDK 要求)。流加载后,视频播放器会使用 loadUrl() 函数加载并播放提供的网址。

您可能还需要为视频元素的 pausestart 事件设置事件监听器,以便用户在 IMA 在广告插播期间暂停时继续播放。

如需使用 DAI,您的自定义播放器必须将直播的 ID3 事件传递给 IMA SDK,如示例代码所示。

dai.js

var isAdBreak;

function initPlayer() {
  videoElement = document.getElementById('video');
  adUiElement = document.getElementById('adUi');
  streamManager = new google.ima.dai.api.StreamManager(videoElement, adUiElement);
  videoElement.addEventListener('pause', onStreamPause);
  videoElement.addEventListener('play', onStreamPlay);

  streamManager.addEventListener(
    [google.ima.dai.api.StreamEvent.Type.LOADED,
     google.ima.dai.api.StreamEvent.Type.ERROR,
     google.ima.dai.api.StreamEvent.Type.AD_BREAK_STARTED,
     google.ima.dai.api.StreamEvent.Type.AD_BREAK_ENDED],
    onStreamEvent,
    false);
...
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');
      isAdBreak = true;
      videoElement.controls = false;
      adUiElement.style.display = 'block';
      break;
    case google.ima.dai.api.StreamEvent.Type.AD_BREAK_ENDED:
      console.log('Ad Break Ended');
      isAdBreak = false;
      videoElement.controls = true;
      adUiElement.style.display = 'none';
      break;
    default:
      break;
  }
}

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

function onStreamPause() {
  console.log('paused');
  if (isAdBreak) {
    videoElement.controls = true;
    adUiElement.style.display = 'none';
  }
}

function onStreamPlay() {
  console.log('played');
  if (isAdBreak) {
    videoElement.controls = false;
    adUiElement.style.display = 'block';
  }
}

大功告成!现在,您正通过 IMA SDK 请求和展示广告。如需详细了解高级 SDK 功能,请参阅其他指南或 GitHub 上的示例