インタラクティブ メディア広告(IMA)のダイナミック広告挿入(DAI)SDK は、ストリームのメディア セグメントに埋め込まれたメタデータ情報(インバンド メタデータ)またはストリーミング マニフェスト ファイルに埋め込まれたメタデータ情報(インマニフェスト メタデータ)に依存して、視聴者の位置とクライアントサイドの広告イベントをトラッキングします。メタデータは、再生されるストリームの種類に応じて異なる形式で送信されます。
動画プレーヤーは、タイミング メタデータをバッチで受信します。プレーヤーによっては、メタデータはスケジュールされた時間に表示されるか、バッチで表示されます。各メタデータ文字列には、トリガーされるタイミングを示すプレゼンテーション タイムスタンプ(PTS)が関連付けられています。
アプリは、メタデータをキャプチャして IMA DAI SDK に転送する役割を担います。SDK には、この情報を渡すための次のメソッドが用意されています。
- onTimedMetadata
このメソッドは、処理の準備ができたメタデータ文字列を SDK に転送します。引数は 1 つです。
metadata
:google_
で始まる文字列値に関連付けられたTXXX
のキーを含むオブジェクト。
- processMetadata
このメソッドは、指定された PTS の後に SDK で処理されるメタデータ文字列をスケジュールします。次の引数を取ります。
type
: 処理中のイベントのタイプを含む文字列。指定できる値は、HLS の場合はID3
、DASH の場合はurn:google:dai:2018
です。data
:google_
で始まる文字列値、またはID3:u\0004u\000u\000u\0000TXXXu\0004u\000u\000u\0000google_xxxxxxxx
形式のバイト配列。timestamp
: データを処理するタイミングのタイムスタンプ(秒単位)。
IMA DAI SDK でサポートされている各ストリーム タイプは、次のセクションで説明するように、一意の形式のタイムド メタデータを使用します。
HLS MPEG2TS ストリーム
MPEG2TS セグメントを使用するリニア DAI HLS ストリームは、インバンド ID3 タグを介して、タイムド メタデータを動画プレーヤーに渡します。これらの ID3 タグは MPEG2TS セグメント内に埋め込まれ、TXXX フィールド名(カスタムのユーザー定義テキスト コンテンツ用)が付けられます。
Safari での再生
Safari は ID3 タグを非表示トラックとして自動的に処理するため、キューチェンジ イベントが正しいタイミングで発生し、各メタデータが処理されます。コンテンツやタイプに関係なく、すべてのメタデータを IMA DAI SDK に渡しても問題ありません。無関係なメタデータは自動的に除外されます。
次の例をご覧ください。
videoElement.textTracks.addEventListener('addtrack', (e) => {
const track = e.track;
if (track.kind === 'metadata') {
track.mode = 'hidden';
track.addEventListener('cuechange', () => {
for (const cue of track.activeCues) {
const metadata = {};
metadata[cue.value.key] = cue.value.data;
streamManager.onTimedMetadata(metadata);
}
});
}
});
...
HLS.js
HLS.js は、FRAG_PARSING_METADATA
イベントを介して ID3 タグをバッチでサンプル配列として提供します。HLS.js は、ID3 データをバイト配列から文字列に変換せず、イベントを対応する PTS にオフセットしません。IMA DAI SDK がこのデコードとフィルタリングを自動的に行うため、サンプルデータをバイト配列から文字列にデコードしたり、無関係な ID3 タグをフィルタで除外したりする必要はありません。
次の例をご覧ください。
hls.on(Hls.Events.FRAG_PARSING_METADATA, (e, data) => {
if (streamManager && data) {
data.samples.forEach((sample) => {
streamManager.processMetadata('ID3', sample.data, sample.pts);
});
}
});
...
HLS CMAF ストリーム
Common Media Application Framework(CMAF)を使用するリニア DAI HLS ストリームは、CMAF を介した ID3 標準に沿って、インバンド eMSGv1 ボックスでタイムド メタデータを渡します。これらの eMSG ボックスは各メディア セグメントの先頭に埋め込まれ、各 ID3 eMSG にはストリームの最後の不連続点からの相対的な PTS が含まれます。
HLS.js の 1.2.0 リリース以降、推奨される両方のプレーヤーが、ID3 タグであるかのように ID3 を CMAF 経由でユーザーに渡します。そのため、次の例は HLS MPEG2TS ストリームの場合と同じです。ただし、すべてのプレーヤーがそうであるとは限らないため、HLS CMAF ストリームのサポートを実装するには、eMSG を介して ID3 を解析する独自のコードが必要になる可能性があります。
Safari での再生
Safari は、eMSG メタデータを介した ID3 を疑似 ID3 イベントとして扱い、非表示トラックとしてバッチで自動的に提供します。これにより、各メタデータを処理するために cuechange イベントが適切なタイミングで発生します。タイミングに関連するかどうかに関係なく、すべてのメタデータを IMA DAI SDK に渡しても問題ありません。DAI 関連以外のメタデータは自動的にフィルタされます。
次の例をご覧ください。
videoElement.textTracks.addEventListener('addtrack', (e) => {
const track = e.track;
if (track.kind === 'metadata') {
track.mode = 'hidden';
track.addEventListener('cuechange', () => {
for (const cue of track.activeCues) {
const metadata = {};
metadata[cue.value.key] = cue.value.data;
streamManager.onTimedMetadata(metadata);
}
});
}
});
...
HLS.js
バージョン 1.2.0 以降、HLS.js は eMSG メタデータ内の ID3 を疑似 ID3 イベントとして扱い、FRAG_PARSING_METADATA
イベントを介してサンプル配列としてバッチで提供します。HLS.js は、ID3 データをバイト配列から文字列に変換せず、イベントを対応する PTS にオフセットしません。IMA DAI SDK がこのデコードを自動的に行うため、サンプルデータをバイト配列から文字列にデコードする必要はありません。
次の例をご覧ください。
hls.on(Hls.Events.FRAG_PARSING_METADATA, (e, data) => {
if (streamManager && data) {
data.samples.forEach((sample) => {
streamManager.processMetadata('ID3', sample.data, sample.pts);
});
}
});
...
DASH ストリーム
リニア DAI DASH ストリームは、カスタム schemeIdUri
値 urn:google:dai:2018
を含むイベント ストリーム内のマニフェスト イベントとしてメタデータを渡します。これらのストリームの各イベントには、テキスト ペイロードと PTS が含まれています。
DASH.js
Dash.js は、各イベント ストリームの schemeIdUri 値にちなんで名付けられたカスタム イベント ハンドラを提供します。これらのカスタム ハンドラはバッチで起動されるため、イベントのタイミングを適切に調整するには、PTS 値を処理する必要があります。IMA DAI SDK では、streamManager メソッド processMetadata()
を使用して、この処理を行うことができます。
次の例をご覧ください。
const dash = dashjs.MediaPlayer().create();
dash.on('urn:google:dai:2018', (payload) => {
const mediaId = payload.event.messageData;
const pts = payload.event.calculatedPresentationTime;
streamManager.processMetadata('urn:google:dai:2018', mediaId, pts);
});
...
Shaka Player
Shaka Player は、timelineregionenter
イベントの一部としてイベントを公開します。Shaka Player との形式の互換性がないため、メタデータ値は詳細プロパティ eventNode.attributes['messageData']
を介して未加工の状態で取得する必要があります。
次の例をご覧ください。
player.addEventListener('timelineregionenter', function(event) {
const detail = event.detail;
if ( detail.eventNode.attributes &&
detail.eventNode.attributes['messageData']) {
const mediaId = detail.eventNode.attributes['messageData'];
const pts = detail.startTime;
streamManager.processMetadata("urn:google:dai:2018", mediaId, pts);
}
});
...
広告連続配信
Pod サービングでは、次の条件に応じて、タイムド メタデータを渡すための構成が異なります。
- ライブ ストリームまたは VOD ストリームのタイプ
- HLS または DASH ストリーム形式
- 使用されているプレーヤーの種類
- 使用されている DAI バックエンドのタイプ
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);
}
}