Vegaでのクライアント側広告挿入
クライアント側広告挿入(CSAI)では、ビデオプレーヤーがコンテンツと広告再生の両方を独自に管理します。サーバーがコンテンツマニフェストに広告セグメントを差し込むサーバー側広告挿入(SSAI)とは異なり、CSAIではコンテンツストリームは変更されません。コンテンツストリームと広告ストリームの切り替えはクライアントアプリが管理します。
CSAIでは、クライアントが実行時にVideo Ad Serving Template(VAST)やVideo Multiple Ad Playlist(VMAP)などのプロトコルを使用して広告サーバーから広告を取得するため、動的な広告挿入が可能です。コンテンツストリームを変更せずに、ユーザーごと、セッションごと、コンテンツごとにリアルタイムで広告のターゲティングを設定できます。これにより、サーバー側でマニフェストを変更することなく、パーソナライズされた広告エクスペリエンスを実現できます。
CSAIでは、広告のタイミング、再生、遷移をアプリで完全に制御できます。アプリは、広告ブレークをいつトリガーするかの決定、広告プレーヤーの初期化と再生動作の制御、メインコンテンツと広告をフレーム単位で切り替える共有サーフェスの管理など、広告のライフサイクルのすべてを担います。
CSAIのテクニック
Vegaでは、広告の挿入タイミングを決定するテクニックとして、帯域外(標準)と帯域内(高度)の2つの方法をサポートしています。
標準のCSAI:帯域外広告
標準のCSAIでは、マニフェストタグではなく外部情報に基づいて、クライアントアプリが広告の挿入タイミングを決定します。プレーヤーは、変更されていないコンテンツマニフェストを受け取り、広告ロジックを別途に処理します。
広告をトリガーする方法には以下があります。
- VMAP: プレーヤーが、特定のタイムスタンプ(0秒、300秒など)に広告ブレークをスケジュールする外部XMLファイルを取得します。
- ハードコードされたロジック: アプリが、プレーヤーの現在の時間位置に基づいて一定の間隔(20秒ごとなど)で広告リクエストをトリガーします。
- サイドカーファイル: アプリが、特定のコンテンツ片に対する広告ブレーク時間のリストを含む別個の構成ファイル(JSON/XML)をコンテンツ管理システム(CMS)からダウンロードします。
- 広告SDK: SDK(Google Interactive Media Adsなど)が、広告ルールに基づいて内部でタイミングを管理します。この場合、開発者が特定のタイムスタンプやマニフェストタグを管理する必要はありません。
帯域外の一般的な実装では、UIレイヤーで広告マーカーが定義され(ハードコードやスケジュールからの取得など)、位置リスナーが挿入を直接トリガーします。サービスレイヤーには広告情報は送信されません。
高度なCSAI:帯域内広告
高度なCSAIでは、プレーヤーがマニフェストをモニタリングして、広告機会を示すインストリームメタデータマーカーを検出します。
一般的なマーカーには以下があります。
| マーカー | プロトコル |
|---|---|
#EXT-X-CUE-OUT / #EXT-X-CUE-IN |
HTTPライブストリーミング(HLS) |
#EXT-X-DATERANGE |
HLSインタースティシャル |
| SCTE(Society of Cable Telecommunications Engineers)-35信号(マニフェストタグに変換) | HLS/HTTPを介した動的適応型ストリーミング(DASH) |
プレーヤーは、マーカー(#EXT-X-CUE-OUTなど)を検出すると、それを広告の提供機会として解釈し、指定されている期間に応じて広告サーバーへのVASTリクエストまたはVMAPリクエストを開始します。広告コンテンツは、メインコンテンツが再生され続けている間に同時に取得され、バッファリングされます。メインコンテンツは、広告の表示時間に到達したときにのみ一時停止されます。この時点までには広告が再生可能な状態になっていると想定され、シームレスなエクスペリエンスが実現します。
ヘッドレスアプローチを使用する帯域内実装では、UIからsendMessage({type: 'adList', ads})を通じてサービスレイヤーに広告リストを送信して、マニフェスト解析で生成されるのと同じデータを提供できます。サービスは広告リストをPlayerSessionに格納し、getCurrentPlaybackPosition()の間に広告マーカーを処理します。広告のプレバッファリング枠に到達すると(startTimeの5秒前)、サービスはUIに{type: 'adMarkers', ad}メッセージを送り返します。これにより、広告の挿入がトリガーされます。
再生の同期戦略
どちらの実装アプローチでも、遷移中にメインプレーヤーと広告プレーヤーを調整するための2つの戦略がサポートされます。
広告の事前バッファリング(シームレス)
遷移が発生する前に、広告プレーヤーを事前に初期化してバッファリングします。これにより、視覚的な中断のないギャップレスなユーザーエクスペリエンスが提供されます。
- メインコンテンツが再生されます。
- 広告マーカーが検出されます。広告プレーヤーを事前に
autoPlay=falseとして初期化します。 - 広告プレーヤーがバッファリングを行います。
canplayイベントが生成されるか(JS)、サービスからREADYステータスが送信されます(ヘッドレス)。 - UIが準備完了のシグナルを受け取ります。広告が再生できる状態になり、スケジュールされた再生時間まで待機します。
- 位置リスナーが、広告の再生時間に到達したことを検出します。メインコンテンツを一時停止します。
- メインコンテンツが一時停止されます。メインサーフェスを消去し、広告サーフェスを設定して、広告を再生します。
- 広告が終了します。広告サーフェスを消去し、広告プレーヤーをクリーンアップします。メインサーフェスを設定し、メインコンテンツを再開します。
次の特徴があります。
- 視覚的な中断は生じません。
- 広告コンテンツは再生前にプレバッファリングされます。
- プレミアム視聴エクスペリエンスに最適です。
autoPlayをfalseに設定します(手動制御)。
広告のインスタント自動再生(ギャップあり)
広告ブレークの発生時に、オンデマンドで広告プレーヤーを初期化します。広告はautoPlay=trueを通じて再生時に読み込まれるため、広告プレーヤーの初期化時に短時間の遷移ギャップが生じることがあります。
- メインコンテンツが再生されます。
- 広告マーカーが検出されます。メインコンテンツを一時停止します。
- メインコンテンツが一時停止されます。メインサーフェスを消去し、広告プレーヤーを
autoPlay=trueとして初期化します。 - 広告プレーヤーの準備が整います。広告サーフェスを設定します。再生が自動的に開始されます。
- 広告が終了します。広告サーフェスを消去し、広告プレーヤーをクリーンアップします。メインサーフェスを設定し、メインコンテンツを再開します。
次の特徴があります。
- 遷移中に画面が一時的に黒くなったり、一時停止したりすることがあります。
- 広告はオンデマンドで読み込まれます。
- よりシンプルな実装です。
autoPlayをtrueに設定します(自動再生)。
連続広告
広告ブレークに複数の連続した広告が含まれる場合は、デバイスの性能に応じて次の3つのアプローチを使用できます。
- 単一の広告プレーヤー(リソースに制約のあるデバイス向け): 広告プレーヤーを一度に1つだけ作成して、広告を1つずつ再生します。この方法では、シームレスでギャップレスな遷移は実現できない可能性があります。メモリやデコーダーが限られているデバイスにのみ推奨されます。
- 複数の広告プレーヤー(高性能デバイス向け): 広告プレーヤーインスタンスを2つ使用して、広告を連続でシームレスに再生します。連続する広告間をギャップレスで遷移できます。十分なデバイスリソースが必要です。
- メインコンテンツプレーヤーの再作成(代替アプローチ): メインコンテンツの現在の再生位置を保存します。最後の広告の再生中にメインプレーヤーを再作成します。こうすることで、リソースに制約のあるデバイスでも2つの個別の広告プレーヤーを作成できます。
CSAIに関する課題
CSAIを実装するときは、次の課題を考慮してください。
- バッファリングと遅延: 広告がオンデマンドで読み込まれる場合(インスタント広告)、コンテンツを一時停止して広告を読み込むと、バッファリングや遅延が発生する可能性があります。これを解決するには、実際の表示時間に到達する前に広告コンテンツをプレバッファリングし、十分にバッファリングされた後にのみメインコンテンツを一時停止します。
- デバイスの互換性: デバイスのハードウェア機能(メモリ、デコーダー、処理能力)はさまざまであるため、デバイスが異なると性能も異なります。
- 単一サーフェスのレンダリング: 広告は、メインコンテンツの最後のフレームをレンダリングした後の最初のフレームから再生する必要があります。サーフェスの切り替え中にフレームの欠落や重なりが発生しないようにしてください。
実装アプローチの選択
Vegaでは、CSAIの実装方法として2つのアプローチを提供しています。アプリのアーキテクチャに合ったアプローチを選択してください。
JSアプローチ
JSアプローチでは、React Nativeコンポーネントを直接統合します。UIコンポーネントレイヤー内で、VideoPlayerインスタンスの作成と管理を行います。アプリはW3C Media APIに直接アクセスし、メソッドを直接呼び出して再生を制御します。
┌─────────────────────────────────────────────────────────┐
│ React Nativeコンポーネントレイヤー │
│ ┌──────────────────┐ ┌──────────────────┐ │
│ │ メインプレーヤー │ │ 広告プレーヤー │ │
│ │ (VideoPlayer) │ │ (VideoPlayer) │ │
│ └──────────────────┘ └──────────────────┘ │
├─────────────────────────────────────────────────────────┤
│ KeplerVideoSurfaceView(共有) │
└─────────────────────────────────────────────────────────┘
次のような場合は、この方法を使用します。
- アプリでシングルスレッドのReact Nativeアーキテクチャを使用している。
- W3C Media APIに直接アクセスする必要がある。
- コンポーネントレベルのシンプルなプレーヤー管理を利用したい。
パッケージ: @amazon-devices/react-native-w3cmedia
このアプローチを実装するには、JSアプローチを使用したクライアント側広告挿入の実装を参照してください。
ヘッドレスアプローチ
ヘッドレスアプローチでは、クライアント/サーバーアーキテクチャを使用します。UIレイヤーのIPlayerClientインスタンスが、独立したサービスレイヤーで管理されるVideoPlayerインスタンスと通信します。これはKeplerPlayerClientTurboModuleを介して行われ、高パフォーマンスのプロセス間通信(IPC)を提供するJavaScript Interface(JSI)が使用されます。
┌─────────────────────────────────────────────────────────┐
│ UIレイヤー(PlayerUI) │
│ ┌──────────────────┐ ┌──────────────────┐ │
│ │ メインプレーヤー │ │ 広告プレーヤー │ │
│ │ クライアント │ │ クライアント │ │
│ │ (IPlayerClient)│ │ (IPlayerClient)│ │
│ └────────┬─────────┘ └─────────┬────────┘ │
│ │ │ │
│ │ KeplerPlayerClientTurboModule │
│ ▼ ▼ │
├─────────────────────────────────────────────────────────┤
│ IPCブリッジ(JSI) │
├─────────────────────────────────────────────────────────┤
│ │ KeplerPlayerServerTurboModule │
│ ▼ ▼ │
│ ┌──────────────────┐ ┌──────────────────┐ │
│ │ PlayerServer │ │ PlayerServer │ │
│ │ ハンドラー │ │ ハンドラー │ │
│ └────────┬─────────┘ └─────────┬────────┘ │
│ │ │ │
│ サービスレイヤー(PlayerService - ヘッドレスJS) │
│ ┌──────────────────┐ ┌──────────────────┐ │
│ │ メインプレーヤー │ │ 広告プレーヤー │ │
│ │ セッション │ │ セッション │ │
│ │ (VideoPlayer) │ │ (VideoPlayer) │ │
│ └──────────────────┘ └──────────────────┘ │
├─────────────────────────────────────────────────────────┤
│ KeplerVideoSurfaceView(共有) │
└─────────────────────────────────────────────────────────┘
次のような場合は、この方法を使用します。
- アプリでマルチスレッドアーキテクチャを使用して、UIレイヤーとサービスレイヤーを分離している。
- JSIベースのIPCによるパフォーマンス上のメリットを必要としている。
PlayerSessionによるセッションベースのプレーヤー管理を利用したい。
パッケージ: VegaプレーヤークライアントおよびVegaプレーヤーサーバー
このアプローチを実装するには、ヘッドレスアプローチを使用したクライアント側広告挿入の実装を参照してください。
関連コンテンツ
Last updated: 2026年3月26日

