Aggiungi funzionalità principali al tuo ricevitore web personalizzato

Questa pagina contiene snippet di codice e descrizioni delle funzionalità disponibili per un'app di ricezione web personalizzata.

  1. Un elemento cast-media-player che rappresenta l'interfaccia utente del player integrata fornita con il ricevitore web.
  2. Stili CSS personalizzati per l'elemento cast-media-player per applicare stili a vari elementi dell'interfaccia utente, come background-image, splash-image e font-family.
  3. Un elemento script per caricare il framework Web Receiver.
  4. Codice JavaScript per intercettare i messaggi e gestire gli eventi.
  5. Mettere in coda i video per la riproduzione automatica.
  6. Opzioni per configurare la riproduzione.
  7. Opzioni per impostare il contesto del ricevitore web.
  8. Opzioni per impostare i comandi supportati dall'app Web Receiver.
  9. Una chiamata JavaScript per avviare l'applicazione Web Receiver.

Configurazione e opzioni dell'applicazione

Configura l'applicazione

CastReceiverContext è la classe più esterna esposta allo sviluppatore e gestisce il caricamento delle librerie sottostanti e l'inizializzazione dell'SDK Web Receiver. L'SDK fornisce API che consentono agli sviluppatori di applicazioni di configurare l'SDK tramite CastReceiverOptions. Queste configurazioni vengono valutate una volta per ogni avvio dell'applicazione e vengono passate all'SDK quando viene impostato il parametro facoltativo nella chiamata a start.

L'esempio seguente mostra come eseguire l'override del comportamento predefinito per rilevare se la connessione di un mittente è ancora attiva. Quando il destinatario web non è stato in grado di comunicare con un mittente per maxInactivity secondi, viene inviato un evento SENDER_DISCONNECTED. La configurazione riportata di seguito sovrascrive questo timeout. Questo può essere utile per risolvere i problemi di debug, in quanto impedisce all'app Web Receiver di chiudere la sessione di Debug remoto di Chrome quando non sono presenti mittenti connessi in stato IDLE.

const context = cast.framework.CastReceiverContext.getInstance();
const options = new cast.framework.CastReceiverOptions();
options.maxInactivity = 3600; // Development only
context.start(options);

Configurare il player

Durante il caricamento dei contenuti, l'SDK Web Receiver fornisce un modo per configurare le variabili di riproduzione come le informazioni DRM, le configurazioni di ripetizione e i gestori delle richieste utilizzando cast.framework.PlaybackConfig. Queste informazioni vengono gestite da PlayerManager e vengono valutate al momento della creazione dei giocatori. I player vengono creati ogni volta che un nuovo caricamento viene passato all'SDK Web Receiver. Le modifiche al PlaybackConfig dopo la creazione del player vengono valutate nel successivo caricamento di contenuti. L'SDK fornisce i seguenti metodi per modificare il PlaybackConfig.

  • CastReceiverOptions.playbackConfig per eseguire l'override delle opzioni di configurazione predefinite durante l'inizializzazione del CastReceiverContext.
  • PlayerManager.getPlaybackConfig() per ottenere la configurazione attuale.
  • PlayerManager.setPlaybackConfig() per eseguire l'override della configurazione corrente. Questa impostazione viene applicata a tutti i caricamenti successivi o fino a quando non viene sostituita di nuovo.
  • PlayerManager.setMediaPlaybackInfoHandler() per applicare configurazioni aggiuntive solo per l'elemento multimediale in carica sopra le configurazioni correnti. Il gestore viene chiamato poco prima della creazione del player. Le modifiche apportate qui non sono permanenti e non sono incluse nelle query a getPlaybackConfig(). Quando viene caricato l'elemento multimediale successivo, questo gestore viene chiamato di nuovo.

L'esempio seguente mostra come impostare PlaybackConfig durante l'inizializzazione di CastReceiverContext. La configurazione sostituisce le richieste in uscita per l'ottenimento dei manifest. Il gestore specifica che le richieste di controllo dell'accesso CORS devono essere effettuate utilizzando credenziali come cookie o intestazioni di autorizzazione.

const playbackConfig = new cast.framework.PlaybackConfig();
playbackConfig.manifestRequestHandler = requestInfo => {
  requestInfo.withCredentials = true;
};
context.start({playbackConfig: playbackConfig});

L'esempio seguente mostra come ignorare PlaybackConfig utilizzando il metodo getter e il metodo setter forniti in PlayerManager. L'impostazione configura il player in modo da riprendere la riproduzione dei contenuti dopo il caricamento di un segmento.

const playerManager =
    cast.framework.CastReceiverContext.getInstance().getPlayerManager();
const playbackConfig = (Object.assign(
            new cast.framework.PlaybackConfig(), playerManager.getPlaybackConfig()));
playbackConfig.autoResumeNumberOfSegments = 1;
playerManager.setPlaybackConfig(playbackConfig);

L'esempio seguente mostra come eseguire l'override di PlaybackConfig per una richiesta di caricamento specifica utilizzando il gestore delle informazioni sulla riproduzione multimediale. L'handler chiama un metodo getLicenseUrlForMedia implementato dall'applicazione per ottenere licenseUrl da contentId dell'elemento corrente.

playerManager.setMediaPlaybackInfoHandler((loadRequestData, playbackConfig) => {
  const mediaInformation = loadRequestData.media;
  playbackConfig.licenseUrl = getLicenseUrlForMedia(mediaInformation.contentId);

  return playbackConfig;
});

Listener di eventi

L'SDK Web Receiver consente all'app Web Receiver di gestire gli eventi del player. L'ascoltatore di eventi accetta un parametro cast.framework.events.EventType (o un array di questi parametri) che specifica gli eventi che devono attivare l'ascoltatore. In cast.framework.events.category puoi trovare array preconfigurati di cast.framework.events.EventType utili per il debug. Il parametro evento fornisce ulteriori informazioni sull'evento.

Ad esempio, se vuoi sapere quando viene trasmessa una variazione di mediaStatus, puoi utilizzare la seguente logica per gestire l'evento:

const playerManager =
    cast.framework.CastReceiverContext.getInstance().getPlayerManager();
playerManager.addEventListener(
    cast.framework.events.EventType.MEDIA_STATUS, (event) => {
      // Write your own event handling code, for example
      // using the event.mediaStatus value
});

Intercettazione dei messaggi

L'SDK Web Receiver consente all'app Web Receiver di intercettare i messaggi ed eseguire codice personalizzato su questi messaggi. L'intercettatore di messaggi accetta un parametro cast.framework.messages.MessageType che specifica il tipo di messaggio da intercettare.

L'intercettatore deve restituire la richiesta modificata o una promessa che si risolve con il valore della richiesta modificato. Se restituisci null, verrà impedita la chiamata al gestore dei messaggi predefinito. Per ulteriori dettagli, consulta Caricare contenuti multimediali.

Ad esempio, se vuoi modificare i dati della richiesta di caricamento, puoi utilizzare la seguente logica per intercettarli e modificarli:

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

playerManager.setMessageInterceptor(
    cast.framework.messages.MessageType.LOAD, loadRequestData => {
      const error = new cast.framework.messages.ErrorData(
                      cast.framework.messages.ErrorType.LOAD_FAILED);
      if (!loadRequestData.media) {
        error.reason = cast.framework.messages.ErrorReason.INVALID_PARAM;
        return error;
      }

      if (!loadRequestData.media.entity) {
        return loadRequestData;
      }

      return thirdparty.fetchAssetAndAuth(loadRequestData.media.entity,
                                          loadRequestData.credentials)
        .then(asset => {
          if (!asset) {
            throw cast.framework.messages.ErrorReason.INVALID_REQUEST;
          }

          loadRequestData.media.contentUrl = asset.url;
          loadRequestData.media.metadata = asset.metadata;
          loadRequestData.media.tracks = asset.tracks;
          return loadRequestData;
        }).catch(reason => {
          error.reason = reason; // cast.framework.messages.ErrorReason
          return error;
        });
    });

context.start();

Gestione degli errori

Quando si verificano errori nell'intercettatore di messaggi, l'app Web Receiver deve restituire un valore cast.framework.messages.ErrorType e cast.framework.messages.ErrorReason appropriati.

playerManager.setMessageInterceptor(
    cast.framework.messages.MessageType.LOAD, loadRequestData => {
      const error = new cast.framework.messages.ErrorData(
                      cast.framework.messages.ErrorType.LOAD_CANCELLED);
      if (!loadRequestData.media) {
        error.reason = cast.framework.messages.ErrorReason.INVALID_PARAM;
        return error;
      }

      ...

      return fetchAssetAndAuth(loadRequestData.media.entity,
                               loadRequestData.credentials)
        .then(asset => {
          ...
          return loadRequestData;
        }).catch(reason => {
          error.reason = reason; // cast.framework.messages.ErrorReason
          return error;
        });
    });

Intercettazione dei messaggi e listener di eventi

Ecco alcune differenze fondamentali tra l'intercettazione dei messaggi e l'ascoltatore di eventi:

  • Un gestore di eventi non ti consente di modificare i dati della richiesta.
  • Un gestore eventi è consigliato per attivare analisi o una funzione personalizzata.
playerManager.addEventListener(cast.framework.events.category.CORE,
    event => {
        console.log(event);
    });
  • L'intercettazione dei messaggi ti consente di ascoltare un messaggio, intercettarlo e modificare i dati della richiesta stessa.
  • L'intercettazione dei messaggi è ideale per gestire la logica personalizzata in merito ai dati della richiesta.

Caricamento dei contenuti multimediali

MediaInformation fornisce numerose proprietà per caricare i contenuti multimediali nel messaggiocast.framework.messages.MessageType.LOAD, tra cui entity, contentUrl e contentId.

  • entity è la proprietà suggerita da utilizzare nell'implementazione sia per le app di invio sia per quelle di ricezione. La proprietà è un URL di link diretto che può essere una playlist o contenuti multimediali. L'applicazione deve analizzare questo URL e compilare almeno uno degli altri due campi.
  • contentUrl corrisponde all'URL riproducibile che il player utilizzerà per caricare i contenuti. Ad esempio, questo URL potrebbe puntare a un manifest DASH.
  • contentId può essere un URL di contenuti riproducibili (simile a quello della proprietà contentUrl ) o un identificatore univoco per i contenuti o la playlist in fase di caricamento. Se utilizzi questa proprietà come identificatore, la tua applicazione deve compilare un URL riproducibile in contentUrl.

Il suggerimento è di utilizzare entity per memorizzare i parametri chiave o ID reali e contentUrl per l'URL dei contenuti multimediali. Un esempio è riportato nel seguente snippet, in cui entity è presente nella richiesta LOAD e viene recuperato il contentUrl riproducibile:

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

      if (!loadRequestData.media.entity) {
        // Copy the value from contentId for legacy reasons if needed
        loadRequestData.media.entity = loadRequestData.media.contentId;
      }

      return thirdparty.fetchAssetAndAuth(loadRequestData.media.entity,
                                          loadRequestData.credentials)
        .then(asset => {
          loadRequestData.media.contentUrl = asset.url;
          ...
          return loadRequestData;
        });
    });

Funzionalità del dispositivo

Il metodo getDeviceCapabilities fornisce informazioni sul dispositivo di trasmissione collegato e sul dispositivo video o audio collegato. Il metodo getDeviceCapabilities fornisce informazioni di assistenza per l'Assistente Google, il Bluetooth e i dispositivi audio e di visualizzazione connessi.

Questo metodo restituisce un oggetto su cui puoi eseguire query passando uno degli enumerati specificati per ottenere la funzionalità del dispositivo per quell'enum. Gli enum sono definiti in cast.framework.system.DeviceCapabilities.

Questo esempio verifica se il dispositivo di ricezione web è in grado di riprodurre HDR e DolbyVision (DV) con le chiavi IS_HDR_SUPPORTED e IS_DV_SUPPORTED, rispettivamente.

const context = cast.framework.CastReceiverContext.getInstance();
context.addEventListener(cast.framework.system.EventType.READY, () => {
  const deviceCapabilities = context.getDeviceCapabilities();
  if (deviceCapabilities &&
      deviceCapabilities[cast.framework.system.DeviceCapabilities.IS_HDR_SUPPORTED]) {
    // Write your own event handling code, for example
    // using the deviceCapabilities[cast.framework.system.DeviceCapabilities.IS_HDR_SUPPORTED] value
  }
  if (deviceCapabilities &&
      deviceCapabilities[cast.framework.system.DeviceCapabilities.IS_DV_SUPPORTED]) {
    // Write your own event handling code, for example
    // using the deviceCapabilities[cast.framework.system.DeviceCapabilities.IS_DV_SUPPORTED] value
  }
});
context.start();

Gestione dell'interazione utente

Un utente può interagire con l'applicazione Web Receiver tramite le applicazioni di invio (web, Android e iOS), i comandi vocali sui dispositivi con l'assistente integrato, i controlli touch sugli smart display e i telecomandi sui dispositivi Android TV. L'SDK Cast fornisce varie API per consentire all'app Web Receiver di gestire queste interazioni, aggiornare l'interfaccia utente dell'applicazione tramite gli stati delle azioni utente e, facoltativamente, inviare le modifiche per aggiornare eventuali servizi di backend.

Comandi multimediali supportati

Gli stati dei controlli dell'interfaccia utente sono basati su MediaStatus.supportedMediaCommands per i controller avanzati del mittente, le app di ricevitore e telecomando per iOS e Android in esecuzione su dispositivi touch e le app di ricevitore sui dispositivi Android TV. Quando nella proprietà è attivato un determinato Command a livello di bit, vengono attivati i pulsanti correlati a quell'azione. Se il valore non è impostato, il pulsante viene disabilitato. Questi valori possono essere modificati sul ricevitore web:

  1. Utilizzo di PlayerManager.setSupportedMediaCommands per impostare il valore specifico Commands
  2. Aggiunta di un nuovo comando utilizzando addSupportedMediaCommands
  3. Rimozione di un comando esistente utilizzando removeSupportedMediaCommands.
playerManager.setSupportedMediaCommands(cast.framework.messages.Command.SEEK |
  cast.framework.messages.Command.PAUSE);

Quando il destinatario prepara il file MediaStatus aggiornato, includerà le modifiche apportate alla proprietà supportedMediaCommands. Quando lo stato viene trasmesso, le app di invio collegate aggiorneranno i pulsanti nella loro UI di conseguenza.

Per ulteriori informazioni sui comandi multimediali e sui dispositivi touch supportati, consulta le guide di Accessing UI controls.

Gestione degli stati delle azioni utente

Quando gli utenti interagiscono con l'interfaccia utente o inviano comandi vocali, possono controllare la riproduzione dei contenuti e delle proprietà correlate all'elemento in riproduzione. Le richieste che controllano la riproduzione vengono gestite automaticamente dall'SDK. Le richieste che modificano le proprietà dell'elemento in riproduzione, ad esempio un comando LIKE, richiedono che l'applicazione di ricezione le gestisca. L'SDK fornisce una serie di API per gestire questi tipi di richieste. Per supportare queste richieste, è necessario:

  • Imposta MediaInformation userActionStates con le preferenze di un utente durante il caricamento di un elemento multimediale.
  • Intercetta i messaggi USER_ACTION e determina l'azione richiesta.
  • Aggiorna MediaInformation UserActionState per aggiornare l'interfaccia utente.

Il seguente snippet intercetta la richiesta LOAD e compila il MediaInformation di LoadRequestData. In questo caso, l'utente apprezza i contenuti in fase di caricamento.

playerManager.setMessageInterceptor(
    cast.framework.messages.MessageType.LOAD, (loadRequestData) => {
      const userActionLike = new cast.framework.messages.UserActionState(
          cast.framework.messages.UserAction.LIKE);
      loadRequestData.media.userActionStates = [userActionLike];

      return loadRequestData;
    });

Lo snippet seguente intercetta il messaggio USER_ACTION e gestisce la chiamata al backend con la modifica richiesta. Quindi effettua una chiamata per aggiornare il UserActionState sul ricevitore.

playerManager.setMessageInterceptor(cast.framework.messages.MessageType.USER_ACTION,
  (userActionRequestData) => {
    // Obtain the media information of the current content to associate the action to.
    let mediaInfo = playerManager.getMediaInformation();

    // If there is no media info return an error and ignore the request.
    if (!mediaInfo) {
        console.error('Not playing media, user action is not supported');
        return new cast.framework.messages.ErrorData(messages.ErrorType.BAD_REQUEST);
    }

    // Reach out to backend services to store user action modifications. See sample below.
    return sendUserAction(userActionRequestData, mediaInfo)

    // Upon response from the backend, update the client's UserActionState.
    .then(backendResponse => updateUserActionStates(backendResponse))

    // If any errors occurred in the backend return them to the cast receiver.
    .catch((error) => {
      console.error(error);
      return error;
    });
});

Il seguente snippet simula una chiamata a un servizio di backend. La funzione controlla UserActionRequestData per vedere il tipo di modifica richiesta dall'utente e effettua una chiamata di rete solo se l'azione è supportata dal backend.

function sendUserAction(userActionRequestData, mediaInfo) {
  return new Promise((resolve, reject) => {
    switch (userActionRequestData.userAction) {
      // Handle user action changes supported by the backend.
      case cast.framework.messages.UserAction.LIKE:
      case cast.framework.messages.UserAction.DISLIKE:
      case cast.framework.messages.UserAction.FOLLOW:
      case cast.framework.messages.UserAction.UNFOLLOW:
      case cast.framework.messages.UserAction.FLAG:
      case cast.framework.messages.UserAction.SKIP_AD:
        let backendResponse = {userActionRequestData: userActionRequestData, mediaInfo: mediaInfo};
        setTimeout(() => {resolve(backendResponse)}, 1000);
        break;
      // Reject all other user action changes.
      default:
        reject(
          new cast.framework.messages.ErrorData(cast.framework.messages.ErrorType.INVALID_REQUEST));
    }
  });
}

Lo snippet seguente prende il UserActionRequestData e aggiunge o rimuove il UserActionState dal MediaInformation. L'aggiornamento del valore UserActionState del MediaInformation modifica lo stato del pulsante associato all'azione richiesta. Questa modifica si riflette nell'interfaccia utente dei controlli dello smart display, nell'app del telecomando e nell'interfaccia utente di Android TV. Viene inoltre trasmesso tramite messaggi MediaStatus in uscita per aggiornare l'interfaccia utente del controller espanso per i mittenti iOS e Android.

function updateUserActionStates(backendResponse) {
  // Unwrap the backend response.
  let mediaInfo = backendResponse.mediaInfo;
  let userActionRequestData = backendResponse.userActionRequestData;

  // If the current item playing has changed, don't update the UserActionState for the current item.
  if (playerManager.getMediaInformation().entity !== mediaInfo.entity) {
    return;
  }

  // Check for existing userActionStates in the MediaInformation.
  // If none, initialize a new array to populate states with.
  let userActionStates = mediaInfo.userActionStates || [];

  // Locate the index of the UserActionState that will be updated in the userActionStates array.
  let index = userActionStates.findIndex((currUserActionState) => {
    return currUserActionState.userAction == userActionRequestData.userAction;
  });

  if (userActionRequestData.clear) {
    // Remove the user action state from the array if cleared.
    if (index >= 0) {
      userActionStates.splice(index, 1);
    }
    else {
      console.warn("Could not find UserActionState to remove in MediaInformation");
    }
  } else {
    // Add the UserActionState to the array if enabled.
    userActionStates.push(
      new cast.framework.messages.UserActionState(userActionRequestData.userAction));
  }

  // Update the UserActionState array and set the new MediaInformation
  mediaInfo.userActionStates = userActionStates;
  playerManager.setMediaInformation(mediaInfo, true);
  return;
}

Comandi vocali

I seguenti comandi multimediali sono attualmente supportati nell'SDK Web Receiver per i dispositivi con l'assistente integrato. Le implementazioni predefinite di questi comandi si trovano in cast.framework.PlayerManager.

Comando Descrizione
Riproduci Riproduci o riprendi la riproduzione dallo stato di messa in pausa.
Metti in pausa Mettere in pausa i contenuti in riproduzione.
Indietro Vai all'elemento multimediale precedente nella coda multimediale.
Avanti Vai all'elemento multimediale successivo nella coda multimediale.
Interrompi Interrompi i contenuti multimediali in riproduzione.
Non ripetere nulla Disattiva la ripetizione degli elementi multimediali nella coda al termine della riproduzione dell'ultimo elemento.
Ripeti singola Ripeti i contenuti multimediali in riproduzione a tempo indeterminato.
Ripeti tutto Ripeti tutti gli elementi della coda dopo la riproduzione dell'ultimo elemento.
Ripeti tutti e Riproduzione casuale Al termine della riproduzione dell'ultimo elemento della coda, mescola la coda e ripeti tutti gli elementi.
Riproduzione casuale Mescola gli elementi multimediali nella coda multimediale.
Sottotitoli codificati ON / OFF Attiva / disattiva i sottotitoli codificati per i tuoi contenuti multimediali. L'opzione Attiva / Disattiva è disponibile anche per lingua.
Spostarsi a un orario assoluto Salta al momento assoluto specificato.
Spostarsi a un momento relativo all'ora attuale Salta in avanti o indietro del periodo di tempo specificato rispetto al tempo di riproduzione corrente.
Riproduci di nuovo Riavvia i contenuti multimediali in riproduzione o riproduci l'ultimo elemento multimediale riprodotto se non è in riproduzione nulla.
Impostare la velocità di riproduzione Variare la velocità di riproduzione dei contenuti multimediali. Questo dovrebbe essere gestito per impostazione predefinita. Puoi utilizzare l'intercettatore di messaggi SET_PLAYBACK_RATE per ignorare le richieste di tariffa in arrivo.

Comandi multimediali supportati con i comandi vocali

Per impedire a un comando vocale di attivare un comando multimediale su un dispositivo con l'assistente integrato, devi prima impostare i comandi multimediali supportati che prevedi di supportare. Poi devi applicare questi comandi attivando la proprietà CastReceiverOptions.enforceSupportedCommands. L'interfaccia utente sui mittenti dell'SDK Cast e sui dispositivi con tocco abilitato cambierà per riflettere queste configurazioni. Se il flag non è attivato, i comandi vocali in arrivo verranno eseguiti.

Ad esempio, se consenti PAUSE dalle tue applicazioni di invio e dai dispositivi con tocco, devi anche configurare il destinatario in modo che rifletta queste impostazioni. Se configurata, qualsiasi comando vocale in arrivo verrà ignorato se non è incluso nell'elenco dei comandi supportati.

Nell'esempio seguente forniamo CastReceiverOptions all'avvio del CastReceiverContext. Abbiamo aggiunto il supporto per il comando PAUSE e abbiamo imposto al player di supportare solo questo comando. Ora, se un comando vocale richiede un'altra operazione, ad esempio SEEK, verrà rifiutato. L'utente riceverà una notifica che lo informa che il comando non è ancora supportato.

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

context.start({
  enforceSupportedCommands: true,
  supportedCommands: cast.framework.messages.Command.PAUSE
});

Puoi applicare una logica separata per ogni comando che vuoi limitare. Rimuovi il flag enforceSupportedCommands e per ogni comando che vuoi limitare puoi intercettare il messaggio in arrivo. Qui intercettiamo la richiesta fornita dall'SDK in modo che i comandi SEEK inviati ai dispositivi con l'assistente integrato non attivino una ricerca nell'applicazione Web Receiver.

Per i comandi multimediali non supportati dalla tua applicazione, restituisci un motivo di errore appropriato, ad esempio NOT_SUPPORTED.

playerManager.setMessageInterceptor(cast.framework.messages.MessageType.SEEK,
  seekData => {
    // Block seeking if the SEEK supported media command is disabled
    if (!(playerManager.getSupportedMediaCommands() & cast.framework.messages.Command.SEEK)) {
      let e = new cast.framework.messages.ErrorData(cast.framework.messages.ErrorType
      .INVALID_REQUEST);
      e.reason = cast.framework.messages.ErrorReason.NOT_SUPPORTED;
      return e;
    }

    return seekData;
  });

Passaggio in background dall'attività vocale

Se la piattaforma Cast mette in background l'audio dell'applicazione a causa dell'attività dell'assistente, ad esempio l'ascolto della voce dell'utente o la risposta, all'avvio dell'attività viene inviato all'applicazione Web Receiver un messaggio FocusState di NOT_IN_FOCUS. Al termine dell'attività viene inviato un altro messaggio con IN_FOCUS. A seconda dell'applicazione e dei contenuti multimediali riprodotti, potresti voler mettere in pausa i contenuti multimediali quando FocusState è NOT_IN_FOCUS intercettando il messaggio di tipo FOCUS_STATE.

Ad esempio, è un'esperienza utente positiva mettere in pausa la riproduzione dell'audiolibro se l'assistente sta rispondendo a una query dell'utente.

playerManager.setMessageInterceptor(cast.framework.messages.MessageType.FOCUS_STATE,
  focusStateRequestData => {
    // Pause content when the app is out of focus. Resume when focus is restored.
    if (focusStateRequestData.state == cast.framework.messages.FocusState.NOT_IN_FOCUS) {
      playerManager.pause();
    } else {
      playerManager.play();
    }

    return focusStateRequestData;
  });

Lingua dei sottotitoli codificati specificata tramite comandi vocali

Quando un utente non specifica esplicitamente la lingua dei sottotitoli codificati, la lingua utilizzata è la stessa in cui è stato pronunciato il comando. In questi scenari, il parametro isSuggestedLanguage del messaggio in arrivo indica se la lingua associata è stata suggerita o richiesta esplicitamente dall'utente.

Ad esempio, isSuggestedLanguage è impostato su true per il comando "Hey Google, attiva i sottotitoli codificati", perché la lingua è stata dedotta dalla lingua in cui è stato pronunciato il comando. Se la lingua è richiesta esplicitamente, ad esempio in "Ok Google, attiva i sottotitoli in inglese", isSuggestedLanguage è impostato su false.

Metadati e trasmissione vocale

Sebbene i comandi vocali vengano gestiti dal Web Receiver per impostazione predefinita, devi assicurarti che i metadati dei tuoi contenuti siano completi e accurati. In questo modo, i comandi vocali vengono gestiti correttamente dall'assistente e i metadati vengono visualizzati correttamente su nuovi tipi di interfacce, come l'app Google Home e gli smart display come Google Home Hub.

Trasferimento dello streaming

La conservazione dello stato della sessione è alla base del trasferimento dello streaming, che consente agli utenti di spostare gli stream audio e video esistenti tra i dispositivi utilizzando i comandi vocali, l'app Google Home o gli smart display. La riproduzione dei contenuti multimediali si interrompe su un dispositivo (la sorgente) e continua su un altro (la destinazione). Qualsiasi dispositivo di trasmissione con il firmware più recente può essere utilizzato come sorgente o destinazione in un trasferimento in streaming.

Il flusso di eventi per il trasferimento dello stream è il seguente:

  1. Sul dispositivo di origine:
    1. La riproduzione dei contenuti multimediali viene interrotta.
    2. L'applicazione Web Receiver riceve un comando per salvare lo stato corrente dei contenuti multimediali.
    3. L'applicazione Web Receiver è chiusa.
  2. Sul dispositivo di destinazione:
    1. L'applicazione Web Receiver è caricata.
    2. L'applicazione Web Receiver riceve un comando per ripristinare lo stato dei contenuti multimediali salvati.
    3. La riproduzione dei contenuti multimediali riprende.

Gli elementi dello stato dei contenuti multimediali includono:

  • Posizione o timestamp specifici del brano, del video o dell'elemento multimediale.
  • La sua posizione in una coda più ampia (ad esempio una playlist o una radio di artisti).
  • L'utente autenticato.
  • Stato di riproduzione (ad esempio, riproduzione o messa in pausa).

Attivazione del trasferimento dello streaming

Per implementare il trasferimento dello stream per il ricevitore web:

  1. Aggiorna supportedMediaCommands con il comando STREAM_TRANSFER:
    playerManager.addSupportedMediaCommands(
    cast.framework.messages.Command.STREAM_TRANSFER, true);
  2. Se vuoi, puoi sostituire gli intercettatori di messaggi SESSION_STATE e RESUME_SESSION come descritto in Mantenimento dello stato della sessione. Sostituisci questi valori solo se i dati personalizzati devono essere memorizzati nell'ambito dello snapshot della sessione. In caso contrario, l'implementazione predefinita per la conservazione degli stati della sessione supporterà il trasferimento dello stream.

Mantenimento dello stato della sessione

L'SDK Web Receiver fornisce un'implementazione predefinita per le app Web Receiver per conservare gli stati della sessione acquisendo uno snapshot dello stato corrente dei contenuti multimediali, convertendo lo stato in una richiesta di caricamento e riprendendo la sessione con la richiesta di caricamento.

Se necessario, la richiesta di caricamento generata dal ricevitore web può essere sostituita nell'intercettatore di messaggi SESSION_STATE. Se vuoi aggiungere dati personalizzati alla richiesta di caricamento, ti consigliamo di inserirli in loadRequestData.customData.

playerManager.setMessageInterceptor(
    cast.framework.messages.MessageType.SESSION_STATE,
    function (sessionState) {
        // Override sessionState.loadRequestData if needed.
        const newCredentials = updateCredentials_(sessionState.loadRequestData.credentials);
        sessionState.loadRequestData.credentials = newCredentials;

        // Add custom data if needed.
        sessionState.loadRequestData.customData = {
            'membership': 'PREMIUM'
        };

        return sessionState;
    });

I dati personalizzati possono essere recuperati da loadRequestData.customData nell'intercettatore di messaggi RESUME_SESSION.

let cred_ = null;
let membership_ = null;

playerManager.setMessageInterceptor(
    cast.framework.messages.MessageType.RESUME_SESSION,
    function (resumeSessionRequest) {
        let sessionState = resumeSessionRequest.sessionState;

        // Modify sessionState.loadRequestData if needed.
        cred_ = sessionState.loadRequestData.credentials;

        // Retrieve custom data.
        membership_ = sessionState.loadRequestData.customData.membership;

        return resumeSessionRequest;
    });

Precaricamento dei contenuti

Il ricevitore web supporta il precaricamento degli elementi multimediali dopo l'elemento di riproduzione corrente nella coda.

L'operazione di precaricamento scarica in anteprima diversi segmenti degli elementi in programma. La specifica viene eseguita sul valore preloadTime nell'oggetto QueueItem (se non viene fornito, il valore predefinito è 20 secondi). Il tempo è espresso in secondi rispetto alla fine dell'elemento attualmente in riproduzione . Sono validi solo i valori positivi. Ad esempio, se il valore è 10 secondi, questo elemento verrà precaricato 10 secondi prima del termine dell'elemento precedente. Se il tempo di precaricamento è superiore al tempo rimanente per currentItem, il precaricamento verrà eseguito il prima possibile. Pertanto, se in queueItem viene specificato un valore molto elevato per il precaricamento, si può ottenere l'effetto di precaricare già l'elemento successivo durante la riproduzione dell'elemento corrente. Tuttavia, lasciamo la scelta e l'impostazione a sviluppatori, in quanto questo valore può influire sulla larghezza di banda e sulle prestazioni dello streaming dell'elemento in riproduzione.

Il precaricamento funzionerà per impostazione predefinita per i contenuti in streaming HLS, DASH e Smooth.

I normali file video e audio MP4, come MP3, non verranno precaricati perché i dispositivi di trasmissione supportano un solo elemento multimediale e non possono essere utilizzati per il precaricamento mentre è ancora in riproduzione un elemento di contenuti esistente.

Messaggi personalizzati

Lo scambio di messaggi è il metodo di interazione principale per le applicazioni Web Receiver.

Un mittente invia messaggi a un ricevitore web utilizzando le API del mittente per la piattaforma in esecuzione (Android, iOS, web). L'oggetto evento (che rappresenta la manifestazione di un messaggio) passato ai listener di eventi ha un elemento di dati (event.data) in cui i dati assumono le proprietà del tipo di evento specifico.

Un'applicazione di ricezione web può scegliere di ascoltare i messaggi in uno spazio dei nomi specificato. In questo modo, l'applicazione Web Receiver supporta il protocollo dello spazio dei nomi. Spetta quindi a qualsiasi mittente connesso che voglia comunicare in questo spazio dei nomi utilizzare il protocollo appropriato.

Tutti gli spazi dei nomi sono definiti da una stringa e devono iniziare con "urn:x-cast:" followed by any string. Ad esempio, "urn:x-cast:com.example.cast.mynamespace".

Ecco uno snippet di codice per consentire al ricevitore web di ascoltare i messaggi personalizzati dei mittenti collegati:

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

const CUSTOM_CHANNEL = 'urn:x-cast:com.example.cast.mynamespace';
context.addCustomMessageListener(CUSTOM_CHANNEL, function(customEvent) {
  // handle customEvent.
});

context.start();

Analogamente, le applicazioni Web Receiver possono tenere informati i mittenti sullo stato del Web Receiver inviando messaggi ai mittenti collegati. Un'applicazione di ricezione web può inviare messaggi utilizzando sendCustomMessage(namespace, senderId, message) su CastReceiverContext. Un destinatario web può inviare messaggi a un singolo mittente, in risposta a un messaggio ricevuto o a causa di una modifica dello stato dell'applicazione. Oltre ai messaggi point-to-point (con un limite di 64 KB), un ricevitore web può anche trasmettere messaggi a tutti i mittenti collegati.

Trasmissione per dispositivi audio

Per assistenza sulla riproduzione solo audio, consulta la guida di Google Cast per i dispositivi audio.

Android TV

Questa sezione illustra in che modo Google Web Receiver utilizza i tuoi input come riproduzione e la compatibilità con Android TV.

Integrazione dell'applicazione con il telecomando

Il ricevitore web di Google in esecuzione sul dispositivo Android TV traduce l'input proveniente dagli ingressi di controllo del dispositivo (ad es. il telecomando portatile) come messaggi di riproduzione multimediale definiti per lo spazio dei nomi urn:x-cast:com.google.cast.media, come descritto in Messaggi di riproduzione multimediale. La tua applicazione deve supportare questi messaggi per controllare la riproduzione dei contenuti multimediali dell'applicazione al fine di consentire il controllo di base della riproduzione dagli input di controllo di Android TV.

Linee guida per la compatibilità con Android TV

Di seguito sono riportati alcuni consigli e problemi comuni da evitare per garantire la compatibilità della tua applicazione con Android TV:

  • Tieni presente che la stringa dello user-agent contiene sia "Android" sia "CrKey"; alcuni siti potrebbero reindirizzare a un sito solo per dispositivi mobili perché rilevano l'etichetta "Android". Non dare per scontato che "Android" nella stringa dello user agent indichi sempre un utente mobile.
  • La suite multimediale di Android potrebbe utilizzare GZIP trasparente per il recupero dei dati. Assicurati che i tuoi dati multimediali possano rispondere a Accept-Encoding: gzip.
  • Gli eventi multimediali HTML5 di Android TV potrebbero essere attivati in momenti diversi rispetto a Chromecast, il che potrebbe rivelare problemi nascosti su Chromecast.
  • Quando aggiorni i contenuti multimediali, utilizza gli eventi correlati ai contenuti multimediali attivati dagli elementi <audio>/<video> come timeupdate, pause e waiting. Evita di utilizzare eventi correlati alla rete come progress, suspend e stalled, in quanto tendono a dipendere dalla piattaforma. Per saperne di più sulla gestione degli eventi multimediali nel ricevitore, consulta Eventi multimediali.
  • Quando configuri i certificati HTTPS del sito del destinatario, assicurati di includere i certificati CA intermedi. Consulta la pagina di test SSL Qualsys per verificare: se il percorso di certificazione attendibile per il tuo sito include un certificato CA con l'etichetta "Download aggiuntivo", questo potrebbe non caricarsi sulle piattaforme Android.
  • Mentre Chromecast mostra la pagina del ricevitore su un piano grafico a 720p, altre piattaforme di trasmissione, tra cui Android TV, potrebbero mostrare la pagina fino a 1080p. Assicurati che la pagina del destinatario si adatti in modo graduale a risoluzioni diverse.