ウェブレシーバーへの Ad Breaks API サポートの追加

1. 概要

Google Cast ロゴ

この Codelab では、Cast Ad Breaks API を使用するカスタム ウェブ レシーバー アプリの作成方法について説明します。

Google Cast とは

Google Cast では、ユーザーはモバイル デバイスからテレビにコンテンツをキャストできます。ユーザーは自分のモバイル デバイスをリモコンとして使い、テレビでのメディア再生を行うことが可能です。

Google Cast SDK を使うと、アプリを拡張してテレビやサウンド システムを制御できます。Cast SDK を使用すると、Google Cast デザイン チェックリストに基づいて、必要な UI コンポーネントを追加できます。

Google Cast のデザイン チェックリストは、サポートされているすべてのプラットフォームでユーザーが直感的に操作できるようにするために、Cast の実装を標準化するためのものです。

達成目標

この Codelab を修了すると、Break API を活用するキャスト レシーバーが完成します。

学習内容

  • キャストのコンテンツに VMAP 休憩や VAST 休憩を含める方法
  • ブレーク クリップをスキップする方法
  • シーク時のデフォルトのブレーク動作をカスタマイズする方法

必要なもの

  • 最新の Google Chrome ブラウザ
  • HTTPS ホスティング サービス(Firebase Hostingngrok など)
  • インターネットにアクセスできる Google Cast デバイス(ChromecastAndroid TV など)。
  • HDMI 入力対応のテレビまたはモニター、または Google Home Hub

エクスペリエンス

この Codelab を進める前に、次の経験があることを確認します。

  • ウェブ開発に関する一般的な知識。
  • Cast Web Receiver アプリを作成する。

このチュートリアルの利用方法をお選びください。

通読するのみ 通読し、演習を行う

ウェブアプリの構築経験をどのように評価されますか。

初心者 中級者 上級者

2. サンプルコードを取得する

すべてのサンプルコードをパソコンにダウンロードします。

ダウンロードした ZIP ファイルを解凍します。

3. レシーバーをローカルにデプロイする

キャスト デバイスでウェブ レシーバーを使用するには、キャスト デバイスからアクセスできる場所にホストする必要があります。https 対応のサーバーがすでにある場合は、以降の手順をスキップして、URL をメモします。これは次のセクションで必要になります。

使用できるサーバーがない場合は、Firebase Hosting または ngrok を使用できます。

サーバーを実行する

選択したサービスを設定したら、app-start に移動してサーバーを起動します。

ホストされているレシーバーの URL をメモします。これは次のセクションで使用します。

4. Cast のデベロッパー コンソールでアプリを登録する

この Codelab に組み込まれているカスタム レシーバーを Chromecast デバイスで実行できるようにするには、アプリを登録する必要があります。アプリケーションを登録するとアプリケーション ID が生成されます。Web Receiver アプリケーションを起動するには、そのアプリケーション ID を設定する必要があります。

[Add New Application] ボタンがハイライト表示されている Google Cast SDK デベロッパー コンソールの画像

[新しいアプリケーションを追加] をクリックします

[Custom Receiver] オプションがハイライト表示された [New Receiver Application] 画面の画像

[カスタム レシーバー] を選択します。これが開発中です。

[Receiver Application URL] フィールドに URL を入力している [New Custom Receiver] 画面の画像

新しいレシーバーの詳細を入力します。Web Receiver アプリケーションをホストする予定の URL を使用してください。アプリケーションを登録したら、コンソールで生成されたアプリケーション ID をメモします。送信側のアプリケーションは、後のセクションでその ID を使用するように構成されます。

また、Google Cast デバイスを登録して、公開前にレシーバー アプリにアクセスできるようにする必要があります。レシーバー アプリを公開すると、すべての Google Cast デバイスで利用できるようになります。この Codelab では、非公開のレシーバー アプリを使用することをおすすめします。

[新しいデバイスを追加] ボタンがハイライト表示されている Google Cast SDK デベロッパー コンソールの画像

[Add new Device] をクリックします。

[キャスト レシーバー デバイスの追加] ダイアログの画像

キャスト デバイスの背面に記載されているシリアル番号を入力し、わかりやすい名前を付けます。シリアル番号は、Google Cast SDK デベロッパー コンソールにアクセスする際に Chrome で画面をキャストして確認することもできます。

レシーバーとデバイスのテスト準備が完了するまで 5 ~ 15 分かかります。5 ~ 15 分待ってから、キャスト デバイスを再起動する必要があります。

5. Start プロジェクトを準備する

この Codelab を開始する前に、広告ブレーク API の概要が記載されている広告デベロッパー ガイドをご確認ください。

ダウンロードしたスタートアプリに Google Cast のサポートを追加する必要があります。以下は、この Codelab で使用する Google Cast の用語です。

  • 送信側アプリはモバイル デバイスやノートパソコンで動作します。
  • レシーバー アプリは Google Cast デバイスで動作します。

これで、お好みのテキスト エディタを使用して、スターター プロジェクトを基にビルドする準備が整いました。

  1. ダウンロードしたサンプルコードから フォルダ アイコンapp-start ディレクトリを選択します。
  2. js/receiver.js と index.html を開きます。

この Codelab の学習を進めるなかで、選択したウェブ ホスティング ソリューションに変更が加えられている必要があります。変更の検証とテストを続けるときは、変更内容がホストサイトに push されていることを確認します。

アプリの設計

前述のとおり、この Codelab ではセンダーアプリを利用してキャスト セッションを開始します。レシーバー アプリは AdBreak API を使用するように変更されます。

この Codelab では、Cast and Command Tool をウェブ センダーとして機能させ、レシーバー アプリを起動します。まず、Chrome ブラウザでツールを開きます。Cast SDK のデベロッパー コンソールで入手したレシーバー アプリ ID を入力し、[設定] をクリックしてセンダーアプリをテスト用に設定します。

注: キャスト アイコンが表示されない場合は、ウェブ レシーバーとキャスト デバイスが Cast Console で正しく登録されていることを確認してください。登録したキャスト デバイスの電源をまだオンにしていない場合は、電源をオフにして再度オンにします。

この Codelab では主にレシーバー アプリを使用します。アプリは、index.html で定義された 1 つのメインビューと、js/receiver.js という JavaScript ファイル 1 つで構成されます。これらについて、以下で詳しく説明します。

index.html

この HTML ファイルには、cast-media-player 要素で提供されるレシーバ アプリの UI が含まれています。また、CAF SDK と Cast Debug Logger ライブラリも読み込まれます。

receiver.js

このスクリプトは、レシーバー アプリのすべてのロジックを管理します。現時点では、キャスト コンテキストを初期化し、初期化時に動画アセットを読み込む基本的な CAF レシーバーが含まれています。Cast and Command ツールにログを返すデバッグロガー機能もいくつか追加されています。

6. コンテンツに VMAP を追加する

Cast Web Receiver SDK は、Digital Video Multiple Ad プレイリスト(VMAP)を通じて指定された広告をサポートします。XML 構造で、メディアのミッドロール挿入点と、それに関連付けられた挿入点クリップのメタデータを指定します。このような広告を挿入するために、SDK では MediaInformation オブジェクト内に vmapAdsRequest プロパティが用意されています。

js/receiver.js ファイルで、VastAdsRequest オブジェクトを作成します。LOAD リクエスト インターセプタ関数を見つけて、次のコードに置き換えます。これには、DoubleClick のサンプル VMAP タグ URL と、ランダムな correlator 値が含まれており、同じ 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 とも呼ばれます)の統合に使用できる API を紹介します。前のセクションの VMAP コードを実装している場合は、コメントアウトします。

読み込みリクエスト インターセプタの後に、次の内容を js/receiver.js ファイルにコピーします。これには、DoubleClick からの 6 つの VAST 広告ブレーククリップとランダムな correlator 値が含まれます。これらのブレーククリップは 5 つのブレークに割り当てられます。各ブレークの position には、プレロール(position0 に設定)とポストロール(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 メッセージのインターセプタを見つけて、次のコードに置き換えます。なお、VMAP の処理は、VAST タイプの広告を表示するためにコメントアウトされています。

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 を呼び出して、ブレーク読み込み用のインターセプタを設定する必要があります。js/receiver.js ファイルの context 変数と playerManager 変数を含む行の後で、インスタンスへの参照を取得するために、次の行をコピーします。

const breakManager = playerManager.getBreakManager();

アプリケーションでインターセプタを設定し、ポストロールブレーク(position 値は -1 であるため)に留意して、30 秒より前に発生するミッドロール挿入点を無視するルールを設定する必要があります。このインターセプタは、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 は、このブレークのリストから、positionseekTo の値に最も近い Break を再生し、isWatched プロパティが false に設定されています。すると、ブレークの isWatched プロパティが true に設定され、プレーヤーがブレーク クリップの再生を開始します。休憩の視聴後、メイン コンテンツは seekTo の位置から再生を再開します。そのようなブレークがない場合、ブレークは再生されず、メイン コンテンツは seekTo の位置から再開します。

シーク再生中の挿入点をカスタマイズするため、Cast SDK では BreakManagersetBreakSeekInterceptor API が用意されています。アプリがその API を介してカスタム ロジックを提供すると、1 つ以上のブレークでシーク操作が行われるたびに SDK はそのカスタム ロジックを呼び出します。コールバック関数には、seekFrom の位置と seekTo の位置との間のすべての区切りを含むオブジェクトが渡されます。次に、アプリケーションは BreakSeekData を変更して返す必要があります。

以下のサンプルでは、その使用方法を示すために、デフォルトの動作をオーバーライドしています。デフォルトの動作をオーバーライドします。具体的には、シークされたブレークをすべて取得し、タイムラインに表示される最初のブレークのみを再生します。

定義の下の js/receiver.js ファイルで、次の内容を setBreakClipLoadInterceptor にコピーします。

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] ボタンをクリックします。[Break Seek Interceptor] にログが出力されていることを確認します。seekFrom の時刻に近いタイミングでブレークを再生するように、デフォルトの動作をオーバーライドするようになりました。

10.完了

最新の Cast Receiver SDK を使用してレシーバ アプリに広告を追加する方法がわかりました。

詳しくは、ミッドロール挿入点に関するデベロッパー ガイドをご覧ください。