Für Google Cast optimierte Web-App

1. Übersicht

Google Cast-Logo

In diesem Codelab erfahren Sie, wie Sie eine vorhandene Webanwendung für Videos so ändern, dass Inhalte auf einem für Google Cast optimierten Gerät gestreamt werden können.

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 anhand der Checkliste für das Google Cast-Design hinzufügen.

Die Google Cast-Design-Checkliste soll die Nutzung von Google Cast auf allen unterstützten Plattformen einfach und vorhersehbar machen.

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 einer Beispiel-Video-App das Google Cast SDK hinzu.
  • Hier erfahren Sie, wie Sie das Cast-Symbol zur Auswahl eines Google Cast-Geräts hinzufügen.
  • So verbindest du dich mit einem Übertragungsgerät und startest einen Media-Receiver.
  • So streamen Sie ein Video.
  • Cast Connect integrieren

Voraussetzungen

  • Die aktuelle Version von Google Chrome.
  • HTTPS-Hostingdienst wie Firebase Hosting oder ngrok
  • Ein Google Cast-Gerät wie Chromecast oder Android TV mit Internetzugang
  • Einen 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 sie jedoch optional. Wenn Sie keinen haben, können Sie den Schritt Unterstützung für Cast Connect hinzufügen am Ende dieser Anleitung überspringen.

Erfahrung

  • Sie müssen über Vorkenntnisse in der Webentwicklung verfügen.
  • Außerdem solltest du schon einmal ferngesehen haben.

Wie möchten Sie diese Anleitung verwenden?

Nur durchlesen Durchlesen und die Übungen absolvieren

Wie würden Sie Ihre Erfahrungen mit der Erstellung von Web-Apps bewerten?

Anfänger Fortgeschrittene Erfahren

Wie würden Sie Ihre Erfahrung mit dem Fernsehen bewerten?

Anfänger Mittelstufe Fortgeschritten

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 zunächst 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 die abgeschlossenen Elemente verwenden zu können, muss sie gehostet werden.

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

Server ausführen

Nachdem Sie den gewünschten Dienst eingerichtet haben, rufen Sie app-done auf und starten Sie den Server.

Rufen Sie in Ihrem Browser die https-URL für das von Ihnen gehostete Beispiel auf.

  1. Die Video-App sollte jetzt angezeigt werden.
  2. Klicken Sie auf die Schaltfläche „Streamen“ und wählen Sie Ihr Google Cast-Gerät aus.
  3. Wähle ein Video aus und klicke auf die Wiedergabeschaltfläche.
  4. Die Wiedergabe des Videos beginnt auf Ihrem Google Cast-Gerät.

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

Klicke im Videoelement auf die Schaltfläche „Pause“, um das Video auf dem Receiver zu pausieren. Klicken Sie im Videoelement auf die Wiedergabeschaltfläche, um die Wiedergabe fortzusetzen.

Klicken Sie auf die Schaltfläche „Streamen“, um das Streaming auf dem Google Cast-Gerät zu beenden.

Bevor wir fortfahren, beenden Sie den Server.

4. Startprojekt vorbereiten

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

Wir müssen der von Ihnen heruntergeladenen Start-App Google Cast hinzufügen. Hier sind einige Google Cast-Begriffe, die wir in diesem Codelab verwenden werden:

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

Jetzt können Sie mit Ihrem bevorzugten Texteditor auf dem Starterprojekt aufbauen:

  1. Wählen Sie das Verzeichnis Ordnersymbolapp-start aus dem Beispielcode-Download aus.
  2. Führen Sie die App mit Ihrem Server aus und sehen Sie sich die Benutzeroberfläche an.

Hinweis: Wenn Sie dieses Codelab durcharbeiten, müssen Sie das Beispiel abhängig vom Dienst auf Ihrem Server neu hosten.

App-Design

Die App ruft eine Liste mit Videos von einem Remote-Webserver ab und stellt eine Liste für den Nutzer zum Stöbern bereit. Nutzer können ein Video auswählen, um die Details aufzurufen, oder das Video lokal auf einem Mobilgerät abspielen.

Die App besteht aus einer Hauptansicht, die in index.html definiert ist, und dem Hauptcontroller CastVideos.js..

index.html

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

Es gibt einige Bereiche für Aufrufe. Wir haben div#main_video, das das Videoelement enthält. In Bezug auf unser Video-Div haben wir div#media_control, das alle Steuerelemente für das Videoelement definiert. Darunter siehst du media_info, in dem die Details des angezeigten Videos angezeigt werden. Im carousel-Div wird schließlich eine Liste von Videos angezeigt.

Die index.html-Datei startet auch das Cast SDK und weist die CastVideos-Funktion an, geladen zu werden.

Die meisten Inhalte, die in diesen Elementen angezeigt werden, werden in CastVideos.js definiert, eingefügt und gesteuert. Sehen wir uns das an.

CastVideos.js

Dieses Script verwaltet die gesamte Logik für die Web-App „Cast Videos“. Die in CastVideos.js definierte Liste der Videos und die zugehörigen Metadaten befinden sich in einem Objekt namens mediaJSON.

Es gibt einige wichtige Bereiche, die zusammen für die Verwaltung und Wiedergabe des Videos sowohl lokal als auch aus der Ferne verantwortlich sind. Insgesamt ist dies eine ziemlich einfache Webanwendung.

CastPlayer ist die Hauptklasse, die die gesamte App verwaltet, den Player einrichtet, Medien auswählt und Ereignisse für die Medienwiedergabe an PlayerHandler bindet. CastPlayer.prototype.initializeCastPlayer ist die Methode, mit der alle Cast-Funktionen eingerichtet werden. Mit CastPlayer.prototype.switchPlayer wird zwischen lokalen und Remote-Spielern gewechselt. 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 zur Verwaltung von Medien und Wiedergabe verantwortlich sind.

Häufig gestellte Fragen

5. Schaltfläche „Streamen“ hinzufügen

Bild einer für Google Cast optimierten App

In einer für Google Cast optimierten App wird die Schaltfläche „Streamen“ im Videoelement angezeigt. Wenn du auf die Schaltfläche „Streamen“ klickst, wird eine Liste der Übertragungsgeräte angezeigt, die du auswählen kannst. Wenn der Nutzer Inhalte lokal auf dem Sendergerät abspielte, wird durch die Auswahl eines Übertragungsgeräts die Wiedergabe auf diesem Gerät gestartet oder fortgesetzt. Der Nutzer kann während der Übertragung jederzeit auf das Cast-Symbol klicken und die Übertragung Ihrer App auf das Übertragungsgerät beenden. Der Nutzer muss auf jedem Bildschirm Ihrer App eine Verbindung zum Übertragungsgerät herstellen oder trennen können. Weitere Informationen hierzu finden Sie in der Checkliste für das Google Cast-Design.

Konfiguration

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

Rufen Sie in Ihrem Browser die URL https für das von Ihnen gehostete Sample auf.

Wenn Sie Änderungen vornehmen, müssen Sie das Beispiel abhängig vom Dienst auf Ihrem Server neu hosten.

Initialisierung

Das Cast-Framework hat ein globales Singleton-Objekt, CastContext, das alle Aktivitäten des Frameworks koordiniert. Dieses Objekt muss früh im Lebenszyklus der App initialisiert werden. Es wird in der Regel über einen Callback aufgerufen, der window['__onGCastApiAvailable'] zugewiesen ist. Dieser wird nach dem Laden des Cast SDK aufgerufen und steht zur Verfügung. In diesem Fall wird die CastContext in CastPlayer.prototype.initializeCastPlayer aufgerufen, was aus dem oben genannten Callback aufgerufen wird.

Beim Initialisieren 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 ID der Empfängeranwendung. Mit dieser wird die Liste der verfügbaren Streaminggerä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 Streamingsitzung 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. In diesem Codelab verwenden wir eine Beispiel-App-ID.

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

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

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

Jetzt müssen wir in CastVideos.js eine neue Methode hinzufügen, die der Methode entspricht, die wir gerade in index.html aufgerufen haben. Jetzt fügen wir eine neue Methode mit dem Namen initializeCastPlayer hinzu, die Optionen für CastContext festlegt und neue RemotePlayer und RemotePlayerControllers initialisiert:

/**
 * This method sets up the CastContext, and a few other members
 * that are necessary to play and control videos on a Cast
 * device.
 */
CastPlayer.prototype.initializeCastPlayer = function() {

    var options = {};

    // Set the receiver application ID to your own (created in
    // the Google Cast Developer Console), or optionally
    // use the chrome.cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID
    options.receiverApplicationId = 'C0868879';

    // Auto join policy can be one of the following three:
    // ORIGIN_SCOPED - Auto connect from same appId and page origin
    // TAB_AND_ORIGIN_SCOPED - Auto connect from same appId, page origin, and tab
    // PAGE_SCOPED - No auto connect
    options.autoJoinPolicy = chrome.cast.AutoJoinPolicy.ORIGIN_SCOPED;

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

    this.remotePlayer = new cast.framework.RemotePlayer();
    this.remotePlayerController = new cast.framework.RemotePlayerController(this.remotePlayer);
    this.remotePlayerController.addEventListener(
        cast.framework.RemotePlayerEventType.IS_CONNECTED_CHANGED,
        this.switchPlayer.bind(this)
    );
};

Zum Schluss 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 die Schaltfläche „Streamen“ hinzufügen, damit der Nutzer ein Streaminggerät auswählen kann. Das Cast SDK bietet eine Komponente für die Übertragungsschaltfläche namens google-cast-launcher mit der ID „castbutton"“. Sie kann dem Videoelement der Anwendung hinzugefügt werden, indem im Bereich media_control einfach ein button eingefügt wird.

Das Schaltflächenelement sieht dann so 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. Im Videoelement sollte die Schaltfläche „Streamen“ angezeigt werden. Wenn Sie darauf klicken, werden die Cast-Geräte in Ihrem lokalen Netzwerk aufgelistet. Die Geräteerkennung wird automatisch vom Chrome-Browser verwaltet. Wählen Sie Ihr Übertragungsgerät aus. Die Beispiel-Empfänger-App wird auf dem Übertragungsgerät geladen.

Die Medienwiedergabe wird noch nicht unterstützt. Videos können daher noch nicht auf dem Übertragungsgerät abgespielt werden. Klicke auf die Schaltfläche „Streamen“, um das Streamen zu beenden.

6. Videoinhalte streamen

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

Wir werden die Beispiel-App so erweitern, dass auch Videos per Fernzugriff auf einem Cast-Gerät wiedergegeben werden können. Dazu müssen wir die verschiedenen Ereignisse abhören, die vom Cast-Framework generiert werden.

Medien streamen

Wenn Sie Medien auf einem Streaminggerät wiedergeben möchten, müssen folgende Schritte ausgeführt werden:

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

Schritt 1 ist so ähnlich wie die Zuordnung eines Objekts zu einem anderen. MediaInfo versteht das Cast SDK und mediaJSON ist die Kapselung eines Medienelements in unserer App. Ein mediaJSON lässt sich ganz einfach einem MediaInfo zuordnen. Schritt 2 haben wir bereits im vorherigen Abschnitt ausgeführt. Schritt 3 ist mit dem Cast SDK ganz einfach.

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

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

In diesem Codelab ist es nicht wichtig, dass Sie genau verstehen, wie die gesamte Logik des Beispiel-Players funktioniert. Der Mediaplayer Ihrer App muss jedoch so geändert werden, dass er sowohl die lokale als auch die Remote-Wiedergabe unterstützt.

Derzeit 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 dem Streamen beginnen, müssen wir die lokale Wiedergabe beenden und einige Steuerelemente deaktivieren. Wenn wir das Streaming in diesem Ansichtscontroller beenden, müssen wir ebenfalls zur lokalen Wiedergabe wechseln. Dazu müssen wir die verschiedenen vom Cast-Framework generierten Ereignisse überwachen.

Verwaltung von Übertragungssitzungen

Beim Cast-Framework umfasst eine Cast-Sitzung die Schritte, um eine Verbindung zu einem Gerät herzustellen, eine Sitzung zu starten oder einer bestehenden Sitzung beizutreten, eine Verbindung zu einer Empfänger-App herzustellen und gegebenenfalls einen Mediensteuerungskanal zu initialisieren. Über den Mediensteuerungskanal sendet und empfängt das Cast-Framework Nachrichten zur Medienwiedergabe vom Empfänger.

Die Übertragungssitzung wird automatisch gestartet, wenn der Nutzer über die Schaltfläche „Streamen“ ein Gerät auswählt, und automatisch beendet, wenn der Nutzer die Verbindung trennt. Die automatische Wiederverbindung mit einer Empfängersitzung aufgrund von Netzwerkproblemen wird ebenfalls vom Cast-Framework verwaltet.

Übertragungssitzungen werden über die CastSession verwaltet, auf die über cast.framework.CastContext.getInstance().getCurrentSession() zugegriffen werden kann. Mit den EventListener-Callbacks können Sitzungsereignisse wie Erstellung, Sperrung, Wiederaufnahme und Beendigung überwacht werden.

In unserer aktuellen Anwendung wird die gesamte Sitzungs- und Statusverwaltung über die setupRemotePlayer-Methode abgewickelt. Konfigurieren Sie das in Ihrer App, indem Sie CastVideos.js den folgenden Code hinzufügen:

/**
 * Set the PlayerHandler target to use the remote player
 */
CastPlayer.prototype.setupRemotePlayer = function () {
    var castSession = cast.framework.CastContext.getInstance().getCurrentSession();

    this.playerHandler.setTarget(playerTarget);

    // Setup remote player volume right on setup
    // The remote player may have had a volume set from previous playback
    if (this.remotePlayer.isMuted) {
        this.playerHandler.mute();
    }
    var currentVolume = this.remotePlayer.volumeLevel * FULL_VOLUME_HEIGHT;
    var p = document.getElementById('audio_bg_level');
    p.style.height = currentVolume + 'px';
    p.style.marginTop = -currentVolume + 'px';

    this.hideFullscreenButton();

    this.playerHandler.play();
};

Wir müssen noch alle Ereignisse aus den Rückrufen binden und alle eingehenden Ereignisse verarbeiten. Das ist ganz einfach. Gehen wir es gleich an:

/**
 * 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 die RemotePlayer und RemotePlayerController eine Reihe praktischer APIs zur Verwaltung der Remote-Medienwiedergabe auf dem Empfänger. Für eine CastSession, die 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 und cast.framework.RemotePlayerController erstellen, wie bereits im Codelab gezeigt.

Als Nächstes müssen wir das aktuell ausgewählte Video auf dem Empfänger laden. Dazu erstellen wir ein MediaInfo-Objekt, das vom SDK verarbeitet und in die Anfrage übergeben wird. 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ügen Sie jetzt 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 abschließend eine Methode hinzu, um alle Cast-Fehlermeldungen zu verarbeiten:

/**
 * 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 : '');
  }
};

Starten Sie jetzt die App. Stellen Sie eine Verbindung zu Ihrem Google Cast-Gerät her und spielen Sie ein Video ab. Das Video sollte jetzt auf dem Receiver wiedergegeben werden.

7. Unterstützung für Cast Connect hinzufügen

Mit der Cast Connect-Mediathek können vorhandene Sender-Apps über das Cast-Protokoll mit Android TV-Apps kommunizieren. Cast Connect basiert auf der Cast-Infrastruktur. Dabei dient Ihre Android TV App als Empfänger.

Abhängigkeiten

  • Chrome-Browser, Version M87 oder höher

Android-Receiver als kompatibel festlegen

Damit die Android TV-Anwendung, auch als Android-Empfänger bezeichnet, gestartet werden kann, müssen wir das Flag androidReceiverCompatible im Objekt CastOptions auf „true“ setzen.

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

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

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

Anmeldedaten für den Start festlegen

Auf der Absenderseite können Sie CredentialsData angeben, um anzugeben, wer an der Sitzung teilnimmt. credentials ist ein String, der vom Nutzer definiert werden kann, solange er von deiner ATV-App verstanden wird. Die CredentialsData wird nur beim Starten oder Beitreten an deine Android TV-App übergeben. Wenn Sie die Einstellung neu festlegen, während eine Verbindung besteht, wird sie nicht an Ihre Android TV App übergeben.

Damit Startanmeldedaten festgelegt werden können, muss CredentialsData nach dem Festlegen der Startoptionen definiert werden.

Fügen Sie der CastVideos.js-Klasse unter der initializeCastPlayer-Funktion 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

Wenn deine Web-Receiver-App und deine Android TV-App credentials unterschiedlich verarbeiten, musst du möglicherweise für jede App separate Anmeldedaten definieren. Fügen Sie dazu in der CastVideos.js-Datei unter playerTarget.load in der setupRemotePlayer-Funktion den folgenden Code hinzu:

...
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 Absender etwas überträgt, verarbeitet das SDK jetzt automatisch, welche Anmeldedaten für die aktuelle Sitzung verwendet werden.

Cast Connect testen

So installierst du die Android TV-APK auf Chromecast mit Google TV:

  1. Ermitteln Sie die IP-Adresse Ihres Android TV-Geräts. Normalerweise finden Sie sie unter Einstellungen > Netzwerk und Internet > (Name des Netzwerks, mit dem Ihr Gerät verbunden ist). Auf der rechten Seite werden die Details und die IP-Adresse Ihres Geräts im Netzwerk angezeigt.
  2. Verwenden Sie die IP-Adresse des Geräts, um über ADB mit dem Terminal eine Verbindung zu ihm herzustellen:
$ adb connect <device_ip_address>:5555
  1. Rufen Sie im Terminalfenster den übergeordneten Ordner für die Codelab-Beispiele auf, die Sie zu Beginn dieses Codelabs heruntergeladen haben. Beispiel:
$ cd Desktop/chrome_codelab_src
  1. Installiere die APK-Datei aus diesem Ordner auf deinem Android TV mit folgendem Befehl:
$ 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 angezeigt werden.
  2. Führe den aktualisierten Websendercode aus und stelle eine Übertragungssitzung mit deinem Android TV-Gerät über das Übertragungssymbol oder über das Drop-down-Menü im Chrome-Browser her.Cast.. Dadurch sollte die Android TV App auf deinem Android-Receiver gestartet werden und du kannst die Wiedergabe über deine Android TV-Fernbedienung steuern.

8. Glückwunsch

Sie wissen jetzt, wie Sie eine Video-App mithilfe der Cast SDK-Widgets in einer Chrome-Web-App für das Streaming mit Chromecast aktivieren.

Weitere Informationen findest du im Entwicklerhandbuch für Websender.