概要
IMA DAI SDK は、Web ページやアプリに依存せず、動画コンテンツと広告を 1 つのストリームに結合し、広告リクエストおよび広告レスポンスのプロセスを SDK から取り除きます。これにより、クライアント側のエラー発生の可能性が減り、コンテンツと広告の間にレイテンシーやバッファリングのない、シームレスなテレビのような体験を実現します。
IMA DAI SDK を使用すると、ライブ リニアおよびビデオ オン デマンド番組向けに個別の広告をターゲティングし、幅広いデバイス サポートでマルチスクリーン リーチを獲得し、Ad Exchange for Video によりすべてのデバイスでプログラマティック収益化を活用できます。
コンテンツの元のフォーマットに関係なく、デジタル化されると、DAI は視聴している個々のユーザーに基づいて、カスタムにターゲット化された動画広告をストリームに結合できます。
バッファリングとレイテンシーを最小限に抑え、広告が適切なフォーマットでレンダリングされることを保証するため、視聴者は期待どおりの放送品質の体験を得られます。
要件
- Ad Manager 360 Advanced アカウントを保有していること。
機能
- シームレスで放送のような視聴体験を提供します。
- 広告がどのネットワークでホストされているかに関わらず、ストリームは Ad Manager サーバー上で結合されます。
Players モジュールを使用した実装 - Plugins セクション
- PLAYERS モジュールを開き、新しいプレーヤーを作成するか、プラグインを追加したいプレーヤーを選択します。
- プレーヤーのリンクを選択して、プレーヤーのプロパティを開きます。
- Overview タブの Plugins セクションを展開します。
-
次に、Add Plugin ボタンを選択し、Brightcove Plugin を選択します。
-
Brightcove Plugin ドロップダウンを展開し、IMA DAI を選択します。
-
Save ボタンを選択します。プレーヤーのプラグイン リストに IMA DAI プラグインが追加されたのを確認できます。
- プレーヤーを公開するには、Publish Changes を選択します。
- 開いているダイアログを閉じるには、Close を選択します。
JSON Editor による実装
プレーヤー 7.21.0 以降では、JSON エディターを使用してプラグインを追加するために以下の手順に従うこともできます。
Players モジュールで、設定するプレーヤーに移動します。Overview タブの JSON Editor セクションを展開します。
"plugins" 配列を変更して、IMA DAI プラグインを追加します。
"plugins": [
{
"name": "imaDai",
"is_packaged": true,
"options": {
...
}
}
]
コードによる実装
IMA DAI プラグインを初期化するには、以下の手順に従ってください。
IMA DAI プラグイン クラスを取得します。
const ImaDaiPlugin = videojs.getPlugin('imaDai');bc プレーヤーを初期化します。
const videoId = 'ima-dai-player'; const player = bc(videoId);IMA DAI プラグインを初期化します。
const imaDai = player.imaDai();IMA_DAI_SDK_LOADEDイベントをリッスンします。imaDai.one(ImaDaiPlugin.EVENTS.IMA_DAI_SDK_LOADED, ({ imaDaiSdk }) => { // The IMA DAI SDK is now ready, and you can send a stream request. });StreamRequest インスタンスを作成します。
streamRequestは、LiveStreamRequest、VODStreamRequest、PodStreamRequestのいずれかのクラスである必要があります。const streamRequest = new VODStreamRequest();フォールバック ストリームを提供します。IMA DAI ストリーム リクエストにはフォールバックが必要です。IMA DAI SDK がストリームの取得に失敗した場合、プレーヤーはこのフォールバック ストリームを使用します。
const fallback = { type: 'your-fallback-type', src: 'your-fallback-src' };プレーヤーのソースを設定します。
player.src({ type: fallback.type, src: fallback.src, imaDai: { streamRequest } });VOD ストリーム リクエスト:
// ... imaDai.one(ImaDaiPlugin.EVENTS.IMA_DAI_SDK_LOADED, ({ imaDaiSdk }) => { const { VODStreamRequest } = imaDaiSdk; const streamRequest = new VODStreamRequest(); streamRequest.videoId = 'tears-of-steel'; streamRequest.contentSourceId = '2528370'; const fallback = { type: 'application/x-mpegURL', src: 'https://bitmovin-a.akamaihd.net/content/sintel/hls/playlist.m3u8' }; player.src({ type: fallback.type, src: fallback.src, imaDai: { streamRequest } }); }); // ...ライブ ストリーム リクエスト:
// ... imaDai.one(ImaDaiPlugin.EVENTS.IMA_DAI_SDK_LOADED, ({ imaDaiSdk }) => { const { LiveStreamRequest } = imaDaiSdk; const streamRequest = new LiveStreamRequest(); streamRequest.assetKey = 'c-rArva4ShKVIAkNfy6HUQ'; const fallback = { type: 'application/x-mpegURL', src: 'https://bitmovin-a.akamaihd.net/content/sintel/hls/playlist.m3u8' }; player.src({ type: fallback.type, src: fallback.src, imaDai: { streamRequest } }); }); // ...Pod 配信ストリーム リクエスト:
// ... imaDai.one(ImaDaiPlugin.EVENTS.IMA_DAI_SDK_LOADED, ({ imaDaiSdk }) => { const { PodStreamRequest } = imaDaiSdk; const streamRequest = new PodStreamRequest(); streamRequest.networkCode = '51636543'; streamRequest.customAssetKey = 'google-sample'; streamRequest.apiKey = ''; // Pod stream request requires podSourceResolver const podStreamUrl = 'https://encodersim.sandbox.google.com/masterPlaylist/9c654d63-5373-4673-8c8d-6d92b66b9d46/master.m3u8?gen-seg-redirect=true&network=51636543&event=google-sample&pids=devrel4628000,devrel896000,devrel3528000,devrel1428000,devrel2628000,devrel1928000&seg-host=dai.google.com&stream_id=[[STREAMID]]'; const podSourceResolver = (streamId) => { const src = podStreamUrl.replace('[[STREAMID]]', streamId); const type = 'application/x-mpegURL'; return { src, type }; }; const fallback = { type: 'application/x-mpegURL', src: 'https://bitmovin-a.akamaihd.net/content/sintel/hls/playlist.m3u8' }; player.src({ type: fallback.type, src: fallback.src, imaDai: { streamRequest, podSourceResolver } }); }); // ...
最終的なコード
const ImaDaiPlugin = videojs.getPlugin('imaDai');
const videoId = 'ima-dai-player';
const player = bc(videoId);
const imaDai = player.imaDai();
imaDai.one(ImaDaiPlugin.EVENTS.IMA_DAI_SDK_LOADED, ({ imaDaiSdk }) => {
const streamRequest = new VODStreamRequest();
const fallback = { type: 'your-fallback-type', src: 'your-fallback-src' };
player.src({
type: fallback.type,
src: fallback.src,
imaDai: { streamRequest }
});
});
ストリーム リクエストの例:
Open Measurement
IMA SDK for HTML5 には、Interactive Advertising Bureau(IAB)が開発した業界標準である Open Measurement(OM)SDK が含まれており、サードパーティによるビューアビリティおよび検証測定を可能にします。IMA SDK for HTML5 を使用する場合、含まれる OM SDK は VAST 広告タグ内のタグを自動的に解析し、OMID API を介して指定された測定ベンダーにビューアビリティ データを送信します。検証スクリプトがアクセスできるコンテンツを制御するために、各リクエストにアクセス モード ルールをオプションで設定できます。詳細を見る
アクセス モード Open Measurement SDK は、検証スクリプトをさまざまなアクセス モードで実行することをサポートしており、検証スクリプトがどの程度アクセスできるかを制御します。4 つのアクセス モードは次のとおりです。
FULL: 検証スクリプトはクリエイティブとパブリッシャー ページに直接アクセスできます。CREATIVE: 検証スクリプトとクリエイティブはパブリッシャー ページからサンドボックス化されています。ただし、スクリプトはクリエイティブに直接アクセスできます。DOMAIN: 検証スクリプトはサンドボックス化されており、クリエイティブやパブリッシャー ページにアクセスできません。ただし、スクリプトは、どのパブリッシャー ドメイン上にあるかを直接確認できる方法で読み込まれます。LIMITED: 検証スクリプトはサンドボックス化されており、クリエイティブやパブリッシャー ページにアクセスできず、どのパブリッシャー ドメイン上にあるかも直接確認できません。
異なる検証スクリプト プロバイダー向けにリクエストのアクセス モード ルールを設定する方法の例を以下に示します。
// ...
imaDai.one(ImaDaiPlugin.EVENTS.IMA_DAI_SDK_LOADED, ({ imaDaiSdk }) => {
const { LiveStreamRequest } = imaDaiSdk;
const streamRequest = new LiveStreamRequest();
streamRequest.assetKey = 'c-rArva4ShKVIAkNfy6HUQ';
streamRequest.omidAccessModeRules = {};
// set full access mode for goole:
streamRequest.omidAccessModeRules[google.ima.OmidVerificationVendor.GOOGLE] = google.ima.OmidAccessMode.FULL;
// set domain acess mode for other verfication script provider:
streamRequest.omidAccessModeRules[google.ima.OmidVerificationVendor.OTHER] = google.ima.OmidAccessMode.DOMAIN;
const fallback = {
type: 'application/x-mpegURL',
src: 'https://bitmovin-a.akamaihd.net/content/sintel/hls/playlist.m3u8'
};
player.src({
type: fallback.type,
src: fallback.src,
imaDai: { streamRequest }
});
});
// ...
プライバシー
CCPA
パブリッシャーが California Consumer Privacy Act(CCPA)に準拠しやすくするために、Google Interactive Media Ads SDK は、Google が制限付きデータ処理(RDP)を有効にするかどうかを示す 2 つの異なるパラメーターをパブリッシャーが使用できるようにします。SDK は、以下のパラメーターを利用して、広告リクエスト レベルで RDP を設定する機能をパブリッシャーに提供します。
- RDP シグナル
- IAB シグナル
RDP シグナル
Google のシグナルを使用して RDP を有効にすることを Google に通知するには、次の例のように、広告タグ パラメーターに rdp=1 を追加します。
// ...
imaDai.one(ImaDaiPlugin.EVENTS.IMA_DAI_SDK_LOADED, ({ imaDaiSdk }) => {
const { LiveStreamRequest } = imaDaiSdk;
const streamRequest = new LiveStreamRequest();
streamRequest.assetKey = 'c-rArva4ShKVIAkNfy6HUQ';
// RDP signal:
streamRequest.adTagParameters = {"rdp": 1};
const fallback = {
type: 'application/x-mpegURL',
src: 'https://bitmovin-a.akamaihd.net/content/sintel/hls/playlist.m3u8'
};
player.src({
type: fallback.type,
src: fallback.src,
imaDai: { streamRequest }
});
});
// ...
IAB シグナル
IAB のシグナルを使用して RDP を有効にすることを Google に通知するには、広告タグ パラメーター us_privacy を使用します。以下のスニペットは、IAB パラメーター "1YNN" で広告リクエストを作成する方法を示しています。
// ...
imaDai.one(ImaDaiPlugin.EVENTS.IMA_DAI_SDK_LOADED, ({ imaDaiSdk }) => {
const { LiveStreamRequest } = imaDaiSdk;
const streamRequest = new LiveStreamRequest();
streamRequest.assetKey = 'c-rArva4ShKVIAkNfy6HUQ';
// IAB signal:
streamRequest.adTagParameters = {"us_privacy": "1YNN"};
const fallback = {
type: 'application/x-mpegURL',
src: 'https://bitmovin-a.akamaihd.net/content/sintel/hls/playlist.m3u8'
};
player.src({
type: fallback.type,
src: fallback.src,
imaDai: { streamRequest }
});
});
// ...
GDPR
Google の更新された EU ユーザー同意ポリシーに基づき、欧州経済領域(EEA)のユーザーに対して特定の開示を行い、法的に必要な場合は Cookie やその他のローカル ストレージの使用、および広告のパーソナライゼーションのための個人データの収集、共有、使用について同意を得る必要があります。このポリシーは、EU の e プライバシー指令および一般データ保護規則(GDPR)の要件を反映しています。詳細を見る。
パーソナライズされていない広告を強制する
パーソナライズされていない広告コンテンツのみを指定するには、広告タグに npa=1 を追加します。
// ...
imaDai.one(ImaDaiPlugin.EVENTS.IMA_DAI_SDK_LOADED, ({ imaDaiSdk }) => {
const { LiveStreamRequest } = imaDaiSdk;
const streamRequest = new LiveStreamRequest();
streamRequest.assetKey = 'c-rArva4ShKVIAkNfy6HUQ';
// Force non-personalized ads:
streamRequest.adTagParameters = {"npa": 1};
const fallback = {
type: 'application/x-mpegURL',
src: 'https://bitmovin-a.akamaihd.net/content/sintel/hls/playlist.m3u8'
};
player.src({
type: fallback.type,
src: fallback.src,
imaDai: { streamRequest }
});
});
// ...
同意年齢未満としてのユーザーのタグ付け
このパラメーターは、その特定の広告リクエストに対して、リマーケティングを含むパーソナライズド広告を無効にします。また、広告測定ピクセルやサードパーティ広告サーバーなど、サードパーティの広告ベンダーへのリクエストも無効にします。実装から行われるすべての広告リクエストにこのタグを含めるには、広告タグに tfua=1 を追加します。
// ...
imaDai.one(ImaDaiPlugin.EVENTS.IMA_DAI_SDK_LOADED, ({ imaDaiSdk }) => {
const { LiveStreamRequest } = imaDaiSdk;
const streamRequest = new LiveStreamRequest();
streamRequest.assetKey = 'c-rArva4ShKVIAkNfy6HUQ';
// Tagging users as under the age of consent:
streamRequest.adTagParameters = {"tfua": 1};
const fallback = {
type: 'application/x-mpegURL',
src: 'https://bitmovin-a.akamaihd.net/content/sintel/hls/playlist.m3u8'
};
player.src({
type: fallback.type,
src: fallback.src,
imaDai: { streamRequest }
});
});
// ...
主な概念
ストリーム時間と相対時間
サーバー側広告挿入(SSAI)を使用する場合、広告とコンテンツは 1 つのストリームに結合されます。
ストリームは 1 つしかないため、時間を理解する方法を作成する必要があります。
- ストリーム時間(または絶対時間): ストリーム全体における時間です。
- 相対時間: 現在再生されているもの(広告かコンテンツか)に依存します。
- 広告を再生している場合、相対時間はその特定の広告内の時間です。
- コンテンツを再生している場合、相対時間はコンテンツ内の時間です。
例:
この 70 秒のストリームでは、広告は 30 秒、コンテンツは 40 秒を占めています。
- 絶対時間の長さ = 70 秒
- 相対時間の長さ(コンテンツ)= 40 秒
- 相対時間の長さ(各広告)= 各個別広告の長さ(10 秒、5 秒など)
スナップバック
スナップバックは、ユーザーがシークして通り過ぎた広告ブレイクの先頭にユーザーを戻し、その広告ブレイクの終了後にシーク先の場所に戻す機能です。詳細を見る。
オプション
| オプション | 説明 | デフォルト値 |
|---|---|---|
debug |
true の場合、デバッグ メッセージを有効にし、追加情報をログに記録します。 | false |
sdkUrl |
セルフホストされた IMA DAI SDK の URL。 | //imasdk.googleapis.com/js/sdkloader/ima3_dai.js |
hideOverlays |
true の場合、広告再生中にオーバーレイを非表示にします。 | false |
静的メンバー
| メンバー | 説明 | 型 | 使用例 |
|---|---|---|---|
DEFAULTS |
使用可能なプラグイン オプションとそのデフォルト値を含むオブジェクト。 | Record<string, any> |
console.log(ImaDaiPlugin.DEFAULTS); |
VERSION |
現在のプラグインのバージョン。 | string |
console.log(ImaDaiPlugin.VERSION); |
EVENTS |
使用可能なプラグイン イベントを含むオブジェクト。 | Record<string, string> |
console.log(ImaDaiPlugin.EVENTS); |
SOURCE_TYPES |
使用可能なプラグイン ソース タイプを含むオブジェクト。 | Record<string, string> |
console.log(ImaDaiPlugin.SOURCE_TYPES); |
インスタンス ゲッター
| ゲッター | 説明 | 型 | 使用例 |
|---|---|---|---|
options |
IMA DAI プラグイン インスタンスの現在のオプションのゲッター。 | Options |
console.log(imaDai.options); |
isImaDaiStream |
IMA DAI ストリームが再生中かどうかを確認します。再生中の場合は true、それ以外の場合は false を返します。 | boolean |
console.log(imaDai.isImaDaiStream); |
contentDuration |
コンテンツの長さ(広告なし)のゲッター。 | number |
console.log(imaDai.contentDuration); |
relativeDuration |
広告モードの場合は現在の広告の長さを取得し、それ以外の場合は広告なしのコンテンツの長さを取得します。 | number |
console.log(imaDai.relativeDuration); |
canSeekNow |
現在シークを実行できるかどうかを確認します。 | boolean |
console.log(imaDai.canSeekNow); |
relativeCurrentTime |
広告モードの場合は現在の広告の現在の時間を取得し、それ以外の場合は現在のコンテンツの時間(広告なし)を取得します。 | number |
console.log(imaDai.relativeCurrentTime); |
totalAdsDuration |
既知のすべての広告の合計の長さを取得します(VOD のみ適用可能)。 | number |
console.log(imaDai.totalAdsDuration); |
インスタンス メソッド
| メソッド | 説明 | 型 | 使用例 |
|---|---|---|---|
updateOptions |
プラグインのオプションを更新します。 | (receivedOptions: Record<string, any>) => void |
imaDai.updateOptions({}); |
streamTimeForContentTime |
指定されたコンテンツ時間を、広告を含むストリーム時間に変換します。 | (contentTime: number) => number |
console.log(imaDai.streamTimeForContentTime(contentTime)); |
contentTimeForStreamTime |
指定されたストリーム時間を、広告なしのコンテンツ時間に変換します。 | (streamTime: number) => number |
console.log(imaDai.contentTimeForStreamTime(streamTime)); |
replaceAdTagParameters |
ライブ ストリームの今後の広告リクエストに使用されるすべての広告タグ パラメーターを置き換えます。 | (adTagParameters: Object|null) => void/code> |
imaDai.replaceAdTagParameters(new_adTagParameters) |
イベント
| イベント | 説明 | 値 | 使用例 |
|---|---|---|---|
IMA_DAI_SDK_LOADED |
IMA DAI SDK の読み込みが完了したときにトリガーされるイベント。 | 'imaDai:imaDaiSdkLoaded' |
imaDai.on(ImaDaiPlugin.EVENTS.IMA_DAI_SDK_LOADED, ({ imaDaiSdk }) => { ... }); |