Crea un ricevitore web personalizzato

1. Panoramica

Logo di Google Cast

Questo codelab ti insegna a creare un'app di ricezione 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 browser Chrome sul proprio dispositivo mobile o 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 una TV o un impianto audio). L'SDK Cast fornisce 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 è fornito per rendere l'esperienza utente di Cast semplice e prevedibile su tutte le piattaforme supportate. Scopri di più qui.

Cosa realizzeremo

Al termine di 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 eseguire la configurazione per lo sviluppo del ricevitore.
  • Nozioni di base su un ricevitore compatibile con Cast basato su Cast Application Framework.
  • Come ricevere un video trasmesso.
  • Come integrare il logger di debug.
  • Come ottimizzare il ricevitore per gli smart display.

Che cosa ti serve

Esperienza

  • Devi avere conoscenze pregresse di sviluppo web.
  • Inoltre, dovrai avere già esperienza di visione della TV.

Come utilizzerai questo tutorial?

Solo lettura Leggi e completa gli esercizi

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

Principiante Intermedio Proficiente

Come giudichi la tua esperienza con la visione della TV?

Principiante Intermedio Proficiente

2. recupera il codice campione

Puoi scaricare tutto il codice di esempio sul tuo computer...

ed espandi il file ZIP scaricato.

3. Eseguire il deployment del ricevitore in locale

Per poter utilizzare il ricevitore web con un dispositivo di trasmissione, il ricevitore deve essere ospitato in un luogo dove il dispositivo di trasmissione può raggiungerlo. Se hai già a disposizione un server che supporta HTTPS, salta le istruzioni riportate di seguito e prendi nota dell'URL, poiché ti servirà nella sezione successiva.

Se non hai un server a tua disposizione, 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 ricevitore ospitato. Lo utilizzerai nella sezione successiva.

4. Registrare un'applicazione in Cast Developer Console

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

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 di ricezione" con l'opzione "Ricevitore personalizzato" evidenziata

Seleziona "Destinatario personalizzato", che è ciò che stiamo creando.

Immagine della schermata "Nuovo destinatario personalizzato" che mostra un URL che un utente sta digitando nel campo "URL dell'applicazione del destinatario"

Inserisci i dettagli del nuovo destinatario, assicurati di utilizzare l'URL che hai ottenuto

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

Devi anche registrare il tuo dispositivo Google Cast in modo che possa accedere all'applicazione del ricevitore prima di pubblicarla. Una volta pubblicata, l'applicazione del ricevitore sarà disponibile per tutti i dispositivi Google Cast. Ai fini di questo codelab, ti consigliamo di utilizzare un'applicazione di ricezione non pubblicata.

Immagine della Google Cast SDK Developer Console con il pulsante "Aggiungi nuovo dispositivo" evidenziato

Fai clic su "Aggiungi nuovo dispositivo"

Immagine della finestra di dialogo "Aggiungi dispositivo ricevente 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 a Google Cast SDK Developer Console

Sono necessari 5-15 minuti prima che il ricevitore e il 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 ricevitore sia pronta per il test, vediamo che aspetto ha un'app ricevitore 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 lo streaming dinamico adattivo su HTTP (DASH)).

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

Immagine della scheda "Controlli di Cast Connect e del logger" dello strumento di comando e controllo (CaC)

  1. Dovresti vedere il nostro strumento CaC.
  2. Utilizza l'ID predefinito del ricevitore di esempio "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 "Cast Connect e Controlli Logger" dello strumento Command and Control (CaC) che indica che lo strumento è connesso a un'app ricevitore

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

Immagine della scheda "Carica contenuti multimediali" dello strumento Comando e controllo (CaC)

  1. Fai clic sul pulsante "Carica per contenuto" per riprodurre un video di esempio.
  2. Il video verrà riprodotto sul tuo dispositivo Google Cast per mostrare come funziona il ricevitore di base con il ricevitore predefinito.

6. Prepara il progetto iniziale

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

  • un'app di invio sia in esecuzione su un dispositivo mobile o un laptop,
  • sul dispositivo Google Cast viene eseguita un'app di ricevitore.

Ora puoi iniziare a sviluppare il progetto iniziale utilizzando il tuo editor di testo preferito:

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

Tieni presente che, mentre lavori a questo codelab, http-server dovrebbe rilevare le modifiche che apporti. Se non si verifica, prova ad terminare e a riavviare http-server.

Design di app

L'app di ricezione inizializza la sessione di trasmissione e rimane in attesa fino all'arrivo di una richiesta LOAD (in altre parole, il comando per riprodurre un contenuto multimediale) da un mittente.

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

index.html

Questo file HTML conterrà l'interfaccia utente per la nostra app ricevitore. Per il momento è vuoto e lo aggiungeremo durante il lab del codice.

receiver.js

Questo script gestirà tutta la logica della nostra app di ricezione. Al momento è solo un file vuoto, ma nella sezione successiva lo trasformeremo in un ricevitore Cast perfettamente funzionante con poche righe di codice.

7. Un ricevitore di trasmissione di base

Un ricevitore di trasmissione di base inizializzerà la sessione di trasmissione all'avvio. Questa operazione è necessaria per comunicare a tutte le applicazioni dei mittenti connesse che la visualizzazione del destinatario è riuscita. Inoltre, il nuovo SDK è preconfigurato per gestire i contenuti multimediali in streaming con bitrate adattivo (utilizzando DASH, HLS e Smooth Streaming) 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 caricamento receiver.js, del <footer> per fornire all'SDK del ricevitore uno spazio per visualizzare l'interfaccia utente predefinita del destinatario che viene spedita con lo script appena aggiunto.

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

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

  • Acquisisci un riferimento a CastReceiverContext, il punto di contatto principale per l'intero SDK del ricevitore
  • memorizzando un riferimento a PlayerManager, l'oggetto che gestisce la riproduzione e che fornisce tutti i hook necessari per collegare la tua logica personalizzata
  • inizializzando 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. Trasmissione di contenuti video "di base"

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

Apri lo strumento di comando e controllo (CaC) nel browser web.

Immagine della scheda &quot;Controlli di Cast Connect e del logger&quot; dello strumento di comando e controllo (CaC)

Assicurati di sostituire il tuo ID app registrato in precedenza nel campo e fai clic su "Imposta ID app". In questo modo, lo strumento viene incaricato di utilizzare il ricevitore quando viene avviata la sessione di trasmissione.

Trasmissione di contenuti multimediali

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

  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 del ricevitore.
  3. Il ricevente 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 dell'applicazione in MediaInfo.contentId. Il destinatario utilizza contentId come identificatore per effettuare le chiamate API di backend appropriate per risolvere l'URL della risorsa effettiva 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 ricevitore in modo che faccia qualcosa di simile nella prossima sezione. Per il momento, fai clic sull'icona Trasmetti e seleziona il tuo dispositivo per aprire il ricevitore.

Immagine della scheda &quot;Cast Connect e Controlli Logger&quot; dello strumento Command and Control (CaC) che indica che lo strumento è 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 i contenuti di esempio.

Immagine della scheda &quot;Carica contenuti multimediali&quot; dello strumento Comando e controllo (CaC)

Pertanto, l'SDK Receiver gestisce immediatamente:

  • Inizializzazione della sessione di trasmissione
  • Gestire 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.

Non esitare a esplorare lo strumento CaC e il relativo codice prima di passare alla sezione successiva, in cui estenderemo il nostro ricevente in modo che comunichi con una semplice API di esempio per soddisfare le richieste LOAD in arrivo dai mittenti.

9. Eseguire l'integrazione con un'API esterna

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

Solitamente le applicazioni lo fanno per i seguenti motivi:

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

Questa funzionalità è implementata principalmente nel metodo PlayerManager setMessageInterceptor(). Questo ti consente di intercettare i messaggi in arrivo per tipo e modificarli prima che raggiungano il gestore dei messaggi interno dell'SDK. In questa sezione trattiamo le richieste LOAD, per le quali eseguiremo le seguenti operazioni:

  • Leggi la richiesta LOAD in arrivo e il relativo contentId personalizzato.
  • Esegui una chiamata GET alla nostra API per cercare la risorsa riproducibile tramite streaming tramite il relativo contentId.
  • Modifica la richiesta LOAD con l'URL dello stream.
  • Modifica l'oggetto MediaInformation per impostare i parametri del tipo di flusso.
  • 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à comuni del ricevitore, pur basandosi su un'esperienza quasi pronta all'uso.

API di esempio

Visita la pagina https://storage.googleapis.com/cpe-sample-media/content.json e dai un'occhiata al nostro catalogo di video di esempio. I contenuti includono gli URL delle immagini poster in formato PNG, nonché gli stream DASH e HLS. Gli stream DASH e HLS rimandano a sorgenti video e audio demuxate 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 intercettatore di caricamento 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 file js/receiver.js, appena 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, specificheremo il tipo di contenuti al destinatario. Queste informazioni forniranno al destinatario l'URL della playlist principale e il tipo MIME dello stream. Aggiungi il seguente codice al file js/receiver.js nell'LOAD dell'Promise() dell'intercettatore:

...
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 il caricamento con i contenuti DASH. Se vuoi testare 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, la richiesta di caricamento richiederà alcune proprietà aggiuntive per utilizzare gli URL HLS dell'API di esempio. Quando il ricevitore è configurato per riprodurre gli stream HLS, il tipo di contenitore predefinito previsto è Transport Stream (TS). Di conseguenza, il ricevitore tenterà di 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 caricamento 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;
            ...
          }
        });
      });
    });

Prova

Ancora una volta, apri lo strumento di comando e controllo (CaC) e imposta il tuo 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 dei contenuti" accanto al pulsante "Carica per contenuti", in modo che la nostra applicazione invii una richiesta LOAD contenente solo il riferimento contentId ai nostri contenuti multimediali.

Immagine della scheda &quot;Carica contenuti multimediali&quot; dello strumento Comando e controllo (CaC)

Supponendo che tutto abbia funzionato correttamente con le modifiche al ricevitore, l'intercettatore dovrebbe occuparsi di trasformare 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 sostituire l'ID contenuto con 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 di ricezione di supportare i controlli touch.

In questa sezione viene spiegato come ottimizzare l'applicazione del ricevitore quando viene lanciata sugli smart display e come personalizzare i controlli del player.

Accesso ai controlli UI

È possibile accedere all'oggetto UI Controls per gli smart display utilizzando cast.framework.ui.Controls.GetInstance(). Aggiungi il seguente codice al 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>, 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 slot in base a MetadataType e MediaStatus.supportedMediaCommands.

Controlli video

Per MetadataType.MOVIE, MetadataType.TV_SHOW e MetadataType.GENERIC, l'oggetto UI Controls per gli 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 UI Controls per gli smart display verrà visualizzato come segue:

Immagine di una musica riprodotta con controlli UI sovrapposti alla parte superiore

  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 del controllo predefinito viene visualizzato come segue:

Immagine dei controlli del media player: barra di avanzamento, pulsante &quot;Riproduci&quot;, pulsanti &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 del controllo predefinito viene visualizzato come segue:

Immagine dei controlli del media player: barra di avanzamento, pulsante &quot;Riproduci&quot;, pulsanti &quot;Avanti&quot; e &quot;Indietro&quot; e pulsanti &quot;Aggiungi alla coda precedente&quot; e &quot;Aggiungi alla coda successiva&quot; abilitati

Quando il valore di supportedMediaCommands è 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 sono disponibili tracce di testo, il pulsante dei sottotitoli codificati viene sempre visualizzato in SLOT_1.

Immagine dei controlli del media player: barra di avanzamento, pulsante &quot;Riproduci&quot;, pulsanti &quot;Avanti&quot; e &quot;Indietro&quot;, pulsanti &quot;Aggiungi alla coda precedente&quot; e &quot;Aggiungi alla coda successiva&quot; e pulsanti &quot;Sottotitoli codificati&quot; abilitati

Per modificare dinamicamente il valore di supportedMediaCommands dopo aver avviato un contesto del ricevitore, puoi chiamare PlayerManager.setSupportedMediaCommands per sostituire il valore. Puoi anche aggiungere un nuovo comando utilizzando addSupportedMediaCommands o rimuovere un comando esistente utilizzando removeSupportedMediaCommands.

Personalizzazione dei pulsanti di controllo

Puoi personalizzare i controlli utilizzando PlayerDataBinder. Aggiungi il seguente codice al tuo file js/receiver.js sotto i touchControl per impostare il primo spazio 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. Implementazione della ricerca dei contenuti multimediali sugli smart display

La consultazione dei contenuti multimediali è una funzionalità CAF receiver che consente agli utenti di esplorare contenuti aggiuntivi sui dispositivi touch. Per implementarlo, utilizzerai PlayerDataBinder per impostare l'UI di BrowseContent. Puoi quindi compilarlo con BrowseItems in base ai contenuti che vuoi visualizzare.

BrowseContent

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

Immagine dell&#39;UI di BrowseContent che mostra due miniature di video e una parte di un terzo

  1. BrowseContent.title
  2. BrowseContent.items

Proporzioni

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

Utilizza BrowseItem per visualizzare il titolo, i sottotitoli, la durata e l'immagine di ogni elemento:

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

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

Impostare i dati di esplorazione dei contenuti multimediali

Puoi fornire un elenco di contenuti multimediali da sfogliare chiamando setBrowseContent. Aggiungi il seguente codice al file js/receiver.js sotto playerDataBinder e al listener di eventi MEDIA_CHANGED per impostare gli elementi di navigazione con il titolo "Programmazione successiva".

// 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 di ricerca dei contenuti multimediali, viene attivato l'intercettatore LOAD. Aggiungi il seguente codice all'intercettatore LOAD per mappare request.media.contentId a 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 Sfoglia contenuti multimediali.

12. Debug delle app di ricezione

L'SDK del ricevitore di Google Cast offre un'altra opzione per consentire agli sviluppatori di eseguire facilmente il debug delle app del ricevitore utilizzando l'API CastDebugLogger e uno strumento di comando e controllo (CaC) aggiuntivo 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 del ricevitore di trasmissione.

<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 attivare 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 visualizzato un overlay con la scritta DEBUG MODE.

Immagine di un video in riproduzione con il messaggio &quot;MODALITÀ DI DEBUG&quot; visualizzato su uno sfondo rosso nell&#39;angolo superiore sinistro del frame

Registra gli eventi del player

Con CastDebugLogger puoi registrare facilmente gli eventi del player attivati dall'SDK CAF receiver 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 nell'overlay di debug del ricevitore con colori diversi. 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ò essere qualsiasi stringa di identificazione che ritieni significativa. CastDebugLogger utilizza i tag per filtrare i log. L'utilizzo dei tag è spiegato in dettaglio di seguito. Il secondo parametro è il messaggio di log.

Per mostrare i log in azione, aggiungili 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 vengono visualizzati nell'overlay di debug impostando il livello di log in loggerLevelByTags per ogni tag personalizzato. Ad esempio, l'attivazione di un tag personalizzato con livello di log cast.framework.LoggerLevel.DEBUG consente di visualizzare 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 avviso.

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

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

Il logger di debug di Google Cast fornisce un overlay di debug sul ricevitore per visualizzare i messaggi di log personalizzati sul dispositivo di trasmissione. Usa showDebugLogs per attivare/disattivare l'overlay di debug e clearDebugLogs per cancellare i messaggi di log nell'overlay.

Aggiungi il seguente codice 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 traslucido sopra un frame video

13. Complimenti

Ora sai come creare un'applicazione di ricezione web personalizzata utilizzando l'SDK Cast Web receiver.

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