Attivazione di Google Cast per un'app web

1. Panoramica

Logo di Google Cast

Questo codelab ti insegnerà a modificare un'app di video web esistente per trasmettere contenuti su un dispositivo compatibile con Google Cast.

Che cos'è Google Cast?

Google Cast consente agli utenti di trasmettere contenuti da un dispositivo mobile a una TV. Gli utenti possono quindi utilizzare il proprio dispositivo mobile come telecomando per la riproduzione di contenuti multimediali sulla TV.

L'SDK Google Cast ti consente di estendere la tua app per controllare una TV o un sistema audio. L'SDK Cast ti consente di aggiungere i componenti dell'interfaccia utente necessari in base all'elenco di controllo per la progettazione di Google Cast.

L'elenco di controllo per la progettazione di Google Cast viene fornito per rendere l'esperienza utente di Google Cast semplice e prevedibile su tutte le piattaforme supportate.

Cosa realizzeremo?

Al termine di questo codelab, avrai a disposizione un'app web video di Chrome in grado di trasmettere video a un dispositivo Google Cast.

Obiettivi didattici

  • Come aggiungere l'SDK Google Cast a un'app video di esempio.
  • Come aggiungere il pulsante Trasmetti per selezionare un dispositivo Google Cast.
  • Come connettersi a un dispositivo di trasmissione e avviare un ricevitore multimediale.
  • Come trasmettere un video.
  • Come integrare Cast Connect

Che cosa ti serve

  • La versione più recente del browser Google Chrome.
  • Servizio di hosting HTTPS come Firebase Hosting o ngrok.
  • Un dispositivo Google Cast, ad esempio Chromecast o Android TV, configurato con accesso a Internet.
  • Una TV o un monitor con ingresso HDMI.
  • Per testare l'integrazione di Cast Connect è necessario un Chromecast con Google TV, ma è facoltativo per gli altri contenuti del codelab. Se non ne hai uno, salta il passaggio Aggiungi supporto per Cast Connect verso la fine di questo tutorial.

Esperienza

  • Devi avere conoscenze pregresse nello sviluppo web.
  • Devi anche aver acquisito una buona conoscenza di come guardare la TV :)

Come userai questo tutorial?

Leggila solo per intero Leggila e completa gli esercizi

Come giudicheresti la tua esperienza con lo sviluppo di app web?

Principiante Intermedio Esperto

Come valuteresti la tua esperienza con la visione della TV?

Principiante Intermedio Esperto

2. Recupera il codice campione

Puoi scaricare tutto il codice campione sul tuo computer...

e decomprimi il file ZIP scaricato.

3. Esegui l'app di esempio

Logo di Google Chrome

Innanzitutto, vediamo l'aspetto dell'app di esempio completata. L'app è un video player di base. L'utente può selezionare un video da un elenco e riprodurlo in locale sul dispositivo o trasmetterlo a un dispositivo Google Cast.

Per poter utilizzare quella completata, è necessario che sia ospitata.

Se non disponi di un server da utilizzare, puoi usare Firebase Hosting o ngrok.

Esegui il server

Dopo aver configurato il servizio che preferisci, vai a app-done e avvia il server.

Nel browser, visita l'URL https dell'esempio che hai ospitato.

  1. Dovresti visualizzare l'app di video.
  2. Fai clic sul pulsante Trasmetti e seleziona il tuo dispositivo Google Cast.
  3. Seleziona un video e fai clic sul pulsante di riproduzione.
  4. La riproduzione del video inizierà sul tuo dispositivo Google Cast.

Immagine di un video riprodotto su un dispositivo di trasmissione

Fai clic sul pulsante di pausa nell'elemento video per mettere in pausa il video sul ricevitore. Fai clic sul pulsante di riproduzione nell'elemento video per continuare la riproduzione del video.

Fai clic sul pulsante Trasmetti per interrompere la trasmissione al dispositivo Google Cast.

Prima di andare avanti, arresta il server.

4. Prepara il progetto di avvio

Immagine di un video riprodotto su un dispositivo di trasmissione

Dobbiamo aggiungere il supporto di Google Cast all'app iniziale che hai scaricato. Ecco alcuni termini della terminologia di Google Cast che utilizzeremo in questo codelab:

  • Un'app del mittente viene eseguita su un dispositivo mobile o laptop,
  • Sul dispositivo Google Cast è in esecuzione un'app per ricevitore.

Ora puoi iniziare a creare sulla base del progetto iniziale utilizzando il tuo editor di testo preferito:

  1. Seleziona la directory icona cartellaapp-start dal download del codice di esempio.
  2. Esegui l'app utilizzando il tuo server ed esplora la UI.

Tieni presente che, poiché stai lavorando con questo codelab, dovrai eseguire il rehosting dell'esempio sul tuo server a seconda del servizio.

Progettazione di app

L'app recupera un elenco di video da un server web remoto e fornisce all'utente un elenco che può sfogliare. Gli utenti possono selezionare un video per visualizzarne i dettagli o riprodurlo localmente sul dispositivo mobile.

L'app è composta da una vista principale, definita in index.html, e dal controller principale CastVideos.js.

index.html

Questo file HTML dichiara quasi tutta l'interfaccia utente dell'app web.

Ci sono alcune sezioni di visualizzazioni, abbiamo il nostro div#main_video, che contiene l'elemento video. In relazione al nostro div video, abbiamo div#media_control, che definisce tutti i controlli per l'elemento video. Sotto, c'è media_info, che mostra i dettagli del video visualizzato. Infine, l'elemento div carousel mostra un elenco di video in un elemento div.

Il file index.html esegue anche il boots dell'SDK Cast e indica alla funzione CastVideos di caricarsi.

La maggior parte dei contenuti inclusi in questi elementi viene definita, inserita e controllata in CastVideos.js. Diamo un'occhiata.

CastVideos.js

Questo script gestisce tutta la logica dell'app web Cast Videos. L'elenco di video e i relativi metadati associati definiti in CastVideos.js è contenuto in un oggetto denominato mediaJSON.

Ci sono alcune sezioni principali che insieme sono responsabili della gestione e della riproduzione del video sia in locale sia in remoto. Nel complesso, si tratta di un'applicazione web piuttosto semplice.

CastPlayer è la classe principale che gestisce l'intera app, configura il player, seleziona i contenuti multimediali e associa gli eventi a PlayerHandler per la riproduzione di contenuti multimediali. CastPlayer.prototype.initializeCastPlayer è il metodo che configura tutte le funzionalità di trasmissione. CastPlayer.prototype.switchPlayer cambia lo stato tra player locali e remoti. CastPlayer.prototype.setupLocalPlayer e CastPlayer.prototype.setupRemotePlayer inizializzano player locali e remoti.

PlayerHandler è la classe responsabile della gestione della riproduzione di contenuti multimediali. Esistono una serie di altri metodi che sono responsabili della gestione dei dettagli relativi alla gestione dei contenuti multimediali e della riproduzione.

Domande frequenti

5. Aggiunta del pulsante Trasmetti

Immagine di un'app compatibile con Google Cast

Un'applicazione compatibile con Google Cast mostra il pulsante Trasmetti nell'elemento video. Se fai clic sul pulsante Trasmetti, viene visualizzato un elenco di dispositivi di trasmissione che l'utente può selezionare. Se l'utente riprodurva i contenuti localmente sul dispositivo mittente, la selezione di un dispositivo di trasmissione avvia o riprende la riproduzione su quel dispositivo. In qualsiasi momento durante una sessione di trasmissione, l'utente può fare clic sul pulsante Trasmetti e interrompere la trasmissione della tua applicazione al dispositivo di trasmissione. L'utente deve essere in grado di connettersi o disconnettersi dal dispositivo di trasmissione mentre è in qualsiasi schermata dell'applicazione, come descritto nell'elenco di controllo per la progettazione di Google Cast.

Configurazione

Il progetto iniziale richiede le stesse dipendenze e la stessa configurazione dell'app di esempio completata, ma questa volta ospita i contenuti di app-start.

Nel browser, visita l'URL https dell'esempio che hai ospitato.

Ricorda che, man mano che apporti le modifiche, dovrai eseguire il rehosting dell'esempio sul server, a seconda del servizio.

Inizializzazione

Il framework Cast ha un oggetto singleton globale, CastContext, che coordina tutte le attività del framework. Questo oggetto deve essere inizializzato all'inizio del ciclo di vita dell'applicazione, in genere richiamato da un callback assegnato a window['__onGCastApiAvailable'], che viene richiamato dopo il caricamento dell'SDK Cast ed è disponibile per l'uso. In questo caso, CastContext viene chiamato in CastPlayer.prototype.initializeCastPlayer, che viene chiamato dal callback sopra indicato.

Durante l'inizializzazione di CastContext è necessario specificare un oggetto JSON options. Questa classe contiene opzioni che influiscono sul comportamento del framework. Il più importante è l'ID applicazione ricevitore, che viene utilizzato per filtrare l'elenco dei dispositivi di trasmissione disponibili per mostrare soltanto i dispositivi in grado di eseguire l'app specificata e per avviare l'applicazione ricevitore all'avvio di una sessione di trasmissione.

Quando sviluppi la tua app compatibile con Google Cast, devi registrarti come sviluppatore di Google Cast e poi ottenere un ID applicazione per la tua app. Per questo codelab utilizzeremo un ID app di esempio.

Aggiungi il seguente codice a index.html alla fine della sezione body:

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

Aggiungi il codice seguente a index.html per inizializzare l'app CastVideos e per inizializzare CastContext:

<script src="CastVideos.js"></script>
<script type="text/javascript">
var castPlayer = new CastPlayer();
window['__onGCastApiAvailable'] = function(isAvailable) {
  if (isAvailable) {
    castPlayer.initializeCastPlayer();
  }
};
</script>

Ora dobbiamo aggiungere un nuovo metodo in CastVideos.js, che corrisponde a quello che abbiamo appena chiamato in index.html. Aggiungiamo un nuovo metodo, chiamato initializeCastPlayer, che imposta le opzioni su CastContext e inizializza i nuovi RemotePlayer e RemotePlayerControllers:

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

Infine, dobbiamo creare le variabili per RemotePlayer e RemotePlayerController:

var CastPlayer = function() {
  //...
  /* Cast player variables */
  /** @type {cast.framework.RemotePlayer} */
  this.remotePlayer = null;
  /** @type {cast.framework.RemotePlayerController} */
  this.remotePlayerController = null;
  //...
};

Pulsante Trasmetti

Ora che il CastContext è stato inizializzato, dobbiamo aggiungere il pulsante Trasmetti per consentire all'utente di selezionare un dispositivo di trasmissione. L'SDK Trasmetti fornisce un componente del pulsante Trasmetti denominato google-cast-launcher con ID "castbutton". Può essere aggiunto all'elemento video dell'applicazione semplicemente aggiungendo button nella sezione media_control.

Ecco come si presenta l'elemento pulsante:

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

Aggiungi il seguente codice a index.html nella sezione media_control:

<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>

Ora aggiorna la pagina nel browser Chrome. Dovresti vedere un pulsante Trasmetti nell'elemento video e quando fai clic su di esso vengono elencati i dispositivi di trasmissione sulla tua rete locale. Il rilevamento dei dispositivi è gestito automaticamente dal browser Chrome. Seleziona il tuo dispositivo di trasmissione e l'app ricevitore di esempio verrà caricata sul dispositivo.

Non abbiamo aggiunto alcun supporto per la riproduzione di contenuti multimediali, quindi non puoi ancora riprodurre video sul dispositivo di trasmissione. Fai clic sul pulsante Trasmetti per interrompere la trasmissione.

6. Trasmettere contenuti video

Immagine di un&#39;app compatibile con Google Cast con il menu di selezione del dispositivo di trasmissione

Estenderemo l'app di esempio anche per riprodurre video da remoto su un dispositivo di trasmissione. Per farlo, dobbiamo ascoltare i vari eventi generati dal framework Cast.

Trasmissione di contenuti multimediali

A un livello generale, se vuoi riprodurre un contenuto multimediale su un dispositivo di trasmissione, è necessario che:

  1. Crea un oggetto JSON MediaInfo dall'SDK Cast che modella un elemento multimediale.
  2. L'utente si connette al dispositivo di trasmissione per avviare l'applicazione di ricezione.
  3. Carica l'oggetto MediaInfo nel ricevitore e riproduci i contenuti.
  4. Tieni traccia dello stato dei contenuti multimediali.
  5. Invia i comandi di riproduzione al destinatario in base alle interazioni dell'utente.

Il passaggio 1 equivale a mappare un oggetto a un altro; MediaInfo è qualcosa che l'SDK Cast è in grado di comprendere, mentre mediaJSON è l'incapsulamento della nostra app per un elemento multimediale; possiamo facilmente mappare un mediaJSON a un MediaInfo. Abbiamo già eseguito il passaggio 2 nella sezione precedente. Il passaggio 3 è facile da eseguire con l'SDK Cast.

L'app di esempio CastPlayer fa già distinzione tra riproduzione locale e remota nel metodo switchPlayer:

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

In questo codelab non è importante capire esattamente come funziona tutta la logica del player di esempio. È però importante comprendere che il media player dell'app dovrà essere modificato per tenere conto delle funzionalità di riproduzione in locale e in remoto.

Al momento il player locale è sempre nello stato di riproduzione locale, poiché non sa ancora nulla sugli stati di trasmissione. Dobbiamo aggiornare l'interfaccia utente in base alle transizioni di stato che avvengono nel framework Cast. Ad esempio, se iniziamo a trasmettere, dobbiamo interrompere la riproduzione locale e disattivare alcuni controlli. Analogamente, se interrompiamo la trasmissione quando siamo in questo controller di visualizzazione, dobbiamo passare alla riproduzione locale. Per farlo, dobbiamo ascoltare i vari eventi generati dal framework Cast.

Gestione della sessione di trasmissione

Per il framework di trasmissione, una sessione di trasmissione combina i passaggi per la connessione a un dispositivo, l'avvio (o la partecipazione a una sessione esistente), la connessione a un'applicazione ricevitore e l'inizializzazione di un canale di controllo multimediale, se opportuno. Il canale di controllo dei contenuti multimediali è il modo in cui il framework di trasmissione invia e riceve dal destinatario i messaggi relativi alla riproduzione di contenuti multimediali.

La sessione di trasmissione viene avviata automaticamente quando l'utente seleziona un dispositivo dal pulsante Trasmetti e viene interrotta automaticamente quando l'utente si disconnette. Anche la riconnessione a una sessione del ricevitore a causa di problemi di rete viene gestita automaticamente dal framework Cast.

Le sessioni di trasmissione sono gestite dalla CastSession, a cui è possibile accedere tramite cast.framework.CastContext.getInstance().getCurrentSession(). I callback EventListener possono essere utilizzati per monitorare gli eventi della sessione, ad esempio la creazione, la sospensione, la ripresa e la chiusura.

Nella nostra applicazione attuale, tutta la gestione delle sessioni e dello stato è gestita per noi tramite il metodo setupRemotePlayer. Per iniziare a configurarlo nella tua app, aggiungi il seguente codice a CastVideos.js:

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

Dobbiamo ancora associare tutti gli eventi dai callback e gestire tutti gli eventi in arrivo. Si tratta di una procedura piuttosto semplice da eseguire, quindi ora ce ne occupiamo:

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

Caricamento contenuti multimediali

Nell'SDK Cast, RemotePlayer e RemotePlayerController forniscono un insieme di pratiche API per la gestione della riproduzione remota di contenuti multimediali sul ricevitore. Per un CastSession che supporta la riproduzione di contenuti multimediali, le istanze di RemotePlayer e RemotePlayerController verranno create automaticamente dall'SDK. È possibile accedervi creando istanze di cast.framework.RemotePlayer e cast.framework.RemotePlayerController rispettivamente, come mostrato in precedenza nel codelab.

A questo punto, dobbiamo caricare il video attualmente selezionato sul destinatario creando un oggetto MediaInfo che l'SDK possa elaborare e trasmettere la richiesta. Per farlo, aggiungi il seguente codice a setupRemotePlayer:

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

    //...
};

Ora aggiungi un metodo per passare dalla riproduzione locale a quella remota e viceversa:

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

Infine, aggiungi un metodo per gestire gli eventuali messaggi di errore di Google Cast:

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

Ora esegui l'app. Collegati al dispositivo di trasmissione e inizia a riprodurre un video. Dovresti vedere il video riprodotto sul ricevitore.

7. Aggiunta dell'assistenza per Cast Connect

La libreria di Cast Connect consente alle applicazioni mittente esistenti di comunicare con le applicazioni Android TV tramite il protocollo Cast. Cast Connect si basa sull'infrastruttura di Cast e la tua app Android TV funge da ricevitore.

Dipendenze

  • Versione del browser Chrome M87 o successive

Imposta il ricevitore Android compatibile

Per avviare l'applicazione Android TV, nota anche come ricevitore Android, dobbiamo impostare il flag androidReceiverCompatible su true nell'oggetto CastOptions.

Aggiungi il seguente codice a CastVideos.js nella funzione initializeCastPlayer:

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

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

Imposta credenziali di avvio

Sul lato del mittente, puoi specificare CredentialsData per indicare chi parteciperà alla sessione. credentials è una stringa che può essere definita dall'utente, purché l'app ATV sia in grado di comprenderla. Il CredentialsData viene trasmesso alla tua app Android TV soltanto durante la fase di lancio o di partecipazione. Se la imposti di nuovo mentre la connessione è attiva, non verrà trasmessa all'app Android TV.

Per impostare le credenziali di lancio, è necessario definire CredentialsData in qualsiasi momento dopo l'impostazione delle opzioni di avvio.

Aggiungi il seguente codice alla classe CastVideos.js nella funzione initializeCastPlayer:

cast.framework.CastContext.getInstance().setOptions(options);
...
let credentialsData = new chrome.cast.CredentialsData("{\"userId\": \"abc\"}");
cast.framework.CastContext.getInstance().setLaunchCredentialsData(credentialsData);
...

Imposta credenziali sulla richiesta di caricamento

Nel caso in cui la tua app Web ricevitore e l'app Android TV gestiscano credentials in modo diverso, potresti dover definire credenziali distinte per ciascuna. A questo scopo, aggiungi il seguente codice in CastVideos.js in playerTarget.load nella funzione setupRemotePlayer:

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

A seconda dell'app del destinatario a cui il mittente trasmette, l'SDK gestisce automaticamente le credenziali da utilizzare per la sessione corrente.

Test di Cast Connect

Procedura per installare l'APK di Android TV su Chromecast con Google TV:

  1. Trova l'indirizzo IP del tuo dispositivo Android TV. Di solito è disponibile in Impostazioni > Rete e Internet > (Nome della rete a cui è connesso il dispositivo). Sulla destra sono visualizzati i dettagli e l'IP del dispositivo sulla rete.
  2. Utilizza l'indirizzo IP del dispositivo per connetterti tramite ADB utilizzando il terminale:
$ adb connect <device_ip_address>:5555
  1. Dalla finestra del terminale, vai alla cartella di primo livello per trovare gli esempi del codelab che hai scaricato all'inizio di questo codelab. Ad esempio:
$ cd Desktop/chrome_codelab_src
  1. Installa il file .apk in questa cartella sulla tua Android TV eseguendo:
$ adb -s <device_ip_address>:5555 install android-tv-app.apk
  1. Ora dovresti riuscire a vedere un'app chiamata Trasmetti video nel menu Le tue app sul dispositivo Android TV.
  2. Esegui il codice web mittente aggiornato e stabilisci una sessione di trasmissione con il tuo dispositivo Android TV utilizzando l'icona di trasmissione o selezionando Cast.. dal menu a discesa del browser Chrome. Ora l'app Android TV sul ricevitore Android dovrebbe essere avviata e potrai controllare la riproduzione usando il telecomando di Android TV.

8. Congratulazioni

Ora sai come attivare la trasmissione di un'app video utilizzando i widget dell'SDK Cast in un'app web di Chrome.

Per ulteriori dettagli, consulta la guida per gli sviluppatori Web mittente.