ウェブレシーバーへの 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 ブラウザ
  • Firebase Hostingngrok などの HTTPS ホスティング サービス。
  • インターネットに接続するように設定された ChromecastAndroid TV などの Google Cast デバイス。
  • HDMI 入力対応のテレビまたはモニター、または Google Nest Hub

経験

この Codelab を続行する前に、次の経験があることを確認してください。

  • ウェブ開発に関する一般的な知識。
  • Cast ウェブ レシーバー アプリをビルドする

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

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

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

<ph type="x-smartling-placeholder"></ph> 初心者 中級 上達 をご覧ください。

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

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

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

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

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

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

サーバーを実行する

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

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

4. Cast Developer Console でアプリを登録する

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

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

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

「New Receiver Application」の画像[カスタム レシーバー] オプションがハイライト表示されたオプション

[Custom Receiver] を選択します。これが構築中のレシーバです。

「新しいカスタムのレシーバー」の画像[Receiver Application URL] に URL が入力されていることを示す画面フィールド

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

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

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

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

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

キャスト デバイスの背面に記載されているシリアル番号を入力し、わかりやすい名前を付けます。シリアル番号は、Google Cast SDK Developer Console にアクセスし、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 では送信側アプリを使用してキャスト セッションを開始し、受信側アプリを使用して広告ブレーク API を使用するように変更します。

この Codelab では、Cast and Command Tool が、レシーバー アプリを起動するためのウェブ送信側として機能します。まず、Chrome ブラウザでツールを開きます。Cast SDK Developer Console に表示された [Receiver App ID] を入力し、[Set] をクリックして送信側アプリをテスト用に設定します。

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

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

index.html

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

receiver.js

このスクリプトは、レシーバーアプリのすべてのロジックを管理します。現時点では、キャスト コンテキストを初期化し、初期化時に動画アセットを読み込む基本的な CAF レシーバーが含まれています。一部のデバッグロガー機能も追加され、Cast および 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 メッセージ インターセプタを見つけ、次のコードに置き換えます。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 秒)、最後のポストロール挿入点の 5 つの挿入点が定義されています。上記の手順を完了すると、位置が 15 秒のプレロールミッドロールのみがスキップされます。

そのためには、アプリで BreakManager を通じて利用できる API を呼び出して、中断読み込み用のインターセプタを設定する必要があります。js/receiver.js ファイルの context 変数と playerManager 変数を含む行の後に、次の行をコピーして、インスタンスへの参照を取得します。

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 は、この中断のリストから、positionseekTo 値に近く、isWatched プロパティが false に設定されている Break を再生します。次に、そのブレークの isWatched プロパティが true に設定され、プレーヤーはそのブレーク クリップの再生を開始します。休憩が視聴されると、メイン コンテンツは seekTo の位置から再生を再開します。そのようなブレークが存在しない場合は、ブレークは再生されず、メイン コンテンツは seekTo の位置から再生を再開します。

移動時に再生する中断をカスタマイズするために、Cast SDK には BreakManagersetBreakSeekInterceptor 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] ボタンをクリックします。Break Seek Interceptor にログが出力されたことに注意してください。デフォルトの動作をオーバーライドして、seekFrom 時刻の近くでブレークを再生する必要があります。

10.完了

最新の Cast Receiver SDK を使って、レシーバー アプリに広告を追加する方法を学びました。

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