Questa pagina contiene snippet di codice e descrizioni delle funzionalità disponibili per un'app ricevitore web personalizzata.
- Un elemento
cast-media-player
che rappresenta l'UI del player integrata fornita con il ricevitore web. - Stili CSS personalizzati per l'elemento
cast-media-player
al fine di applicare uno stile a vari elementi dell'interfaccia utente comebackground-image
,splash-image
efont-family
. - Un elemento script per caricare il framework Web ricevir.
- Codice JavaScript per intercettare i messaggi e gestire gli eventi.
- Coda per la riproduzione automatica.
- Opzioni per configurare la riproduzione.
- Opzioni per impostare il contesto del ricevitore web.
- Opzioni per impostare i comandi supportati dall'app Web Receiver.
- 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, gestisce il caricamento delle librerie sottostanti e gestisce l'inizializzazione dell'SDK Web ricevir. 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 trasmesse all'SDK quando si imposta il parametro facoltativo nella chiamata a start
.
L'esempio seguente mostra come eseguire l'override del comportamento predefinito per rilevare se una connessione del mittente è ancora attiva. Quando il ricevitore web non è in grado di comunicare con un mittente per maxInactivity
secondi, viene inviato un evento SENDER_DISCONNECTED
. La configurazione seguente sostituisce questo timeout. Questo può essere utile durante il debug dei problemi poiché impedisce all'app Web Ricevir di chiudere la sessione di Chrome Remote Debugger 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);
Configura il player
Durante il caricamento dei contenuti, l'SDK Web ricevir consente di configurare le variabili di riproduzione
come le informazioni
DRM,
le configurazioni dei nuovi tentativi e i gestori delle richieste utilizzando
cast.framework.PlaybackConfig
.
Queste informazioni vengono gestite da
PlayerManager
e vengono valutate al momento della creazione dei player. I player vengono creati ogni volta che viene passato un nuovo carico all'SDK Web ricevir. Le modifiche apportate alla PlaybackConfig
dopo la creazione del player vengono valutate al successivo caricamento di contenuti. L'SDK fornisce i seguenti metodi per modificare PlaybackConfig
.
CastReceiverOptions.playbackConfig
per eseguire l'override delle opzioni di configurazione predefinite durante l'inizializzazione diCastReceiverContext
.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 finché non viene eseguito nuovamente l'override.PlayerManager.setMediaPlaybackInfoHandler()
per applicare configurazioni aggiuntive solo all'elemento multimediale caricato sopra le configurazioni correnti. Il gestore viene chiamato subito prima della creazione del player. Le modifiche apportate qui non sono permanenti e non sono incluse nelle query ingetPlaybackConfig()
. Quando viene caricato l'elemento multimediale successivo, questo gestore viene richiamato.
L'esempio seguente mostra come impostare PlaybackConfig
durante l'inizializzazione di CastReceiverContext
. La configurazione sostituisce le richieste in uscita
per l'ottenimento di manifest. Il gestore specifica che le richieste CORS Access-Control 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 eseguire l'override di PlaybackConfig
utilizzando il getter e il setter forniti in PlayerManager
. L'impostazione consente di configurare il player in modo che riprenda 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 di contenuti multimediali. Il gestore chiama il metodo getLicenseUrlForMedia
implementato dall'applicazione per ottenere licenseUrl
dal metodo 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 Submitr consente all'app Web ricevir di gestire gli eventi del player. Il listener di eventi prende 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
che sono 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 Receiver di intercettare i messaggi ed eseguire codice personalizzato su questi messaggi. L'intercettatore dei messaggi utilizza un parametro cast.framework.messages.MessageType
che specifica il tipo di messaggio da intercettare.
L'intercettatore deve restituire la richiesta modificata o una Promise che viene risolta con il valore della richiesta modificato. La restituzione di null
impedirà la chiamata al gestore di messaggi predefinito. Per ulteriori dettagli, vedi Caricamento di 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 dei messaggi, l'app ricevitore web dovrebbe restituire un elemento 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
Di seguito sono riportate alcune differenze fondamentali tra l'intercettazione dei messaggi e il listener di eventi:
- Un listener di eventi non consente di modificare i dati della richiesta.
- Il listener di eventi è ideale per attivare l'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 delle richieste stessi.
- L'intercettazione dei messaggi è utilizzata al meglio per gestire la logica personalizzata per quanto riguarda la richiesta di dati.
Caricamento contenuti multimediali in corso...
MediaInformation
fornisce numerose proprietà per caricare contenuti multimediali nel
messaggio cast.framework.messages.MessageType.LOAD
, tra cui entity
, contentUrl
e contentId
.
entity
è la proprietà suggerita da utilizzare nella tua implementazione per le app per mittente e destinatario. La proprietà è l'URL di un link diretto che può essere una playlist o
contenuti multimediali specifici.
Il
contentUrl
è progettato per un URL riproducibile e può essere utilizzato una volta disponibile.
Il campo contentId
è stato ritirato a causa dell'ambiguità del fatto che il valore sia un URL dei contenuti multimediali, un ID reale o un parametro chiave per la ricerca personalizzata.
Il suggerimento è quello di utilizzare entity
per archiviare l'ID reale o i parametri chiave e di usare contentUrl
per l'URL del contenuto multimediale. Un esempio di ciò è mostrato nel seguente snippet, in cui entity
è presente nella richiesta LOAD
e viene recuperato il valore 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 connesso e sul dispositivo video o audio collegato. Il metodo getDeviceCapabilities
fornisce informazioni di supporto per l'Assistente Google, il Bluetooth, il display e i dispositivi audio connessi.
Questo metodo restituisce un oggetto su cui puoi eseguire query passando una delle enum specificate per ottenere la capacità del dispositivo per quell'enumerazione. Le enum sono
definite in
cast.framework.system.DeviceCapabilities
.
Questo esempio verifica se il dispositivo ricevitore web è in grado di riprodurre rispettivamente i tasti HDR e DolbyVision (DV) con i tasti 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 dell'interazione utente
Un utente può interagire con l'applicazione ricevitore web tramite applicazioni del mittente (web, Android e iOS), comandi vocali su dispositivi con l'assistente integrato, controlli touch su smart display e telecomandi sui dispositivi Android TV. L'SDK Cast fornisce varie API per consentire all'app Web Ricevir di gestire queste interazioni, aggiornare l'interfaccia utente dell'applicazione tramite gli stati di azione dell'utente e, facoltativamente, inviare le modifiche per aggiornare i servizi di backend.
Comandi multimediali supportati
Gli stati dei controlli dell'interfaccia utente sono determinati dall'elemento
MediaStatus.supportedMediaCommands
per i controller espansi per mittente per iOS e Android, per le app di ricezione e per il controllo remoto
in esecuzione su dispositivi touch e per le app di ricezione sui dispositivi Android TV. Quando
un particolare Command
a livello di bit è abilitato nella proprietà, i pulsanti correlati
a questa azione sono abilitati. Se il valore non è impostato, il pulsante è disabilitato. Questi valori possono essere modificati sul ricevitore web tramite:
- Utilizzando
PlayerManager.setSupportedMediaCommands
per impostare ilCommands
specifico - Aggiunta di un nuovo comando utilizzando
addSupportedMediaCommands
- 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 alla proprietà supportedMediaCommands
. Quando lo stato viene trasmesso, le app del mittente connesse aggiornano di conseguenza i pulsanti nella loro UI.
Per ulteriori informazioni sui comandi multimediali e sui dispositivi touch supportati, consulta la guida Accessing UI controls
.
Gestione degli stati delle azioni dell'utente
Quando gli utenti interagiscono con l'interfaccia utente o inviano comandi vocali, possono controllare la riproduzione dei contenuti e le proprietà relative 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, ad esempio un comando LIKE
,
devono essere gestite dall'applicazione destinatario. L'SDK fornisce una serie di API per gestire questi tipi di richieste. Per supportare queste richieste, è necessario fare quanto segue:
- Imposta
MediaInformation
userActionStates
con le preferenze di un utente quando carichi un elemento multimediale. - Intercetta
USER_ACTION
messaggi e determina l'azione richiesta. - Aggiorna
MediaInformation
UserActionState
per aggiornare l'interfaccia utente.
Lo snippet seguente intercetta la richiesta LOAD
e compila il
MediaInformation
di LoadRequestData
. In questo caso, all'utente piacciono
i contenuti caricati.
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 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 seguente simula una chiamata a un servizio di backend. La funzione controlla UserActionRequestData
per vedere il tipo di modifica richiesta dall'utente ed 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 UserActionState
da MediaInformation
. L'aggiornamento di UserActionState
di MediaInformation
modifica lo stato del pulsante associato all'azione richiesta. Questa modifica si riflette nell'interfaccia utente
dei controlli degli smart display, nell'app Controllo remoto e in quella di Android TV. Inoltre, viene 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 abilitati per l'assistente. Le implementazioni predefinite di questi comandi si trovano in cast.framework.PlayerManager
.
Comando | Descrizione |
---|---|
Riproduci | Consente di riprodurre o riprendere la riproduzione dallo stato in pausa. |
Metti in pausa | Metti in pausa i contenuti attualmente in riproduzione. |
Indietro | Salta all'elemento multimediale precedente nella coda dei contenuti multimediali. |
Avanti | Passa all'elemento multimediale successivo nella coda degli elementi multimediali. |
Interrompi | Interrompi la riproduzione dei contenuti multimediali attualmente in corso. |
Nessuna ripetizione | Disattiva la ripetizione degli elementi multimediali nella coda al termine della riproduzione dell'ultimo elemento in coda. |
Singolo ripetuto | Ripeti i contenuti multimediali attualmente in riproduzione a tempo indeterminato. |
Ripeti tutto | Ripetere tutti gli elementi in coda una volta riprodotto l'ultimo elemento in coda. |
Ripeti tutto e riproduci in ordine casuale | Una volta terminata la riproduzione dell'ultimo elemento in coda, metti la coda in ordine casuale e ripeti tutti gli elementi in coda. |
Riproduzione casuale | Visualizza in modo casuale gli elementi multimediali nella tua coda di contenuti multimediali. |
Sottotitoli codificati attivi / disattivati | Attiva / disattiva sottotitoli per i tuoi contenuti multimediali. L'opzione Attiva / Disattiva è disponibile anche in base alla lingua. |
Vai al tempo assoluto | Salta al tempo assoluto specificato. |
Vai all'ora relativa all'ora corrente | Va avanti o indietro del periodo di tempo specificato rispetto all'ora di riproduzione corrente. |
Gioca di nuovo | Riavvia il contenuto multimediale attualmente in riproduzione o riproduci l'ultimo elemento multimediale riprodotto se non è in corso la riproduzione di alcun elemento. |
Imposta la velocità di riproduzione | Varia la velocità di riproduzione dei contenuti multimediali. Questa operazione dovrebbe essere gestita per impostazione predefinita. Puoi utilizzare l'intercettatore dei messaggi SET_PLAYBACK_RATE per eseguire l'override delle richieste di tariffe in entrata. |
Comandi multimediali supportati con comandi vocali
Per evitare che un comando vocale attivi un comando multimediale su un dispositivo con l'assistente integrato, devi prima impostare i comandi di contenuti multimediali supportati che prevedi di supportare. Quindi devi applicare in modo forzato questi comandi abilitando la proprietà CastReceiverOptions.enforceSupportedCommands
. L'interfaccia utente dei mittenti dell'SDK 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 a PAUSE
dalle applicazioni del mittente e dai dispositivi touch, devi anche configurare il destinatario in modo che rifletta queste impostazioni. Una volta configurati, i comandi vocali in arrivo verranno ignorati se non sono inclusi nell'elenco dei comandi supportati.
Nell'esempio seguente viene fornito CastReceiverOptions
all'avvio di CastReceiverContext
. Abbiamo aggiunto il supporto per il comando PAUSE
e
impostato il player in modo che supporti solo tale comando. Se un comando vocale richiede un'altra operazione, come SEEK
, verrà rifiutato. All'utente verrà comunicato che il comando non è ancora supportato.
const context = cast.framework.CastReceiverContext.getInstance();
context.start({
enforceSupportedCommands: true,
supportedCommands: cast.framework.messages.Command.PAUSE
});
Puoi applicare logica separata per ciascun 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 a dispositivi con l'assistente integrato
non attivino una ricerca nella tua applicazione Web Ricevir.
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;
});
Background dell'attività vocale
Se la piattaforma Cast elimina l'audio della tua applicazione in background a causa di attività dell'assistente quali l'ascolto della voce dell'utente o il dialogo, un messaggio FocusState
di NOT_IN_FOCUS
viene inviato all'applicazione ricevitore web all'avvio dell'attività. Viene inviato un altro messaggio con IN_FOCUS
al termine dell'attività.
A seconda dell'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, mettere in pausa la riproduzione di un audiolibro è una buona esperienza utente 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 codificati specificata dalla voce
Quando un utente non indica esplicitamente la lingua dei sottotitoli codificati, la
lingua utilizzata per i sottotitoli è quella 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, il criterio 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", il criterio isSuggestedLanguage
è impostato su false
.
Metadati e trasmissione vocale
Sebbene i comandi vocali vengano gestiti per impostazione predefinita dal ricevitore web, devi assicurarti che i metadati relativi ai tuoi contenuti siano completi e accurati. Ciò garantisce che i comandi vocali vengano gestiti correttamente dall'assistente e che i metadati vengano visualizzati correttamente nei 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, in cui gli utenti possono spostare gli stream audio e video esistenti su più dispositivi utilizzando i comandi vocali, l'app Google Home o gli smart display. La riproduzione dei contenuti multimediali viene interrotta su un dispositivo (la sorgente) e continua su un altro (la destinazione). Qualsiasi dispositivo di trasmissione dotato del firmware più recente può fungere da origine o destinazione in un trasferimento dello streaming.
Il flusso di eventi per il trasferimento dello streaming è:
- Sul dispositivo di origine:
- La riproduzione dei contenuti multimediali si interrompe.
- L'applicazione ricevitore web riceve un comando per salvare l'attuale stato dei contenuti multimediali.
- L'applicazione Web Receiver è arrestata.
- Sul dispositivo di destinazione:
- L'applicazione ricevitore web è stata caricata.
- L'applicazione ricevitore web riceve un comando per ripristinare lo stato multimediale salvato.
- 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.
- ma viene inserita in una coda più ampia (ad esempio una playlist o la radio di un artista).
- L'utente autenticato.
- Stato di riproduzione (ad esempio, in riproduzione o in pausa).
Abilitazione del trasferimento dello streaming
Per implementare il trasferimento dello streaming per il ricevitore web:
- Aggiorna
supportedMediaCommands
con il comandoSTREAM_TRANSFER
:playerManager.addSupportedMediaCommands( cast.framework.messages.Command.STREAM_TRANSFER, true);
- Facoltativamente, esegui l'override degli intercettori dei messaggi
SESSION_STATE
eRESUME_SESSION
come descritto in Conservazione dello stato della sessione. Esegui l'override di questi valori solo se i dati personalizzati devono essere archiviati come parte dello snapshot della sessione. In caso contrario, l'implementazione predefinita per la conservazione degli stati della sessione supporterà il trasferimento dello streaming.
Conservazione dello stato della sessione
L'SDK Web ricevir fornisce un'implementazione predefinita per consentire alle app Web di ricevere gli stati delle sessioni acquisendo un'istantanea dello stato attuale dei contenuti multimediali, convertendo lo stato in una richiesta di caricamento e ripristinando la sessione con la richiesta di caricamento.
La richiesta di carico generata dal ricevitore web può essere ignorata nell'intercettatore dei messaggi SESSION_STATE
, se necessario. 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 dei 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 di elementi multimediali dopo l'elemento di riproduzione corrente nella coda.
L'operazione di precaricamento consente di scaricare diversi segmenti dei prossimi elementi. La specifica viene eseguita sul valore preloadTime nell'oggetto QueueItem (il valore predefinito è 20 secondi se non fornito). Il tempo è espresso in secondi, in relazione 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 rimasto nell'elemento currentItem, il precaricamento verrà eseguito il prima possibile. Pertanto, se nell'elementoQueueItem viene specificato un valore molto elevato di precaricamento, si potrebbe avere l'effetto di precaricare già l'elemento corrente ogni volta che riproduciamo l'elemento corrente. Tuttavia, lasciamo l'impostazione e la scelta allo sviluppatore poiché questo valore può influire sulla larghezza di banda e sulle prestazioni di streaming dell'elemento in riproduzione corrente.
Il precaricamento funzionerà per impostazione predefinita per i contenuti in streaming HLS, DASH e fluido.
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 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 di ricezione web.
Un mittente invia messaggi a un ricevitore web utilizzando le API del mittente per la piattaforma eseguita dal mittente (Android, iOS, Web). L'oggetto evento (ovvero la manifestazione di un messaggio) che viene passato ai listener di eventi dispone di un elemento di dati (event.data
) in cui i dati assumono le proprietà del tipo di evento specifico.
Un'applicazione ricevitore web può scegliere di rimanere in ascolto per i messaggi in uno spazio dei nomi specificato. In virtù di ciò, si dice che l'applicazione Ricevitore web supporti quel protocollo dello spazio dei nomi. Spetta quindi a tutti i mittenti connessi che desiderano 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 il ricevitore web può ascoltare per 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 tenere informati i mittenti sullo stato del ricevitore web inviando messaggi ai mittenti connessi. Un'applicazione ricevitore web può inviare messaggi utilizzando sendCustomMessage(namespace, senderId, message)
su CastReceiverContext
.
Un ricevitore 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 alla messaggistica point-to-point (con un limite di 64 kB), un ricevitore web può anche trasmettere messaggi a tutti i mittenti connessi.
Trasmetti per dispositivi audio
Per assistenza relativa alla riproduzione di solo audio, consulta la guida di Google Cast per i dispositivi audio.
Android TV
Questa sezione illustra il modo in cui il ricevitore web di Google utilizza i tuoi ingressi per la riproduzione e la compatibilità con Android TV.
Integrazione dell'applicazione con il telecomando
Il ricevitore web di Google in esecuzione sul dispositivo Android TV converte l'input proveniente dagli input di controllo del dispositivo (ovvero il telecomando portatile) come messaggi di riproduzione multimediali definiti per lo spazio dei nomi urn:x-cast:com.google.cast.media
, come descritto in Messaggi di riproduzione dei contenuti multimediali. L'applicazione deve supportare questi messaggi per controllare la riproduzione dei contenuti multimediali dell'applicazione e consentire il controllo di base della riproduzione dagli ingressi di controllo di Android TV.
Linee guida relative alla compatibilità con Android TV
Di seguito sono riportati alcuni consigli ed errori comuni da evitare per garantire che la tua applicazione sia compatibile con Android TV:
- Tieni presente che la stringa dello user agent contiene sia "Android" che "C commento"; 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 dispositivi mobili.
- Lo stack multimediale di Android potrebbe utilizzare un file 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 con tempistiche diverse rispetto a Chromecast e potrebbero rivelare problemi nascosti su Chromecast.
- Quando aggiorni i contenuti multimediali, utilizza gli eventi correlati ai contenuti multimediali attivati dagli elementi
<audio>/<video>
, cometimeupdate
,pause
ewaiting
. Evita di utilizzare eventi relativi al networking comeprogress
,suspend
estalled
, poiché tendono a dipendere dalla piattaforma. Consulta Eventi multimediali per ulteriori informazioni sulla gestione degli eventi multimediali nel ricevitore. - Quando configuri i certificati HTTPS del sito destinatario, assicurati di includere certificati CA intermedi. Consulta la pagina di test SSL Qualsys per verificare: se il percorso della certificazione attendibile per il tuo sito include un certificato CA con l'etichetta "download aggiuntivo", potrebbe non essere caricato sulle piattaforme basate su Android.
- Mentre Chromecast mostra la pagina del ricevitore su un piano grafico da 720p, altre piattaforme di trasmissione, tra cui Android TV, potrebbero visualizzare la pagina con una risoluzione massima di 1080p. Assicurati che la pagina del ricevitore venga ridimensionata a diverse risoluzioni.