Für Google Cast optimierte Web-App

1. Übersicht

Google Cast-Logo

In diesem Codelab erfahren Sie, wie Sie eine Webvideo-App so anpassen, dass Inhalte auf ein für Google Cast optimiertes Gerät gestreamt werden.

Was ist Google Cast?

Mit Google Cast können Nutzer Inhalte von Mobilgeräten 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 so erweitern, dass sie einen Fernseher oder ein Soundsystem steuern kann. Mit dem Cast SDK können Sie die erforderlichen UI-Komponenten anhand der Checkliste für das Google Cast-Design hinzufügen.

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

Ziele

Wenn Sie dieses Codelab abgeschlossen haben, haben Sie eine Webvideo-App für Chrome, mit der Sie Videos auf ein Google Cast-Gerät streamen können.

Lerninhalte

  • Hinzufügen des Google Cast SDK zu einer Beispiel-Video-App
  • Hier erfahren Sie, wie Sie das Cast-Symbol zur Auswahl eines Google Cast-Geräts hinzufügen.
  • Verbindung zu einem Übertragungsgerät herstellen und einen Medienempfänger starten
  • 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 Internetverbindung
  • 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. Falls Sie keines haben, überspringen Sie den Schritt Cast Connect-Unterstützung hinzufügen gegen Ende dieser Anleitung.

Erfahrung

  • Sie müssen über Vorkenntnisse in der Webentwicklung verfügen.
  • Außerdem benötigen Sie Vorkenntnisse in Bezug auf Fernsehen. :)

Wie möchten Sie diese Anleitung nutzen?

<ph type="x-smartling-placeholder"></ph> Nur bis zum Ende lesen Lies sie dir durch und absolviere die Übungen

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

<ph type="x-smartling-placeholder"></ph> Neuling Leicht fortgeschritten Kompetent

Wie würden Sie Ihre Erfahrungen mit Fernsehen bewerten?

<ph type="x-smartling-placeholder"></ph> Neuling Leicht fortgeschritten Kompetent

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 wiedergeben oder auf ein Google Cast-Gerät streamen.

Um die abgeschlossenen Elemente verwenden zu können, muss sie gehostet werden.

Wenn Sie keinen Server haben, können Sie Firebase Hosting oder ngrok verwenden.

Server ausführen

Sobald Sie den Dienst Ihrer Wahl eingerichtet haben, rufen Sie app-done auf und starten Sie Ihren 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 das Cast-Symbol und wählen Sie Ihr 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 wiedergegeben.

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 des Videos fortzusetzen.

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

Bevor wir weitermachen, müssen Sie den Server anhalten.

4. Startprojekt vorbereiten

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

Wir müssen der heruntergeladenen Start-App Unterstützung für Google Cast hinzufügen. Im Folgenden finden Sie einige Google Cast-Begriffe, die wir in diesem Codelab verwenden:

  • eine Absender-App auf einem Mobilgerät oder Laptop ausgeführt wird,
  • Eine Receiver-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 Download des Beispielcodes 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 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 zur Verfügung, die der Nutzer durchsuchen kann. 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 Haupt-Controller CastVideos.js..

index.html

Diese HTML-Datei deklariert fast die gesamte Benutzeroberfläche für die Webanwendung.

Es gibt einige Bereiche der Ansichten. Wir haben die div#main_video, die das Videoelement enthält. In Bezug auf unser Video-div-Element haben wir div#media_control, mit dem alle Steuerelemente für das Videoelement definiert werden. Darunter befindet sich media_info, wodurch die Details des aktuellen Videos angezeigt werden. Schließlich zeigt das div-Element carousel eine Liste von Videos in einem div-Element an.

Die Datei index.html führt außerdem Bootstrapping des Cast SDK aus und weist die Funktion CastVideos an, zu laden.

Der größte Teil des Inhalts für diese Elemente wird in CastVideos.js definiert, eingeschleust und gesteuert. Sehen wir uns das an.

CastVideos.js

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

Es gibt einige Hauptbereiche, die zusammen für die Verwaltung und Wiedergabe des Videos sowohl lokal als auch remote verantwortlich sind. Insgesamt handelt es sich um eine ziemlich unkomplizierte 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. CastPlayer.prototype.switchPlayer wechselt den Status zwischen lokalem und Remote-Player. 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 weiterer Methoden, die für die Details der Verwaltung von Medien und der Wiedergabe verantwortlich sind.

Häufig gestellte Fragen

5. Cast-Symbol hinzufügen

Bild einer für Google Cast optimierten App

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 der Übertragungsgeräte angezeigt, die der Nutzer auswählen kann. Wenn der Nutzer Inhalte lokal auf dem Sendergerät wiedergegeben hat, wird die Wiedergabe auf diesem Übertragungsgerät gestartet oder fortgesetzt, wenn ein Übertragungsgerät ausgewählt wird. 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

Das Startprojekt erfordert dieselben Abhängigkeiten und dieselbe Einrichtung wie für die fertige Beispielanwendung. Dieses Mal hosten Sie jedoch den Inhalt von app-start.

Rufen Sie in Ihrem Browser die https-URL für das von Ihnen gehostete Beispiel 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, das 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 das 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 das Verhalten des Frameworks beeinflussen. Das Wichtigste ist die ID der Empfänger-App. Sie wird verwendet, um die Liste der verfügbaren Übertragungsgeräte so zu filtern, dass nur Geräte angezeigt werden, auf denen die jeweilige App ausgeführt werden kann. Außerdem wird die Empfänger-App gestartet, wenn eine Übertragung gestartet wird.

Wenn Sie eine für Google Cast optimierte App entwickeln, müssen Sie sich als Cast-Entwickler registrieren und eine App-ID für Ihre App erhalten. In diesem Codelab verwenden wir eine Beispiel-App-ID.

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

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

Fügen Sie in index.html den folgenden Code ein, um die CastVideos-App sowie 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)
    );
};

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 CastContext initialisiert wurde, muss das Cast-Symbol hinzugefügt werden, damit der Nutzer ein Übertragungsgerät auswählen kann. Das Cast SDK bietet eine Komponente für das Cast-Symbol mit dem Namen google-cast-launcher und der ID "castbutton"". Es kann dem Videoelement der App durch einfaches Hinzufügen von button im Abschnitt media_control hinzugefügt werden.

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 jetzt die Seite in Ihrem Chrome-Browser. Im Videoelement sollte ein Cast-Symbol zu sehen sein. Wenn Sie darauf klicken, werden die Übertragungsgeräte in Ihrem lokalen Netzwerk aufgelistet. Die Geräteerkennung wird automatisch vom Chrome-Browser verwaltet. Wähle dein Übertragungsgerät aus. Die Beispiel-Empfänger-App wird auf dem Übertragungsgerät geladen.

Wir haben noch keine Unterstützung für die Medienwiedergabe, daher können Sie derzeit noch keine Videos auf dem Übertragungsgerät wiedergeben. Klicken Sie auf das Cast-Symbol, um das Streamen zu beenden.

6. Streamen von Videoinhalten

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

Wir erweitern die Beispiel-App so, dass Videos auch per Fernzugriff auf Übertragungsgeräten 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 wiedergeben möchten, müssen folgende Voraussetzungen erfüllt sein:

  1. Erstelle über das Cast SDK ein MediaInfo-JSON-Objekt, 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. Beobachten Sie den Medienstatus.
  5. Wiedergabebefehle basierend auf Nutzerinteraktionen an den Empfänger senden

Schritt 1 ist so, als würden Sie ein Objekt einem anderen zuordnen. MediaInfo versteht das Cast SDK und mediaJSON steht für die Kapselung eines Medienelements durch unsere App. können wir mediaJSON ganz einfach MediaInfo zuordnen. Schritt 2 im vorherigen Abschnitt wurde bereits ausgeführt. Schritt 3 lässt sich mit dem Cast SDK ganz einfach durchführen.

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

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

In diesem Codelab ist es nicht wichtig, zu verstehen, wie die gesamte Beispiellogik von Playern funktioniert. Sie müssen jedoch verstehen, dass der Mediaplayer Ihrer App modifiziert werden muss, um sowohl die lokale als auch die Remote-Wiedergabe zu erkennen.

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 im Cast-Framework aktualisieren. Wenn wir beispielsweise mit dem Streamen beginnen, müssen wir die lokale Wiedergabe beenden und einige Steuerelemente deaktivieren. Wenn wir das Streaming beenden, während wir uns in diesem Ansicht-Controller befinden, müssen wir ebenfalls zur lokalen Wiedergabe wechseln. Dazu müssen wir auf die verschiedenen Ereignisse warten, die vom Cast-Framework generiert werden.

Streamingsitzung verwalten

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.

Das Streamen wird automatisch gestartet, wenn der Nutzer ein Gerät über das Cast-Symbol auswählt, und automatisch beendet, wenn der Nutzer die Verbindung trennt. Auch die Wiederherstellung einer Verbindung zu einer Empfängersitzung aufgrund von Netzwerkproblemen erfolgt automatisch durch das Cast-Framework.

Streamingsitzungen werden vom CastSession verwaltet, auf den ü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. Beginnen wir damit, dies in deiner App zu konfigurieren, indem wir den folgenden Code in die Datei CastVideos.js einfü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 Rückrufen binden und alle eingehenden Ereignisse verarbeiten. Das ist ziemlich einfach.

/**
 * 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, mit denen du die Remote-Medienwiedergabe auf dem Receiver verwalten kannst. Bei einem CastSession, das die Medienwiedergabe unterstützt, werden vom SDK automatisch Instanzen von RemotePlayer und RemotePlayerController erstellt. Sie können darauf zugreifen, indem Sie Instanzen von cast.framework.RemotePlayer bzw. cast.framework.RemotePlayerController erstellen, wie weiter oben im Codelab gezeigt.

Als Nächstes laden wir das aktuell ausgewählte Video auf den Empfänger. Dazu erstellen wir ein MediaInfo-Objekt, das vom SDK verarbeitet und die Anfrage übergeben wird. Fügen Sie dazu den folgenden Code in setupRemotePlayer ein:

/**
 * 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 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 zum Verarbeiten von Cast-Fehlermeldungen hinzu:

/**
 * Makes human-readable message from chrome.cast.Error
 * @param {chrome.cast.Error} error
 * @return {string} error message
 */
CastPlayer.getErrorMessage = function(error) {
  switch (error.code) {
    case chrome.cast.ErrorCode.API_NOT_INITIALIZED:
      return 'The API is not initialized.' +
        (error.description ? ' :' + error.description : '');
    case chrome.cast.ErrorCode.CANCEL:
      return 'The operation was canceled by the user' +
        (error.description ? ' :' + error.description : '');
    case chrome.cast.ErrorCode.CHANNEL_ERROR:
      return 'A channel to the receiver is not available.' +
        (error.description ? ' :' + error.description : '');
    case chrome.cast.ErrorCode.EXTENSION_MISSING:
      return 'The Cast extension is not available.' +
        (error.description ? ' :' + error.description : '');
    case chrome.cast.ErrorCode.INVALID_PARAMETER:
      return 'The parameters to the operation were not valid.' +
        (error.description ? ' :' + error.description : '');
    case chrome.cast.ErrorCode.RECEIVER_UNAVAILABLE:
      return 'No receiver was compatible with the session request.' +
        (error.description ? ' :' + error.description : '');
    case chrome.cast.ErrorCode.SESSION_ERROR:
      return 'A session could not be created, or a session was invalid.' +
        (error.description ? ' :' + error.description : '');
    case chrome.cast.ErrorCode.TIMEOUT:
      return 'The operation timed out.' +
        (error.description ? ' :' + error.description : '');
  }
};

Führen Sie nun die App aus. Stellen Sie eine Verbindung zu Ihrem Übertragungsgerät her und starten Sie die Wiedergabe eines Videos. Das Video sollte auf dem Receiver wiedergegeben werden.

7. Cast Connect-Unterstützung hinzufügen

Über die Cast Connect-Bibliothek können bestehende Absender-Apps über das Cast-Protokoll mit Android TV-Apps kommunizieren. Cast Connect baut auf der Cast-Infrastruktur auf, wobei deine Android TV-App als Receiver fungiert.

Abhängigkeiten

  • Chrome-Browser, Version M87 oder höher

Mit Android Receiver kompatibel

Zum Starten der Android TV App, die auch als Android-Receiver bezeichnet wird, müssen wir das androidReceiverCompatible-Flag im CastOptions-Objekt auf „true“ setzen.

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

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

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

Anmeldedaten für den Start festlegen

Auf der Absenderseite können Sie CredentialsData angeben, um anzugeben, wer an der Sitzung teilnimmt. Die credentials ist ein String, der vom Nutzer definiert werden kann, sofern die ATV-App ihn lesen kann. Die CredentialsData wird nur während des Starts oder der Teilnahme an deiner Android TV App übergeben. Wenn Sie die Einstellung neu festlegen, während eine Verbindung besteht, wird sie nicht an Ihre Android TV App übergeben.

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

Fügen Sie der CastVideos.js-Klasse 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 bei Ladeanfrage festlegen

Falls die Web Receiver App und die Android TV App credentials unterschiedlich verarbeiten, musst du möglicherweise separate Anmeldedaten für jede App definieren. Um das zu erreichen, fügen Sie in der setupRemotePlayer-Funktion unter playerTarget.load den folgenden Code in die Datei CastVideos.js 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 Absender etwas ü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. Normalerweise befindet sich die Option unter Einstellungen > Netzwerk und Internet > (Netzwerkname, 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. 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. 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. Sie sollten jetzt auf Ihrem Android TV-Gerät im Menü Meine Apps eine App mit dem Namen Videos streamen finden.
  2. Führen Sie den aktualisierten Web Sender Code aus und starten Sie eine Streamingsitzung mit Ihrem Android TV-Gerät. Verwenden Sie dazu das Cast-Symbol oder wählen Sie Cast.. aus dem Drop-down-Menü in Ihrem Chrome-Browser aus. Dadurch sollte die Android TV App auf deinem Android-Receiver gestartet werden und du kannst die Wiedergabe über die Android TV-Fernbedienung steuern.

8. Glückwunsch

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

Weitere Informationen finden Sie im Web Sender-Entwicklerleitfaden.