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

Google Cast-Logo

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

Die Checkliste für das Design von Google Cast soll es Nutzern der Cast-Nutzung auf allen unterstützten Plattformen erleichtern.

Ziele

Nach Abschluss dieses Codelabs haben Sie eine Chrome-Webvideo-App, mit der Sie Videos auf ein Google Cast-Gerät streamen können.

Lerninhalte

  • Das Google Cast SDK einer Beispielvideo-App hinzufügen
  • Hier erfährst du, wie du das Cast-Symbol zur Auswahl eines Google Cast-Geräts hinzufügst.
  • Verbindung zu einem Cast-Gerät herstellen und einen Medienempfänger starten.
  • So streamen Sie ein Video
  • Cast Connect einbinden

Voraussetzungen

  • Der neueste Google Chrome-Browser.
  • HTTPS-Hostingdienst wie Firebase Hosting oder ngrok
  • Ein Google Cast-Gerät wie Chromecast oder Android TV, das mit dem Internet verbunden ist.
  • Fernseher oder Monitor mit HDMI-Eingang
  • Zum Testen der Cast Connect-Integration ist Chromecast mit Google TV erforderlich, für den Rest des Codelabs aber optional. Wenn Sie keine haben, überspringen Sie den Schritt Cast Connect-Unterstützung hinzufügen gegen Ende dieser Anleitung.

Plattform

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

Wie werden Sie diese Anleitung verwenden?

Nur Lesen Lesen und lesen

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

Neuling Leicht fortgeschrittener Profi

Wie würdest du deine Erfahrung beim Fernsehen bewerten?

Neuling Fortgeschrittener Anfänger 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 die fertige Beispiel-App an. 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.

Damit du das fertige Video nutzen kannst, muss es gehostet werden.

Wenn Sie keinen Server zur Verfügung haben, können Sie Firebase Hosting oder ngrok verwenden.

Server ausführen

Nachdem du einen Dienst deiner Wahl eingerichtet hast, rufe app-done auf und starte deinen Server.

Rufen Sie in Ihrem Browser die HTTPS-URL für das von Ihnen gehostete Beispiel 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 im Videoelement auf die Schaltfläche „Pause“, um das Video auf dem Empfänger zu pausieren. Klicke auf die Wiedergabeschaltfläche im Videoelement, um die Wiedergabe des Videos fortzusetzen.

Klicke auf das Cast-Symbol, um das Streamen auf das Google Cast-Gerät zu beenden.

Beenden Sie den Server, bevor wir fortfahren.

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. Hier sind einige Google Cast-Begriffe, die wir in diesem Codelab verwenden werden:

  • Eine Absender-App wird auf einem Mobilgerät oder Laptop ausgeführt.
  • Eine Empfänger-App wird auf dem Google Cast-Gerät ausgeführt.

Jetzt können Sie mit Ihrem bevorzugten Texteditor auf das Startprojekt aufbauen:

  1. Wählen Sie das Verzeichnis Ordnersymbolapp-start aus dem Beispielcode aus.
  2. Führen Sie die Anwendung über Ihren Server aus und sehen Sie sich die Benutzeroberfläche an.

Hinweis: Wenn Sie dieses Codelab durcharbeiten, müssen Sie das Beispiel je nach Dienst auf Ihrem Server neu hosten.

App-Design

Die App ruft eine Liste von 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, die in index.html und dem Hauptcontroller CastVideos.js. definiert ist

index.html

In dieser HTML-Datei wird fast die gesamte Benutzeroberfläche der Webanwendung deklariert.

Es gibt einige Bereiche mit Aufrufen, beispielsweise div#main_video mit dem Videoelement. Im Zusammenhang mit unserem div-Videoelement gibt es div#media_control, das alle Steuerelemente für das Videoelement definiert. Darunter befindet sich media_info, mit dem die Details des angezeigten Videos angezeigt werden. Schließlich zeigt das carousel-div-Element eine Liste von Videos in einem div-Element an.

Die Datei index.html führt außerdem ein Bootstrapping für das Cast SDK durch und weist die Funktion CastVideos an, zu laden.

Der größte Teil des Inhalts dieser Elemente 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 „Cast-Videos“. Die Liste der Videos und die zugehörigen Metadaten, die in CastVideos.js definiert sind, ist in einem Objekt namens mediaJSON enthalten.

Es gibt einige wichtige Abschnitte, die zusammen für die Verwaltung und Wiedergabe des Videos sowohl lokal als auch remote verantwortlich sind. Insgesamt ist dies eine relativ unkomplizierte 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 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 eine Reihe anderer Methoden, die für die Verwaltung von Medien und der Wiedergabe verantwortlich sind.

Häufig gestellte Fragen

5. Cast-Symbol hinzufügen

Bild einer Cast-fähigen App

Für Google Cast optimierte Apps zeigen das Cast-Symbol im Videoelement an. Durch Klicken auf das Cast-Symbol wird eine Liste der Übertragungsgeräte angezeigt, die der Nutzer auswählen kann. Wenn der Nutzer Inhalte lokal auf dem Absendergerät abspielt, wird die Wiedergabe auf diesem Gerät gestartet oder fortgesetzt. Der Nutzer kann während des Streamens jederzeit auf das Cast-Symbol klicken und die Übertragung der App auf das Übertragungsgerät beenden. Der Nutzer muss in der Lage sein, sich auf einem beliebigen Bildschirm Ihrer App mit dem Übertragungsgerät zu verbinden oder die Verbindung damit zu trennen, wie in der Google Cast-Design-Checkliste beschrieben.

Konfiguration

Für das Startprojekt sind dieselben Abhängigkeiten und die gleiche Einrichtung wie für die fertige Beispielanwendung erforderlich, aber diesmal 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 die Änderungen 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 zu Beginn des Lebenszyklus der Anwendung initialisiert werden. Es wird normalerweise von einem Callback aufgerufen, der window['__onGCastApiAvailable'] zugewiesen ist, der nach dem Laden des Cast SDKs aufgerufen wird und verfügbar ist. In diesem Fall wird CastContext in CastPlayer.prototype.initializeCastPlayer aufgerufen, was über den zuvor erwähnten Callback erfolgt.

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 davon ist die Empfängeranwendungs-ID. Damit wird die Liste der verfügbaren Cast-Geräte gefiltert, sodass nur Geräte angezeigt werden, auf denen die angegebene App ausgeführt werden kann. Außerdem wird die Empfängeranwendung gestartet, wenn eine Cast-Sitzung gestartet wird.

Wenn Sie Ihre eigene Cast-fähige App entwickeln, müssen Sie sich als Cast-Entwickler registrieren und dann eine App-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 den 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 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 gerade in index.html aufgerufenen Methode entspricht. Jetzt fügen wir eine neue Methode mit dem Namen initializeCastPlayer hinzu, mit der Optionen für CastContext festgelegt und neue RemotePlayer- und RemotePlayerControllers-Werte 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 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 eine Cast-Schaltflächenkomponente namens google-cast-launcher mit der ID „castbutton". Sie kann dem Videoelement der App hinzugefügt werden. Fügen Sie einfach eine button im Abschnitt media_control hinzu.

So sieht das Schaltflächenelement aus:

<google-cast-launcher id="castbutton"></google-cast-launcher>

Fügen Sie im Abschnitt media_control den folgenden Code zu index.html 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 jetzt die Seite in Ihrem Chrome-Browser. Das Cast-Symbol sollte im Videoelement zu sehen sein. 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 keine Medienwiedergabe unterstützt, sodass du noch keine Videos über das Übertragungsgerät wiedergeben kannst. Klicke auf das Cast-Symbol, um das Streamen zu beenden.

6. Videoinhalte streamen

Bild einer Cast-fähigen App mit Auswahlmenü für das Cast-Gerät

Die Beispiel-App wird erweitert, damit du Videos auch per Fernzugriff auf einem Übertragungsgerät wiedergeben kannst. Dazu müssen wir die verschiedenen Ereignisse beobachten, 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:

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

Im ersten Schritt wird ein Objekt einem anderen zugeordnet. MediaInfo ist etwas, das vom Cast SDK verstanden wird, und mediaJSON ist die Kapselung unserer App für ein Mediakostenelement. Wir können mediaJSON einfach einem MediaInfo zuordnen. Wir haben Schritt 2 bereits im vorherigen Abschnitt ausgeführt. Schritt 3 ist mit dem Cast SDK ganz einfach.

Die Beispiel-App CastPlayer unterscheidet in der switchPlayer-Methode bereits zwischen der lokalen und der Remote-Wiedergabe:

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

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

Momentan ist der lokale Player immer im lokalen Wiedergabestatus, da er noch nichts über den Streamingstatus weiß. Wir müssen die Benutzeroberfläche basierend auf Statusübergängen aktualisieren, die im Cast-Framework stattfinden. Wenn wir beispielsweise mit der Übertragung 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 überwachen, die vom Cast-Framework generiert werden.

Cast-Sitzungsverwaltung

Für das Cast-Framework umfasst eine Cast-Sitzung die Schritte zum Herstellen einer Verbindung mit einem Gerät, zum Starten (oder Antreten einer bestehenden Sitzung), zum Herstellen einer Verbindung mit einer Empfängeranwendung und zum Initialisieren eines Mediensteuerkanals. Der Mediensteuerungskanal ist die Methode, über die das Cast-Framework Nachrichten zur Medienwiedergabe vom Empfänger sendet und empfängt.

Die Streamingsitzung wird automatisch gestartet, wenn der Nutzer ein Gerät über das Cast-Symbol auswählt, und wird automatisch beendet, wenn der Nutzer die Verbindung trennt. Die Verbindung zu einer Empfängersitzung aufgrund von Netzwerkproblemen wird auch automatisch vom Cast-Framework übernommen.

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

In unserer aktuellen Anwendung übernehmen wir die gesamte Sitzungs- und Statusverwaltung in der Methode setupRemotePlayer. Beginnen wir mit der Konfiguration in deiner App, indem wir CastVideos.js 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 immer noch alle Ereignisse von Callbacks binden und alle eingehenden Ereignisse verarbeiten. Das ist eine ziemlich einfache Aufgabe, die wir uns jetzt darum kümmern können:

/**
 * 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 Verwaltung der Remote-Medienwiedergabe auf dem Empfänger. Bei einem CastSession, der 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 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 den 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 nun 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 abschließend 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 : '');
  }
};

Starte jetzt die App. Stelle eine Verbindung zu deinem Übertragungsgerät her und starte die Videowiedergabe. Das Video sollte auf dem Receiver wiedergegeben werden.

7. Cast Connect-Unterstützung hinzufügen

Mit der Cast Connect-Bibliothek können bestehende Absender-Apps über Android Cast mit Android TV-Apps kommunizieren. Cast Connect baut auf der Cast-Infrastruktur auf, wobei deine Android TV App als Empfänger fungiert.

Abhängigkeiten

  • Chrome-Browser, Version M87 oder höher

Mit Android Receiver kompatibel

Zum Starten der App für Android TV, auch Android Receiver genannt, müssen Sie das androidReceiverCompatible-Objekt im Objekt CastOptions auf „true“ setzen.

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 die Einführung festlegen

Auf der Seite des Absenders können Sie angeben, wer CredentialsData der Sitzung beitreten darf. credentials ist ein String, der vom Nutzer definiert werden kann, solange Ihre ATV-App ihn verstehen kann. Die CredentialsData wird nur während des Starts oder beim Beitritt an deine Android TV App übertragen. Wenn Sie sie noch einmal einrichten, während Sie verbunden sind, wird sie nicht an Ihre Android TV App übertragen.

Zum Festlegen von Anmeldedaten muss „CredentialsData“ nach dem Festlegen der Optionen für den Start festgelegt 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 Anfrage zum Laden festlegen

Wenn die Web Receiver App und die Android TV App credentials unterschiedlich verarbeiten, müssen Sie möglicherweise für jede App eigene Anmeldedaten definieren. Fügen Sie in der Datei 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 der Absender streamt, verarbeitet das SDK jetzt automatisch, welche Anmeldedaten für die aktuelle Sitzung verwendet werden sollen.

Cast Connect testen

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 diese Option in der Regel unter Einstellungen > Netzwerk & Internet > (Netzwerkname, mit dem Ihr Gerät verbunden ist). Rechts 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 der obersten 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:
$ adb -s <device_ip_address>:5555 install android-tv-app.apk
  1. Auf Ihrem Android TV-Gerät sollte jetzt im Menü Meine Apps eine App mit dem Namen Videos streamen zu sehen sein.
  2. Führen Sie den aktualisierten Websender-Code aus und richten Sie mit Ihrem Android TV-Gerät eine Streamingsitzung über das Cast-Symbol ein oder wählen Sie im Drop-down-Menü Ihres Chrome-Browsers Cast.. aus. Die Android TV App sollte jetzt auf Ihrem Android Receiver gestartet werden und Sie können die Wiedergabe mit der Fernbedienung für Android TV steuern.

8. Glückwunsch

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

Weitere Informationen finden Sie im Entwicklerleitfaden Web Sender.