Für Google Cast optimierte Web-App

1. Überblick

Google Cast-Logo

In diesem Codelab erfahren Sie, wie Sie eine vorhandene 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 gemäß der Google Cast-Design-Checkliste hinzufügen.

Die Checkliste für das Design von Google Cast enthält eine einfache und vorhersehbare Checkliste für alle unterstützten Plattformen.

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

  • Google Cast SDK einer Beispielvideo-App hinzufügen
  • Hinzufügen des Cast-Symbols zur Auswahl eines Google Cast-Geräts
  • Hier erfahren Sie, wie Sie eine Verbindung zu einem Übertragungsgerät herstellen und einen Medienempfänger starten.
  • So streamen Sie ein Video.
  • Cast Connect-Integration

Voraussetzungen

  • Die neueste Version von Google Chrome.
  • HTTPS-Hostingdienst wie Firebase Hosting oder ngrok
  • Ein Google Cast-Gerät wie Chromecast oder Android TV mit Internetzugang
  • Fernseher oder Monitor mit HDMI-Eingang
  • Zum Testen der Cast Connect-Integration ist ein Chromecast mit Google TV erforderlich, für den Rest des Codelabs jedoch optional. Wenn Sie keinen haben, können Sie den Schritt Unterstützung für Cast Connect hinzufügen am Ende dieser Anleitung überspringen.

Plattform

  • Sie müssen über Vorkenntnisse in der Webentwicklung verfügen.
  • Außerdem benötigst du Vorkenntnisse im Fernsehen.

Wie werden Sie dieses Tutorial verwenden?

Nur lesen Lesen und die Übungen abschließen

Wie würden Sie Ihre Erfahrungen mit der Entwicklung von Webanwendungen bewerten?

Neuling Fortgeschritten Profi

Wie würdest du deine Erfahrung mit 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 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 verwenden zu können, muss sie gehostet werden.

Falls Ihnen 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, rufen Sie app-done auf und starten Sie den Server.

Rufen Sie in Ihrem Browser die HTTPS-URL des von Ihnen gehosteten Beispiels auf.

  1. Die Video-App sollte jetzt 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. Die Wiedergabe des Videos auf Ihrem Google Cast-Gerät beginnt.

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

Klicken Sie im Videoelement auf die Schaltfläche „Pause“, 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

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

Wir müssen der heruntergeladenen Start-App Unterstützung für Google Cast hinzufügen. Hier sind einige Google Cast-Terminologie, die wir in diesem Codelab verwenden werden:

  • eine Absender-App auf einem Mobilgerät oder Laptop
  • 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:

  1. Wählen Sie das Verzeichnis Ordnersymbolapp-start aus dem heruntergeladenen Beispielcode aus.
  2. 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 zur Verfügung. Nutzer können ein Video auswählen, um die Details zu sehen, oder das Video 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 UI für die Webanwendung.

Es gibt einige Abschnitte mit Aufrufen, zum Beispiel das div#main_video, das 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 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 stellt außerdem ein Bootstrapping für das Cast SDK bereit und weist die Funktion CastVideos an, zu laden.

Der größte Teil der Inhalte in diesen Elementen 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 ihrer zugehörigen Metadaten, die in CastVideos.js definiert sind, ist in einem Objekt mit dem Namen mediaJSON enthalten.

Es gibt einige Hauptabschnitte, die zusammen für die Verwaltung und Wiedergabe des Videos sowohl lokal als auch remote verantwortlich sind. 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 Medienwiedergabe. CastPlayer.prototype.initializeCastPlayer ist die Methode, mit der alle Cast-Funktionen eingerichtet werden. CastPlayer.prototype.switchPlayer wechselt 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

Bild einer für Google Cast optimierten App

In einer für Google Cast optimierten App wird das Cast-Symbol im Videoelement angezeigt. Wenn der Nutzer auf das Cast-Symbol klickt, wird eine Liste mit Übertragungsgeräten angezeigt. Wenn der Nutzer Inhalte lokal auf dem Sendergerät wiedergegeben hat, wird durch die Auswahl eines Übertragungsgeräts die Wiedergabe auf diesem Übertragungsgerät gestartet oder fortgesetzt. Der Nutzer kann jederzeit während einer Sitzung auf das Cast-Symbol klicken und das Streaming Ihrer App auf das Übertragungsgerät beenden. Der Nutzer muss sich in der Lage sein, sich mit dem Übertragungsgerät zu verbinden bzw. die Verbindung zu trennen, während er einen beliebigen Bildschirm Ihrer App geöffnet hat, wie in der Checkliste für das Design für Google Cast beschrieben.

Konfiguration

Für das Startprojekt sind dieselben Abhängigkeiten und dieselbe Einrichtung wie für die fertige Beispiel-App erforderlich, aber dieses Mal wird der Inhalt von app-start gehostet.

Rufen Sie in Ihrem Browser die URL https 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, in der Regel über einen Callback, der window['__onGCastApiAvailable'] zugewiesen ist. Dieser wird nach dem Laden des Cast SDK aufgerufen und steht zur Verwendung zur Verfügung. In diesem Fall wird die CastContext in CastPlayer.prototype.initializeCastPlayer aufgerufen, die über den zuvor erwähnten 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 App-ID des Empfängers. 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. Beim Start einer Streaming-Sitzung wird die Empfänger-App auch gestartet.

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 anfordern. Für dieses 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 sowie 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 mit dem Namen initializeCastPlayer hinzu, mit der Optionen für CastContext festgelegt und neue RemotePlayer und RemotePlayerControllers initialisiert werden:

/**
 * 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 Sie 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, müssen wir das Cast-Symbol hinzufügen, damit der Nutzer ein Übertragungsgerät auswählen kann. Das Cast SDK enthält eine Cast-Schaltflächenkomponente namens google-cast-launcher mit der ID "castbutton"". Sie kann zum Videoelement der App hinzugefügt werden, indem Sie einfach eine button zum Abschnitt media_control hinzufügen.

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. Das Videoelement sollte eine Cast-Schaltfläche enthalten. Wenn Sie darauf klicken, werden die Cast-Gerä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 dann auf das Übertragungsgerät geladen.

Wir haben keine Unterstützung für die Medienwiedergabe hergestellt, sodass Sie im Moment noch keine Videos auf dem Übertragungsgerät abspielen können. Klicken Sie auf das Cast-Symbol, um das Streaming zu beenden.

6. Videoinhalte streamen

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

Wir werden die Beispiel-App erweitern, damit Videos auch aus der Ferne auf einem Übertragungsgerät abgespielt werden können. Dazu müssen wir auf die verschiedenen Ereignisse warten, die vom Cast-Framework generiert werden.

Medien werden gestreamt

Wenn Sie Medien auf einem Übertragungsgerät abspielen möchten, müssen folgende Voraussetzungen erfüllt sein:

  1. Erstellen Sie aus dem Cast SDK ein MediaInfo-JSON-Objekt, das ein Medienelement modelliert.
  2. Der Nutzer stellt eine Verbindung zum Übertragungsgerät her, um die Empfangs-App zu starten.
  3. Laden Sie das MediaInfo-Objekt in den Empfänger und geben Sie den Inhalt wieder.
  4. Verfolgen Sie den Medienstatus.
  5. Sendet Wiedergabebefehle auf der Grundlage von Nutzerinteraktionen an den Empfänger.

In Schritt 1 wird ein Objekt einem anderen zugeordnet. MediaInfo ist etwas, das das Cast SDK versteht, und mediaJSON ist die Kapselung eines Medienelements in unserer App. Ein mediaJSON kann ganz einfach einem MediaInfo zugeordnet werden. Wir haben Schritt 2 bereits im vorherigen Abschnitt ausgeführt. Schritt 3 lässt sich ganz einfach mit dem Cast SDK durchführen.

Die Beispiel-App CastPlayer unterscheidet bereits mit der Methode switchPlayer zwischen lokaler und Remote-Wiedergabe:

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

Es ist nicht wichtig, dass du in diesem Codelab genau verstehst, wie die gesamte Beispiel-Playerlogik funktioniert. Beachten Sie jedoch, dass der Mediaplayer Ihrer App so angepasst werden muss, dass er sowohl die lokale als auch die Remote-Wiedergabe erkennt.

Momentan befindet sich der lokale Player immer im lokalen Wiedergabestatus, da er noch nichts über die Übertragungsstatus hat. Wir müssen die Benutzeroberfläche basierend auf Statusübergängen aktualisieren, die im Cast-Framework stattfinden. Wenn Sie beispielsweise mit dem Streamen beginnen, müssen wir die lokale Wiedergabe beenden und einige Steuerelemente deaktivieren. Das Gleiche gilt, wenn wir das Streaming beenden, während wir uns im Ansichts-Controller befinden, müssen wir zur lokalen Wiedergabe wechseln. 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: Verbindung zu einem Gerät herstellen, Sitzung starten oder einer bestehenden beitreten, Verbindung zu einer Empfänger-App herstellen und gegebenenfalls einen Mediensteuerungskanal initialisieren. Über den Mediensteuerungskanal sendet und empfängt das Cast-Framework Nachrichten zur Medienwiedergabe vom Empfänger.

Die Übertragung wird automatisch gestartet, wenn der Nutzer ein Gerät über das Cast-Symbol auswählt, und automatisch beendet, wenn der Nutzer die Verbindung trennt. 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 werden die gesamte Sitzungs- und Zustandsverwaltung über die setupRemotePlayer-Methode abgewickelt. Beginnen wir damit, dies in deiner App zu konfigurieren, indem du deiner CastVideos.js den folgenden Code hinzufügst:

/**
 * 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 zuvor im Codelab gezeigt.

Als Nächstes muss das aktuell ausgewählte Video auf den Empfänger geladen werden, indem ein MediaInfo-Objekt erstellt wird, 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

Mit der 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-Browserversion M87 oder höher

Kompatibel mit Android-Receivern festlegen

Um die Android TV App zu starten, die auch als Android-Empfänger bezeichnet wird, muss das androidReceiverCompatible-Flag im CastOptions-Objekt auf „true“ gesetzt werden.

Fügen Sie 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 die ATV-App ihn verstehen kann. Die CredentialsData wird nur beim Start oder der Zeit des Beitritts an deine Android TV-App weitergegeben. Wenn du sie wieder festlegst, während eine Verbindung besteht, wird sie nicht an deine Android TV App übergeben.

Zum Festlegen von Startanmeldedaten muss CredentialsData jederzeit nach dem Festlegen der Startoptionen definiert werden.

Fügen Sie Ihrer 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 in deiner Web-Receiver-App und deiner Android TV-App unterschiedlich verarbeitet werden, musst du unter Umständen für beide separate Anmeldedaten definieren. Um dies zu beheben, fügen Sie den folgenden Code in Ihrem CastVideos.js unter playerTarget.load in der setupRemotePlayer-Funktion 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 überträgt, 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:

  1. 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) zu finden. Auf der rechten Seite werden die Details und die IP-Adresse Ihres Geräts im Netzwerk angezeigt.
  2. Verwende die IP-Adresse deines Geräts, um über das Terminal über ADB eine Verbindung zu ihm herzustellen:
$ adb connect <device_ip_address>:5555
  1. Gehen Sie im Terminalfenster zum Ordner der obersten Ebene mit den Codelab-Beispielen, die Sie zu Beginn dieses Codelabs heruntergeladen haben. Beispiel:
$ cd Desktop/chrome_codelab_src
  1. Installieren Sie die in diesem Ordner enthaltene 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
  1. Sie sollten nun eine App mit dem Namen Videos streamen im Menü Meine Apps auf Ihrem Android TV-Gerät sehen.
  2. Führe den aktualisierten Web Sender-Code aus und starte eine Streaming-Sitzung 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 mit der Fernbedienung Ihres Android TV steuern.

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 für Webabsender.