Crea un ricevitore web personalizzato

1. Panoramica

Logo di Google Cast

Questo codelab ti insegnerà a creare un'app ricevitore web personalizzata per riprodurre contenuti su dispositivi compatibili 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 o il browser Chrome su computer come telecomando per la riproduzione di contenuti multimediali sulla TV.

L'SDK Google Cast consente alla tua app di controllare i dispositivi compatibili con Google Cast (ad esempio, la TV o il sistema audio). L'SDK Cast fornisce i componenti UI necessari in base all'elenco di controllo per la progettazione di Google Cast.

Viene fornito un elenco di controllo per la progettazione di Google Cast per rendere l'esperienza utente di Cast semplice e prevedibile su tutte le piattaforme supportate. Scopri di più qui.

Cosa realizzeremo

Una volta completato questo codelab, avrai un'app HTML5 che funge da ricevitore personalizzato in grado di visualizzare contenuti video su dispositivi compatibili con Google Cast.

Obiettivi didattici

  • Come configurare lo sviluppo dei ricevitori.
  • Nozioni di base su un ricevitore compatibile con Google Cast basato sul framework dell'applicazione Cast.
  • Come ricevere un video trasmesso in trasmissione.
  • Come integrare Debug Logger.
  • Come ottimizzare il ricevitore per gli smart display.

Che cosa ti serve

Esperienza

  • È richiesta una conoscenza pregressa dello sviluppo web.
  • È necessaria anche una conoscenza pregressa di come guardare la TV :)

Come userai questo tutorial?

Leggi solo tutto Leggi e completa gli esercizi

Come valuteresti 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 decomprimere il file ZIP scaricato.

3. Deployment locale del ricevitore

Per poter utilizzare il ricevitore web con un dispositivo di trasmissione, il dispositivo deve essere ospitato in un luogo dove il dispositivo di trasmissione può raggiungerlo. Se è già disponibile un server che supporta il protocollo HTTPS, ignora le seguenti istruzioni e prendi nota dell'URL, che ti servirà nella sezione successiva.

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-start e avvia il server.

Prendi nota dell'URL del destinatario ospitato. Lo utilizzerai nella prossima sezione.

4. Registrare un'applicazione nella Console per gli sviluppatori di Google Cast

Devi registrare la tua applicazione per poter eseguire un ricevitore personalizzato, come integrato in questo codelab, sui dispositivi Chromecast. Dopo aver registrato la tua applicazione, riceverai un ID applicazione che l'applicazione mittente deve utilizzare per eseguire chiamate API, ad esempio per avviare un'applicazione destinatario.

Immagine della Developer Console dell'SDK Google Cast con il pulsante "Aggiungi nuova applicazione" evidenziato

Fai clic su "Aggiungi nuova applicazione"

Immagine della schermata "Nuova applicazione ricevitore" con l'opzione "Ricevitore personalizzato" evidenziata

Seleziona "Ricevitore personalizzato". È quello che stiamo realizzando.

Immagine della schermata "Nuovo ricevitore personalizzato" che mostra l'URL che qualcuno sta digitando nel campo "URL applicazione del destinatario"

Inserisci i dettagli del nuovo destinatario e assicurati di utilizzare l'URL ottenuto

nell'ultima sezione. Prendi nota dell'ID applicazione assegnato al nuovo ricevitore.

Devi inoltre registrare il dispositivo Google Cast in modo che possa accedere all'applicazione ricevitore prima di pubblicarla. Una volta pubblicata, l'applicazione del ricevitore sarà disponibile per tutti i dispositivi Google Cast. Ai fini di questo codelab è consigliabile lavorare con un'applicazione ricevitore non pubblicata.

Immagine della Console per gli sviluppatori dell'SDK Google Cast con il pulsante "Aggiungi nuovo dispositivo" evidenziato

Fai clic su "Aggiungi nuovo dispositivo".

Immagine della finestra di dialogo "Aggiungi dispositivo ricevitore di trasmissione"

Inserisci il numero di serie stampato sul retro del dispositivo di trasmissione e assegnagli un nome descrittivo. Puoi trovare il numero di serie anche trasmettendo lo schermo in Chrome quando accedi alla Console per gli sviluppatori dell'SDK Google Cast.

Saranno necessari 5-15 minuti prima che ricevitore e dispositivo siano pronti per i test. Dopo aver atteso 5-15 minuti, devi riavviare il dispositivo di trasmissione.

5. Esegui l'app di esempio

Logo di Google Chrome

Mentre attendiamo che la nostra nuova applicazione destinatario sia pronta per i test, vediamo come appare un esempio di app destinatario completata. Il ricevitore che creeremo sarà in grado di riprodurre contenuti multimediali utilizzando lo streaming a velocità in bit adattiva (Utilizzeremo contenuti di esempio codificati per lo streaming adattivo dinamico su HTTP (DASH)).

Nel browser, apri lo strumento Comando e controllo (CaC).

Immagine della scheda "Cast Connect & Logger Controls" dello strumento Command and Control (CaC)

  1. Dovresti vedere lo strumento CaC.
  2. Usa l'ID ricevitore di esempio predefinito "CC1AD845" e fai clic sul pulsante "Set App ID" (Imposta ID app).
  3. Fai clic sul pulsante Trasmetti in alto a sinistra e seleziona il tuo dispositivo Google Cast.

Immagine della scheda "Cast Connect & Logger Controls" dello strumento Command and Control (CaC) che indica che il dispositivo è connesso a un'app ricevitore

  1. Vai alla scheda "Carica contenuti multimediali" in alto.

Immagine della scheda "Carica contenuti multimediali" dello strumento Command and Control (CaC)

  1. Fai clic sul pulsante "Carica per contenuti" per riprodurre un video di esempio.
  2. Il video inizierà a essere riprodotto sul dispositivo Google Cast per mostrare la funzionalità di base del ricevitore quando usa il ricevitore predefinito.

6. Prepara il progetto di avvio

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

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

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

  1. Seleziona la directory icona cartellaapp-start dal download del codice campione.
  2. Apri js/receiver.js e index.html

Tieni presente che, man mano che svolgi questo codelab, http-server dovrebbe rilevare le modifiche che apporti. Se noti che non è così, prova a terminare e riavviare http-server.

Progettazione dell'app

L'app del destinatario inizializza la sessione di trasmissione e rimane in modalità standby finché il mittente non riceve una richiesta LOAD (in altre parole, il comando per riprodurre un contenuto multimediale).

L'app è costituita da una visualizzazione principale, definita in index.html, e da un file JavaScript chiamato js/receiver.js contenente tutta la logica necessaria per il funzionamento del destinatario.

index.html

Questo file HTML conterrà l'interfaccia utente dell'app ricevitore. Per il momento è vuoto e lo aggiungeremo durante il codelab.

receiver.js

Questo script gestirà tutta la logica dell'app ricevitore. Al momento si tratta di un file vuoto, ma lo trasformeremo in un ricevitore di trasmissione completamente funzionante con poche righe di codice nella sezione successiva.

7. Un ricevitore di trasmissione di base

Un ricevitore di trasmissione di base inizializza la sessione di trasmissione all'avvio. Questa operazione è necessaria per comunicare a tutte le applicazioni del mittente connesse che hanno visualizzato il destinatario correttamente. Inoltre, il nuovo SDK è preconfigurato per gestire da subito contenuti multimediali in streaming a velocità in bit adattiva (utilizzando DASH, HLS e streaming fluido) e file MP4 semplici. Proviamo.

Inizializzazione

Aggiungi il seguente codice a index.html nell'intestazione:

<head>
  ...

  <script src="//www.gstatic.com/cast/sdk/libs/caf_receiver/v3/cast_receiver_framework.js"></script>
</head>

Aggiungi il seguente codice a index.html <body> prima del <footer> caricamento receiver.js, per fornire all'SDK del destinatario lo spazio necessario per visualizzare l'UI del destinatario predefinita fornita con lo script che hai appena aggiunto.

<cast-media-player></cast-media-player>

Ora dobbiamo inizializzare l'SDK in js/receiver.js, composto da:

  • l'acquisizione di un riferimento a CastReceiverContext, il tuo punto di ingresso principale per l'intero SDK Ricevir
  • memorizzando un riferimento a PlayerManager, l'oggetto che gestisce la riproduzione e fornisce tutti gli hook necessari per collegare la propria logica personalizzata
  • inizializzare l'SDK chiamando start() su CastReceiverContext

Aggiungi il seguente codice a js/receiver.js.

const context = cast.framework.CastReceiverContext.getInstance();
const playerManager = context.getPlayerManager();

context.start();

8. Trasmettere contenuti video "di base"

Ai fini di questo codelab, utilizza lo strumento CaC per provare il tuo nuovo ricevitore.

Nel browser web, seleziona lo strumento Comando e controllo (CaC).

Immagine della scheda &quot;Cast Connect & Logger Controls&quot; dello strumento Command and Control (CaC)

Assicurati di sostituire il tuo ID app come registrato in precedenza nel campo e fai clic su "Imposta ID app". Questa opzione indica allo strumento di utilizzare il ricevitore all'avvio della sessione di trasmissione.

Trasmissione di contenuti multimediali

A livello generale, per riprodurre contenuti multimediali su un dispositivo di trasmissione è necessario che:

  1. Il mittente crea un oggetto JSON MediaInfo dall'SDK Cast che modella un elemento multimediale.
  2. Il mittente si connette al dispositivo di trasmissione per avviare l'applicazione del destinatario.
  3. Il destinatario carica l'oggetto MediaInfo tramite una richiesta LOAD per riprodurre i contenuti.
  4. Il destinatario monitora e tiene traccia dello stato dei contenuti multimediali.
  5. Il mittente invia comandi di riproduzione al destinatario per controllare la riproduzione in base alle interazioni dell'utente con l'app del mittente.

In questo primo tentativo di base completeremo MediaInfo con l'URL di un asset riproducibile (memorizzato in MediaInfo.contentUrl).

Un mittente reale utilizza un identificatore multimediale specifico per l'applicazione in MediaInfo.contentId. Il destinatario usa contentId come identificatore per effettuare le chiamate API di backend appropriate per risolvere l'URL effettivo della risorsa e impostarlo su MediaInfo.contentUrl.. Il destinatario gestirà anche attività come l'acquisizione di licenze DRM o l'inserimento di informazioni sulle interruzioni pubblicitarie.

Estenderemo il tuo ricevitore in modo che possa fare qualcosa di simile nella prossima sezione. Per ora, fai clic sull'icona Trasmetti e seleziona il tuo dispositivo per aprire il ricevitore.

Immagine della scheda &quot;Cast Connect & Logger Controls&quot; dello strumento Command and Control (CaC) che indica che il dispositivo è connesso a un&#39;app ricevitore

Vai alla scheda "Carica contenuti multimediali" e fai clic sul pulsante "Carica per contenuti". Il ricevitore dovrebbe iniziare a riprodurre il contenuto del campione.

Immagine della scheda &quot;Carica contenuti multimediali&quot; dello strumento Command and Control (CaC)

Quindi, immediatamente l'SDK ricevitore gestisce:

  • Inizializzazione della sessione di trasmissione
  • Gestire le richieste LOAD in arrivo dai mittenti che contengono asset riproducibili
  • Offri un'interfaccia utente di base del player pronta per essere visualizzata sullo schermo di casa.

Esplora liberamente lo strumento CaC e il relativo codice prima di passare alla sezione successiva, in cui estenderemo il nostro destinatario per parlare con una semplice API di esempio per soddisfare le richieste LOAD in arrivo dai mittenti.

9. Integrazione con un'API esterna

In linea con il modo in cui la maggior parte degli sviluppatori interagisce con i ricevitori di trasmissione nelle applicazioni reali, modificheremo il nostro ricevitore per gestire le richieste LOAD che fanno riferimento ai contenuti multimediali previsti dalla relativa chiave API, anziché inviare l'URL di una risorsa riproducibile.

Le applicazioni in genere fanno questo perché:

  • Il mittente potrebbe non conoscere l'URL dei contenuti.
  • L'applicazione Cast è progettata per gestire l'autenticazione, altra logica di business o chiamate API direttamente sul ricevitore.

Questa funzionalità è implementata principalmente nel metodo PlayerManager setMessageInterceptor(). In questo modo puoi intercettare i messaggi in arrivo per tipo e modificarli prima che raggiungano il gestore di messaggi interno dell'SDK. In questa sezione ci occuperemo delle richieste LOAD in cui eseguiremo le seguenti operazioni:

  • Leggi la richiesta LOAD in arrivo e la relativa contentId personalizzata.
  • Effettua una chiamata GET alla nostra API per cercare l'asset riproducibile in streaming in base al relativo contentId.
  • Modifica la richiesta LOAD con l'URL dello stream.
  • Modifica l'oggetto MediaInformation per impostare i parametri del tipo di stream.
  • Passa la richiesta all'SDK per la riproduzione o rifiuta il comando se non siamo in grado di cercare i contenuti multimediali richiesti.

L'API di esempio fornita mostra gli hook dell'SDK per personalizzare le attività di ricezione comuni, utilizzando comunque un'esperienza per lo più pronta all'uso.

API di esempio

Vai su https://storage.googleapis.com/cpe-sample-media/content.json per dare un'occhiata al nostro catalogo di video di esempio. I contenuti includono gli URL per le immagini poster in formato png e per gli stream DASH e HLS. Gli stream DASH e HLS puntano a sorgenti video e audio separate e archiviate in contenitori mp4 frammentati.

{
  "bbb": {
    "author": "The Blender Project",
    "description": "Grumpy Bunny is grumpy",
    "poster": "https://[...]/[...]/BigBuckBunny/images/screenshot1.png",
    "stream": {
      "dash": "https://[...]/[...]/BigBuckBunny/BigBuckBunny_master.mpd",
      "hls": "https://[...]/[...]/BigBuckBunny/BigBuckBunny_master.m3u8",
    "title": "Big Buck Bunny"
  },
  "fbb_ad": {
    "author": "Google Inc.",
    "description": "Introducing Chromecast. The easiest way to enjoy [...]",
    "poster": "https://[...]/[...]/ForBiggerBlazes/images/screenshot8.png",
    "stream": {
      "dash": "https://[...]/[...]/ForBiggerBlazes/ForBiggerBlazes.mpd",
      "hls": "https://[...]/[...]/ForBiggerBlazes/ForBiggerBlazes.m3u8",
    "title": "For Bigger Blazes"
  },

  [...]

}

Nel passaggio successivo, mapperemo la chiave di ogni voce (ad esempio bbb, fbb_ad) all'URL dello stream dopo che il destinatario è stato chiamato con una richiesta LOAD.

Intercetta la richiesta LOAD

In questo passaggio creeremo un intercettore di carico con una funzione che effettua una richiesta XHR al file JSON ospitato. Una volta ottenuto il file JSON, analizzeremo i contenuti e imposteremo i metadati. Nelle sezioni seguenti personalizzeremo i parametri MediaInformation per specificare il tipo di contenuti.

Aggiungi il seguente codice al file js/receiver.js, subito prima della chiamata a context.start().

function makeRequest (method, url) {
  return new Promise(function (resolve, reject) {
    let xhr = new XMLHttpRequest();
    xhr.open(method, url);
    xhr.onload = function () {
      if (this.status >= 200 && this.status < 300) {
        resolve(JSON.parse(xhr.response));
      } else {
        reject({
          status: this.status,
          statusText: xhr.statusText
        });
      }
    };
    xhr.onerror = function () {
      reject({
        status: this.status,
        statusText: xhr.statusText
      });
    };
    xhr.send();
  });
}

playerManager.setMessageInterceptor(
    cast.framework.messages.MessageType.LOAD,
    request => {
      return new Promise((resolve, reject) => {
        // Fetch content repository by requested contentId
        makeRequest('GET', 'https://storage.googleapis.com/cpe-sample-media/content.json').then(function (data) {
          let item = data[request.media.contentId];
          if(!item) {
            // Content could not be found in repository
            reject();
          } else {
            // Add metadata
            let metadata = new
               cast.framework.messages.GenericMediaMetadata();
            metadata.title = item.title;
            metadata.subtitle = item.author;

            request.media.metadata = metadata;

            // Resolve request
            resolve(request);
          }
        });
      });
    });

La sezione successiva illustra come configurare la proprietà media della richiesta di caricamento per i contenuti DASH.

Utilizzo dei contenuti DASH dell'API di esempio

Ora che abbiamo preparato l'intercettatore del carico, specifichiamo il tipo di contenuti per il destinatario. Queste informazioni forniscono al destinatario l'URL della playlist principale e il tipo MIME dello stream. Aggiungi il seguente codice al file js/receiver.js nell'elemento Promise() dell'intercettatore LOAD:

...
playerManager.setMessageInterceptor(
    cast.framework.messages.MessageType.LOAD,
    request => {
      return new Promise((resolve, reject) => {
          ...
          } else {
            // Adjusting request to make requested content playable
            request.media.contentUrl = item.stream.dash;
            request.media.contentType = 'application/dash+xml';
            ...
          }
        });
      });
    });

Una volta completato questo passaggio, puoi procedere con il test per provare a caricare i contenuti DASH. Se invece vuoi provare il caricamento con contenuti HLS, vai al passaggio successivo.

Utilizzo del contenuto HLS dell'API di esempio

L'API di esempio include contenuti HLS e DASH. Oltre a impostare contentType come abbiamo fatto nel passaggio precedente, la richiesta di caricamento avrà bisogno di alcune proprietà aggiuntive per utilizzare gli URL HLS dell'API di esempio. Quando il destinatario è configurato per riprodurre i flussi HLS, il tipo di container predefinito previsto è Transport Stream (TS). Di conseguenza, il destinatario proverà ad aprire gli stream MP4 di esempio in formato TS se viene modificata solo la proprietà contentUrl. Nella richiesta di caricamento, l'oggetto MediaInformation deve essere modificato con proprietà aggiuntive, in modo che il destinatario sappia che i contenuti sono di tipo MP4 e non TS. Aggiungi il seguente codice al file js/receiver.js nell'intercettatore di carico per modificare le proprietà contentUrl e contentType. Aggiungi anche le proprietà HlsSegmentFormat e HlsVideoSegmentFormat.

...
playerManager.setMessageInterceptor(
    cast.framework.messages.MessageType.LOAD,
    request => {
      return new Promise((resolve, reject) => {
          ...
          } else {
            // Adjusting request to make requested content playable
            request.media.contentUrl = item.stream.hls;
            request.media.contentType = 'application/x-mpegurl';
            request.media.hlsSegmentFormat = cast.framework.messages.HlsSegmentFormat.FMP4;
            request.media.hlsVideoSegmentFormat = cast.framework.messages.HlsVideoSegmentFormat.FMP4;
            ...
          }
        });
      });
    });

Test

Apri di nuovo lo strumento Comando e controllo (CaC) e imposta l'ID app sull'ID app del destinatario. Seleziona il tuo dispositivo utilizzando il pulsante Trasmetti.

Vai alla scheda "Carica contenuti multimediali". Questa volta elimina il testo nel campo "URL contenuti" accanto al pulsante "Carica in base ai contenuti". In questo modo, la nostra applicazione dovrà inviare una richiesta LOAD contenente solo il riferimento contentId ai nostri contenuti multimediali.

Immagine della scheda &quot;Carica contenuti multimediali&quot; dello strumento Command and Control (CaC)

Supponendo che tutto abbia funzionato correttamente con le modifiche apportate al ricevitore, l'intercettore dovrebbe occuparsi di plasmare l'oggetto MediaInfo in qualcosa che l'SDK possa riprodurre sullo schermo.

Fai clic sul pulsante "Carica per contenuti" per verificare se i contenuti multimediali vengono riprodotti correttamente. Non esitare a cambiare Content ID impostandolo su un altro ID nel file content.json.

10. Ottimizzazione per gli smart display

Gli smart display sono dispositivi con funzionalità touch che consentono alle applicazioni del ricevitore di supportare i controlli touch.

Questa sezione spiega come ottimizzare l'applicazione ricevitore quando viene lanciata su smart display e come personalizzare i controlli del player.

Accesso ai controlli UI

È possibile accedere all'oggetto Controlli UI per gli smart display utilizzando cast.framework.ui.Controls.GetInstance(). Aggiungi il seguente codice al tuo file js/receiver.js sopra context.start():

...

// Optimizing for smart displays
const touchControls = cast.framework.ui.Controls.getInstance();

context.start();

Se non usi l'elemento <cast-media-player>, devi impostare touchScreenOptimizedApp in CastReceiverOptions. In questo codelab, verrà utilizzato l'elemento <cast-media-player>.

context.start({ touchScreenOptimizedApp: true });

I pulsanti di controllo predefiniti vengono assegnati a ogni slot in base ai criteri MetadataType e MediaStatus.supportedMediaCommands.

Controlli video

Per MetadataType.MOVIE, MetadataType.TV_SHOW e MetadataType.GENERIC, l'oggetto Controlli UI per smart display verrà visualizzato come nell'esempio riportato di seguito.

Immagine di un video in riproduzione con i controlli UI sovrapposti

  1. --playback-logo-image
  2. MediaMetadata.subtitle
  3. MediaMetadata.title
  4. MediaStatus.currentTime
  5. MediaInformation.duration
  6. ControlsSlot.SLOT_SECONDARY_1: ControlsButton.QUEUE_PREV
  7. ControlsSlot.SLOT_PRIMARY_1: ControlsButton.SEEK_BACKWARD_30
  8. PLAY/PAUSE
  9. ControlsSlot.SLOT_PRIMARY_2: ControlsButton.SEEK_FORWARD_30
  10. ControlsSlot.SLOT_SECONDARY_2: ControlsButton.QUEUE_NEXT

Controlli audio

Per MetadataType.MUSIC_TRACK, l'oggetto Controlli UI per smart display verrà visualizzato come segue:

Immagine della musica in riproduzione con i controlli UI sovrapposti

  1. --playback-logo-image
  2. MusicTrackMediaMetadata.albumName
  3. MusicTrackMediaMetadata.title
  4. MusicTrackMediaMetadata.albumArtist
  5. MusicTrackMediaMetadata.images[0]
  6. MediaStatus.currentTime
  7. MediaInformation.duration
  8. ControlsSlot.SLOT_SECONDARY_1: ControlsButton.NO_BUTTON
  9. ControlsSlot.SLOT_PRIMARY_1: ControlsButton.QUEUE_PREV
  10. PLAY/PAUSE
  11. ControlsSlot.SLOT_PRIMARY_2: ControlsButton.QUEUE_NEXT
  12. ControlsSlot.SLOT_SECONDARY_2: ControlsButton.NO_BUTTON

Aggiornamento dei comandi multimediali supportati

L'oggetto Controlli UI determina anche se un ControlsButton viene mostrato o meno in base a MediaStatus.supportedMediaCommands.

Quando il valore di supportedMediaCommands è uguale a ALL_BASIC_MEDIA, il layout di controllo predefinito viene visualizzato come segue:

Immagine dei controlli del media player: barra di avanzamento, pulsante &quot;Riproduci&quot;, &quot;Vai avanti&quot; e &quot;Vai indietro&quot; attivati

Quando il valore di supportedMediaCommands è uguale a ALL_BASIC_MEDIA | QUEUE_PREV | QUEUE_NEXT, il layout di controllo predefinito viene visualizzato come segue:

Immagine dei controlli del media player: barra di avanzamento, pulsante &quot;Riproduci&quot;, &quot;Vai avanti&quot; e &quot;Salta indietro&quot; e pulsanti &quot;Coda precedente&quot; e &quot;Coda successiva&quot; attivati

Quando il valore disupportedMediaCommands è uguale a PAUSE | QUEUE_PREV | QUEUE_NEXT, il layout di controllo predefinito viene visualizzato come segue:

Immagine dei controlli del media player: barra di avanzamento, pulsante &quot;Riproduci&quot; e pulsanti &quot;Coda precedente&quot; e &quot;Coda successiva&quot; attivati

Quando le tracce di testo sono disponibili, il pulsante per i sottotitoli codificati verrà sempre visualizzato in SLOT_1.

Immagine dei controlli del lettore multimediale: barra di avanzamento, pulsante &quot;Riproduci&quot;, &quot;Vai avanti&quot; e &quot;Vai indietro&quot;, &quot;Coda precedente&quot; e &quot;Coda successiva&quot; e pulsanti &quot;Sottotitoli codificati&quot; attivati

Per modificare in modo dinamico il valore supportedMediaCommands dopo aver avviato un contesto del destinatario, puoi chiamare PlayerManager.setSupportedMediaCommands per sostituire il valore. Inoltre, puoi aggiungere un nuovo comando utilizzando addSupportedMediaCommands o rimuovere un comando esistente utilizzando removeSupportedMediaCommands.

Personalizzazione dei pulsanti di controllo

Puoi personalizzare i controlli usando PlayerDataBinder. Aggiungi il seguente codice al tuo file js/receiver.js sotto i touchControl per impostare il primo slot dei tuoi controlli:

...

// Optimizing for smart displays
const touchControls = cast.framework.ui.Controls.getInstance();
const playerData = new cast.framework.ui.PlayerData();
const playerDataBinder = new cast.framework.ui.PlayerDataBinder(playerData);

playerDataBinder.addEventListener(
  cast.framework.ui.PlayerDataEventType.MEDIA_CHANGED,
  (e) => {
    if (!e.value) return;

    // Clear default buttons and re-assign
    touchControls.clearDefaultSlotAssignments();
    touchControls.assignButton(
      cast.framework.ui.ControlsSlot.SLOT_PRIMARY_1,
      cast.framework.ui.ControlsButton.SEEK_BACKWARD_30
    );
  });

context.start();

11. Implementare la navigazione multimediale sugli smart display

La funzione Sfoglia contenuti multimediali è una funzionalità di ricezione CAF che consente agli utenti di esplorare contenuti aggiuntivi sui dispositivi touch. Per implementare questa funzionalità, utilizzerai PlayerDataBinder per impostare la UI di BrowseContent. Puoi quindi completarlo con BrowseItems in base ai contenuti che vuoi visualizzare.

BrowseContent

Di seguito è riportato un esempio dell'interfaccia utente di BrowseContent e delle sue proprietà:

Immagine dell&#39;interfaccia utente di BrowsingContent che mostra due miniature video e una parte di un terzo

  1. BrowseContent.title
  2. BrowseContent.items

Formato

Utilizza l'targetAspectRatio property per selezionare le proporzioni migliori per i tuoi asset immagine. L'SDK CAF ricevitore supporta tre proporzioni: SQUARE_1_TO_1, PORTRAIT_2_TO_3, LANDSCAPE_16_TO_9.

BrowseItem

Usa BrowseItem per visualizzare titolo, sottotitolo, durata e immagine di ciascun elemento:

Immagine dell&#39;interfaccia utente di BrowsingContent che mostra due miniature video e una parte di un terzo

  1. BrowseItem.image
  2. BrowseItem.duration
  3. BrowseItem.title
  4. BrowseItem.subtitle

Impostare i dati della consultazione di contenuti multimediali

Puoi fornire un elenco di contenuti multimediali per la navigazione chiamando il numero setBrowseContent. Aggiungi il seguente codice al file js/receiver.js sotto playerDataBinder e nel listener di eventi MEDIA_CHANGED per impostare gli elementi di consultazione con il titolo "Prossimi video".

// Optimizing for smart displays
const touchControls = cast.framework.ui.Controls.getInstance();
const playerData = new cast.framework.ui.PlayerData();
const playerDataBinder = new cast.framework.ui.PlayerDataBinder(playerData);

...

let browseItems = getBrowseItems();

function getBrowseItems() {
  let browseItems = [];
  makeRequest('GET', 'https://storage.googleapis.com/cpe-sample-media/content.json')
  .then(function (data) {
    for (let key in data) {
      let item = new cast.framework.ui.BrowseItem();
      item.entity = key;
      item.title = data[key].title;
      item.subtitle = data[key].description;
      item.image = new cast.framework.messages.Image(data[key].poster);
      item.imageType = cast.framework.ui.BrowseImageType.MOVIE;
      browseItems.push(item);
    }
  });
  return browseItems;
}

let browseContent = new cast.framework.ui.BrowseContent();
browseContent.title = 'Up Next';
browseContent.items = browseItems;
browseContent.targetAspectRatio = cast.framework.ui.BrowseImageAspectRatio.LANDSCAPE_16_TO_9;

playerDataBinder.addEventListener(
  cast.framework.ui.PlayerDataEventType.MEDIA_CHANGED,
  (e) => {
    if (!e.value) return;

    ....

    // Media browse
    touchControls.setBrowseContent(browseContent);
  });

Se fai clic su un elemento della consultazione di contenuti multimediali, verrà attivato l'intercettatore LOAD. Aggiungi il seguente codice al tuo intercettore LOAD per mappare request.media.contentId al request.media.entity dall'elemento di esplorazione dei contenuti multimediali:

playerManager.setMessageInterceptor(
    cast.framework.messages.MessageType.LOAD,
    request => {
      ...

      // Map contentId to entity
      if (request.media && request.media.entity) {
        request.media.contentId = request.media.entity;
      }

      return new Promise((resolve, reject) => {
            ...
        });
    });

Puoi anche impostare l'oggetto BrowseContent su null per rimuovere l'interfaccia utente di esplorazione dei contenuti multimediali.

12. Debug delle app ricevitori

L'SDK Cast ricevitore fornisce agli sviluppatori un'altra opzione per eseguire facilmente il debug delle app del ricevitore utilizzando l'API CastDebugLogger e uno strumento Command and Control (CaC) complementare per acquisire i log.

Inizializzazione

Per incorporare l'API, aggiungi lo script di origine CastDebugLogger nel file index.html. L'origine deve essere dichiarata nel tag <head> dopo la dichiarazione dell'SDK Cast Receiver.

<head>
  ...
  <script src="//www.gstatic.com/cast/sdk/libs/caf_receiver/v3/cast_receiver_framework.js"></script>
  <!-- Cast Debug Logger -->
  <script src="//www.gstatic.com/cast/sdk/libs/devtools/debug_layer/caf_receiver_logger.js"></script>
</head>

In js/receiver.js nella parte superiore del file e sotto playerManager, aggiungi il seguente codice per recuperare l'istanza CastDebugLogger e abilitare il logger:

const context = cast.framework.CastReceiverContext.getInstance();
const playerManager = context.getPlayerManager();

// Debug Logger
const castDebugLogger = cast.debug.CastDebugLogger.getInstance();
const LOG_TAG = 'MyAPP.LOG';

// Enable debug logger and show a 'DEBUG MODE' overlay at top left corner.
context.addEventListener(cast.framework.system.EventType.READY, () => {
  if (!castDebugLogger.debugOverlayElement_) {
      castDebugLogger.setEnabled(true);
  }
});

Quando il logger di debug è attivato, sul ricevitore viene mostrato un overlay che mostra DEBUG MODE.

Immagine di un video in riproduzione con il messaggio &quot;MODALITÀ DI DEBUG&quot; che appare su uno sfondo rosso nell&#39;angolo in alto a sinistra del frame

Eventi del player di log

Con CastDebugLogger puoi registrare facilmente gli eventi del player attivati dall'SDK CAF ricevitore e utilizzare diversi livelli di logger per registrare i dati sugli eventi. La configurazione loggerLevelByEvents utilizza cast.framework.events.EventType e cast.framework.events.category per specificare quali eventi verranno registrati.

Aggiungi il seguente codice sotto la dichiarazione castDebugLogger per registrare quando viene attivato un evento CORE del player o viene trasmessa una modifica mediaStatus:

// Debug Logger
const castDebugLogger = cast.debug.CastDebugLogger.getInstance();

// Enable debug logger and show a 'DEBUG MODE' overlay at top left corner.
context.addEventListener(cast.framework.system.EventType.READY, () => {
  if (!castDebugLogger.debugOverlayElement_) {
      castDebugLogger.setEnabled(true);
  }
});

// Set verbosity level for Core events.
castDebugLogger.loggerLevelByEvents = {
  'cast.framework.events.category.CORE': cast.framework.LoggerLevel.INFO,
  'cast.framework.events.EventType.MEDIA_STATUS': cast.framework.LoggerLevel.DEBUG
}

Messaggi di log e tag personalizzati

L'API CastDebugLogger consente di creare messaggi di log che vengono visualizzati con colori diversi sull'overlay di debug del destinatario. Sono disponibili i seguenti metodi di log, elencati in ordine di priorità, dalla più alta alla più bassa:

  • castDebugLogger.error(custom_tag, message);
  • castDebugLogger.warn(custom_tag, message);
  • castDebugLogger.info(custom_tag, message);
  • castDebugLogger.debug(custom_tag, message);

Per ogni metodo di log, il primo parametro è un tag personalizzato. Può trattarsi di qualsiasi stringa identificativa che ritieni significativa. CastDebugLogger utilizza i tag per filtrare i log. L'utilizzo dei tag viene spiegato in dettaglio di seguito. Il secondo parametro è il messaggio di log.

Per mostrare i log in azione, aggiungi log all'intercettore LOAD.

playerManager.setMessageInterceptor(
  cast.framework.messages.MessageType.LOAD,
  request => {
    castDebugLogger.info(LOG_TAG, 'Intercepting LOAD request');

    // Map contentId to entity
    if (request.media && request.media.entity) {
      request.media.contentId = request.media.entity;
    }

    return new Promise((resolve, reject) => {
      // Fetch content repository by requested contentId
      makeRequest('GET', 'https://storage.googleapis.com/cpe-sample-media/content.json')
        .then(function (data) {
          let item = data[request.media.contentId];
          if(!item) {
            // Content could not be found in repository
            castDebugLogger.error(LOG_TAG, 'Content not found');
            reject();
          } else {
            // Adjusting request to make requested content playable
            request.media.contentUrl = item.stream.dash;
            request.media.contentType = 'application/dash+xml';
            castDebugLogger.warn(LOG_TAG, 'Playable URL:', request.media.contentUrl);

            // Add metadata
            let metadata = new cast.framework.messages.MovieMediaMetadata();
            metadata.metadataType = cast.framework.messages.MetadataType.MOVIE;
            metadata.title = item.title;
            metadata.subtitle = item.author;

            request.media.metadata = metadata;

            // Resolve request
            resolve(request);
          }
      });
    });
  });

Puoi stabilire quali messaggi visualizzare sull'overlay di debug impostando il livello di log in loggerLevelByTags per ogni tag personalizzato. Ad esempio, se attivi un tag personalizzato a livello di log cast.framework.LoggerLevel.DEBUG, verranno visualizzati tutti i messaggi aggiunti con messaggi di log di errore, avviso, informazioni e debug. L'attivazione di un tag personalizzato a livello di WARNING mostrerà solo messaggi di log di errore e di avviso.

La configurazione loggerLevelByTags è facoltativa. Se un tag personalizzato non è configurato per il suo livello di log, tutti i messaggi di log verranno visualizzati sull'overlay di debug.

Aggiungi il seguente codice sotto il logger eventi di CORE:

// Set verbosity level for Core events.
castDebugLogger.loggerLevelByEvents = {
  'cast.framework.events.category.CORE': cast.framework.LoggerLevel.INFO,
  'cast.framework.events.EventType.MEDIA_STATUS': cast.framework.LoggerLevel.DEBUG
}

// Set verbosity level for custom tags.
castDebugLogger.loggerLevelByTags = {
    [LOG_TAG]: cast.framework.LoggerLevel.DEBUG,
};

Overlay di debug

Cast Debug Logger fornisce un overlay di debug sul ricevitore per visualizzare i tuoi messaggi di log personalizzati sul dispositivo di trasmissione. Utilizza showDebugLogs per attivare/disattivare l'overlay di debug e clearDebugLogs per cancellare i messaggi di log sull'overlay.

Aggiungi il codice seguente per visualizzare l'anteprima dell'overlay di debug sul ricevitore.

context.addEventListener(cast.framework.system.EventType.READY, () => {
  if (!castDebugLogger.debugOverlayElement_) {
      // Enable debug logger and show a 'DEBUG MODE' overlay at top left corner.
      castDebugLogger.setEnabled(true);

      // Show debug overlay
      castDebugLogger.showDebugLogs(true);

      // Clear log messages on debug overlay
      castDebugLogger.clearDebugLogs();
  }
});

Immagine che mostra l&#39;overlay di debug, un elenco di messaggi di log di debug su uno sfondo trasparente sopra un frame video

13. Congratulazioni

Ora sai come creare un'applicazione ricevitore web personalizzata utilizzando l'SDK Cast Web ricevir.

Per ulteriori dettagli, consulta la guida per gli sviluppatori Ricevitore web.