Crea un ricevitore web personalizzato

1. Panoramica

Logo di Google Cast

Questo codelab ti insegnerà come creare un'app personalizzata Ricevitore web per riprodurre contenuti sui dispositivi compatibili.

Che cos'è Google Cast?

Google Cast consente agli utenti di trasmettere contenuti da un dispositivo mobile alla TV. Gli utenti possono quindi utilizzare il dispositivo mobile o il browser Chrome per desktop 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, una TV o un impianto audio). L'SDK Cast ti fornisce i componenti necessari dell'interfaccia utente basati sull'elenco di controllo per la progettazione di Google Cast.

L'elenco di controllo per la progettazione di Google Cast viene fornito per semplificare e prevedere l'esperienza utente con tutte le piattaforme supportate. Scopri di più qui.

Cosa realizzeremo?

Dopo aver completato il codelab, avrai un'app HTML5 che funge da destinatario personalizzato personale in grado di mostrare contenuti video sui dispositivi compatibili con Google Cast.

Obiettivi didattici

  • Come eseguire la configurazione per lo sviluppo del ricevitore.
  • Nozioni di base su un ricevitore compatibile con Google Cast basato sul framework delle applicazioni di trasmissione.
  • Come ricevere un video trasmesso.
  • Come integrare il logger di debug.
  • Come ottimizzare il ricevitore per smart display.

Che cosa ti serve

Esperienza

  • Devi conoscere già le nozioni di sviluppo del Web.
  • Avrai anche bisogno di una conoscenza precedente della TV.

Come utilizzerai questo tutorial?

Leggilo solo per te Leggilo e completa gli esercizi

Come valuteresti la tua esperienza con la creazione di app web?

Principiante Intermedio Esperto

Come giudichi 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. Deployment del ricevitore localmente

Per poter usare il ricevitore web con un dispositivo di trasmissione, il dispositivo deve essere ospitato in una posizione in cui può raggiungerlo. Se hai già a disposizione un server che supporta https, salta le istruzioni riportate di seguito e prendi nota dell'URL, che ti servirà nella prossima sezione.

Se non hai un server disponibile, puoi utilizzare 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. La utilizzerai nella sezione successiva.

4. Registra un'applicazione in Google Developers Console

Devi registrare la tua applicazione per poter eseguire un ricevitore personalizzato, come integrato in questo codelab, su dispositivi Chromecast. Dopo aver registrato la tua applicazione, riceverai un ID che la tua applicazione mittente deve utilizzare per eseguire le chiamate API, ad esempio per lanciare un'applicazione di ricezione.

Immagine della console per gli sviluppatori dell'SDK Google Cast con il pulsante "Aggiungi nuova applicazione" evidenziato

Fai clic su "Aggiungi nuova applicazione"

Immagine della schermata "Nuova applicazione di ricezione" con l'opzione "Destinatario personalizzato" evidenziata

Seleziona "Destinatario personalizzato", che stiamo creando.

Immagine della schermata "Nuovo destinatario personalizzato" che mostra un URL che qualcuno sta digitando nel campo "URL applicazione destinatario"

Inserisci i dettagli del nuovo destinatario, assicurati di utilizzare l'URL con cui hai ricevuto

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

Devi inoltre registrare il tuo dispositivo Google Cast in modo che possa accedere all'applicazione del destinatario prima di pubblicarlo. Una volta pubblicata, l'applicazione di ricezione sarà disponibile per tutti i dispositivi Google Cast. Ai fini di questo codelab, consigliamo di utilizzare un'applicazione di ricezione 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 di ricezione Cast"

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.

Occorrono 5-15 minuti prima che il ricevitore e il dispositivo siano pronti per il 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 di ricezione sia pronta per il test, vediamo che aspetto ha un'app di ricezione di esempio completata. Il ricevitore che creeremo sarà in grado di riprodurre contenuti multimediali utilizzando lo streaming con velocità in bit adattiva (utilizzeremo contenuti di esempio codificati per Dynamic Streaming adattivo su HTTP (DASH)).

Nel browser, apri lo strumento Command and Control (CaC).

Immagine della scheda "Controlli per la trasmissione e logger" dello strumento Command and Control (CaC)

  1. Dovresti visualizzare il nostro strumento CaC.
  2. Utilizza l'ID destinatario predefinito "CC1AD845" e fai clic sul pulsante "Imposta ID app".
  3. Fai clic sul pulsante Trasmetti in alto a sinistra e seleziona il tuo dispositivo Google Cast.

Immagine della scheda "Controlli per la trasmissione e logger" dello strumento Comando e controllo (CaC) che indica che è collegata all'app del ricevitore

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

Immagine della scheda "Load Media" dello strumento Command and Control (CaC)

  1. Fai clic sul pulsante "Carica per contenuto" per riprodurre un video di esempio.
  2. La riproduzione del video inizierà sul tuo dispositivo Google Cast per mostrare le funzionalità di base del ricevitore usando il ricevitore predefinito.

6. Prepara il progetto di avvio

Dobbiamo aggiungere il supporto per Google Cast all'app iniziale che hai scaricato. Di seguito sono riportate alcune terminologia di Google Cast che utilizzeremo in questo codelab:

  • L'app mittente sia eseguita su un dispositivo mobile o laptop
  • L'app destinatario viene eseguita sul dispositivo Google Cast.

Ora puoi creare il progetto di base utilizzando il tuo editor di testo preferito:

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

Tieni presente che, mentre lavori con questo codelab, http-server dovrebbe essere in grado di rilevare le modifiche che apporti. In caso contrario, prova a terminare e riavviare http-server.

Progettazione di app

L'app del ricevitore inizializza la sessione di trasmissione e resta in attesa fino all'arrivo di una richiesta LOAD (in altre parole, il comando di riproduzione di un contenuto multimediale) da un mittente.

L'app è composta da una vista principale, definita in index.html, e da un file JavaScript chiamato js/receiver.js, che contiene tutta la logica per far funzionare il nostro ricevitore.

index.html

Questo file HTML conterrà l'interfaccia utente della nostra app di ricezione. Per il momento è vuota e la aggiungeremo al lab durante il codelab.

Destinatario.js

Questo script gestirà tutta la logica dell'app del ricevitore. Al momento è solo un file vuoto, ma nella prossima sezione lo trasformeremo in un ricevitore Cast completamente funzionante con solo poche righe di codice.

7. Un ricevitore di base Cast

Un ricevitore di trasmissione di base inizializza la sessione di trasmissione all'avvio. È necessario comunicare tutte le applicazioni del mittente connesse che hanno visualizzato correttamente il destinatario. Inoltre, il nuovo SDK è preconfigurato per gestire i contenuti multimediali di streaming con velocità in bit adattiva (utilizzando DASH, HLS e lo streaming fluido) e i 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 di receiver.js, per fornire all'SDK del ricevitore lo spazio necessario per visualizzare l'UI predefinita del destinatario che utilizza lo script appena aggiunto.

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

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

  • l'acquisizione di un riferimento a CastReceiverContext, il tuo punto di ingresso principale all'intero SDK del destinatario
  • memorizza un riferimento al PlayerManager, l'oggetto che gestisce la riproduzione e fornisce tutti i hook di cui hai bisogno per collegare la tua logica personalizzata
  • inizializza l'SDK chiamando start() il giorno CastReceiverContext

Aggiungi quanto segue a js/receiver.js.

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

context.start();

8. Trasmissione di contenuti video "di base"

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

Punta il browser web allo strumento Command and Control (CaC).

Immagine della scheda &quot;Controlli per la trasmissione e logger&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". In questo modo indichi allo strumento di utilizzare il ricevitore quando avvii la sessione di trasmissione.

Trasmissione di contenuti multimediali

A livello generale, per riprodurre contenuti multimediali su un dispositivo di trasmissione è necessario procedere nel seguente modo:

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

Nel primo tentativo di base, completeremo MediaInfo con un URL di asset riproducibile (memorizzato in MediaInfo.contentUrl).

Un mittente reale utilizza un identificatore dei contenuti multimediali specifico dell'applicazione in MediaInfo.contentId. Il destinatario utilizza 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 delle licenze DRM o l'inserimento di informazioni sulle interruzioni pubblicitarie.

Nella prossima sezione estenderemo il ricevitore per fare qualcosa di simile a questo. Per ora, fai clic sull'icona Trasmetti e seleziona il dispositivo per aprire il ricevitore.

Immagine della scheda &quot;Controlli per la trasmissione e logger&quot; dello strumento Comando e controllo (CaC) che indica che è collegata all&#39;app del ricevitore

Vai alla scheda "Carica contenuti multimediali" e fai clic sul pulsante "Carica per contenuto". Il destinatario dovrebbe iniziare a riprodurre i contenuti di esempio.

Immagine della scheda &quot;Load Media&quot; dello strumento Command and Control (CaC)

L'SDK del ricevitore pronto all'uso:

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

Esplora lo strumento CaC e il relativo codice prima di passare alla sezione successiva, in cui estenderemo il ricevitore 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 l'interazione della maggior parte degli sviluppatori con i destinatari di trasmissione nelle applicazioni reali, modificheremo il destinatario per gestire le richieste LOAD che fanno riferimento ai contenuti multimediali previsti tramite la relativa chiave API, anziché inviare un URL di asset riproducibile.

Le applicazioni in genere lo fanno perché:

  • Il mittente potrebbe non conoscere l'URL dei contenuti.
  • L'applicazione Cast è progettata per gestire l'autenticazione, altre logiche 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 affronteremo le richieste di LOAD in cui eseguiremo le seguenti operazioni:

  • Leggi la richiesta LOAD in arrivo e il suo contentId personalizzato.
  • Effettua una chiamata GET alla nostra API per cercare l'asset riproducibile in streaming entro il giorno contentId.
  • Modifica la richiesta LOAD con l'URL dello stream.
  • Modifica l'oggetto MediaInformation per impostare i parametri per il tipo di stream.
  • Passa la richiesta all'SDK per la riproduzione oppure 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 la personalizzazione delle attività comuni dei destinatari, pur continuando a fare affidamento su un'esperienza preconfigurata.

API di esempio

Vai su https://storage.googleapis.com/cpe-sample-media/content.json con il browser e dai un'occhiata al nostro catalogo video di esempio. I contenuti includono gli URL delle immagini poster in formato png, oltre agli stream DASH e HLS. I flussi DASH e HLS puntano a sorgenti video e audio demux archiviate in container 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 ha ricevuto una richiesta LOAD.

Intercetta la richiesta LOAD

In questo passaggio creeremo un intercettore del carico con una funzione che invia 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 tuo file js/receiver.js, subito prima della chiamata al numero 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 il intercettatore del carico, specifichiamo il tipo di contenuti per il destinatario. Queste informazioni forniranno al destinatario l'URL della playlist principale e il tipo MIME dello stream. Aggiungi il codice seguente al file js/recipientr.js nell'Promise() dell'intercettore 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 a Test It Out per provare a caricarlo con i contenuti DASH. Se vuoi provare il caricamento con contenuti HLS, vai al passaggio successivo.

Utilizzo dei contenuti HLS dell'API di esempio

L'API di esempio include contenuti HLS e DASH. Oltre a impostare contentType come abbiamo fatto nel passaggio precedente, per poter utilizzare gli URL HLS dell'API di esempio sono necessarie alcune proprietà aggiuntive per la richiesta di caricamento. Quando il ricevitore è configurato per riprodurre i flussi HLS, il tipo di container predefinito previsto è il flusso di trasporto (TS). Di conseguenza, il destinatario proverà ad aprire gli stream MP4 di esempio in formato TS se solo la proprietà contentUrl viene modificata. 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 di tipo TS. Aggiungi il codice seguente al file js/recipientr.js nell'intercettore del 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;
            ...
          }
        });
      });
    });

Provalo

Come già detto, apri lo strumento Command and Control (CaC) e imposta il tuo ID app sull'ID app del ricevitore. Seleziona il dispositivo utilizzando il pulsante Trasmetti.

Vai alla scheda "Carica contenuti multimediali". Questa volta elimina il testo nel campo "URL dei contenuti" accanto al pulsante "Carica per contenuto", che obbliga la nostra applicazione a inviare una richiesta LOAD contenente solo il riferimento contentId ai nostri contenuti multimediali.

Immagine della scheda &quot;Load Media&quot; dello strumento Command and Control (CaC)

Presupponendo che tutto funzioni correttamente con le modifiche apportate al ricevitore, l'intercettore dovrebbe occuparsi di plasmare l'oggetto MediaInfo in un elemento che l'SDK può riprodurre sullo schermo.

Fai clic sul pulsante "Carica per contenuto" per verificare se i contenuti multimediali vengono riprodotti correttamente. Puoi cambiare l'ID contenuto in 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 controlli abilitati al tocco.

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

Accesso ai controlli dell'interfaccia utente

È possibile accedere all'oggetto Controlli dell'interfaccia utente per 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 utilizzi l'elemento <cast-media-player>, dovrai impostare touchScreenOptimizedApp in CastReceiverOptions. In questo codelab utilizziamo l'elemento <cast-media-player>.

context.start({ touchScreenOptimizedApp: true });

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

Controlli video

Per MetadataType.MOVIE, MetadataType.TV_SHOW e MetadataType.GENERIC, l'oggetto Controlli dell'interfaccia utente per smart display verrà visualizzato come nell'esempio seguente.

Immagine di un video in riproduzione con i controlli dell&#39;interfaccia utente 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 dell'interfaccia utente per gli smart display verrà visualizzato come segue:

Immagine di un brano che viene riprodotto con controlli dell&#39;interfaccia utente 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 dell'interfaccia utente determina anche se un valore ControlsButton viene visualizzato o meno in base al valore 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 lettore multimediale: barra di avanzamento, pulsante &quot;Riproduci&quot;, pulsante &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 lettore multimediale: barra di avanzamento, pulsante &quot;Riproduci&quot;, pulsante &quot;Vai avanti&quot; e &quot;Vai indietro&quot; e pulsanti &quot;Metti in coda la precedente&quot; e &quot;Coda successiva&quot; attivati

Quando il valore disupportedMediaCommands è uguale a PAUSE | QUEUE_PREV | QUEUE_NEXT, il layout di controllo predefinito sarà il seguente:

Immagine dei controlli del lettore multimediale: 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 sottotitoli viene sempre mostrato all'indirizzo SLOT_1.

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

Per modificare dinamicamente il valore di supportedMediaCommands dopo aver avviato un contesto del destinatario, puoi chiamare PlayerManager.setSupportedMediaCommands per sostituire il valore. Inoltre, puoi aggiungere un nuovo comando usando addSupportedMediaCommands oppure rimuovere un comando esistente usando removeSupportedMediaCommands.

Personalizzazione dei pulsanti di controllo

Puoi personalizzare i controlli usando PlayerDataBinder. Aggiungi il seguente codice al file js/receiver.js sotto i controlli touch per impostare il primo slot dei 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

Sfoglia contenuti multimediali è una funzionalità del ricevitore CAF che consente agli utenti di esplorare contenuti aggiuntivi sui dispositivi touch. Per implementare questa funzionalità, utilizzerai PlayerDataBinder per impostare l'UI di BrowseContent. Potrai poi completarlo con BrowseItems in base ai contenuti che vuoi mostrare.

Esplora contenuti

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

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

  1. BrowseContent.title
  2. BrowseContent.items

Proporzioni

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

Sfoglia articolo

Utilizza BrowseItem per visualizzare il titolo, il sottotitolo, la durata e l'immagine di ciascun elemento:

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

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

Imposta i dati relativi alla esplorazione dei contenuti multimediali

Puoi fornire un elenco di contenuti multimediali per la navigazione chiamando setBrowseContent. Aggiungi il seguente codice al file js/receiver.js sotto playerDataBinder e nel listener di eventi MEDIA_CHANGED per impostare gli elementi di esplorazione 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 multimediale, viene attivato l'intercettatore LOAD. Aggiungi il seguente codice al tuo intercettatore LOAD per mappare request.media.contentId all'elemento request.media.entity da Sfoglia 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'UI di Sfoglia contenuti multimediali.

12. Debug delle app di ricezione

L'SDK Cast Receiver offre agli sviluppatori un'altra opzione per eseguire facilmente il debug delle app del ricevitore usando 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 il tag playerManager, aggiungi il codice seguente 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 un messaggio &quot;MODALITÀ DEBUG&quot; visualizzato su uno sfondo rosso nell&#39;angolo in alto a sinistra del frame

Eventi del log player

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

Aggiungi il seguente codice sotto la dichiarazione castDebugLogger per registrare quando viene attivato un evento CORE del giocatore o quando 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 visualizzati nell'overlay di debug del destinatario con colori diversi. Sono disponibili i metodi di log elencati di seguito, in ordine decrescente.

  • 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ò essere qualsiasi stringa di identificazione che trovi significativa. CastDebugLogger utilizza i tag per filtrare i log. L'utilizzo dei tag è spiegato dettagliatamente di seguito. Il secondo parametro è il messaggio di log.

Per mostrare i log in azione, aggiungi log all'intercettatore 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 controllare quali messaggi mostrare nell'overlay di debug impostando il livello di log in loggerLevelByTags per ogni tag personalizzato. Ad esempio, se attivi un tag personalizzato con il livello di log cast.framework.LoggerLevel.DEBUG, verranno visualizzati tutti i messaggi aggiunti con un messaggio di errore, avviso, informazioni e debug dei log. Se attivi un tag personalizzato con livello WARNING, verranno visualizzati solo messaggi di errore e di avviso.

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

Aggiungi il seguente codice sotto il logger eventi 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

Logger 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 su un frame video

13. Congratulazioni

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

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