1. 概要
この Codelab では、既存のウェブ動画アプリを変更して、Google Cast 対応デバイスにコンテンツをキャストする方法について説明します。
Google Cast とは
Google Cast では、ユーザーはモバイル デバイスからテレビにコンテンツをキャストできます。ユーザーは自分のモバイル デバイスをリモコンとして使い、テレビでのメディア再生を行うことが可能です。
Google Cast SDK を使うと、アプリを拡張してテレビやサウンド システムを制御できます。Cast SDK では、Google Cast デザイン チェックリストに基づいて必要な UI コンポーネントを追加できます。
Google Cast デザイン チェックリストは、サポートされているすべてのプラットフォームにわたって、Cast ユーザー エクスペリエンスをシンプルで予測可能なものにするために使用します。
達成目標
この Codelab を完了すると、Chrome ウェブ動画アプリで Google Cast デバイスに動画をキャストできるようになります。
学習内容
- サンプル動画アプリに Google Cast SDK を追加する方法
- Google Cast デバイスを選択するキャスト アイコンを追加する方法
- キャスト デバイスに接続してメディア レシーバーを起動する方法
- 動画をキャストする方法
- Cast Connect を統合する方法
必要なもの
- 最新の Google Chrome ブラウザ。
- Firebase Hosting や ngrok などの HTTPS ホスティング サービス。
- インターネットに接続できる Chromecast や Android TV などの Google Cast デバイス
- HDMI 入力対応のテレビまたはモニター
- Cast Connect の統合をテストするには Chromecast with Google TV が必要ですが、この Codelab の残りの部分では必須ではありません。ない場合は、このチュートリアルの最後にある Cast Connect のサポートを追加する手順をスキップしてください。
エクスペリエンス
- ウェブ開発の知識が必要です。
- 一般的なテレビの視聴経験も必要です。
このチュートリアルの利用方法をお選びください。
ウェブアプリの作成経験をどのように評価されますか。
テレビ視聴のご経験についてお答えください。
2. サンプルコードを取得する
サンプルコードはすべてパソコンにダウンロードできます。
ダウンロードした ZIP ファイルを解凍します。
3. サンプルアプリを実行します。
まず、完成したサンプルアプリがどのようなものか見てみましょう。このアプリは基本的な動画プレーヤーです。ユーザーはリストから動画を選択し、デバイス上でローカルに再生するか、Google Cast デバイスにキャストできます。
完成したものを使用するには、これをホストする必要があります。
使用できるサーバーがない場合は、Firebase Hosting または ngrok を使用できます。
サーバーを実行する
目的のサービスが設定されたら、app-done
に移動してサーバーを起動します。
ブラウザで、ホストしたサンプルの HTTPS URL にアクセスします。
- 動画アプリが表示されます。
- キャスト アイコンをクリックし、使用する Google Cast デバイスを選択します。
- 動画を選択して、再生ボタンをクリックします。
- Google Cast デバイスで動画の再生が開始されます。
動画要素の一時停止ボタンをクリックすると、レシーバーの動画が一時停止します。動画要素の再生ボタンをクリックすると、動画の再生が継続されます。
キャスト アイコンをクリックして、Google Cast デバイスへのキャストを停止します。
次に進む前に、サーバーを停止します。
4. 開始用プロジェクトを準備する
ダウンロードした開始用アプリに Google Cast のサポートを追加する必要があります。この Codelab で使用する Google Cast の用語は以下のとおりです。
- 送信側アプリはモバイル デバイスやノートパソコンで動作します。
- レシーバー アプリは Google Cast デバイスで動作します。
お好きなテキスト エディタを使用して、開始用プロジェクトを基に作業する準備を行います。
- ダウンロードしたサンプルコードの
app-start
ディレクトリを選択します。 - サーバーを使用してアプリを実行し、UI を確認します。
この Codelab の作業を進めていくと、サービスによっては、サンプルをサーバーに再ホストする必要があります。
アプリの設計
アプリはリモートのウェブサーバーから動画のリストを取得し、ユーザーがブラウジングできるようにリストを提供します。動画を選択すると、その詳細情報を表示したり、モバイル デバイスで動画をローカルに再生したりできます。
アプリは、index.html
で定義されるメインビューとメイン コントローラ(CastVideos.js.
)で構成されます。
index.html
この html ファイルでは、ウェブアプリの UI のほぼすべてが宣言されています。
ビューはいくつかのセクションに分かれていて、div#main_video
には動画要素が含まれます。動画 div に関連すると、動画要素のすべてのコントロールを定義する div#media_control
があります。その下には、ビューに動画の詳細を表示する media_info
があります。最後の carousel
div には div 内の動画のリストが表示されます。
index.html
ファイルでは Cast SDK も自動的に実行され、CastVideos
関数に読み込みを指示します。
これらの要素に代入されるコンテンツのほとんどは、CastVideos.js
で定義、注入、制御されます。では、その内容を見てみましょう。
CastVideos.js
このスクリプトは、動画キャスト ウェブアプリのすべてのロジックを管理します。CastVideos.js
で定義された動画のリストと関連するメタデータは、mediaJSON
という名前のオブジェクトに含まれています。
いくつかの主要なセクションの組み合わせによって、ローカルとリモートでの動画の管理と再生を制御しています。全体的にとてもシンプルな設計のウェブ アプリケーションです。
CastPlayer
は、アプリ全体の管理、プレーヤーの設定、メディアの選択、メディア再生用の PlayerHandler
へのイベントのバインドを管理するメインクラスです。CastPlayer.prototype.initializeCastPlayer
は、すべてのキャスト機能を設定するメソッドです。CastPlayer.prototype.switchPlayer
は、ローカル プレーヤーとリモート プレーヤーとで状態を切り替えます。CastPlayer.prototype.setupLocalPlayer
と CastPlayer.prototype.setupRemotePlayer
は、それぞれローカル プレーヤーとリモート プレーヤーを初期化します。
PlayerHandler
はメディア再生を管理するクラスです。メディアと再生の管理の詳細を制御する方法は他にもいくつかあります。
よくある質問
5. キャスト アイコンの追加
キャスト対応アプリでは、動画要素にキャスト アイコンが表示されます。キャスト アイコンをクリックすると、ユーザーが選択できるキャスト デバイスのリストが表示されます。送信側のデバイスでコンテンツをローカルで再生している場合は、キャスト デバイスを選択すると、そのキャスト デバイスで再生が開始または再開されます。キャスト セッション中、ユーザーはいつでもキャスト アイコンをクリックして、キャスト デバイスへのアプリのキャストを停止できます。Google Cast デザイン チェックリストで規定されているとおり、アプリのどの画面でもキャスト デバイスに接続または接続を解除できるようにする必要があります。
構成
開始用プロジェクトでは、完成したサンプルアプリと同じように、依存関係の設定とセットアップを行う必要がありますが、今回は app-start
の内容をホストします。
ブラウザで、ホストしたサンプルの https
URL にアクセスします。
変更を行う場合は、サービスに応じてサーバーでサンプルを再ホストする必要があります。
初期化
キャスト フレームワークには、グローバル シングルトン オブジェクトの CastContext
があり、これによりフレームワークのすべてのアクティビティが調整されます。このオブジェクトは、アプリのライフサイクルの早い段階で初期化する必要があります。通常は、Cast SDK が読み込まれた後、window['__onGCastApiAvailable']
に割り当てられたコールバックから呼び出されて使用できるようになります。この場合、CastContext
は、前述のコールバックから呼び出される CastPlayer.prototype.initializeCastPlayer
で呼び出されます。
CastContext
を初期化するときは、options
JSON オブジェクトを指定する必要があります。このクラスには、フレームワークの動作に影響を与えるオプションが含まれています。最も重要なオプションはレシーバー アプリの ID で、利用可能なキャスト デバイスのリストをフィルタして、指定したアプリを実行できるデバイスのみを表示したり、キャスト セッションの開始時にレシーバー アプリを起動したりするために使用されます。
独自の Cast 対応アプリを開発する場合は、Cast デベロッパーとして登録してからアプリのアプリ ID を取得する必要があります。この Codelab では、サンプルのアプリ ID を使用します。
body
セクションの最後にある index.html
に次のコードを追加します。
<script type="text/javascript" src="https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1"></script>
index.html
に次のコードを追加して、CastVideos
アプリと CastContext
を初期化します。
<script src="CastVideos.js"></script>
<script type="text/javascript">
var castPlayer = new CastPlayer();
window['__onGCastApiAvailable'] = function(isAvailable) {
if (isAvailable) {
castPlayer.initializeCastPlayer();
}
};
</script>
次に、先ほど index.html
で呼び出したメソッドに対応する新しいメソッドを CastVideos.js
に追加する必要があります。CastContext にオプションを設定し、新しい RemotePlayer
と RemotePlayerControllers
を初期化する新しいメソッド initializeCastPlayer
を追加します。
/**
* This method sets up the CastContext, and a few other members
* that are necessary to play and control videos on a Cast
* device.
*/
CastPlayer.prototype.initializeCastPlayer = function() {
var options = {};
// Set the receiver application ID to your own (created in
// the Google Cast Developer Console), or optionally
// use the chrome.cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID
options.receiverApplicationId = 'C0868879';
// Auto join policy can be one of the following three:
// ORIGIN_SCOPED - Auto connect from same appId and page origin
// TAB_AND_ORIGIN_SCOPED - Auto connect from same appId, page origin, and tab
// PAGE_SCOPED - No auto connect
options.autoJoinPolicy = chrome.cast.AutoJoinPolicy.ORIGIN_SCOPED;
cast.framework.CastContext.getInstance().setOptions(options);
this.remotePlayer = new cast.framework.RemotePlayer();
this.remotePlayerController = new cast.framework.RemotePlayerController(this.remotePlayer);
this.remotePlayerController.addEventListener(
cast.framework.RemotePlayerEventType.IS_CONNECTED_CHANGED,
this.switchPlayer.bind(this)
);
};
最後に、RemotePlayer
と RemotePlayerController
の変数を作成します。
var CastPlayer = function() {
//...
/* Cast player variables */
/** @type {cast.framework.RemotePlayer} */
this.remotePlayer = null;
/** @type {cast.framework.RemotePlayerController} */
this.remotePlayerController = null;
//...
};
キャスト アイコン
CastContext
が初期化されたので、ユーザーがキャスト デバイスを選択できるようにキャスト アイコンを追加する必要があります。Cast SDK には、ID が「castbutton"
」の google-cast-launcher
というキャスト アイコン コンポーネントが用意されています。media_control
セクションに button
を追加するだけで、アプリの動画要素に追加できます。
アイコン要素は次のようになります。
<google-cast-launcher id="castbutton"></google-cast-launcher>
media_control
セクションの index.html
に次のコードを追加します。
<div id="media_control">
<div id="play"></div>
<div id="pause"></div>
<div id="progress_bg"></div>
<div id="progress"></div>
<div id="progress_indicator"></div>
<div id="fullscreen_expand"></div>
<div id="fullscreen_collapse"></div>
<google-cast-launcher id="castbutton"></google-cast-launcher>
<div id="audio_bg"></div>
<div id="audio_bg_track"></div>
<div id="audio_indicator"></div>
<div id="audio_bg_level"></div>
<div id="audio_on"></div>
<div id="audio_off"></div>
<div id="duration">00:00:00</div>
</div>
Chrome ブラウザでページを更新します。動画要素にキャスト アイコンが表示されます。このアイコンをクリックすると、ローカル ネットワーク上のキャスト デバイスがリストに表示されます。デバイスの検出は Chrome ブラウザによって自動的に管理されます。キャスト デバイスを選択すると、サンプル レシーバー アプリがキャスト デバイスに読み込まれます。
メディア再生の機能はまだ設定していないため、キャスト デバイスで動画を再生することはできません。キャスト アイコンをクリックしてキャストを停止します。
6. 動画コンテンツのキャスト
キャスト デバイスでも動画をリモートで再生できるようにサンプルアプリを拡張します。そのためには、キャスト フレームワークによって生成された各種イベントをリッスンする必要があります。
メディアのキャスト
大まかに言うと、キャスト デバイスでメディアを再生するには、次のことを行う必要があります。
- Cast SDK を使用して、メディア アイテムをモデル化する
MediaInfo
JSON
オブジェクトを作成します。 - ユーザーがキャスト デバイスに接続してレシーバー アプリを起動します。
MediaInfo
オブジェクトをレシーバーに読み込み、コンテンツを再生します。- メディアのステータスを追跡します。
- ユーザーの操作に基づいて再生コマンドをレシーバーに送信します。
ステップ 1 では、オブジェクトを別のオブジェクトにマッピングします。MediaInfo
は Cast SDK が解釈できるもので、mediaJSON
はアプリでメディア アイテムをカプセル化したものです。mediaJSON
は MediaInfo
に簡単にマッピングできます。前のセクションのステップ 2 はすでに完了しています。ステップ 3 は Cast SDK で簡単に行うことができます。
サンプルアプリの CastPlayer
では、switchPlayer
メソッドでローカルの再生とリモートの再生をすでに区別しています。
if (cast && cast.framework) {
if (this.remotePlayer.isConnected) {
//...
この Codelab では、すべてのサンプル プレーヤーにおけるロジックの仕組みを正確に理解する必要はありません。ここで重要なのは、アプリのメディア プレーヤーを調整して、ローカルとリモートの再生を認識させる必要があるということです。
現時点では、ローカル プレーヤーはキャスト状態について何も認識していないため、常にローカルの再生状態になっています。キャスト フレームワークで発生する状態遷移に基づいて UI を更新する必要があります。たとえば、キャストを開始するときは、ローカルの再生を停止して、いくつかのコントロールを無効にする必要があります。同様に、このビュー コントローラを使用しているときにキャストを停止した場合は、ローカルの再生に移行する必要があります。これに対応するには、キャスト フレームワークによって生成された各種イベントをリッスンする必要があります。
キャスト セッションの管理
キャスト フレームワークにおいて、キャスト セッションは、デバイスへの接続、起動(または既存のセッションへの参加)、レシーバー アプリへの接続、メディア コントロール チャネルの初期化(該当する場合)というプロセスを組み合わせたものになります。メディア コントロール チャネルは、キャスト フレームワークがメディア再生に関するメッセージをレシーバーと送受信する方法です。
ユーザーがキャスト アイコンからデバイスを選択すると、キャスト セッションが自動的に開始し、ユーザーが切断すると自動的に停止します。ネットワークの問題によるレシーバー セッションへの再接続も、キャスト フレームワークによって自動的に処理されます。
キャスト セッションは CastSession
によって管理され、cast.framework.CastContext.getInstance().getCurrentSession()
からアクセスできます。EventListener
コールバックを使用して、作成、一時停止、再開、終了などのセッション イベントをモニタリングできます。
現在のアプリケーションでは、セッションと状態の管理はすべて setupRemotePlayer
メソッドで処理されています。アプリでこれを構成するために、次のコードを CastVideos.js
に追加します。
/**
* Set the PlayerHandler target to use the remote player
*/
CastPlayer.prototype.setupRemotePlayer = function () {
var castSession = cast.framework.CastContext.getInstance().getCurrentSession();
this.playerHandler.setTarget(playerTarget);
// Setup remote player volume right on setup
// The remote player may have had a volume set from previous playback
if (this.remotePlayer.isMuted) {
this.playerHandler.mute();
}
var currentVolume = this.remotePlayer.volumeLevel * FULL_VOLUME_HEIGHT;
var p = document.getElementById('audio_bg_level');
p.style.height = currentVolume + 'px';
p.style.marginTop = -currentVolume + 'px';
this.hideFullscreenButton();
this.playerHandler.play();
};
コールバックからのすべてのイベントをバインドし、受信したすべてのイベントを処理する必要もあります。これは次のように簡単に処理できます。
/**
* Set the PlayerHandler target to use the remote player
*/
CastPlayer.prototype.setupRemotePlayer = function () {
var castSession = cast.framework.CastContext.getInstance().getCurrentSession();
// Add event listeners for player changes which may occur outside sender app
this.remotePlayerController.addEventListener(
cast.framework.RemotePlayerEventType.IS_PAUSED_CHANGED,
function() {
if (this.remotePlayer.isPaused) {
this.playerHandler.pause();
} else {
this.playerHandler.play();
}
}.bind(this)
);
this.remotePlayerController.addEventListener(
cast.framework.RemotePlayerEventType.IS_MUTED_CHANGED,
function() {
if (this.remotePlayer.isMuted) {
this.playerHandler.mute();
} else {
this.playerHandler.unMute();
}
}.bind(this)
);
this.remotePlayerController.addEventListener(
cast.framework.RemotePlayerEventType.VOLUME_LEVEL_CHANGED,
function() {
var newVolume = this.remotePlayer.volumeLevel * FULL_VOLUME_HEIGHT;
var p = document.getElementById('audio_bg_level');
p.style.height = newVolume + 'px';
p.style.marginTop = -newVolume + 'px';
}.bind(this)
);
// This object will implement PlayerHandler callbacks with
// remotePlayerController, and makes necessary UI updates specific
// to remote playback
var playerTarget = {};
playerTarget.play = function () {
if (this.remotePlayer.isPaused) {
this.remotePlayerController.playOrPause();
}
var vi = document.getElementById('video_image');
vi.style.display = 'block';
var localPlayer = document.getElementById('video_element');
localPlayer.style.display = 'none';
}.bind(this);
playerTarget.pause = function () {
if (!this.remotePlayer.isPaused) {
this.remotePlayerController.playOrPause();
}
}.bind(this);
playerTarget.stop = function () {
this.remotePlayerController.stop();
}.bind(this);
playerTarget.getCurrentMediaTime = function() {
return this.remotePlayer.currentTime;
}.bind(this);
playerTarget.getMediaDuration = function() {
return this.remotePlayer.duration;
}.bind(this);
playerTarget.updateDisplayMessage = function () {
document.getElementById('playerstate').style.display = 'block';
document.getElementById('playerstatebg').style.display = 'block';
document.getElementById('video_image_overlay').style.display = 'block';
document.getElementById('playerstate').innerHTML =
this.mediaContents[ this.currentMediaIndex]['title'] + ' ' +
this.playerState + ' on ' + castSession.getCastDevice().friendlyName;
}.bind(this);
playerTarget.setVolume = function (volumeSliderPosition) {
// Add resistance to avoid loud volume
var currentVolume = this.remotePlayer.volumeLevel;
var p = document.getElementById('audio_bg_level');
if (volumeSliderPosition < FULL_VOLUME_HEIGHT) {
var vScale = this.currentVolume * FULL_VOLUME_HEIGHT;
if (volumeSliderPosition > vScale) {
volumeSliderPosition = vScale + (pos - vScale) / 2;
}
p.style.height = volumeSliderPosition + 'px';
p.style.marginTop = -volumeSliderPosition + 'px';
currentVolume = volumeSliderPosition / FULL_VOLUME_HEIGHT;
} else {
currentVolume = 1;
}
this.remotePlayer.volumeLevel = currentVolume;
this.remotePlayerController.setVolumeLevel();
}.bind(this);
playerTarget.mute = function () {
if (!this.remotePlayer.isMuted) {
this.remotePlayerController.muteOrUnmute();
}
}.bind(this);
playerTarget.unMute = function () {
if (this.remotePlayer.isMuted) {
this.remotePlayerController.muteOrUnmute();
}
}.bind(this);
playerTarget.isMuted = function() {
return this.remotePlayer.isMuted;
}.bind(this);
playerTarget.seekTo = function (time) {
this.remotePlayer.currentTime = time;
this.remotePlayerController.seek();
}.bind(this);
this.playerHandler.setTarget(playerTarget);
// Setup remote player volume right on setup
// The remote player may have had a volume set from previous playback
if (this.remotePlayer.isMuted) {
this.playerHandler.mute();
}
var currentVolume = this.remotePlayer.volumeLevel * FULL_VOLUME_HEIGHT;
var p = document.getElementById('audio_bg_level');
p.style.height = currentVolume + 'px';
p.style.marginTop = -currentVolume + 'px';
this.hideFullscreenButton();
this.playerHandler.play();
};
メディアの読み込み
Cast SDK には、レシーバーでのリモート メディア再生を管理できる便利な API RemotePlayer
と RemotePlayerController
が用意されています。メディア再生をサポートする CastSession
の場合、RemotePlayer
と RemotePlayerController
のインスタンスは SDK によって自動的に作成されます。これらのインスタンスには、Codelab の前半で説明したように、それぞれ cast.framework.RemotePlayer
と cast.framework.RemotePlayerController
のインスタンスを作成してアクセスできます。
次に、SDK がリクエストを処理して渡す MediaInfo オブジェクトを作成して、レシーバーで現在選択されている動画を読み込む必要があります。そのために、setupRemotePlayer
に次のコードを追加します。
/**
* Set the PlayerHandler target to use the remote player
*/
CastPlayer.prototype.setupRemotePlayer = function () {
//...
playerTarget.load = function (mediaIndex) {
console.log('Loading...' + this.mediaContents[mediaIndex]['title']);
var mediaInfo = new chrome.cast.media.MediaInfo(
this.mediaContents[mediaIndex]['sources'][0], 'video/mp4');
mediaInfo.metadata = new chrome.cast.media.GenericMediaMetadata();
mediaInfo.metadata.metadataType = chrome.cast.media.MetadataType.GENERIC;
mediaInfo.metadata.title = this.mediaContents[mediaIndex]['title'];
mediaInfo.metadata.images = [
{'url': MEDIA_SOURCE_ROOT + this.mediaContents[mediaIndex]['thumb']}];
var request = new chrome.cast.media.LoadRequest(mediaInfo);
castSession.loadMedia(request).then(
this.playerHandler.loaded.bind(this.playerHandler),
function (errorCode) {
this.playerState = PLAYER_STATE.ERROR;
console.log('Remote media load error: ' +
CastPlayer.getErrorMessage(errorCode));
}.bind(this));
}.bind(this);
//...
};
次に、ローカル再生とリモート再生を切り替えるメソッドを追加します。
/**
* This is a method for switching between the local and remote
* players. If the local player is selected, setupLocalPlayer()
* is run. If there is a cast device connected we run
* setupRemotePlayer().
*/
CastPlayer.prototype.switchPlayer = function() {
this.stopProgressTimer();
this.resetVolumeSlider();
this.playerHandler.stop();
this.playerState = PLAYER_STATE.IDLE;
if (cast && cast.framework) {
if (this.remotePlayer.isConnected) {
this.setupRemotePlayer();
return;
}
}
this.setupLocalPlayer();
};
最後に、キャストのエラー メッセージを処理するメソッドを追加します。
/**
* Makes human-readable message from chrome.cast.Error
* @param {chrome.cast.Error} error
* @return {string} error message
*/
CastPlayer.getErrorMessage = function(error) {
switch (error.code) {
case chrome.cast.ErrorCode.API_NOT_INITIALIZED:
return 'The API is not initialized.' +
(error.description ? ' :' + error.description : '');
case chrome.cast.ErrorCode.CANCEL:
return 'The operation was canceled by the user' +
(error.description ? ' :' + error.description : '');
case chrome.cast.ErrorCode.CHANNEL_ERROR:
return 'A channel to the receiver is not available.' +
(error.description ? ' :' + error.description : '');
case chrome.cast.ErrorCode.EXTENSION_MISSING:
return 'The Cast extension is not available.' +
(error.description ? ' :' + error.description : '');
case chrome.cast.ErrorCode.INVALID_PARAMETER:
return 'The parameters to the operation were not valid.' +
(error.description ? ' :' + error.description : '');
case chrome.cast.ErrorCode.RECEIVER_UNAVAILABLE:
return 'No receiver was compatible with the session request.' +
(error.description ? ' :' + error.description : '');
case chrome.cast.ErrorCode.SESSION_ERROR:
return 'A session could not be created, or a session was invalid.' +
(error.description ? ' :' + error.description : '');
case chrome.cast.ErrorCode.TIMEOUT:
return 'The operation timed out.' +
(error.description ? ' :' + error.description : '');
}
};
アプリを実行し、キャスト デバイスに接続して動画の再生を開始します。動画がレシーバーで再生されます。
7. Cast Connect のサポートを追加する
Cast Connect ライブラリを使用すると、既存のセンダー アプリケーションは Cast プロトコルを介して Android TV アプリケーションと通信できます。Cast Connect は Cast インフラストラクチャ上に構築されており、Android TV アプリがレシーバーとして機能します。
依存関係
- Chrome ブラウザ バージョン M87 以降
Android Receiver 互換の設定
Android TV アプリ(Android レシーバーとも呼ばれる)を起動するには、CastOptions
オブジェクトで androidReceiverCompatible
フラグを true に設定する必要があります。
initializeCastPlayer
関数の CastVideos.js
に次のコードを追加します。
var options = {};
...
options.androidReceiverCompatible = true;
cast.framework.CastContext.getInstance().setOptions(options);
起動時の認証情報を設定する
送信側では、セッションに参加するユーザーを表す CredentialsData
を指定できます。credentials
は、ATV アプリが理解できる限り、ユーザー定義可能な文字列です。CredentialsData
は、起動時または参加時にのみ Android TV アプリに渡されます。接続中に再度設定しても、Android TV アプリには渡されません。
起動認証情報を設定するには、起動オプションの設定後に CredentialsData
を定義する必要があります。
次のコードを CastVideos.js
クラスの initializeCastPlayer
関数の下に追加します。
cast.framework.CastContext.getInstance().setOptions(options);
...
let credentialsData = new chrome.cast.CredentialsData("{\"userId\": \"abc\"}");
cast.framework.CastContext.getInstance().setLaunchCredentialsData(credentialsData);
...
読み込みリクエストで認証情報を設定する
ウェブ レシーバー アプリと Android TV アプリで credentials
の処理が異なる場合は、それぞれに個別の認証情報を定義する必要があります。これを処理するには、setupRemotePlayer
関数の playerTarget.load
の下の CastVideos.js
に次のコードを追加します。
...
var request = new chrome.cast.media.LoadRequest(mediaInfo);
request.credentials = 'user-credentials';
request.atvCredentials = 'atv-user-credentials';
...
送信側がキャストするレシーバーアプリに応じて、SDK は現在のセッションに使用する認証情報を自動的に処理します。
Cast Connect のテスト
Chromecast with Google TV に Android TV APK をインストールする手順は次のとおりです。
- Android TV デバイスの IP アドレスを確認します。通常は、[設定] > [ネットワークとインターネット] > [デバイスが接続されているネットワーク名] で確認できます。右側には、詳細情報とネットワーク上のデバイスの IP が表示されます。
- デバイスの IP アドレスを使用して、ターミナルから ADB 経由で接続します。
$ adb connect <device_ip_address>:5555
- ターミナル ウィンドウから、この Codelab の冒頭でダウンロードした Codelab サンプルの最上位フォルダに移動します。例:
$ cd Desktop/chrome_codelab_src
- 次のコマンドを実行して、このフォルダ内の .apk ファイルを Android TV にインストールします。
$ adb -s <device_ip_address>:5555 install android-tv-app.apk
- Android TV デバイスの [アプリ] メニューに「Cast Videos」という名前のアプリが表示されます。
- 更新したウェブ送信元コードを実行し、キャスト アイコンを使用するか、Chrome ブラウザのプルダウン メニューから
Cast..
を選択して、Android TV デバイスとキャスト セッションを確立します。これにより、Android Receiver で Android TV アプリが起動され、Android TV リモコンを使用して再生を操作できるようになります。
8. 完了
Chrome ウェブアプリで Cast SDK ウィジェットを使用して動画アプリをキャスト対応にする方法は以上です。
詳しくは、ウェブ送信者のデベロッパー ガイドをご覧ください。