1. Überblick
In diesem Codelab erfahren Sie, wie Sie eine Webvideo-App ändern können, um Inhalte auf ein für Google Cast optimiertes Gerät zu streamen.
Was ist Google Cast?
Mit Google Cast können Nutzer Inhalte von einem Mobilgerät auf einen Fernseher streamen. Nutzer können dann ihr Mobilgerät als Fernbedienung für die Medienwiedergabe auf dem Fernseher verwenden.
Mit dem Google Cast SDK können Sie Ihre App erweitern, um einen Fernseher oder ein Soundsystem zu steuern. Mit dem Cast SDK können Sie die erforderlichen UI-Komponenten basierend auf der Checkliste für das Google Cast-Design hinzufügen.
Die Checkliste für das Google Cast-Design enthält eine einfache und vorhersehbare Checkliste für Cast auf allen unterstützten Plattformen.
Ziele
Wenn Sie dieses Codelab abgeschlossen haben, verfügen Sie über eine Chrome-Webvideo-App, mit der Sie Videos auf ein Google Cast-Gerät streamen können.
Lerninhalte
- So fügen Sie das Google Cast SDK einer Beispiel-Video-App hinzu:
- Hinzufügen des Cast-Symbols zur Auswahl eines Google Cast-Geräts
- So stellen Sie eine Verbindung zu einem Übertragungsgerät her und starten einen Medienempfänger.
- So streamen Sie ein Video.
- Cast Connect einbinden
Voraussetzungen
- Der aktuelle Google Chrome-Browser.
- HTTPS-Hostingdienst wie Firebase Hosting oder ngrok
- Ein Google Cast-Gerät wie Chromecast oder Android TV mit Internetzugang
- Ein Fernseher oder Monitor mit HDMI-Eingang
- Zum Testen der Cast Connect-Integration ist Chromecast mit Google TV erforderlich, für den Rest des Codelab ist dies jedoch optional. Wenn Sie keine Google Cast Connect-Unterstützung haben, können Sie den Schritt Unterstützung für Cast Connect hinzufügen gegen Ende dieser Anleitung überspringen.
Plattform
- Sie müssen bereits über Kenntnisse in der Webentwicklung verfügen.
- Vorkenntnisse im Fernsehen werden benötigt :)
Wie werden Sie diese Anleitung verwenden?
Wie würden Sie Ihre Erfahrung mit der Entwicklung von Webanwendungen bewerten?
Wie würdest du deine Erfahrung beim Fernsehen bewerten?
2. Beispielcode abrufen
Sie können den gesamten Beispielcode auf Ihren Computer herunterladen...
und entpacken Sie die heruntergeladene ZIP-Datei.
3. Beispiel-App ausführen
Sehen wir uns zuerst an, wie die fertige Beispiel-App aussieht. Die App ist ein einfacher Videoplayer. Der Nutzer kann ein Video aus einer Liste auswählen und es dann lokal auf dem Gerät abspielen oder auf ein Google Cast-Gerät streamen.
Um abgeschlossene Elemente verwenden zu können, muss sie gehostet werden.
Wenn kein Server zur Verfügung steht, können Sie Firebase Hosting oder ngrok verwenden.
Server ausführen
Nachdem Sie den Dienst Ihrer Wahl eingerichtet haben, gehen Sie zu app-done
und starten Sie Ihren Server.
Rufen Sie in Ihrem Browser die HTTPS-URL des gehosteten Beispiels auf.
- Die Video-App sollte jetzt angezeigt werden.
- Klicke auf das Cast-Symbol und wähle dein Google Cast-Gerät aus.
- Wähle ein Video aus und klicke auf die Wiedergabeschaltfläche.
- Das Video wird auf Ihrem Google Cast-Gerät wiedergegeben.
Klicken Sie auf die Pause-Schaltfläche im Videoelement, um das Video auf dem Empfänger anzuhalten. Klicken Sie im Videoelement auf die Wiedergabeschaltfläche, um die Wiedergabe des Videos fortzusetzen.
Klicke auf das Cast-Symbol, um das Streamen auf das Google Cast-Gerät zu beenden.
Stoppen Sie zuerst den Server.
4. Startprojekt vorbereiten
Wir müssen der heruntergeladene Start-App Support für Google Cast hinzufügen. Hier sind einige Google Cast-Terminologie, die wir in diesem Codelab verwenden werden:
- Wenn eine Absender-App auf einem Mobilgerät oder Laptop ausgeführt wird
- Eine Empfänger-App wird auf dem Google Cast-Gerät ausgeführt.
Jetzt können Sie mit Ihrem bevorzugten Texteditor auf dem Startprojekt aufbauen:
- Wählen Sie das Verzeichnis
app-start
aus dem heruntergeladenen Beispielcode aus. - Führen Sie die Anwendung auf Ihrem Server aus und erkunden Sie die Benutzeroberfläche.
Hinweis: Während Sie dieses Codelab durcharbeiten, müssen Sie das Beispiel je nach Dienst neu auf Ihrem Server hosten.
App-Design
Die App ruft eine Liste mit Videos von einem Remote-Webserver ab und stellt dem Nutzer eine Liste bereit. Nutzer können ein Video auswählen, um die Details aufzurufen, oder es lokal auf dem Mobilgerät abspielen.
Die App besteht aus einer Hauptansicht, die in index.html
definiert ist, und dem Hauptcontroller (CastVideos.js.
).
index.html
Diese HTML-Datei deklariert fast die gesamte Benutzeroberfläche für die Webanwendung.
Es gibt einige Abschnitte mit Aufrufen, zum Beispiel div#main_video
, das das Videoelement enthält. In Bezug auf unser Video-Div haben wir div#media_control
, mit dem alle Steuerelemente für das Videoelement definiert werden. Darunter befindet sich media_info
mit den Details des angezeigten Videos. Schließlich zeigt das div-Element carousel
eine Liste von Videos in einem div-Element an.
Die Datei index.html
führt auch ein Bootstrapping des Cast SDK aus und weist die Funktion CastVideos
an, zu laden.
Der Großteil des Inhalts, der in diese Elemente eingefügt wird, wird in CastVideos.js
definiert, eingeschleust und gesteuert. Sehen wir uns das an.
CastVideos.js
Dieses Skript verwaltet die gesamte Logik für die Cast-Videos-Web-App. Die Liste der Videos und der zugehörigen Metadaten, die in CastVideos.js
definiert sind, ist in einem Objekt mit dem Namen mediaJSON
enthalten.
Es gibt mehrere Hauptbereiche, die zusammen dafür zuständig sind, das Video lokal und remote zu verwalten und abzuspielen. Insgesamt ist dies eine ziemlich einfache Webanwendung.
CastPlayer
ist die Hauptklasse, die die gesamte App verwaltet. Sie richtet den Player ein, wählt Medien aus und bindet Ereignisse an PlayerHandler
für die Wiedergabe von Medien. CastPlayer.prototype.initializeCastPlayer
ist die Methode, mit der alle Streamingfunktionen eingerichtet werden. CastPlayer.prototype.switchPlayer
wechselt den Status zwischen lokalen und Remote-Playern. CastPlayer.prototype.setupLocalPlayer
und CastPlayer.prototype.setupRemotePlayer
initialisieren lokale und Remote-Player.
PlayerHandler
ist die Klasse, die für die Verwaltung der Medienwiedergabe verantwortlich ist. Es gibt noch eine Reihe anderer Methoden, die für die Verwaltung von Medien und die Wiedergabe verantwortlich sind.
Häufig gestellte Fragen
5. Cast-Symbol hinzufügen
In einer für Google Cast optimierten App wird das Cast-Symbol im Videoelement angezeigt. Wenn Nutzer auf das Cast-Symbol klicken, wird eine Liste mit Übertragungsgeräten angezeigt, die der Nutzer auswählen kann. Wenn der Nutzer Inhalte lokal auf dem Sendergerät wiedergibt, wird durch die Auswahl eines Übertragungsgeräts die Wiedergabe auf diesem Übertragungsgerät gestartet oder fortgesetzt. Der Nutzer kann während einer Streamingsitzung jederzeit auf das Cast-Symbol klicken und das Streamen der App auf das Übertragungsgerät beenden. Der Nutzer muss sich auf jedem Bildschirm Ihrer App mit dem Übertragungsgerät verbinden oder die Verbindung trennen können, wie in der Checkliste für das Google Cast-Design beschrieben.
Konfiguration
Für das Startprojekt sind dieselben Abhängigkeiten und dieselbe Einrichtung wie für die fertiggestellte Beispiel-App erforderlich, aber hosten Sie dieses Mal den Inhalt von app-start
.
Rufen Sie in Ihrem Browser die https
-URL für das von Ihnen gehostete Beispiel auf.
Denken Sie daran, dass Sie das Beispiel je nach Dienst neu auf Ihrem Server hosten müssen, wenn Sie Änderungen vornehmen.
Initialisierung
Das Cast-Framework hat ein globales Singleton-Objekt, das CastContext
, das alle Aktivitäten des Frameworks koordiniert. Dieses Objekt muss früh im Lebenszyklus der App initialisiert werden. Der Aufruf erfolgt in der Regel über einen Callback, der window['__onGCastApiAvailable']
zugewiesen ist. Dieser wird nach dem Laden des Cast SDK aufgerufen und kann verwendet werden. In diesem Fall wird das CastContext
in CastPlayer.prototype.initializeCastPlayer
aufgerufen, das über den oben genannten Callback aufgerufen wird.
Beim Initialisieren von CastContext
muss ein JSON-Objekt vom Typ options
angegeben werden. Diese Klasse enthält Optionen, die das Verhalten des Frameworks beeinflussen. Die wichtigste davon ist die ID der Empfänger-App. Sie wird verwendet, um die Liste der verfügbaren Übertragungsgeräte zu filtern, sodass nur Geräte angezeigt werden, auf denen die angegebene App ausgeführt werden kann. Außerdem wird die Empfangs-App beim Start einer Streaming-Sitzung gestartet.
Wenn Sie Ihre eigene für Google Cast optimierte App entwickeln, müssen Sie sich als Cast-Entwickler registrieren und dann eine App-ID für Ihre App anfordern. In diesem Codelab verwenden wir eine Beispiel-App-ID.
Fügen Sie index.html
ganz am Ende des Abschnitts body
den folgenden Code hinzu:
<script type="text/javascript" src="https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1"></script>
Füge index.html
den folgenden Code hinzu, um die CastVideos
-App und CastContext
zu initialisieren:
<script src="CastVideos.js"></script>
<script type="text/javascript">
var castPlayer = new CastPlayer();
window['__onGCastApiAvailable'] = function(isAvailable) {
if (isAvailable) {
castPlayer.initializeCastPlayer();
}
};
</script>
Jetzt müssen wir in CastVideos.js
eine neue Methode hinzufügen, die der Methode entspricht, die wir gerade in index.html
aufgerufen haben. Fügen wir eine neue Methode namens initializeCastPlayer
hinzu, die Optionen für CastContext festlegt und neue RemotePlayer
und RemotePlayerControllers
initialisiert:
/**
* 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)
);
};
Schließlich müssen wir die Variablen für RemotePlayer
und RemotePlayerController
erstellen:
var CastPlayer = function() {
//...
/* Cast player variables */
/** @type {cast.framework.RemotePlayer} */
this.remotePlayer = null;
/** @type {cast.framework.RemotePlayerController} */
this.remotePlayerController = null;
//...
};
Cast-Symbol
Nachdem CastContext
initialisiert wurde, muss das Cast-Symbol hinzugefügt werden, damit der Nutzer ein Übertragungsgerät auswählen kann. Das Cast SDK stellt eine Cast-Schaltflächenkomponente namens google-cast-launcher
mit der ID "castbutton"
" bereit. Sie kann zum Videoelement der App hinzugefügt werden, indem im Abschnitt "media_control
" einfach ein button
hinzugefügt wird.
So sieht das Schaltflächenelement aus:
<google-cast-launcher id="castbutton"></google-cast-launcher>
Fügen Sie index.html
im Abschnitt media_control
den folgenden Code hinzu:
<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>
Aktualisieren Sie nun die Seite in Ihrem Chrome-Browser. Im Videoelement sollte eine Cast-Schaltfläche zu sehen sein. Wenn Sie darauf klicken, werden die Übertragungsgeräte in Ihrem lokalen Netzwerk aufgelistet. Die Geräteerkennung wird automatisch vom Chrome-Browser verwaltet. Wähle dein Übertragungsgerät aus. Die Beispiel-Empfänger-App wird auf das Übertragungsgerät geladen.
Wir haben keine Unterstützung für die Medienwiedergabe bereitgestellt, daher können Sie im Moment noch keine Videos auf dem Übertragungsgerät abspielen. Klicke auf das Cast-Symbol, um das Streamen zu beenden.
6. Videoinhalte streamen
Die Beispiel-App wird in Zukunft auch für die Remote-Wiedergabe von Videos auf einem Übertragungsgerät verfügbar sein. Dazu müssen wir auf die verschiedenen Ereignisse warten, die vom Cast-Framework generiert werden.
Medien streamen
Wenn Sie Medien auf einem Übertragungsgerät abspielen möchten, müssen folgende Voraussetzungen erfüllt sein:
- Erstellen Sie aus dem Cast SDK ein
MediaInfo
-JSON
-Objekt, das ein Medienelement modelliert. - Der Nutzer stellt eine Verbindung zum Übertragungsgerät her, um die Empfangs-App zu starten.
- Laden Sie das
MediaInfo
-Objekt in den Empfänger und geben Sie den Inhalt wieder. - Verfolgen Sie den Medienstatus.
- Wiedergabebefehle basierend auf Nutzerinteraktionen an den Empfänger senden.
In Schritt 1 wird ein Objekt einem anderen zugeordnet. MediaInfo
ist etwas, das das Cast SDK versteht, und mediaJSON
ist die Kapselung der App für ein Medienelement. Ein mediaJSON
kann ganz einfach einem MediaInfo
zugeordnet werden. Schritt 2 haben wir bereits im vorherigen Abschnitt ausgeführt. Schritt 3 ist mit dem Cast SDK ganz einfach durchzuführen.
Die Beispiel-App CastPlayer
unterscheidet bereits in der switchPlayer
-Methode zwischen lokaler und Remote-Wiedergabe:
if (cast && cast.framework) {
if (this.remotePlayer.isConnected) {
//...
In diesem Codelab ist es nicht wichtig, die Funktionsweise der Beispiel-Player-Logik genau zu verstehen. Der Mediaplayer Ihrer App muss jedoch modifiziert werden, damit sowohl die lokale als auch die Remote-Wiedergabe erkannt werden kann.
Momentan befindet sich der lokale Player immer im lokalen Wiedergabestatus, da er noch nichts über die Übertragungsstatus weiß. Wir müssen die UI basierend auf Statusübergängen im Cast-Framework aktualisieren. Wenn Sie beispielsweise mit dem Streamen beginnen, müssen wir die lokale Wiedergabe beenden und einige Steuerelemente deaktivieren. Ebenso müssen wir zur lokalen Wiedergabe wechseln, wenn wir das Streaming beenden, während wir uns in diesem Ansichts-Controller befinden. Dazu müssen wir auf die verschiedenen Ereignisse warten, die vom Cast-Framework generiert werden.
Streamingsitzung verwalten
Für das Cast-Framework umfasst eine Streamingsitzung die Schritte zum Verbinden mit einem Gerät, Starten einer Sitzung oder Betreten einer bestehenden Sitzung, Verbinden mit einer Empfangs-App und Initialisieren eines Mediensteuerungskanals. Über den Mediensteuerungskanal sendet und empfängt das Cast-Framework Nachrichten zur Medienwiedergabe vom Empfänger.
Die Streamingsitzung wird automatisch gestartet, wenn der Nutzer ein Gerät über das Cast-Symbol auswählt, und automatisch beendet, wenn der Nutzer die Verbindung getrennt hat. Das erneute Herstellen einer Verbindung zu einer Empfängersitzung aufgrund von Netzwerkproblemen wird ebenfalls automatisch vom Cast-Framework übernommen.
Streamingsitzungen werden von der CastSession
verwaltet, auf die über cast.framework.CastContext.getInstance().getCurrentSession()
zugegriffen werden kann. Die EventListener
-Callbacks können zum Überwachen von Sitzungsereignissen wie der Erstellung, Sperrung, Wiederaufnahme und Beendigung verwendet werden.
In unserer aktuellen Anwendung wird die gesamte Sitzungs- und Statusverwaltung mit der Methode setupRemotePlayer
abgewickelt. Beginnen wir damit, dies in Ihrer App zu konfigurieren, indem Sie der CastVideos.js
den folgenden Code hinzufügen:
/**
* 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();
};
Wir müssen trotzdem alle Ereignisse von Callbacks binden und alle eingehenden Ereignisse verarbeiten. Das lässt sich ganz einfach umsetzen:
/**
* 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();
};
Medien werden geladen
Im Cast SDK bieten RemotePlayer
und RemotePlayerController
eine Reihe praktischer APIs für die Remote-Medienwiedergabe auf dem Receiver. Bei einer CastSession
, die die Medienwiedergabe unterstützt, werden Instanzen von RemotePlayer
und RemotePlayerController
automatisch vom SDK erstellt. Sie können darauf zugreifen, indem Sie Instanzen von cast.framework.RemotePlayer
bzw. cast.framework.RemotePlayerController
erstellen, wie weiter oben im Codelab gezeigt.
Als Nächstes müssen wir das aktuell ausgewählte Video auf den Empfänger laden, indem wir ein MediaInfo-Objekt erstellen, damit das SDK die Anfrage verarbeiten und übergeben kann. Fügen Sie dazu setupRemotePlayer
den folgenden Code hinzu:
/**
* 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);
//...
};
Fügen Sie nun eine Methode hinzu, um zwischen lokaler und Remote-Wiedergabe zu wechseln:
/**
* 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();
};
Fügen Sie schließlich eine Methode zur Verarbeitung von Cast-Fehlermeldungen hinzu:
/**
* 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 : '');
}
};
Führen Sie nun die App aus. Stellen Sie eine Verbindung zu Ihrem Übertragungsgerät her und starten Sie die Wiedergabe eines Videos. Das Video sollte auf dem Receiver wiedergegeben werden.
7. Cast Connect-Unterstützung hinzufügen
Über die Cast Connect-Bibliothek können vorhandene Sender-Apps über das Cast-Protokoll mit Android TV-Apps kommunizieren. Cast Connect basiert auf der Cast-Infrastruktur, wobei Ihre Android TV App als Empfänger fungiert.
Abhängigkeiten
- Chrome-Browser, Version M87 oder höher
Kompatibel mit Android-Receivern
Um die Android TV App zu starten, die auch als Android Receiver bezeichnet wird, müssen wir das Flag androidReceiverCompatible
im CastOptions
-Objekt auf true setzen.
Fügen Sie Ihrem CastVideos.js
in der Funktion initializeCastPlayer
den folgenden Code hinzu:
var options = {};
...
options.androidReceiverCompatible = true;
cast.framework.CastContext.getInstance().setOptions(options);
Start-Anmeldedaten festlegen
Auf der Absenderseite können Sie CredentialsData
angeben, um anzugeben, wer der Sitzung beitritt. „credentials
“ ist ein String, der vom Nutzer definiert werden kann, solange er von deiner ATV-App verstanden wird. Die CredentialsData
werden nur beim Start oder während des Beitritts an deine Android TV-App weitergegeben. Wenn Sie sie bei bestehender Verbindung erneut festlegen, wird sie nicht an die Android TV App weitergegeben.
Zum Festlegen von Start-Anmeldedaten muss CredentialsData
jederzeit definiert werden, nachdem die Startoptionen festgelegt wurden.
Fügen Sie der Klasse CastVideos.js
unter der Funktion initializeCastPlayer
den folgenden Code hinzu:
cast.framework.CastContext.getInstance().setOptions(options);
...
let credentialsData = new chrome.cast.CredentialsData("{\"userId\": \"abc\"}");
cast.framework.CastContext.getInstance().setLaunchCredentialsData(credentialsData);
...
Anmeldedaten für Ladeanfrage festlegen
Falls credentials
von Ihrer Web Receiver App und Ihrer Android TV App unterschiedlich verarbeitet wird, müssen Sie möglicherweise separate Anmeldedaten für die beiden Apps definieren. Fügen Sie daher den folgenden Code in Ihrem CastVideos.js
unter playerTarget.load
in der Funktion setupRemotePlayer
ein:
...
var request = new chrome.cast.media.LoadRequest(mediaInfo);
request.credentials = 'user-credentials';
request.atvCredentials = 'atv-user-credentials';
...
Abhängig von der Empfänger-App, an die Ihr Sender Inhalte streamt, verarbeitet das SDK jetzt automatisch, welche Anmeldedaten für die aktuelle Sitzung verwendet werden.
Cast Connect wird getestet
So installieren Sie das Android TV-APK auf Chromecast mit Google TV:
- Ermitteln Sie die IP-Adresse Ihres Android TV-Geräts. Sie ist normalerweise unter Einstellungen > Netzwerk und Internet > (Netzwerkname, mit dem Ihr Gerät verbunden ist) verfügbar. Rechts werden die Details und die IP-Adresse Ihres Geräts im Netzwerk angezeigt.
- Verwenden Sie die IP-Adresse Ihres Geräts, um über das Terminal über ADB eine Verbindung zu ihm herzustellen:
$ adb connect <device_ip_address>:5555
- Gehen Sie in Ihrem Terminalfenster zum Ordner der obersten Ebene für die Codelab-Beispiele, die Sie zu Beginn dieses Codelabs heruntergeladen haben. Beispiel:
$ cd Desktop/chrome_codelab_src
- Installieren Sie die in diesem Ordner vorhandene APK-Datei auf Ihrem Android TV-Gerät .Führen Sie dazu den folgenden Befehl aus:
$ adb -s <device_ip_address>:5555 install android-tv-app.apk
- Im Menü Meine Apps auf deinem Android TV-Gerät sollte jetzt eine App mit dem Namen Videos streamen zu finden sein.
- Führe den aktualisierten Web Sender-Code aus und starte eine Streamingsitzung mit deinem Android TV-Gerät. Verwende dazu das Streaming-Symbol oder wähle im Drop-down-Menü deines Chrome-Browsers
Cast..
aus. Dadurch sollte die Android TV App auf Ihrem Android Receiver gestartet werden und Sie können die Wiedergabe über die Fernbedienung Ihres Android TV steuern.
8. Glückwunsch
Jetzt wissen Sie, wie Sie mithilfe der Cast SDK-Widgets einer Chrome-Web-App eine Video-App für Google Cast aktivieren.
Weitere Informationen finden Sie im Entwicklerleitfaden für Websender.