1. 概要

この Codelab では、Cast Ad Breaks API を使用するカスタム ウェブ レシーバー アプリを構築する方法について説明します。
Google Cast とは
Google Cast では、ユーザーはモバイル デバイスからテレビにコンテンツをキャストできます。ユーザーは自分のモバイル デバイスをリモコンとして使い、テレビでのメディア再生を行うことが可能です。
Google Cast SDK を使うと、アプリを拡張してテレビやサウンド システムを制御できます。Cast SDK では、Google Cast デザイン チェックリストに沿って、必要な UI コンポーネントを追加できます。
Google Cast デザイン チェックリストは、キャストの実装を標準化し、サポートされているすべてのプラットフォームでユーザー エクスペリエンスを直感的なものにするために設けられています。
達成目標
この Codelab を完了すると、Break API を活用する Cast レシーバーが作成されます。
学習内容
- キャスト用のコンテンツに VMAP と VAST のブレークを含める方法
- 休憩クリップをスキップする方法
- シーク時のデフォルトのブレーク動作をカスタマイズする方法
必要なもの
- 最新の Google Chrome ブラウザ。
- Firebase Hosting や ngrok などの HTTPS ホスティング サービス。
- インターネットに接続できる Chromecast や Android TV などの Google Cast デバイス。
- HDMI 入力対応のテレビまたはモニター、または Google Nest Hub
エクスペリエンス
この Codelab を進める前に、次の経験があることを確認してください。
- 一般的なウェブ開発の知識。
- Cast ウェブ レシーバー アプリケーションの構築。
このチュートリアルの利用方法をお選びください。
ウェブアプリ作成のご経験についてお答えください。
2. サンプルコードを取得する
すべてのサンプルコードをパソコンにダウンロードできます。
ダウンロードした ZIP ファイルを解凍します。
3. ローカルでレシーバーをデプロイする
キャスト デバイスでウェブ レシーバーを使用するには、キャスト デバイスからアクセスできる場所でウェブ レシーバーをホストする必要があります。HTTPS に対応しているサーバーを使用できる場合は、次の手順をスキップして、サーバーの URL をメモしておきます。この情報は次のセクションで必要になります。
使用できるサーバーがない場合は、Firebase Hosting または ngrok を使用できます。
サーバーを実行する
選択したサービスを設定したら、app-start に移動してサーバーを起動します。
ホスト型レシーバの URL をメモします。これは次のセクションで使用します。
4. Cast Developer Console でアプリを登録する
この Codelab で作成するカスタム レシーバーを Chromecast デバイスで実行できるようにするには、アプリの登録が必要です。アプリを登録すると、アプリ ID が生成されます。センダーアプリでウェブ レシーバー アプリを起動するには、この ID を設定する必要があります。
![[Add New Application] ボタンがハイライト表示された Google Cast SDK デベロッパー コンソールの画像](https://google-developers.gonglchuangl.net/static/cast/codelabs/cast-ads-receiver/img/d8b39f5d33d33db4.png?authuser=2&hl=ja)
[Add new application](新しいアプリを追加)をクリックします。
![[カスタム レシーバ] オプションがハイライト表示された [New Receiver Application] 画面の画像](https://google-developers.gonglchuangl.net/static/cast/codelabs/cast-ads-receiver/img/e8c19e57b85c7d.png?authuser=2&hl=ja)
[Custom Receiver(カスタム レシーバー)] を選択します(これを今から作成します)。
![[新しいカスタム レシーバ] 画面の画像。[レシーバ アプリケーション URL] フィールドに URL が入力されている](https://google-developers.gonglchuangl.net/static/cast/codelabs/cast-ads-receiver/img/bf364a7d382e3c58.png?authuser=2&hl=ja)
新しいレシーバーの詳細を入力します。ウェブ レシーバ アプリケーションをホストする予定の場所を指す URL を必ず使用してください。アプリケーションを登録すると、コンソールによってアプリケーション ID が生成されます。この ID をメモしておきます。送信側アプリケーションは、後のセクションでその識別子を使用するように構成されます。
また、Google Cast デバイスを登録して、公開前のレシーバー アプリにアクセスできるようにしておく必要があります。レシーバー アプリを公開した後は、すべての Google Cast デバイスからアクセスできるようになります。この Codelab では、公開していないレシーバー アプリを使用することをおすすめします。
![[新しいデバイスを追加] ボタンがハイライト表示された Google Cast SDK Developer Console の画像](https://google-developers.gonglchuangl.net/static/cast/codelabs/cast-ads-receiver/img/a446325da6ebd627.png?authuser=2&hl=ja)
[Add new Device(新しいデバイスを追加)] をクリックします。
![[Add Cast Receiver Device] ダイアログの画像](https://google-developers.gonglchuangl.net/static/cast/codelabs/cast-ads-receiver/img/a21355793a3f4cd5.png?authuser=2&hl=ja)
キャスト デバイスの背面に記載されているシリアル番号を入力し、わかりやすい名前を付けます。シリアル番号は、Google Cast SDK Developer Console へのアクセス時に Chrome で画面をキャストして確認することもできます。
レシーバーとデバイスをテストする準備ができるまでには 5 ~ 15 分かかります。5 ~ 15 分待ってから、キャスト デバイスを再起動します。
5. 開始用プロジェクトを準備する
この Codelab を始める前に、広告ブレーク API の概要を説明している広告デベロッパー ガイドを確認しておくとよいでしょう。
ダウンロードした開始用アプリを Google Cast 対応にする必要があります。この Codelab で使用する Google Cast の用語は以下のとおりです。
- 送信側アプリはモバイル デバイスやノートパソコンで動作します。
- レシーバー アプリは Google Cast デバイスで動作します。
お好きなテキスト エディタを使用して、開始用プロジェクトを基に作業する準備を行います。
- ダウンロードしたサンプルコードの

app-startディレクトリを選択します。 js/receiver.jsと index.html を開きます。
この Codelab の作業を進めていくと、選択したウェブホスティング ソリューションに変更が自動的に適用されます。検証とテストを続行する際は、変更をホストサイトにプッシュしていることを確認してください。
アプリの設計
前述のとおり、この Codelab では、センダー アプリケーションを使用して Cast セッションを開始し、広告ブレーク API を使用するように変更するレシーバー アプリケーションを使用します。
この Codelab では、Cast and Command Tool がウェブ送信者として機能し、レシーバー アプリを起動します。まず、Chrome ブラウザでツールを開きます。Cast SDK デベロッパー コンソールで指定されたレシーバー アプリ ID を入力し、[設定] をクリックして、テスト用の送信側アプリを構成します。
注: キャスト アイコンが表示されない場合は、Web レシーバとキャスト デバイスが Cast Developer Console に正しく登録されていることを確認してください。まだ行っていない場合は、登録したばかりのキャスト デバイスの電源を入れ直します。
この Codelab の主な焦点はレシーバー アプリです。レシーバー アプリは、index.html で定義されるメインビューと、js/receiver.js という JavaScript ファイルで構成されます。これらについては、以下で詳しく説明します。
index.html
この HTML ファイルには、cast-media-player 要素によって提供されるレシーバー アプリの UI が含まれています。また、CAF SDK と Cast Debug Logger ライブラリも読み込みます。
receiver.js
このスクリプトは、レシーバー アプリのすべてのロジックを管理します。現在のところ、キャスト コンテキストを初期化し、初期化時に動画アセットを読み込む基本的な CAF レシーバーが含まれています。また、Cast と Command ツールにロギングを戻すためのデバッグ ロガー機能も追加されています。
6. コンテンツに VMAP を追加する
Cast Web Receiver SDK は、VMAP とも呼ばれる Digital Video Multiple Ad Playlists で指定された広告をサポートしています。XML 構造では、メディアのミッドロール挿入点と、関連するミッドロール挿入点クリップのメタデータを指定します。これらの広告を挿入するために、SDK は MediaInformation オブジェクトに vmapAdsRequest プロパティを提供します。
js/receiver.js ファイルで、VastAdsRequest オブジェクトを作成します。読み込みリクエスト インターセプタ関数を見つけて、次のコードに置き換えます。このタグには、DoubleClick のサンプル VMAP タグ URL が含まれており、ランダムな相関子の値が提供されています。これにより、同じ URL への後続のリクエストで、まだ視聴されていない広告ブレークを含む XML テンプレートが生成されます。
playerManager.setMessageInterceptor(
cast.framework.messages.MessageType.LOAD, (loadRequestData) => {
castDebugLogger.info('MyAPP.LOG', 'Intercepting LOAD request');
// Create the VMAP Ads request data and append it to the MediaInformation.
const vmapUrl =
'https://pubads.g.doubleclick.net/gampad/ads?sz=640x480&iu=/124319096/external/ad_rule_samples&ciu_szs=300x250&ad_rule=1&impl=s&gdfp_req=1&env=vp&output=vmap&unviewed_position_start=1&cust_params=deployment%3Ddevsite%26sample_ar%3Dpremidpost&cmsid=496&vid=short_onecue&correlator=' +
Math.floor(Math.random() * Math.pow(10, 10));
let vmapRequest = new cast.framework.messages.VastAdsRequest();
vmapRequest.adTagUrl = vmapUrl;
loadRequestData.media.vmapAdsRequest = vmapRequest;
castDebugLogger.warn(
'MyAPP.LOG', 'Playable URL: ' + loadRequestData.media.contentId);
return loadRequestData;
});
js/receiver.js への変更を保存し、ファイルをウェブサーバーにアップロードします。キャスト アイコンをクリックして、キャストとコマンド ツールでキャスト セッションを開始します。VMAP 広告が再生され、その後メイン コンテンツが再生される必要があります。
7. コンテンツに VAST を追加する
前述のように、Web Receiver SDK ではさまざまな種類の広告がサポートされています。このセクションでは、VAST とも呼ばれる Digital Video Ad Serving Template 広告を統合するために使用できる API について説明します。前のセクションの VMAP コードを実装している場合は、コメントアウトします。
次のコードをコピーして、js/receiver.js ファイルの読み込みリクエスト インターセプタの後ろに貼り付けます。これには、DoubleClick の 6 つの VAST ブレーク クリップとランダムな相関子の値が含まれています。これらのブレイク クリップは 5 つのブレイクに割り当てられます。各ブレークの position は、メイン コンテンツを基準とした秒単位の時間に設定されます。これには、プレロール(position が 0 に設定)とポストロール(position が -1 に設定)のブレークが含まれます。
const addVASTBreaksToMedia = (mediaInformation) => {
mediaInformation.breakClips = [
{
id: 'bc1',
title: 'bc1 (Pre-roll)',
vastAdsRequest: {
adTagUrl: generateVastUrl('preroll')
}
},
{
id: 'bc2',
title: 'bc2 (Mid-roll)',
vastAdsRequest: {
adTagUrl: generateVastUrl('midroll')
}
},
{
id: 'bc3',
title: 'bc3 (Mid-roll)',
vastAdsRequest: {
adTagUrl: generateVastUrl('midroll')
}
},
{
id: 'bc4',
title: 'bc4 (Mid-roll)',
vastAdsRequest: {
adTagUrl: generateVastUrl('midroll')
}
},
{
id: 'bc5',
title: 'bc5 (Mid-roll)',
vastAdsRequest: {
adTagUrl: generateVastUrl('midroll')
}
},
{
id: 'bc6',
title: 'bc6 (Post-roll)',
vastAdsRequest: {
adTagUrl: generateVastUrl('postroll')
}
}
];
mediaInformation.breaks = [
{id: 'b1', breakClipIds: ['bc1'], position: 0},
{id: 'b2', breakClipIds: ['bc2'], position: 15},
{id: 'b3', breakClipIds: ['bc3', 'bc4'], position: 60},
{id: 'b4', breakClipIds: ['bc5'], position: 100},
{id: 'b5', breakClipIds: ['bc6'], position: -1}
];
};
注: ブレークの breakClipIds プロパティは配列です。つまり、複数のブレーク クリップを各ブレークに割り当てることができます。
js/receiver.js file で、LOAD メッセージ インターセプタを見つけて、次のコードに置き換えます。VAST タイプの広告を表示するために、VMAP の処理はコメントアウトされています。
playerManager.setMessageInterceptor(
cast.framework.messages.MessageType.LOAD, (loadRequestData) => {
castDebugLogger.info('MyAPP.LOG', 'Intercepting LOAD request');
// Create the VMAP Ads request data and append it to the MediaInformation.
// const vmapUrl =
// 'https://pubads.g.doubleclick.net/gampad/ads?sz=640x480&iu=/124319096/external/ad_rule_samples&ciu_szs=300x250&ad_rule=1&impl=s&gdfp_req=1&env=vp&output=vmap&unviewed_position_start=1&cust_params=deployment%3Ddevsite%26sample_ar%3Dpremidpost&cmsid=496&vid=short_onecue&correlator=' +
// Math.floor(Math.random() * Math.pow(10, 10));
// let vmapRequest = new cast.framework.messages.VastAdsRequest();
// vmapRequest.adTagUrl = vmapUrl;
// loadRequestData.media.vmapAdsRequest = vmapRequest;
// Append VAST ad breaks to the MediaInformation.
addVASTBreaksToMedia(loadRequestData.media);
castDebugLogger.warn(
'MyAPP.LOG', 'Playable URL: ' + loadRequestData.media.contentId);
return loadRequestData;
});
js/receiver.js への変更を保存し、ファイルをウェブサーバーにアップロードします。キャスト アイコンをクリックして、キャストとコマンド ツールでキャスト セッションを開始します。VAST 広告が再生され、その後にメイン コンテンツが再生されるはずです。
8. 広告ブレークのスキップ
CAF には、広告の動作に関するカスタム ビジネスルールの実装を支援する BreakManager というクラスがあります。この機能の 1 つにより、アプリケーションは特定の条件に基づいてブレークとブレーク クリップをプログラムでスキップできます。この例では、コンテンツの最初の 30 秒以内の位置にある広告ブレークはスキップされますが、ポストロールのブレークはスキップされません。前のセクションで構成した VAST 広告を使用する場合、1 つのプレロール ブレーク、3 つのミッドロール ブレーク(15 秒、60 秒、100 秒)、1 つのポストロール ブレークの合計 5 つのブレークが定義されています。この手順を完了すると、位置が 15 秒のプレロールとミッドロールのみがスキップされます。
そのため、アプリケーションは BreakManager を介して利用可能な API を呼び出して、ブレーク読み込みのインターセプタを設定する必要があります。context 変数と playerManager 変数を含む行の後に、次の行を js/receiver.js ファイルにコピーして、インスタンスへの参照を取得します。
const breakManager = playerManager.getBreakManager();
アプリは、30 秒より前に発生する広告ブレークを無視するルールでインターセプタを設定する必要があります。ただし、ポストロール ブレーク(position 値が -1)は考慮する必要があります。このインターセプタは PlayerManager の LOAD インターセプタと同様に機能しますが、ブレーククリップの読み込みに特化しています。これは、LOAD リクエスト インターセプタの後、addVASTBreaksToMedia 関数宣言の前に設定します。
以下を js/receiver.js ファイルにコピーします。
breakManager.setBreakClipLoadInterceptor((breakClip, breakContext) => {
/**
* The code will skip playback of break clips if the break position is within
* the first 30 seconds.
*/
let breakObj = breakContext.break;
if (breakObj.position >= 0 && breakObj.position < 30) {
castDebugLogger.debug(
'MyAPP.LOG',
'Break Clip Load Interceptor skipping break with ID: ' + breakObj.id);
return null;
} else {
return breakClip;
}
});
注: ここで null を返すと、BreakClip の処理がスキップされます。Break にブレーク クリップが定義されていない場合、ブレーク自体がスキップされます。
js/receiver.js への変更を保存し、ファイルをウェブサーバーにアップロードします。キャスト アイコンをクリックして、キャストとコマンド ツールでキャスト セッションを開始します。VAST 広告が処理される必要があります。プレロール広告と最初のミッドロール広告(position が 15 秒)は再生されません。
9. ブレーク シークの動作をカスタマイズする
ブレークをシークする場合、デフォルトの実装では、シーク オペレーションの seekFrom 値と seekTo 値の間の位置にあるすべての Break アイテムを取得します。このブレークのリストから、SDK は position が seekTo 値に最も近く、isWatched プロパティが false に設定されている Break を再生します。そのブレークの isWatched プロパティが true に設定され、プレーヤーがブレーク クリップの再生を開始します。ブレイクが視聴されると、メイン コンテンツの再生が seekTo の位置から再開されます。そのようなブレークが存在しない場合、ブレークは再生されず、メイン コンテンツの再生が seekTo の位置から再開されます。
シーク時に再生されるブレークをカスタマイズするために、Cast SDK は BreakManager に setBreakSeekInterceptor API を提供しています。アプリケーションがその API を介してカスタム ロジックを提供すると、1 つ以上のブレークに対してシーク オペレーションが実行されるたびに、SDK がそのロジックを呼び出します。コールバック関数には、seekFrom の位置と seekTo の位置の間のすべてのブレークを含むオブジェクトが渡されます。その後、アプリは BreakSeekData を変更して返す必要があります。
使用方法を示すため、次のサンプルでは、シークされたすべてのブレークを取得し、タイムラインに表示される最初のブレークのみを再生することで、デフォルトの動作をオーバーライドしています。
次のコードを setBreakClipLoadInterceptor の定義の下にある js/receiver.js ファイルにコピーします。
breakManager.setBreakSeekInterceptor((breakSeekData) => {
/**
* The code will play an unwatched break between the seekFrom and seekTo
* position. Note: If the position of a break is less than 30 then it will be
* skipped due to the setBreakClipLoadInterceptor code.
*/
castDebugLogger.debug(
'MyAPP.LOG',
'Break Seek Interceptor processing break ids ' +
JSON.stringify(breakSeekData.breaks.map(adBreak => adBreak.id)));
// Remove all other breaks except for the first one.
breakSeekData.breaks.splice(1,breakSeekData.breaks.length);
return breakSeekData;
});
注: 関数が値を返さない場合、または null を返す場合、ブレークは再生されません。
js/receiver.js への変更を保存し、ファイルをウェブサーバーにアップロードします。キャスト アイコンをクリックして、キャストとコマンド ツールでキャスト セッションを開始します。VAST 広告が処理される必要があります。プレロール広告と最初のミッドロール広告(position が 15 秒)は再生されません。
再生時間が 30 秒に達するまで待って、ブレーク クリップの読み込みインターセプターによってスキップされたすべてのブレークを通過します。到達したら、[メディア コントロール] タブに移動してシーク コマンドをディスパッチします。[Seek Into Media] 入力に 300 秒を入力し、[TO] ボタンをクリックします。ブレーク シーク インターセプタに出力されたログに注目してください。デフォルトの動作がオーバーライドされ、seekFrom の時刻に近いタイミングでブレークが再生されるようになります。
10. 完了
最新の Cast Receiver SDK を使用してレシーバー アプリに広告を追加する方法は以上です。
詳しくは、広告ブレークのデベロッパー ガイドをご覧ください。