借助 IMA SDK,您可以轻松将多媒体广告集成到您的网站和应用中。IMA SDK 可以从任何 与 VAST 兼容的广告服务器请求广告,并管理应用中的广告播放。借助 IMA DAI SDK,应用可以针对广告和内容视频(VOD 或直播内容)发出流式传输请求。然后,SDK 会返回一个合并的视频串流,这样您就不必在应用中管理广告视频和内容视频之间的切换。
选择您感兴趣的 DAI 解决方案
全方位 DAI
本指南介绍了如何将 IMA DAI SDK 集成到简单的视频播放器应用中。如果您想查看或跟随完成的示例集成,请从 GitHub 下载简单示例。
IMA DAI 概览
实现 IMA DAI SDK 涉及两个主要组件,如本指南中所示:
StreamRequest
-VODStreamRequest
或LiveStreamRequest
:用于定义数据流请求的对象。流式传输请求可以是视频点播或直播。请求中会指定内容 ID,以及 API 密钥或身份验证令牌和其他参数。StreamManager
:一种对象,用于处理动态广告插播数据流以及与 DAI 后端的互动。直播管理器还会处理跟踪 ping,并将直播和广告事件转发给发布商。
前提条件
- 三个空文件
- dai.html
- dai.css
- dai.js
- 在用于测试的计算机或网络服务器上安装 Python
启动开发服务器
由于 IMA DAI SDK 加载依赖项所用的协议与其加载时所在网页使用的协议相同,因此您需要使用网络服务器来测试应用。要启动本地开发服务器,最快的方法是使用 Python 的内置服务器。
在包含
index.html
文件的目录下使用命令行运行以下命令:python -m http.server 8000
在网络浏览器中,前往
http://localhost:8000/
您也可以使用任何其他网络服务器,例如 Apache HTTP Server。
创建一个简单的视频播放器
首先,修改 dai.html,以创建一个简单的 HTML5 视频元素和一个用于点击的 div。此外,还要添加必要的标记来加载 dai.css 和 dai.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 DAI 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 DAI SDK
接下来,在 dai.html 中使用脚本标记添加 IMA 框架,将其放在 dai.js 对应的标记之前。
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 数据流。构造函数接受视频元素,生成的实例接受广告界面元素来处理广告点击。
然后,定义请求数据流的函数。此示例包含适用于视频点播和直播的函数,它们分别创建 VODStreamRequest
和 LiveStreamRequest
实例,然后使用 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()
函数来处理 LOADED
、ERROR
、AD_BREAK_STARTED
和 AD_BREAK_ENDED
事件。此函数用于处理流加载和错误,以及在广告播放期间停用播放器控件(这是 SDK 的要求)。加载数据流后,视频播放器会使用 loadUrl()
函数加载并播放所提供的网址。
您可能还需要为视频元素的 pause
和 start
事件设置事件监听器,以便在 IMA 在广告插播期间暂停时允许用户继续播放。
如需使用 DAI,您的自定义播放器必须将直播的 ID3 事件传递给 IMA DAI 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 DAI SDK 请求和展示广告了。如需了解更高级的 SDK 功能,请参阅其他指南或 GitHub 上的示例。