Aggiungi funzionalità principali al tuo ricevitore web personalizzato

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

  1. Un elemento cast-media-player che rappresenta l'UI del player integrata fornita con il ricevitore web.
  2. Stili CSS simili per l'elemento cast-media-player in modo da applicare uno stile a vari elementi UI quali background-image, splash-image e font-family.
  3. Un elemento script per caricare il framework del ricevitore web.
  4. Codice JavaScript per intercettare i messaggi e gestire gli eventi.
  5. Coda 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 Ricevitore web.

Configurazione e opzioni dell'applicazione

CastReceiverContext è la classe più esterna esposta allo sviluppatore e gestisce il caricamento delle librerie sottostanti e gestisce l'inizializzazione dell'SDK Web Receiver.

Se l'API Web Receiver rileva che un mittente è disconnesso, aumenterà l'evento SENDER_DISCONNECTED. Se il destinatario web non è in grado di comunicare con il mittente per i secondi che abbiamo descritto come maxInactivity, verrà generato anche l'evento SENDER_DISCONNECTED. Durante lo sviluppo, è consigliabile impostare maxInactivity su un valore elevato, in modo che l'app Web Receiver non si chiuda durante il debug dell'app con Chrome Remote Debugger:

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

Tuttavia, per un'applicazione di ricezione web pubblicata è meglio non impostare maxInactivity, ma basarsi sul valore predefinito. Tieni presente che le opzioni Web Recipient sono impostate una sola volta nell'applicazione.

L'altra configurazione è cast.framework.PlaybackConfig. Può essere impostato come segue:

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

Questa configurazione influisce sulla riproduzione di tutti i contenuti e sostanzialmente fornisce il comportamento di override. Per un elenco dei comportamenti che gli sviluppatori possono eseguire, consulta la definizione di cast.framework.PlaybackConfig. Per cambiare la configurazione tra i contenuti, puoi utilizzare PlayerManager per ottenere la playbackConfig attuale, modificare o aggiungere un override e reimpostare playbackConfig in questo modo:

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

Se PlaybackConfig non è stato sostituito, getPlaybackConfig() restituisce un oggetto null. Qualsiasi proprietà su PlaybackConfig that utilizzerà undefined per i valori predefiniti.

listener di eventi

L'SDK Ricevitore web consente alla tua app Ricevitore web di gestire gli eventi del player. Il listener di eventi utilizza un parametro cast.framework.events.EventType (o un array di questi parametri) che specifica gli eventi che devono attivare il listener. Gli array preconfigurati di cast.framework.events.EventType, utili per il debug, sono disponibili in cast.framework.events.category. Il parametro evento fornisce ulteriori informazioni sull'evento.

Ad esempio, se vuoi sapere quando viene trasmessa una modifica 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 alla tua app web ricevitore di intercettare i messaggi ed eseguire codice personalizzato. L'intercettazione del messaggio utilizza un parametro cast.framework.messages.MessageType che specifica il tipo di intercettazione del messaggio.

L'intercettatore deve restituire la richiesta modificata o una promessa che si risolve con il valore della richiesta modificata. La restituzione di null impedirà la chiamata al gestore di messaggi predefinito. Per ulteriori dettagli, consulta la sezione Caricamento di contenuti multimediali.

Ad esempio, se vuoi modificare i dati di 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'intercettazione dei messaggi, l'app del ricevitore web dovrebbe restituire 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 del messaggio rispetto al listener di eventi

Di seguito sono riportate alcune differenze chiave tra l'intercettazione dei messaggi e il listener di eventi:

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

Caricamento di contenuti multimediali in corso...

MediaInformation fornisce diverse proprietà per caricare contenuti multimediali nel messaggio cast.framework.messages.MessageType.LOAD tra cui entity, contentUrl e contentId.

entity è la proprietà suggerita da utilizzare nell'implementazione per le app sia per il mittente sia per il destinatario. La proprietà è un URL link diretto che può essere una playlist o contenuti multimediali specifici.

contentUrl è progettato per un URL riproducibile e può essere utilizzato una volta disponibile.

L'elemento contentId è stato ritirato a causa dell'ambiguità del valore dell'URL del elemento multimediale, di un ID reale o di un parametro chiave per la ricerca personalizzata.

Ti suggeriamo di utilizzare entity per archiviare l'ID reale o i parametri chiave e usare contentUrl per l'URL del contenuto multimediale. Un esempio di ciò viene mostrato nel seguente snippet in cui l'elemento entity è presente nella richiesta LOAD e l'elemento contentUrl riproducibile viene recuperato:

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

Il metodo getDeviceCapabilities fornisce informazioni sul dispositivo di trasmissione connesso 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 display connessi.

Questo metodo restituisce un oggetto su cui è possibile eseguire query passando in una delle enumerazioni specificate per ottenere la capacità del dispositivo per l'enumerazione. Le enumerazioni sono definite in cast.framework.system.DeviceCapabilities.

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

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 delle interazioni degli utenti

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

Comandi multimediali supportati

Gli stati dei controlli UI sono determinati dalle MediaStatus.supportedMediaCommands per i controller espansi per mittenti iOS e Android, le app di ricezione e di controllo remoto dei dispositivi in esecuzione sui dispositivi touch e dei ricevitori sui dispositivi Android TV. Quando nella proprietà è abilitato un particolare Command, i pulsanti correlati all'azione vengono attivati. Se il valore non è impostato, il pulsante è disattivato. Questi valori possono essere modificati sul ricevitore web come segue:

  1. Utilizzo di PlayerManager.setSupportedMediaCommands per impostare Commands specifici
  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 l'elemento MediaStatus aggiornato, includerà le modifiche nella proprietà supportedMediaCommands. Quando lo stato viene trasmesso, le app dei mittenti connessi aggiornano di conseguenza i pulsanti nella UI.

Per ulteriori informazioni sui comandi multimediali e sui dispositivi touch supportati, consulta la guida Accessing UI controls.

Gestione degli stati delle azioni degli utenti

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

  • Intercetta i messaggi di USER_ACTION e determina l'azione richiesta.
  • Aggiorna l'UserActionState MediaInformation per aggiornare la UI.

Lo snippet riportato di seguito intercetta il messaggio USER_ACTION e gestisce la chiamata al backend con la modifica richiesta. Effettua quindi una chiamata per aggiornare 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;
    });
});

Lo snippet riportato di seguito simula una chiamata a un servizio di backend. La funzione controlla il UserActionRequestData per vedere il tipo di modifica richiesta dall'utente e esegue 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 riportato di seguito prende UserActionRequestData e aggiunge o rimuove UserActionState da MediaInformation. L'aggiornamento di UserActionState di MediaInformation modifica lo stato del pulsante associato all'azione richiesta. Questa modifica viene applicata nell'interfaccia utente dei controlli dello smart display, dell'app di controllo remoto e dell'interfaccia utente di Android TV. Inoltre, è trasmesso tramite i messaggi in uscita MediaStatus per aggiornare l'UI 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 del ricevitore web 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 in pausa.
Metti in pausa Metti in pausa i contenuti attualmente in riproduzione.
Indietro Passa all'elemento multimediale precedente nella coda multimediale.
Avanti Vai al prossimo elemento multimediale nella coda multimediale.
Interrompi Interrompi i contenuti multimediali attualmente in riproduzione.
Non ripetere più Disattiva la ripetizione degli elementi multimediali in coda una volta terminata la riproduzione dell'ultimo elemento della coda.
Ripeti singolo Ripeti i contenuti multimediali attualmente in riproduzione a tempo indeterminato.
Ripeti tutto Ripeti tutti gli elementi in coda dopo aver riprodotto l'ultimo elemento della coda.
Ripeti tutto e in ordine casuale Una volta terminata la riproduzione dell'ultimo elemento della coda, ripeti la riproduzione e metti tutti gli elementi in coda.
Riproduzione casuale Metti in ordine casuale gli elementi multimediali nella tua coda multimediale.
Attivare / disattivare i sottotitoli codificati Attiva / disattiva i sottotitoli per i contenuti multimediali. Attiva / Disattiva è disponibile anche per lingua.
Da Vai a tempo assoluto Passa al tempo assoluto specificato.
Vai a Tempo relativo all'ora corrente Manda avanti o indietro del periodo di tempo specificato in relazione al tempo di riproduzione corrente.
Gioca di nuovo Riavvia il dispositivo multimediale attualmente in riproduzione o l'ultimo elemento multimediale in riproduzione se nulla è attualmente in riproduzione.
Impostare la velocità di riproduzione Varia la velocità di riproduzione dei contenuti multimediali. Questa opzione deve essere gestita per impostazione predefinita. Puoi utilizzare l'intercettatore dei messaggi SET_PLAYBACK_RATE per eseguire l'override delle richieste di tariffe in arrivo.

Comandi multimediali supportati con 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 hai intenzione di supportare. Quindi devi imporre questi comandi abilitando la proprietà CastReceiverOptions.enforceSupportedCommands. L'interfaccia utente dei mittenti dell'SDK di Google Cast e dei dispositivi abilitati al tocco cambierà per riflettere queste configurazioni. Se il flag non è abilitato, verranno eseguiti i comandi vocali in arrivo.

Ad esempio, se consenti l'accesso PAUSE dalle applicazioni dei mittenti e dai dispositivi abilitati al tocco, devi anche configurare il ricevitore in modo da riflettere tali impostazioni. Una volta configurati, tutti i comandi vocali in arrivo verranno eliminati se non sono inclusi nell'elenco dei comandi supportati.

Nell'esempio seguente, forniamo il CastReceiverOptions quando avvii CastReceiverContext. Abbiamo aggiunto il supporto per il comando PAUSE e abbiamo imposto al player di supportare solo quel comando. Se un comando vocale richiede un'altra operazione, come SEEK, verrà negato. L'utente verrà avvisato 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. In questo caso, intercetta la richiesta fornita dall'SDK per far sì che i comandi SEEK emessi sui dispositivi con l'assistente integrato non attivino una ricerca nell'applicazione Ricevitore web.

Per i comandi multimediali che la tua applicazione non supporta, restituisci il 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;
  });

Background delle attività vocali

Se la piattaforma di trasmissione riproduce in background il suono dell'applicazione a causa di attività dell'assistente, ad esempio ascolto del parlato o risposta dell'utente, viene inviato un messaggio FocusState di NOT_IN_FOCUS all'applicazione ricevitore web all'avvio dell'attività. Al termine dell'attività viene inviato un altro messaggio con IN_FOCUS. A seconda della tua applicazione e dei contenuti multimediali in riproduzione, potresti voler mettere in pausa i contenuti multimediali quando FocusState è NOT_IN_FOCUS intercettando il tipo di messaggio FOCUS_STATE.

Ad esempio, è utile mettere in pausa la riproduzione degli audiolibri se l'assistente risponde 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 specificati

Quando un utente non menziona esplicitamente la lingua dei sottotitoli, la lingua utilizzata per i sottotitoli è 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" perché la lingua è stata dedotta dalla lingua in cui è stato pronunciato il comando. Se la lingua viene richiesta esplicitamente, ad esempio in "Hey Google, attiva i sottotitoli in inglese", isSuggestedLanguage viene impostato su false.

Metadati e trasmissione vocale

Anche se i comandi vocali vengono gestiti dal ricevitore web per impostazione predefinita, devi assicurarti che i metadati dei tuoi contenuti siano completi e accurati. Ciò garantisce che i comandi vocali siano gestiti correttamente dall'assistente e che i metadati vengano visualizzati correttamente su nuovi tipi di interfacce, come l'app Google Home e smart display come Google Home Hub.

Trasferimento dello streaming

La conservazione dello stato della sessione è la base del trasferimento dello streaming, in cui gli utenti possono spostare gli stream audio e video esistenti sui vari dispositivi utilizzando i comandi vocali, l'app Google Home o smart display. La riproduzione dei contenuti multimediali viene interrotta su un dispositivo (l'origine) e continua su un altro (la destinazione). Qualsiasi dispositivo di trasmissione con il firmware più recente può fungere da origine o destinazione in un trasferimento di streaming.

Il flusso di eventi per il trasferimento dello streaming è:

  1. Sul dispositivo di origine:
    1. La riproduzione dei contenuti multimediali viene interrotta.
    2. L'applicazione Ricevitore web riceve un comando per salvare lo stato multimediale corrente.
    3. L'applicazione Ricevitore web è stata disattivata.
  2. Sul dispositivo di destinazione:
    1. L'applicazione Ricevitore web è stata caricata.
    2. L'applicazione Ricevitore web 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 specifica o timestamp del brano, del video o dell'elemento multimediale.
  • e si trova in una coda più ampia, ad esempio una playlist o una radio dell'artista.
  • L'utente autenticato.
  • Stato di riproduzione (ad esempio, riproduzione o pausa).

Abilitazione del trasferimento dello streaming

Per implementare il trasferimento dello streaming per il ricevitore web:

  1. Aggiorna supportedMediaCommands con il comando STREAM_TRANSFER:
    playerManager.addSupportedMediaCommands(
    cast.framework.messages.Command.STREAM_TRANSFER, true);
  2. Facoltativamente, esegui l'override dei intercettatori dei messaggi SESSION_STATE e RESUME_SESSION come descritto nella sezione Preservare lo stato della sessione. Sostituiscile solo se i dati personalizzati devono essere archiviati come parte dello snapshot della sessione. Altrimenti, l'implementazione predefinita per preservare gli stati della sessione supporterà il trasferimento dello streaming.

Conservazione dello stato della sessione

L'SDK del ricevitore web fornisce un'implementazione predefinita per le app del ricevitore web che preservano gli stati della sessione mediante l'acquisizione di uno snapshot dell'attuale stato dei contenuti multimediali, la conversione dello stato in una richiesta di caricamento e la ripresa della sessione con la richiesta di carico.

Se necessario, la richiesta di carico generata dal ricevitore web può essere sostituita nell'intercettazione dei messaggi SESSION_STATE. Se vuoi aggiungere dati personalizzati nella richiesta di caricamento, ti suggeriamo 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'intercettazione dei messaggi di 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 contenuti

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

L'operazione di precaricamento scarica diversi segmenti degli elementi futuri. La specifica viene eseguita sul valore preloadTime nell'oggetto QueueItem (il valore predefinito è 20 secondi se non specificato). Il tempo è espresso in secondi e corrisponde alla fine dell'elemento attualmente in riproduzione . Solo i valori positivi sono validi. Ad esempio, se il valore è 10 secondi, questo elemento verrà caricato 10 secondi prima del termine dell'elemento precedente. Se il tempo di precaricamento è superiore al tempo ancora disponibile nell'elemento Current, il precaricamento viene eseguito appena possibile. Quindi, se un valore di precaricamento molto elevato è specificato su codeItem, si può ottenere l'effetto di ogni volta che si esegue la riproduzione dell'elemento corrente, stiamo già precaricando l'elemento successivo. Tuttavia, lasciamo all'impostazione e alla scelta questa opzione per lo sviluppatore in quanto questo valore può influire sulla larghezza di banda e sulle prestazioni di streaming dell'elemento di riproduzione corrente.

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

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

Messaggi personalizzati

Lo scambio di messaggi è il metodo di interazione chiave per le applicazioni del ricevitore web.

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

Un'applicazione Ricevitore web può scegliere di ascoltare i messaggi in uno spazio dei nomi specificato. In base a ciò, si dice che l'applicazione Web Receiver supporti il protocollo dello spazio dei nomi. Spetta quindi a tutti i mittenti connessi che vogliono comunicare su quello spazio dei nomi utilizzare il protocollo appropriato.

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

Ecco uno snippet di codice che consente al ricevitore web di ascoltare i messaggi personalizzati provenienti dai mittenti connessi:

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 Ricevitore web possono mantenere informati i mittenti sullo stato del ricevitore web inviando messaggi ai mittenti connessi. 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 il messaggio point-to-point (con un limite di 64 kb), un ricevitore web può anche trasmettere messaggi a tutti i mittenti connessi.

Trasmetti per i dispositivi audio

Consulta la guida ai dispositivi Google Cast per l'audio per ricevere assistenza sulla riproduzione dei soli audio.

Android TV

Questa sezione illustra come il ricevitore web di Google utilizza i tuoi input per la riproduzione e la compatibilità con Android TV.

Integrazione dell'applicazione con il telecomando

Il ricevitore Google Web in esecuzione sul dispositivo Android TV traduce gli input provenienti dagli input di controllo del dispositivo (come il telecomando portatile) come messaggi di riproduzione dei contenuti multimediali definiti per lo spazio dei nomi urn:x-cast:com.google.cast.media, come descritto nei messaggi di riproduzione dei contenuti multimediali. L'applicazione deve supportare questi messaggi per controllare la riproduzione dei contenuti multimediali dell'applicazione per consentire il controllo di riproduzione di base dagli input di controllo di Android TV.

Linee guida per la compatibilità con Android TV

Ecco alcuni consigli e insidie comuni da evitare per assicurarti che la tua applicazione sia compatibile con Android TV:

  • Tieni presente che la stringa user agent contiene sia "Android" che "C Chrome"; 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 di dispositivo mobile.
  • Lo stack multimediale di Android potrebbe utilizzare GZIP trasparente per recuperare i dati. Assicurati che i 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 eventi correlati ai contenuti multimediali attivati da elementi <audio>/<video>, come timeupdate, pause e waiting. Evita di utilizzare eventi di networking come progress, suspend e stalled, poiché questi eventi dipendono dalla piattaforma. Per ulteriori informazioni 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 di Qualsys per verificare se il percorso di certificazione attendibile del tuo sito include un certificato CA denominato "Download aggiuntivo", è possibile che non venga caricato su piattaforme basate su Android.
  • Mentre Chromecast mostra la pagina del ricevitore su un piano grafico a 720p, altre piattaforme di trasmissione, inclusa Android TV, potrebbero mostrare la pagina fino a 1080p. Assicurati che la pagina del ricevitore venga ridimensionata in modo controllato a risoluzioni diverse.