Web-App für Google Cast aktivieren

Mit Sammlungen den Überblick behalten Sie können Inhalte basierend auf Ihren Einstellungen speichern und kategorisieren.

1. Übersicht

Logo: Google Cast

In diesem Codelab erfahren Sie, wie Sie eine vorhandene Web-Video-App ändern, 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 ihr Mobilgerät dann 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 gemäß der Checkliste für das Google Cast-Design hinzufügen.

Die Checkliste für das Google Cast-Design soll dafür sorgen, dass Cast auf allen unterstützten Plattformen einfach und vorhersehbar funktioniert.

Ziele

Wenn Sie dieses Codelab abgeschlossen haben, haben Sie 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 Beispielvideo-App hinzu
  • So fügen Sie das Cast-Symbol zum Auswählen eines Google Cast-Geräts hinzu
  • Eine Verbindung zu einem Übertragungsgerät herstellen und einen Medienempfänger starten
  • Ein Video streamen
  • So integrieren Sie Cast Connect

Voraussetzungen

  • Der aktuelle Google Chrome-Browser
  • npm.
  • Ein Google Cast-Gerät wie Chromecast oder Android TV, das mit Internetzugang konfiguriert ist.
  • Ein Fernseher oder Monitor mit HDMI-Eingang.
  • Zum Testen der Cast Connect-Integration ist Chromecast mit Google TV erforderlich. Für den Rest des Codelabs ist dies optional. Wenn Sie keine haben, können Sie den Schritt Support für Cast Connect hinzufügen am Ende dieser Anleitung überspringen.

Plattform

  • Dafür benötigen Sie Vorkenntnisse in der Webentwicklung.
  • Außerdem benötigst du Vorkenntnisse zum Fernsehen.

Wie verwenden Sie diese Anleitung?

Nur durchlesen Lies dir die Übungen durch

Wie würden Sie Ihre Erfahrungen im Erstellen von Webanwendungen bewerten?

Anfänger Fortgeschritten Profi

Wie würdest du deine Erfahrung mit dem Fernsehen bewerten?

Neuling Fortgeschritten Profi

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

Google Chrome-Logo

Sehen wir uns zuerst an, wie die ausgefüllte 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 wiedergeben oder auf ein Google Cast-Gerät streamen.

Anwendung ausführen

Falls Ihnen kein Server zur Verfügung steht, ist das kein Problem. Sie können node.js, das Knotenmodul http-server und ngrok, installieren.

npm install -g http-server
npm install -g ngrok

Wenn Sie http-server verwenden, gehen Sie in der Konsole so vor:

cd app-done
http-server

Sie sollten dann Folgendes sehen:

Starting up http-server, serving ./
Available on:
  http://127.0.0.1:8080
  http://172.19.17.192:8080
Hit CTRL-C to stop the server

Beachten Sie den verwendeten lokalen Port und führen Sie folgende Schritte in einem neuen Terminal aus, um den lokalen Absender über ngrok mit HTTPS freizugeben: (8080 sollte der Port des HTTP-Servers sein.)

ngrok http 8080

Dadurch wird ein ngrok-Tunnel zu Ihrem lokalen HTTP-Server eingerichtet. Dadurch erhalten Sie einen global verfügbaren HTTPS-gesicherten Endpunkt, den Sie im nächsten Schritt verwenden können (https://116ec943.eu.ngrok.io):

ngrok by @inconshreveable                                                                                                                                                                                                                                     (Ctrl+C to quit)

Session Status         online
Version                2.2.4
Web Interface          http://127.0.0.1:8080
Forwarding             http://116ec943.eu.ngrok.io -> localhost:8080
Forwarding             https://116ec943.eu.ngrok.io -> localhost:8080

Sowohl ngrok als auch http-server sollten während des Codelabs weiter ausgeführt werden. Alle lokal vorgenommenen Änderungen sind sofort verfügbar.

Rufen Sie in Ihrem Browser die von ngrok zurückgegebene HTTPS-URL auf.

  1. Die Video-App sollte angezeigt werden.
  2. Klicke auf das Cast-Symbol und wähle dein Google Cast-Gerät aus.
  3. Wähle ein Video aus und klicke auf die Wiedergabeschaltfläche.
  4. Das Video wird auf Ihrem Google Cast-Gerät abgespielt.

Bild eines Videos, das auf einem Übertragungsgerät wiedergegeben wird

Klicke auf die Pause-Schaltfläche im Videoelement, um das Video auf dem Empfänger zu pausieren. Klicke 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.

Wir müssen den Server anhalten, bevor wir fortfahren. Rufen Sie das Terminal mit ausgeführtem http-server auf und beenden Sie den Prozess mit folgendem Befehl:

CTRL-C

Rufen Sie das Terminal mit ausgeführtem ngrok auf und beenden Sie den Prozess mit folgendem Befehl:

CTRL-C

4. Startprojekt vorbereiten

Bild eines Videos, das auf einem Übertragungsgerät wiedergegeben wird

Wir müssen die heruntergeladene Start-App für Google Cast unterstützen. Im Folgenden finden Sie einige Begriffe von Google Cast, die wir in diesem Codelab verwenden werden:

  • 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 Projekt „Starter“ aufbauen:

  1. Wählen Sie das Verzeichnis Ordnersymbolapp-start aus dem Beispielcode-Download aus.
  2. Führen Sie die App mit http-server und ngrok aus und sehen Sie sich die UI an.

Hinweis: Während Sie dieses Codelab durcharbeiten, sollte http-server von Ihnen vorgenommene Änderungen übernehmen. Wenn dies der Fall ist, versuchen Sie, http-server zu beenden und neu zu starten.

App-Design

Die App ruft eine Liste mit Videos von einem Remote-Webserver ab und stellt dem Nutzer eine Liste zur Verfügung. Nutzer können ein Video auswählen, um sich die Details anzusehen, oder das Video lokal auf dem Mobilgerät abspielen.

Die App besteht aus einer Hauptansicht (in index.html definiert) und einem Hauptcontroller (CastVideos.js.)

index.html

In dieser HTML-Datei wird fast die gesamte Benutzeroberfläche für die Web-App deklariert.

Es gibt ein paar Bereiche, in denen unser div#main_video-Element das Videoelement enthält. In Bezug auf unser Video-div gibt es div#media_control, das alle Steuerelemente für das Videoelement definiert. Darunter befindet sich media_info, das die Details des angezeigten Videos anzeigt. Schließlich zeigt das div-Element carousel eine Liste von Videos in einem div-Element an.

Die Datei index.html startet außerdem das Cast SDK und weist die Funktion CastVideos an, zu laden.

Der Großteil der Inhalte, die in diese Elemente eingefügt werden, wird in CastVideos.js definiert, eingefügt und gesteuert. Sehen wir uns das genauer an.

CastVideos.js

Dieses Skript verwaltet die gesamte Logik für die Web-App für Cast-Videos. Die Liste der Videos und die zugehörigen Metadaten, die in CastVideos.js definiert sind, sind in einem Objekt mit dem Namen mediaJSON enthalten.

Es gibt einige wichtige Bereiche, die gemeinsam dafür sorgen, dass das Video sowohl lokal als auch remote verwaltet und abgespielt werden kann. Insgesamt ist dies eine recht einfache Webanwendung.

CastPlayer ist die Hauptklasse, die die gesamte App verwaltet, den Player einrichtet, Medien auswählt und Ereignisse zur Wiedergabe von Medien an PlayerHandler bindet. CastPlayer.prototype.initializeCastPlayer ist die Methode, mit der alle Cast-Funktionen eingerichtet werden. CastPlayer.prototype.switchPlayer wechselt den Status zwischen lokalen und Remote-Playern. Mit CastPlayer.prototype.setupLocalPlayer und CastPlayer.prototype.setupRemotePlayer werden lokale und Remote-Player initialisiert.

PlayerHandler ist die Klasse, die für die Verwaltung der Medienwiedergabe verantwortlich ist. Es gibt eine Reihe anderer Methoden, die für die Details der Verwaltung von Medien und der Wiedergabe verantwortlich sind.

Häufig gestellte Fragen

5. Cast-Symbol hinzufügen

Bild einer für Google Cast optimierten App

Für Google Cast optimierte Apps zeigen das Cast-Symbol im Videoelement an. Wenn Nutzer auf das Cast-Symbol klicken, wird eine Liste der Übertragungsgeräte angezeigt, die der Nutzer auswählen kann. Wenn der Nutzer Inhalte lokal auf dem Gerät des Absenders abgespielt hat, wird durch Auswahl eines Übertragungsgeräts die Wiedergabe auf diesem Übertragungsgerät gestartet oder fortgesetzt. Der Nutzer kann jederzeit während einer Streamingsitzung auf das Cast-Symbol klicken und die Übertragung Ihrer App an das Cast-Gerät beenden. Der Nutzer muss in der Lage sein, auf jedem Bildschirm Ihrer App eine Verbindung zum Cast-Gerät herzustellen bzw. zu trennen, wie in der Google Cast-Design-Checkliste beschrieben.

Konfiguration

Für das Startprojekt sind dieselben Abhängigkeiten und Einrichtungen erforderlich wie für die fertige Beispiel-App.

Wenn Sie http-server verwenden, gehen Sie in der Konsole so vor:

cd app-start
http-server

Sie sollten dann Folgendes sehen:

Starting up http-server, serving ./
Available on:
  http://127.0.0.1:8080
  http://172.19.17.192:8080
Hit CTRL-C to stop the server

Beachten Sie den verwendeten lokalen Port und führen Sie folgende Schritte in einem neuen Terminal aus, um den lokalen Absender über ngrok mit HTTPS freizugeben: (8080 sollte der Port des HTTP-Servers sein.)

ngrok http 8080

Dadurch wird ein ngrok-Tunnel zu Ihrem lokalen HTTP-Server eingerichtet. Dadurch erhalten Sie einen global verfügbaren HTTPS-gesicherten Endpunkt, den Sie im nächsten Schritt verwenden können (https://116ec943.eu.ngrok.io):

ngrok by @inconshreveable                                                                                                                                                                                                                                     (Ctrl+C to quit)

Session Status         online
Version                2.2.4
Web Interface          http://127.0.0.1:8080
Forwarding             http://116ec943.eu.ngrok.io -> localhost:8080
Forwarding             https://116ec943.eu.ngrok.io -> localhost:8080

Sowohl ngrok als auch http-server sollten während des Codelabs weiter ausgeführt werden. Alle lokal vorgenommenen Änderungen sind sofort verfügbar.

Rufen Sie in Ihrem Browser die von ngrok zurückgegebene HTTPS-URL auf.

Initialisierung

Das Cast-Framework hat das globale Singleton-Objekt CastContext, das alle Aktivitäten des Frameworks koordiniert. Dieses Objekt muss zu Beginn des Lebenszyklus der Anwendung initialisiert werden. Dies ist normalerweise verfügbar, normalerweise über einen Callback, der window['__onGCastApiAvailable'] zugewiesen wird und nach dem Laden des Cast SDK aufgerufen wird. In diesem Fall wird die CastContext in CastPlayer.prototype.initializeCastPlayer aufgerufen, die aus dem zuvor genannten Callback aufgerufen wird.

Bei der Initialisierung von CastContext muss ein options-JSON-Objekt angegeben werden. Diese Klasse enthält Optionen, die sich auf das Verhalten des Frameworks auswirken. Die wichtigste ist die ID der Empfängeranwendung. Damit wird die Liste der verfügbaren Übertragungsgeräte so gefiltert, dass nur Geräte angezeigt werden, die die angegebene App ausführen können. Außerdem wird die Empfängeranwendung gestartet, wenn eine Übertragungssitzung gestartet wird.

Wenn Sie Ihre eigene für Google Cast optimierte App entwickeln, müssen Sie sich als Cast-Entwickler registrieren und dann eine Anwendungs-ID für Ihre App abrufen. Für dieses Codelab verwenden wir eine Beispiel-App-ID.

Fügen Sie index.html ganz am Ende des Abschnitts body folgenden Code hinzu:

<script type="text/javascript" src="https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1"></script>

Fügen Sie index.html den folgenden Code hinzu, um die CastVideos-App zu initialisieren und die 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>

Nun müssen wir eine neue Methode in CastVideos.js hinzufügen, die der gerade in index.html aufgerufenen Methode entspricht. Lassen Sie uns eine neue Methode namens initializeCastPlayer hinzufügen, 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)
    );
};

Abschließend 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 die CastContext initialisiert wurde, müssen wir das Cast-Symbol hinzufügen, damit der Nutzer ein Übertragungsgerät auswählen kann. Das Cast SDK umfasst die Cast-Schaltflächenkomponente google-cast-launcher mit der ID castbutton". Sie kann dem Videoelement der App hinzugefügt werden, indem eine button im Abschnitt media_control 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 sollten Sie ein Cast-Symbol sehen. Wenn Sie darauf klicken, werden die Cast-Geräte in Ihrem lokalen Netzwerk aufgelistet. Die Geräteerkennung wird automatisch über den Chrome-Browser verwaltet. Wählen Sie Ihr Übertragungsgerät aus. Die Beispiel-Empfänger-App wird dann auf dem Übertragungsgerät geladen.

Wir haben noch keine Medienwiedergabe unterstützt, sodass Sie noch keine Videos über das Cast-Gerät abspielen können. Klicke auf das Cast-Symbol, um das Streaming zu beenden.

6. Streamen von Videoinhalten

Bild einer für Google Cast optimierten App mit Auswahlmenü für Übertragungsgeräte

Wir erweitern die Beispiel-App, damit du auch Videos per Remotezugriff auf einem Übertragungsgerät abspielen kannst. Dazu müssen wir die verschiedenen Ereignisse im Cast-Framework beobachten.

Medien streamen

Wenn Sie Medien auf einem Übertragungsgerät abspielen möchten, gilt Folgendes:

  1. Erstellen Sie über das Cast SDK ein MediaInfo-Objekt vom Typ JSON, mit dem ein Mediaplan modelliert wird.
  2. Der Nutzer stellt eine Verbindung zum Übertragungsgerät her, um die Empfängeranwendung zu starten.
  3. Laden Sie das Objekt MediaInfo in Ihren Receiver und spielen Sie den Inhalt ab.
  4. Verfolgen Sie den Medienstatus.
  5. Sende basierend auf Nutzerinteraktionen Wiedergabebefehle an den Empfänger.

Schritt 1 ist die Zuordnung eines Objekts zu einem anderen. MediaInfo versteht das Cast SDK und mediaJSON steht für die Kapselung eines Media-Elements in der App. Wir können ein mediaJSON einfach einem MediaInfo zuordnen. Wir haben Schritt 2 bereits im vorherigen Abschnitt ausgeführt. Schritt 3 ist mit dem Cast SDK ganz einfach.

In der Beispiel-App CastPlayer wird in der switchPlayer-Methode bereits zwischen lokaler und Remote-Wiedergabe unterschieden:

if (cast && cast.framework) {
  if (this.remotePlayer.isConnected) {
    //...

In diesem Codelab ist es nicht wichtig, dass du genau verstehst, wie die gesamte Beispiellogik funktioniert. Es ist jedoch wichtig zu verstehen, dass der Mediaplayer Ihrer App so angepasst werden muss, dass die lokale und die Remote-Wiedergabe berücksichtigt werden.

Im Moment ist der lokale Player immer im lokalen Wiedergabestatus, da er noch nichts über den Streaming-Status weiß. Wir müssen die Benutzeroberfläche basierend auf Statusübergängen aktualisieren, die im Cast-Framework erfolgen. Wenn wir beispielsweise mit dem Streamen beginnen, müssen wir die lokale Wiedergabe beenden und einige Steuerelemente deaktivieren. Wenn wir in diesem Ansicht-Controller das Streamen beenden, müssen wir zur lokalen Wiedergabe übergehen. Dazu müssen wir die verschiedenen Ereignisse im Cast-Framework beobachten.

Cast-Sitzungsverwaltung

Beim Cast-Framework werden bei einer Cast-Sitzung die folgenden Schritte durchgeführt: Verbinden mit einem Gerät, Starten (oder Teilnehmen an einer bestehenden) Sitzung, Verbinden mit einer Empfängeranwendung und Initialisieren eines Mediensteuerungskanals (falls zutreffend). Über den Mediensteuerungskanal wird festgelegt, wie das Cast-Framework Nachrichten zur Medienwiedergabe sendet und vom Empfänger empfängt.

Die Streamingsitzung wird automatisch gestartet, wenn der Nutzer ein Gerät über die Cast-Schaltfläche auswählt, und wird automatisch beendet, wenn der Nutzer die Verbindung trennt. Die Verbindung mit einer Empfängersitzung aufgrund von Netzwerkproblemen wird ebenfalls automatisch über das Cast-Framework hergestellt.

Streamingsitzungen werden von der CastSession verwaltet, auf die über cast.framework.CastContext.getInstance().getCurrentSession() zugegriffen werden kann. Mit den EventListener-Callbacks können Sie Sitzungsereignisse wie das Erstellen, Sperren, Wiederaufnahme und Beenden von Sitzungen beobachten.

In unserer aktuellen Anwendung übernehmen wir die gesamte Sitzungs- und Statusverwaltung in der Methode setupRemotePlayer. Lassen Sie uns mit der Konfiguration in Ihrer App beginnen, indem Sie den folgenden Code zu CastVideos.js 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 immer noch alle Ereignisse von Callbacks binden und alle eingehenden Ereignisse verarbeiten. Das ist eine recht einfache Aufgabe, also kümmern wir uns jetzt darum:

/**
 * 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 einige praktische APIs zur Verwaltung der Remote-Wiedergabe von Medien auf dem Empfänger. Bei einem CastSession, der die Medienwiedergabe unterstützt, werden vom SDK automatisch Instanzen von RemotePlayer und RemotePlayerController erstellt. Sie können darauf zugreifen, indem Sie Instanzen von cast.framework.RemotePlayer bzw. cast.framework.RemotePlayerController erstellen, wie oben im Codelab gezeigt.

Als Nächstes müssen wir das aktuell ausgewählte Video auf dem Empfänger laden, indem wir ein MediaInfo-Objekt erstellen, das vom SDK verarbeitet und die Anfrage übergeben werden kann. Fügen Sie dazu folgenden Code zu setupRemotePlayer 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üge jetzt eine Methode hinzu, um zwischen der lokalen und der 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 zum Verarbeiten 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ühre jetzt die App aus. Stelle eine Verbindung zu deinem Übertragungsgerät her und starte die Wiedergabe eines Videos. Sie sollten das Video auf dem Empfänger sehen.

7. Cast Connect-Unterstützung hinzufügen

Über die Cast Connect-Bibliothek können bestehende Absenderanwendungen mit Android TV-Apps über das Cast-Protokoll kommunizieren. Cast Connect baut auf der Cast-Infrastruktur auf und die Android TV App fungiert als Empfänger.

Abhängigkeiten

  • Chrome-Version M87 oder höher

Mit Android Receiver kompatibel

Zum Starten der Android TV-App, die auch als Android Receiver bezeichnet wird, muss das Flag androidReceiverCompatible im Objekt CastOptions auf „true“ gesetzt werden.

Fügen Sie der Datei CastVideos.js in der Funktion initializeCastPlayer den folgenden Code hinzu:

var options = {};
...
options.androidReceiverCompatible = true;

cast.framework.CastContext.getInstance().setOptions(options);

Anmeldedaten für den Start festlegen

Auf Absenderseite können Sie CredentialsData angeben, um anzugeben, wer an der Sitzung teilnimmt. credentials ist ein String, der vom Nutzer definiert werden kann, solange Ihre ATV-App sie verstehen kann. CredentialsData wird nur während der Einführung oder beim Beitritt an deine Android TV App übergeben. Wenn du sie später noch einmal verbindest, wird sie nicht an deine Android TV App weitergegeben.

Zum Festlegen von Anmeldedaten für die Einführung muss CredentialsData jederzeit nach dem Festlegen der Optionen für die Einführung definiert werden.

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

Für den Fall, dass Ihre Web Receiver App und Ihre Android TV App credentials unterschiedlich verarbeiten, müssen Sie möglicherweise für jeden eine eigene Anmeldedaten erstellen. Fügen Sie dazu in der Funktion CastVideos.js unter playerTarget.load in der Funktion setupRemotePlayer den folgenden Code ein:

...
var request = new chrome.cast.media.LoadRequest(mediaInfo);
request.credentials = 'user-credentials';
request.atvCredentials = 'atv-user-credentials';
...

Je nachdem, an welche Empfänger-App Ihr Absender streamt, verarbeitet das SDK automatisch, welche Anmeldedaten für die aktuelle Sitzung verwendet werden sollen.

Cast Connect wird getestet

So installieren Sie das Android TV-APK auf Chromecast mit Google TV:

  1. Suchen Sie die IP-Adresse Ihres Android TV-Geräts. Sie finden sie in der Regel unter Einstellungen > Netzwerk > Internetname des Geräts. Auf der rechten Seite werden die Details und die IP-Adresse Ihres Geräts im Netzwerk angezeigt.
  2. Verwenden Sie die IP-Adresse für Ihr Gerät, um über ADB eine Verbindung über das Terminal herzustellen:
$ adb connect <device_ip_address>:5555
  1. Gehen Sie im Terminalfenster zum Ordner auf oberster Ebene für die Codelab-Beispiele, die Sie zu Beginn dieses Codelabs heruntergeladen haben. Beispiel:
$ cd Desktop/chrome_codelab_src
  1. Installieren Sie die APK-Datei in diesem Ordner auf Ihrem Android TV-Gerät:
$ adb -s <device_ip_address>:5555 install android-tv-app.apk
  1. Sie sollten jetzt auf Ihrem Android TV-Gerät im Menü Meine Apps den Namen Videos streamen sehen.
  2. Führe den aktualisierten Websendercode aus und richte mit deinem Android TV-Gerät eine Streamingsitzung über das Cast-Symbol ein oder wähle Cast.. im Drop-down-Menü deines Chrome-Browsers aus. Dadurch sollte die Android TV App auf deinem Android Receiver gestartet und die Wiedergabe über die Fernbedienung des Android TV gesteuert werden.

8. Glückwunsch

Jetzt wissen Sie, wie Sie mithilfe der Cast SDK-Widgets in einer Chrome-Web-App eine Video-App für Google Cast aktivieren.

Weitere Informationen finden Sie im Entwicklerleitfaden Web Sender.