ウェブ センダー アプリに高度な機能を追加する

ミッドロール挿入点

ウェブ送信者 SDK は、特定のメディア ストリーム内のミッドロール挿入点とコンパニオン広告をサポートしています。

ミッドロール挿入点の仕組みについて詳しくは、ウェブ レシーバーのミッドロール挿入点の概要をご覧ください。

ブレークは送信側と受信側の両方で指定できますが、プラットフォーム間で一貫した動作を維持するために、ウェブ レシーバーと Android TV レシーバーで指定することをおすすめします。

ウェブでは、BreakClip と Break を使用して、読み込みコマンドでミッドロール挿入点を指定します。

let breakClip1 = new BreakClip('bc0');
breakClip1.title = 'Clip title'
breakClip1.posterUrl = 'https://www.some.url';
breakClip1.duration = 60;
breakClip.whenSKippable = 5;

let breakClip2 = ...
let breakClip3 = ...

let break1 = new Break('b0', ['bc0', 'bc1', 'bc2'], 10);

let mediaInfo = new chrome.cast.media.MediaInfo(<contentId>, '<contentType');
...
mediaInfo.breakClips = [breakClip1, breakClip2, breakClip3];
mediaInfo.breaks = [break1];

let request = new chrome.cast.media.LoadRequest(mediaInfo);

cast.framework.CastContext.getInstance().getCurrentSession().loadMedia(request)

トラック API の使用

トラックは、テキスト(字幕またはキャプション)オブジェクト、またはオーディオや動画のストリーム オブジェクトです。Tracks API を使用すると、アプリケーションでこれらのオブジェクトを操作できます。

Track オブジェクトは、SDK のトラックを表します。トラックを構成し、次のように一意の ID を割り当てることができます。

var englishSubtitle = new chrome.cast.media.Track(1, // track ID
  chrome.cast.media.TrackType.TEXT);
englishSubtitle.trackContentId = 'https://some-url/caption_en.vtt';
englishSubtitle.trackContentType = 'text/vtt';
englishSubtitle.subtype = chrome.cast.media.TextTrackType.SUBTITLES;
englishSubtitle.name = 'English Subtitles';
englishSubtitle.language = 'en-US';
englishSubtitle.customData = null;

var frenchSubtitle = new chrome.cast.media.Track(2, // track ID
  chrome.cast.media.TrackType.TEXT);
frenchSubtitle.trackContentId = 'https://some-url/caption_fr.vtt';
frenchSubtitle.trackContentType = 'text/vtt';
frenchSubtitle.subtype = chrome.cast.media.TextTrackType.SUBTITLES;
frenchSubtitle.name = 'French Subtitles';
frenchSubtitle.language = 'fr';
frenchSubtitle.customData = null;

var frenchAudio = new chrome.cast.media.Track(3, // track ID
  chrome.cast.media.TrackType.AUDIO);
frenchAudio.trackContentId = 'trk0001';
frenchAudio.trackContentType = 'audio/mp3';
frenchAudio.subtype = null;
frenchAudio.name = 'French Audio';
frenchAudio.language = 'fr';
frenchAudio.customData = null;

メディア アイテムには複数のトラックを含めることができます。たとえば、複数の字幕(それぞれ異なる言語)や複数の代替音声ストリーム(異なる言語)を含めることができます。

MediaInfo は、メディア アイテムをモデル化するクラスです。Track オブジェクトのコレクションをメディア アイテムに関連付けるには、その tracks プロパティを更新します。この関連付けは、メディアがレシーバーに読み込まれる前に行う必要があります。

var tracks = [englishSubtitle, frenchSubtitle, frenchAudio];
var mediaInfo = new chrome.cast.media.MediaInfo(mediaURL);
mediaInfo.contentType = 'video/mp4';
mediaInfo.metadata = new chrome.cast.media.GenericMediaMetadata();
mediaInfo.customData = null;
mediaInfo.streamType = chrome.cast.media.StreamType.BUFFERED;
mediaInfo.textTrackStyle = new chrome.cast.media.TextTrackStyle();
mediaInfo.duration = null;
mediaInfo.tracks = tracks;

アクティブなトラックは、メディア activeTrackIds リクエストで設定できます。

メディア アイテムに関連付けられている 1 つ以上のトラックを、メディアの読み込み後に有効にすることもできます。それには、EditTracksInfoRequest(opt_activeTrackIds, opt_textTrackStyle) を呼び出し、有効にするトラックの ID を opt_activeTrackIds で渡します。どちらのパラメータもオプションであり、アクティビティ追跡またはスタイルを任意に設定できます。たとえば、フランス語の字幕(2)とフランス語の音声(3)を有効にする方法は次のとおりです。

var activeTrackIds = [2, 3];
var tracksInfoRequest = new chrome.cast.media.EditTracksInfoRequest(activeTrackIds);
media.editTracksInfo(tracksInfoRequest, successCallback, errorCallback);

現在のメディアからすべてのオーディオ トラックまたは動画トラックを削除するには、mediaInfo.tracks=null(空の配列)を設定してメディアを再読み込みします。

現在のメディアからすべてのテキスト トラックを削除する(字幕をオフにするなど)には、次のいずれかを行います。

  • var activeTrackIds = [2, 3];(前述)を更新して、音声トラックである [3] のみを含めます。
  • mediaInfo.tracks=null を設定します。テキスト字幕(track.hidden)をオフにするためにメディアを再読み込みする必要はありません。以前に有効にした trackId を含まない activeTracksId 配列を送信すると、テキスト トラックが無効になります。

テキスト トラックのスタイル設定

TextTrackStyle は、テキスト トラックのスタイル設定情報をカプセル化するオブジェクトです。既存の TextTrackStyle オブジェクトを作成または更新した後、次のように editTrackInfo メソッドを呼び出すことで、現在再生中のメディア アイテムに適用できます。

var textTrackStyle = new chrome.cast.media.TextTrackStyle();
var tracksInfoRequest = new chrome.cast.media.EditTracksInfoRequest(textTrackStyle);
media.editTracksInfo(tracksInfoRequest, successCallback, errorCallback);

コールバックの結果(成功またはエラー)でリクエストのステータスを追跡し、それに応じて元の送信者を更新できます。

アプリは、システムまたはアプリ自体が提供する設定を使用して、ユーザーがテキスト トラックのスタイルを更新できるようにする必要があります。

次のテキスト トラック スタイル要素のスタイルを設定できます。

  • フォアグラウンド(テキスト)の色と透過度
  • 背景の色と透明度
  • エッジの種類
  • エッジの色
  • フォントの拡大 / 縮小
  • フォント ファミリー
  • フォント スタイル

たとえば、テキストの色を赤に設定し、不透明度を 75% に設定するには、次のようにします。

var textTrackStyle = new chrome.cast.media.TextTrackStyle();
textTrackStyle.foregroundColor = '#80FF0000';

音量の調整

RemotePlayer と RemotePlayerController を使用して、レシーバーの音量を設定できます。

function changeVolume(newVolume) {
  player.volumeLevel = newVolume;
  playerController.setVolumeLevel();
  // Update sender UI to reflect change
}

送信側アプリは、音量を制御する際に次のガイドラインに準拠する必要があります。

  • 送信側アプリは、送信側 UI が常に受信側ごとの音量を報告するように、受信側と同期する必要があります。RemotePlayerEventType.VOLUME_LEVEL_CHANGED コールバックと RemotePlayerEventType.IS_MUTED_CHANGED コールバックを使用して、送信側の音量を維持します。詳細については、ステータスの更新をご覧ください。
  • 送信側アプリは、アプリが受信側に読み込まれるときに、音量を特定の事前定義されたレベルに設定したり、送信側デバイスの着信音 / メディア音量に設定したりしてはなりません。

デザイン チェックリストの送信側の音量調節をご覧ください。

レシーバーにメディア メッセージを送信する

Media Messages は、送信側から受信側に送信できます。たとえば、SKIP_AD メッセージを受信側に送信するには、次のようにします。

// Get a handle to the skip button element
const skipButton = document.getElementById('skip');
skipButton.addEventListener("click", function() {
  if (castSession) {
    const media = castSession.getMediaSession();
    castSession.sendMessage('urn:x-cast:com.google.cast.media', {
      type: 'SKIP_AD',
      requestId: 1,
      mediaSessionId: media.mediaSessionId
    });
  }
});

ステータスの更新

複数の送信側が同じ受信側に接続されている場合、各送信側は、受信側の変更が他の送信側から開始されたものであっても、その変更を認識することが重要です。

このため、アプリは必要なすべてのリスナーを RemotePlayerController に登録する必要があります。現在のメディアの TextTrackStyle が変更されると、接続されているすべての送信者に通知され、現在のメディア セッションの対応するプロパティ(MediaInfo フィールドの activeTrackIds や textTrackStyle など)がコールバックで送信者に送信されます。この場合、受信側 SDK は新しいスタイルが以前のスタイルと異なるかどうかを確認せず、接続されているすべての送信者に通知します。

進行状況インジケーター

送信側に進行状況インジケーター付きの再生位置を表示することは、ほとんどのアプリで必須です。Cast API は Cast メディア プロトコルを使用します。このプロトコルは、このシナリオや他のシナリオでの帯域幅消費を最適化するため、独自のステータス同期を実装する必要はありません。API を使用してメディア再生の進行状況インジケーターを適切に実装するには、CastVideos-chrome サンプルアプリをご覧ください。

CORS の要件

アダプティブ メディア ストリーミングの場合、Google Cast では CORS ヘッダーが必要ですが、シンプルな MP4 メディア ストリームでも、トラックが含まれている場合は CORS が必要です。メディアでトラックを有効にする場合は、トラック ストリームとメディア ストリームの両方で CORS を有効にする必要があります。そのため、サーバー上のシンプルな MP4 メディアで CORS ヘッダーを使用できない場合に、シンプルな字幕トラックを追加すると、適切な CORS ヘッダーを含めるようにサーバーを更新しない限り、メディアをストリーミングできなくなります。

Content-Type、Accept-Encoding、Range のヘッダーが必要です。最後の 2 つのヘッダー(Accept-Encoding と Range)は、以前は必要なかった可能性がある追加のヘッダーです。

ワイルドカード「*」は Access-Control-Allow-Origin ヘッダーに使用できません。ページに保護されたメディア コンテンツがある場合は、ワイルドカードではなくドメインを使用する必要があります。

ウェブページを再読み込みせずにセッションを再開する

既存の CastSession を再開するには、参加しようとしているセッションの sessionId を指定して requestSessionById(sessionId) を使用します。

sessionId は、loadMedia() を呼び出した後、getSessionId() を使用してアクティブな CastSession で確認できます。

推奨される方法は次のとおりです。

  1. loadMedia() を呼び出してセッションを開始します。
  2. sessionId をローカルに保存する
  3. 必要に応じて、requestSessionById(sessionId) を使用してセッションに再度参加します。
let sessionId;

function rejoinCastSession() {
  chrome.cast.requestSessionById(sessionId);

  // Add any business logic to load new content or only resume the session
}

document.getElementById('play-button').addEventListener(("click"), function() {
  if (sessionId == null) {
    let castSession = cast.framework.CastContext.getInstance().getCurrentSession();
    if (castSession) {
      let mediaInfo = createMediaInfo();
      let request = new chrome.cast.media.LoadRequest(mediaInfo);
      castSession.loadMedia(request)

      sessionId = CastSession.getSessionId();
    } else {
      console.log("Error: Attempting to play media without a Cast Session");
    }
  } else {
    rejoinCastSession();
  }
});

次のステップ

これで、ウェブ送信側アプリに追加できる機能の説明は終了です。これで、別のプラットフォーム(Android または iOS)用の送信側アプリを作成したり、受信側アプリを作成したりできるようになりました。