IMA SDK を使用すると、マルチメディア広告をウェブサイトやアプリに簡単に統合できます。IMA SDK は、 VAST 準拠のあらゆる広告サーバーから広告をリクエストし、アプリでの広告再生を管理できます。IMA DAI SDK を使用すると、アプリは広告とコンテンツ動画(VOD またはライブ コンテンツ)のストリーム リクエストを行います。SDK は結合された動画ストリームを返すため、アプリ内で広告とコンテンツの動画を切り替える必要はありません。
関心のある DAI ソリューションを選択する
Pod Serving DAI
このガイドでは、hls.js を再生に利用する動画プレーヤーで HTML5 向け IMA DAI SDK を使用して、ライブまたは VOD コンテンツの DAI Pod Serving ストリームを再生する方法について説明します。HLS.js と Safari Playback の両方をサポートする完了済みのサンプル統合を表示またはフォローするには、HLS Pod サービングの例をご覧ください。DASH.js のサポートについては、DASH Pod サービングの例をご覧ください。これらのサンプルアプリは、HTML5 DAI GitHub リリース ページからダウンロードできます。
DAI Pod Serving の概要
IMA DAI SDK を使用してポッド サービングを実装するには、次の 2 つの主要コンポーネントが必要です。このガイドでは、これらのコンポーネントについて説明します。
PodStreamRequest
/PodVodStreamRequest
: Google の広告サーバーへのストリーム リクエストを定義するオブジェクト。リクエストではネットワーク コードを指定します。また、PodStreamRequest
にはカスタム アセットキーと、必要に応じてAPI キーも必要です。どちらにも、他のオプション パラメータが含まれています。StreamManager
: 動画ストリームと IMA DAI SDK 間の通信を処理するオブジェクト(トラッキング ピングの発行、ストリーム イベントのパブリッシャーへの転送など)。
前提条件
始める前に、次のものが必要になります。
3 つの空のファイル:
- dai.html
- dai.css
- dai.js
Python がパソコン、またはテストに使用するウェブサーバーやその他のホスト型開発環境にインストールされている
開発環境を構成する
SDK は、読み込まれたページと同じプロトコルを使用して依存関係を読み込むため、ウェブサーバーを使用してアプリをテストする必要があります。ローカルの開発用サーバーを起動する簡単な方法は、Python の組み込みサーバーを使用することです。
index.html
ファイルを含むディレクトリから次のコマンドを実行します。python -m http.server 8000
ウェブブラウザで
http://localhost:8000/
にアクセスします。Apache HTTP Server などの他のホスト型開発環境やウェブサーバーも使用できます。
動画プレーヤーを作成する
まず、dai.html を変更して、HTML5 動画要素と広告 UI 要素に使用する div を作成します。また、dai.css ファイルと dai.js ファイルを読み込み、hls.js
動画プレーヤーをインポートするために必要なタグを追加します。
次に、dai.css を変更して、ページ要素のサイズと位置を指定します。最後に、dai.js で、ストリーム リクエスト情報を保持する変数と、ページの読み込み時に実行する initPlayer()
関数を定義します。
ストリーム リクエストの定数は次のとおりです。
BACKUP_STREAM
: 広告プロセスで致命的なエラーが発生した場合に再生するバックアップ ストリームの URL。STREAM_URL
: ライブ配信でのみ使用されます。マニフェスト マニピュレータまたは連続広告配信を使用する第三者パートナーから提供された動画ストリーム URL。リクエストを行う前に、IMA DAI SDK から提供されたストリーム ID を挿入する必要があります。この場合、ストリーム URL にはプレースホルダ[[STREAMID]]
が含まれます。このプレースホルダは、リクエストを行う前にストリーム ID に置き換えられます。NETWORK_CODE
: アド マネージャー 360 アカウントのネットワーク コード。CUSTOM_ASSET_KEY
: ライブ配信でのみ使用されます。Ad Manager 360 で Pod 配信イベントを識別するカスタム アセットキー。これは、マニフェスト マニピュレータまたは第三者の Pod Serving パートナーによって作成できます。API_KEY
: ライブ配信でのみ使用されます。IMA DAI SDK からストリーム ID を取得するために必要となる場合がある、オプションの API キー。
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 Demo (HLS.JS)</h2>
<video id="video"></video>
<div id="adUi"></div>
</body>
</html>
dai.css
#video,
#adUi {
width: 640px;
height: 360px;
position: absolute;
top: 35px;
left: 0;
}
#adUi {
cursor: pointer;
}
dai.js
var BACKUP_STREAM =
'https://storage.googleapis.com/interactive-media-ads/media/bbb.m3u8'
// Stream Config.
const STREAM_URL = "";
const NETWORK_CODE = "";
const CUSTOM_ASSET_KEY = "";
const API_KEY = "";
var hls = new Hls(); // hls.js video player
var videoElement;
var adUiElement;
function initPlayer() {
videoElement = document.getElementById('video');
adUiElement = document.getElementById('adUi');
}
IMA DAI SDK を読み込む
次に、dai.html で、dai.js のタグの前にスクリプトタグを挿入して、DAI フレームワークを追加します。
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 を初期化して、ライブ ストリームまたは VOD ストリームのリクエストを行う
ライブ配信 Pod の配信
一連の広告をリクエストするには、DAI ストリームのリクエストと管理を行う ima.dai.api.StreamManager
を作成します。コンストラクタは動画要素を受け取り、結果のインスタンスは広告 UI 要素を受け取って広告のインタラクションを処理します。
次に、Pod Serving のライブストリームをリクエストする関数を定義します。この関数は、まず PodStreamRequest
を作成し、ステップ 2 で指定された streamRequest パラメータで構成してから、そのリクエスト オブジェクトを使用して streamManager.requestStream()
を呼び出します。
dai.js
function initPlayer() {
videoElement = document.getElementById('video');
adUiElement = document.getElementById('adUi');
streamManager = new google.ima.dai.api.StreamManager(videoElement, adUiElement)
requestLivePodStream(NETWORK_CODE, CUSTOM_ASSET_KEY, API_KEY);
}
function requestLivePodStream(networkCode, customAssetKey, apiKey) {
// clear HLS.js instance, if in use
if (hls) {
hls.destroy();
}
// Generate a Pod Serving live Stream Request
const streamRequest = new google.ima.dai.api.PodStreamRequest();
streamRequest.networkCode = networkCode;
streamRequest.customAssetKey = customAssetKey;
streamRequest.apiKey = apiKey;
streamRequest.format = 'hls';
streamManager.requestStream(streamRequest);
}
VOD Pod Serving
一連の広告をリクエストするには、DAI ストリームのリクエストと管理を行う ima.dai.api.StreamManager
を作成します。コンストラクタは動画要素を受け取り、結果のインスタンスは広告 UI 要素を受け取って広告のインタラクションを処理します。
次に、Pod Serving VOD ストリームをリクエストする関数を定義します。この関数は、まず PodVodStreamRequest
を作成し、ステップ 2 で指定された streamRequest パラメータで構成してから、そのリクエスト オブジェクトを使用して streamManager.requestStream()
を呼び出します。
dai.js
function initPlayer() {
videoElement = document.getElementById('video');
adUiElement = document.getElementById('adUi');
streamManager = new google.ima.dai.api.StreamManager(videoElement, adUiElement)
requestVodPodStream(NETWORK_CODE);
}
function requestVodPodStream(networkCode) {
// clear HLS.js instance, if in use
if (hls) {
hls.destroy();
}
// Generate a Pod Serving VOD Stream Request
const streamRequest = new google.ima.dai.api.PodVodStreamRequest();
streamRequest.networkCode = networkCode;
streamRequest.format = 'hls';
streamManager.requestStream(streamRequest);
}
ストリーム イベントを処理する
ライブ配信 Pod の配信
次に、主要な動画イベントのイベント リスナーを実装します。この例では、onStreamEvent()
関数を呼び出して STREAM_INITIALIZED
、ERROR
、AD_BREAK_STARTED
、AD_BREAK_ENDED
の各イベントを処理しています。この関数は、ストリームの読み込みとエラーを処理します。また、広告の再生中にプレーヤーのコントロールを無効にします。これは SDK で必要です。ストリームが読み込まれると、動画プレーヤーは loadStream()
関数を使用して、指定された URL を読み込んで再生します。
dai.js
var isAdBreak;
function initPlayer() {
videoElement = document.getElementById('video');
adUiElement = document.getElementById('adUi');
streamManager = new google.ima.dai.api.StreamManager(videoElement, adUiElement);
streamManager.addEventListener(
[google.ima.dai.api.StreamEvent.Type.STREAM_INITIALIZED,
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.STREAM_INITIALIZED:
console.log('Stream initialized');
loadStream(e.getStreamData().streamId);
break;
case google.ima.dai.api.StreamEvent.Type.ERROR:
console.log('Error loading stream, playing backup stream.' + e);
loadStream('');
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 loadStream(streamID) {
var url;
if(streamID) {
url = STREAM_URL.replace('[[STREAMID]]', streamID);
} else {
console.log('Stream Initialization Failed');
url = BACKUP_STREAM;
}
console.log('Loading:' + url);
hls.loadSource(url);
hls.attachMedia(videoElement);
}
VOD Pod Serving
次に、主要な動画イベントのイベント リスナーを実装します。この例では、onStreamEvent()
関数を呼び出して STREAM_INITIALIZED
、LOADED
、ERROR
、AD_BREAK_STARTED
、AD_BREAK_ENDED
の各イベントを処理しています。この関数は、ストリームの読み込みとエラーを処理するほか、広告の再生中にプレーヤーのコントロールを無効にします。これは SDK で必要となる処理です。
また、VOD Pod Serving ストリームでは、STREAM_INITIALIZED
イベントに応じて StreamManager.loadStreamMetadata()
を呼び出す必要があります。また、動画テクノロジー パートナー(VTP)にストリーム URL をリクエストする必要があります。loadStreamMetadata()
呼び出しが成功すると、LOADED
イベントがトリガーされます。ここで、ストリーム URL を使用して loadStream()
関数を呼び出し、ストリームを読み込んで再生する必要があります。
var isAdBreak;
function initPlayer() {
videoElement = document.getElementById('video');
adUiElement = document.getElementById('adUi');
streamManager = new google.ima.dai.api.StreamManager(videoElement, adUiElement);
streamManager.addEventListener(
[google.ima.dai.api.StreamEvent.Type.STREAM_INITIALIZED,
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.STREAM_INITIALIZED:
const streamId = e.getStreamData().streamId;
// 'vtpInterface' is a place holder for your own video technology
// partner (VTP) API calls.
vtpInterface.requestStreamURL({
'streamId': streamId,
})
.then( (vtpStreamUrl) => {
streamUrl = vtpStreamUrl;
streamManager.loadStreamMetadata();
}, (error) => {
// Handle the error.
});
break;
case google.ima.dai.api.StreamEvent.Type.LOADED:
loadStream(streamUrl);
break;
case google.ima.dai.api.StreamEvent.Type.ERROR:
console.log('Error loading stream, playing backup stream.' + e);
loadStream();
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 loadStream(url) {
if(url) {
console.log('Loading:' + url);
hls.loadSource(url);
} else {
console.log('Stream Initialization Failed');
hls.loadSource(BACKUP_STREAM);
}
hls.attachMedia(videoElement);
}
ストリーム メタデータを処理する
このステップでは、広告イベントが発生したときに SDK に通知するメタデータのイベント リスナーを実装します。ストリーム内メタデータ イベントのリスニングは、ストリーム形式(HLS または DASH)、ストリーム タイプ(ライブ ストリームまたは VOD ストリーム)、プレーヤー タイプ、使用されている DAI バックエンドのタイプによって異なります。詳しくは、Timed Metadata ガイドをご覧ください。
HLS ストリーム形式(ライブ ストリームと VOD ストリーム、HLS.js プレーヤー)
HLS.js プレーヤーを使用している場合は、HLS.js FRAG_PARSING_METADATA
イベントをリッスンして ID3 メタデータを取得し、StreamManager.processMetadata()
を使用して SDK に渡します。
すべてが読み込まれて準備が整った後に動画を自動的に再生するには、HLS.js の MANIFEST_PARSED
イベントをリッスンして再生をトリガーします。
function loadStream(streamID) {
hls.loadSource(url);
hls.attachMedia(videoElement);
// Timed metadata is passed HLS stream events to the streamManager.
hls.on(Hls.Events.FRAG_PARSING_METADATA, parseID3Events);
hls.on(Hls.Events.MANIFEST_PARSED, startPlayback);
}
function parseID3Events(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((sample) => {
streamManager.processMetadata('ID3', sample.data, sample.pts);
});
}
}
function startPlayback() {
console.log('Video Play');
videoElement.play();
}
DASH.js(DASH ストリーム形式、ライブ ストリームと VOD ストリームの種類)
DASH.js プレーヤーを使用している場合は、ライブ ストリームまたは VOD ストリームの ID3 メタデータをリッスンするために、異なる文字列を使用する必要があります。
- ライブ配信:
'https://developer.apple.com/streaming/emsg-id3'
- VOD ストリーム:
'urn:google:dai:2018'
StreamManager.processMetadata()
を使用して ID3 メタデータを SDK に渡します。
すべての読み込みが完了して準備が整った後に動画コントロールを自動的に表示するには、DASH.js の MANIFEST_LOADED
イベントをリッスンします。
const googleLiveSchema = 'https://developer.apple.com/streaming/emsg-id3';
const googleVodSchema = 'urn:google:dai:2018';
dashPlayer.on(googleLiveSchema, processMetadata);
dashPlayer.on(googleVodSchema, processMetadata);
dashPlayer.on(dashjs.MediaPlayer.events.MANIFEST_LOADED, loadlistener);
function processMetadata(metadataEvent) {
const messageData = metadataEvent.event.messageData;
const timestamp = metadataEvent.event.calculatedPresentationTime;
// Use StreamManager.processMetadata() if your video player provides raw
// ID3 tags, as with dash.js.
streamManager.processMetadata('ID3', messageData, timestamp);
}
function loadlistener() {
showControls();
// This listener must be removed, otherwise it triggers as addional
// manifests are loaded. The manifest is loaded once for the content,
// but additional manifests are loaded for upcoming ad breaks.
dashPlayer.off(dashjs.MediaPlayer.events.MANIFEST_LOADED, loadlistener);
}
ライブ ストリーム(DASH ストリーム形式)での Shaka Player
ライブ配信の再生に Shaka Player を使用している場合は、文字列 'emsg'
を使用してメタデータ イベントをリッスンします。次に、StreamManager.onTimedMetadata()
の呼び出しでイベント メッセージ データを使用します。
shakaPlayer.addEventListener('emsg', (event) => onEmsgEvent(event));
function onEmsgEvent(metadataEvent) {
// Use StreamManager.onTimedMetadata() if your video player provides
// processed metadata, as with Shaka player livestreams.
streamManager.onTimedMetadata({'TXXX': metadataEvent.detail.messageData});
}
VOD ストリーム(DASH ストリーム形式)を含む Shaka Player
VOD ストリームの再生に Shaka Player を使用している場合は、文字列 'timelineregionenter'
を使用してメタデータ イベントをリッスンします。次に、'urn:google:dai:2018'
という文字列を使用して、StreamManager.processMetadata()
の呼び出しでイベント メッセージ データを使用します。
shakaPlayer.addEventListener('timelineregionenter', (event) => onTimelineEvent(event));
function onTimelineEvent(metadataEvent) {
const detail = metadataEvent.detail;
if ( detail.eventElement.attributes &&
detail.eventElement.attributes['messageData'] &&
detail.eventElement.attributes['messageData'].value ) {
const mediaId = detail.eventElement.attributes['messageData'].value;
const pts = detail.startTime;
// Use StreamManager.processMetadata() if your video player provides raw
// ID3 tags, as with Shaka player VOD streams.
streamManager.processMetadata('urn:google:dai:2018', mediaId, pts);
}
}
プレーヤー イベントを処理する
動画要素の pause
イベントと start
イベントにイベント リスナーを追加して、広告ブレーク中に SDK が一時停止したときにユーザーが再生を再開できるようにします。
function loadStream(streamUrl) {
...
videoElement.addEventListener('pause', onStreamPause);
videoElement.addEventListener('play', onStreamPlay);
}
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 アセットをクリーンアップする
IMA DAI SDK を使用して Pod サービング ストリームで広告のリクエストと表示を正常に完了したら、Pod サービング セッションの完了後にリソースをクリーンアップすることをおすすめします。StreamManager.destroy()
を呼び出して、ストリームの再生を停止し、すべての広告トラッキングを停止して、読み込まれたすべてのストリーム アセットを解放します。
SDK の高度な機能について詳しくは、他のガイドまたは GitHub のサンプルをご覧ください。