Esta página contém snippets de código e descrições dos recursos disponíveis para um app receptor da Web personalizado
- Um elemento
cast-media-player
que representa a interface integrada do player fornecidos com o receptor da Web. - Estilo personalizado semelhante a CSS para o elemento
cast-media-player
a fim de estilizar vários Elementos da interface, comobackground-image
,splash-image
efont-family
. - Um elemento de script para carregar o framework do receptor da Web.
- Código JavaScript para interceptar mensagens e processar eventos.
- Fila para reprodução automática.
- Opções para configurar a reprodução.
- Opções para definir o contexto do receptor da Web.
- Opções para definir comandos compatíveis com o app Web Receiver.
- Uma chamada JavaScript para iniciar o aplicativo receptor da Web.
Configuração e opções do aplicativo
Configurar o aplicativo
A
CastReceiverContext
é a classe mais externa exposta ao desenvolvedor e gerencia o carregamento de
bibliotecas subjacentes e cuida da inicialização do SDK do receptor da Web. O SDK
fornece APIs que permitem aos desenvolvedores de aplicativos configurar o SDK por meio de
CastReceiverOptions
Essas configurações são avaliadas uma vez por inicialização do aplicativo e são passadas para
o SDK ao definir o parâmetro opcional na chamada para
start
O exemplo abaixo mostra como modificar o comportamento padrão para detectar se um
do remetente ainda estiver conectado. Quando o receptor da Web não
conseguiu se comunicar com um remetente para
maxInactivity
segundos, um evento SENDER_DISCONNECTED
é enviado. A configuração abaixo
substitui esse tempo limite. Isso pode ser útil na depuração de problemas, pois evita
o app Receptor da Web feche a sessão do depurador remoto do Google Chrome quando houver
não há remetentes conectados no estado IDLE
.
const context = cast.framework.CastReceiverContext.getInstance();
const options = new cast.framework.CastReceiverOptions();
options.maxInactivity = 3600; // Development only
context.start(options);
Configurar o player
Ao carregar conteúdo, o SDK do receptor da Web oferece uma maneira de configurar a reprodução
variáveis como DRM
informações,
repetir configurações e solicitar manipuladores usando
cast.framework.PlaybackConfig
.
Essas informações são processadas pelo
PlayerManager
e é avaliada quando os jogadores são criados. Os jogadores são criados
sempre que um novo carregamento é transmitido para o SDK do receptor da Web. Modificações nos
As PlaybackConfig
após a criação do player são avaliadas na próxima
carregamento de conteúdo. O SDK fornece os métodos a seguir para modificar a
PlaybackConfig
:
CastReceiverOptions.playbackConfig
para substituir as opções de configuração padrão ao inicializar oCastReceiverContext
.PlayerManager.getPlaybackConfig()
para obter a configuração atual.PlayerManager.setPlaybackConfig()
para substituir a configuração atual. Essa configuração é aplicada a todos os carregamentos subsequentes ou até que seja substituído novamente.PlayerManager.setMediaPlaybackInfoHandler()
para aplicar configurações adicionais somente para o item de mídia sendo carregado as configurações atuais. O manipulador é chamado pouco antes do player criação. As mudanças feitas aqui não são permanentes e não são incluídas nas consultas paragetPlaybackConfig()
. Quando o próximo item de mídia é carregado, esse gerenciador é chamado novamente.
O exemplo abaixo mostra como definir o PlaybackConfig
ao inicializar o
CastReceiverContext
. A configuração substitui as solicitações enviadas
a obtenção de manifestos. O gerenciador especifica que as solicitações de controle de acesso do CORS
devem ser feitas usando credenciais como cookies ou cabeçalhos de autorização.
const playbackConfig = new cast.framework.PlaybackConfig();
playbackConfig.manifestRequestHandler = requestInfo => {
requestInfo.withCredentials = true;
};
context.start({playbackConfig: playbackConfig});
O exemplo abaixo mostra como substituir o PlaybackConfig
usando o getter.
e setter fornecidos em PlayerManager
. Essa configuração define o player
retomar a reprodução do conteúdo depois que 1 segmento tiver sido carregado.
const playerManager =
cast.framework.CastReceiverContext.getInstance().getPlayerManager();
const playbackConfig = (Object.assign(
new cast.framework.PlaybackConfig(), playerManager.getPlaybackConfig()));
playbackConfig.autoResumeNumberOfSegments = 1;
playerManager.setPlaybackConfig(playbackConfig);
O exemplo abaixo mostra como substituir o PlaybackConfig
para uma carga específica
usando o gerenciador de informações de reprodução de mídia. O gerenciador chama um aplicativo
implementou o método getLicenseUrlForMedia
para extrair o licenseUrl
do
contentId
do item atual.
playerManager.setMediaPlaybackInfoHandler((loadRequestData, playbackConfig) => {
const mediaInformation = loadRequestData.media;
playbackConfig.licenseUrl = getLicenseUrlForMedia(mediaInformation.contentId);
return playbackConfig;
});
Listener de eventos
O SDK do receptor da Web permite que seu app processe os eventos do jogador. A
listener de eventos recebe uma
cast.framework.events.EventType
(ou uma matriz desses parâmetros) que especifica os eventos que
deve acionar o listener. Matrizes pré-configuradas de
cast.framework.events.EventType
que são úteis para depuração podem ser encontradas em
cast.framework.events.category
.
O parâmetro do evento fornece mais informações sobre o evento.
Por exemplo, se você quer saber quando um
mediaStatus
a mudança está sendo transmitida, use a seguinte lógica para lidar com a
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
});
Interceptação de mensagens
O SDK do receptor da Web permite que seu app intercepte mensagens e
executar código personalizado nessas mensagens. O interceptador de mensagens toma
cast.framework.messages.MessageType
que especifica o tipo de mensagem que deve ser interceptado.
O interceptador precisa retornar a solicitação modificada ou uma promessa que resolva
com o valor modificado. Retornar null
impede a chamada da função
gerenciador de mensagens padrão. Consulte Como carregar mídia para mais detalhes.
Por exemplo, se você quiser alterar os dados da solicitação de carregamento, use o seguinte lógica para interceptá-lo e modificá-lo:
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();
Tratamento de erros
Quando ocorrem erros no interceptador de mensagens, o app Receptor da Web deve retornar
um adequado
cast.framework.messages.ErrorType
e
cast.framework.messages.ErrorReason
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;
});
});
Interceptação de mensagens x listener de eventos
Algumas diferenças importantes entre interceptação de mensagens e listener de eventos são da seguinte forma:
- Um listener de eventos não permite que você modifique os dados da solicitação.
- Um listener de eventos é melhor usado para acionar análises ou uma função personalizada.
playerManager.addEventListener(cast.framework.events.category.CORE,
event => {
console.log(event);
});
- A interceptação de mensagens permite ouvir, interceptar e modificar os dados da solicitação.
- A interceptação de mensagens é mais usada para lidar com lógica personalizada em relação à solicitar dados.
Como carregar mídia
MediaInformation
tem diversas propriedades para carregar mídia no
cast.framework.messages.MessageType.LOAD
mensagem incluindo entity
,
contentUrl
e contentId
.
- O
entity
é a propriedade sugerida a ser usada em sua implementação para o remetente e aplicativos receptores. A propriedade é um URL de link direto que pode ser uma playlist ou conteúdo de mídia. Seu aplicativo deve analisar esse URL e preencher pelo menos um dos outros dois campos. - O
contentUrl
corresponde ao URL de reprodução que será usado pelo player para carregar o conteúdo. Por exemplo, esse URL pode direcionar para um manifesto DASH. - O
contentId
pode ser um URL de conteúdo jogável (semelhante ao decontentUrl
propriedade) ou um identificador único para o conteúdo ou a playlist sendo carregada. Se estiver usando essa propriedade como um identificador, seu aplicativo deverá preencher um URL reproduzível emcontentUrl
.
A sugestão é usar entity
para armazenar o ID real ou os parâmetros principais e
use contentUrl
para o URL da mídia. Um exemplo disso é mostrado
snippet a seguir, em que entity
está presente na solicitação LOAD
e no
contentUrl
reproduzível é recuperado:
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;
});
});
Recursos do dispositivo
A
getDeviceCapabilities
fornece informações sobre o dispositivo de transmissão conectado e o vídeo ou
dispositivo de áudio conectado a ele. O método getDeviceCapabilities
oferece suporte
informações sobre o Google Assistente, o Bluetooth e a tela e o áudio conectados
dispositivos.
Esse método retorna um objeto que você pode consultar transmitindo um dos
tipos enumerados especificados para obter a capacidade do dispositivo para esse tipo enumerado. Os tipos enumerados são
definido em
cast.framework.system.DeviceCapabilities
Este exemplo verifica se o dispositivo receptor da Web é capaz de reproduzir HDR e
DolbyVision (DV) com as chaves IS_HDR_SUPPORTED
e IS_DV_SUPPORTED
;
respectivamente.
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();
Como processar a interação do usuário
Um usuário pode interagir com seu aplicativo receptor da Web pelo remetente aplicativos (Web, Android e iOS), comandos de voz no Google Assistente dispositivos, controles por toque em smart displays e controles remotos no Android TV dispositivos. O SDK do Cast fornece várias APIs para permitir que o app receptor da Web para lidar com essas interações, atualizar a interface do aplicativo estados de ação do usuário, e, opcionalmente, enviar as alterações para atualizar os serviços de back-end.
Comandos de mídia compatíveis
Os estados dos controles de interface são determinados pelo
MediaStatus.supportedMediaCommands
para controladores expandidos, receptor e controle remoto de remetente iOS e Android
Apps executados em dispositivos de toque e apps receptores em dispositivos Android TV. Quando um
Command
bit a bit específico é ativado na propriedade, os botões que são
relacionadas à ação estão ativados. Se o valor não for definido, o botão será
desativado. Esses valores podem ser alterados no Web Receiver por meio de:
- Usando
PlayerManager.setSupportedMediaCommands
para definirCommands
- Adicionar um novo comando usando
addSupportedMediaCommands
- Remover um comando atual usando
removeSupportedMediaCommands
playerManager.setSupportedMediaCommands(cast.framework.messages.Command.SEEK |
cast.framework.messages.Command.PAUSE);
Quando o receptor prepara o MediaStatus
atualizado, ele inclui o
mudanças na propriedade supportedMediaCommands
. Quando o status for
transmitidas, os apps do remetente conectados vão atualizar os botões na interface
de acordo.
Para mais informações sobre comandos de mídia e dispositivos de toque compatíveis, consulte
Accessing UI controls
guia.
Como gerenciar estados de ação do usuário
Quando os usuários interagem com a interface ou enviam comandos de voz, eles podem controlar o
reprodução do conteúdo e das propriedades relacionadas ao item em reprodução. Solicitações
que controlam a reprodução são tratados automaticamente pelo SDK. Solicitações que
modificar as propriedades do item em reprodução, como um comando LIKE
;
exigem que o aplicativo receptor as processe. O SDK oferece uma série de
APIs para lidar com esses tipos de solicitações. Para dar suporte a essas solicitações, os seguintes
precisa ser feito:
- Defina o
MediaInformation
userActionStates
com as preferências do usuário ao carregar um item de mídia. - Interceptar
USER_ACTION
mensagens e determinar a ação solicitada. - Atualize o
UserActionState
doMediaInformation
para atualizar a interface.
O snippet a seguir intercepta a solicitação LOAD
e preenche a
MediaInformation
de LoadRequestData
. Nesse caso, o usuário gosta da
conteúdo que está sendo carregado.
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;
});
O snippet a seguir intercepta a mensagem USER_ACTION
e processa as chamadas
back-end com a alteração solicitada. Em seguida, ele faz uma chamada para atualizar
UserActionState
no receptor.
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;
});
});
O snippet a seguir simula uma chamada para um serviço de back-end. A função verifica
o UserActionRequestData
para ver o tipo de mudança que o usuário solicitou.
e só faz uma chamada de rede se ela tiver suporte do back-end.
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));
}
});
}
O snippet a seguir usa o UserActionRequestData
e adiciona ou
remove o UserActionState
do MediaInformation
. Atualizar o
UserActionState
da MediaInformation
muda o estado do botão que
está associado à ação solicitada. Essa mudança é refletida nos modelos
interface de controles de tela, app de controle remoto e interface do Android TV. Também é
transmitida por mensagens MediaStatus
enviadas para atualizar a interface do
controle expandido para remetentes de 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;
}
Comandos de voz
No momento, os comandos de mídia a seguir são suportados no SDK do receptor da Web para
Dispositivos com Google Assistente. As implementações padrão desses comandos são
encontrado em
cast.framework.PlayerManager
Comando | Descrição |
---|---|
Tocar | Reproduzir ou retomar a reprodução a partir do estado pausado. |
Pausar | Pausar conteúdo em reprodução. |
Anterior | Pule para o item de mídia anterior na fila de mídia. |
Próxima | Pule para o próximo item de mídia da fila. |
Parar | Interrompe a mídia em reprodução. |
Repetir nenhuma | Desativar a repetição de itens de mídia na fila quando a reprodução do último item da fila for concluída. |
Repetir único | Repetir a mídia em reprodução indefinidamente. |
Repetir tudo | Repita todos os itens na fila depois que o último item da fila for reproduzido. |
Repetir tudo e ordem aleatória | Quando a reprodução do último item da fila terminar, embaralhar a fila e repetir todos os itens. |
Ordem aleatória | Embaralhe os itens de mídia na fila de mídia. |
Legendas ATIVADAS / DESATIVADAS | Ativar / desativar o closed caption para sua mídia. Ativar / desativar também está disponível por idioma. |
Procurar até o tempo absoluto | Pula para o tempo absoluto especificado. |
Procurar um tempo relativo ao horário atual | Pula para frente ou para trás no período especificado em relação ao tempo de reprodução atual. |
Jogar de novo | Reinicie a mídia em reprodução ou o último item de mídia reproduzido se nada estiver em reprodução. |
Definir a velocidade do vídeo | Variem a velocidade de reprodução de mídia. Isso deve ser tratado por padrão. Você pode usar o interceptador de mensagens SET_PLAYBACK_RATE para substituir as solicitações de tarifa recebidas. |
Comandos de mídia compatíveis com voz
Para evitar que um comando de voz acione um comando de mídia em um Assistente,
dispositivo ativado, defina primeiro o
comandos de mídia compatíveis
que você planeja apoiar. Em seguida, você precisa aplicar esses comandos ativando
as
CastReceiverOptions.enforceSupportedCommands
. A interface nos remetentes do SDK do Cast e em dispositivos com recurso de toque vai mudar para
refletem essas configurações. Se a sinalização não estiver ativada, a voz de entrada
serão executados.
Por exemplo, se você permitir o uso de PAUSE
nos aplicativos remetente e
dispositivos com tela touch, você também precisa configurar o receptor para refletir essas
configurações. Quando configurados, todos os comandos de voz recebidos são descartados
incluídos na lista de comandos compatíveis.
No exemplo abaixo, fornecemos o CastReceiverOptions
ao iniciar
o CastReceiverContext
. Adicionamos suporte ao comando PAUSE
e
fez com que o player fosse compatível apenas com esse comando. Agora, se um comando de voz
solicita outra operação, como SEEK
, ela será negada. O usuário será
notificado de que ainda não há suporte para o comando.
const context = cast.framework.CastReceiverContext.getInstance();
context.start({
enforceSupportedCommands: true,
supportedCommands: cast.framework.messages.Command.PAUSE
});
É possível aplicar uma lógica separada para cada comando que você quer restringir. Remover
a sinalização enforceSupportedCommands
e para cada comando que você quer
você poderá interceptar a mensagem recebida. Aqui, interceptamos a solicitação
fornecidos pelo SDK para que comandos SEEK
emitidos pelos dispositivos com Google Assistente
não acionarão uma busca no aplicativo receptor da Web.
Para comandos de mídia não compatíveis com seu aplicativo, retorne uma
motivo do erro, como
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;
});
Segundo plano da atividade de voz
Se a plataforma de transmissão colocar o som do seu aplicativo em segundo plano devido ao Google Assistente
como ouvir a fala do usuário ou dar sua resposta, um
FocusState
de NOT_IN_FOCUS
é enviada para o aplicativo receptor da Web quando o
atividade será iniciada. Outra mensagem com IN_FOCUS
é enviada quando a atividade termina.
Dependendo do seu aplicativo e da mídia que está sendo reproduzida, você pode querer
pausar mídia quando o FocusState
for NOT_IN_FOCUS
, interceptando a mensagem
digite FOCUS_STATE
.
Por exemplo, recomendamos pausar a reprodução de audiolivros se o O Google Assistente está respondendo a uma consulta do usuário.
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;
});
Idioma da legenda especificado por voz
Quando um usuário não diz explicitamente o idioma das legendas, o
O idioma usado para as legendas é o mesmo que o comando foi falado.
Nesses cenários,
isSuggestedLanguage
da mensagem recebida indica se o idioma associado foi
sugerida ou explicitamente solicitada pelo usuário.
Por exemplo, isSuggestedLanguage
está definido como true
para o comando "Ok Google,
ativar as legendas", porque o idioma foi inferido
foi falado. Se o idioma for explicitamente solicitado, como em "OK
Google, ative as legendas em inglês", isSuggestedLanguage
é definido como false
.
Metadados e transmissão de voz
Embora os comandos de voz sejam tratados pelo receptor da Web por padrão, você deve garantir que os metadados do seu conteúdo estejam completos e precisos. Isso garante que os comandos de voz sejam tratados corretamente pelo Google Assistente e que os metadados aparece corretamente em novos tipos de interface, como o app Google Home e e smart displays, como o Google Home Hub.
Transferência de stream
A preservação do estado da sessão é a base da transferência de stream, em que Os usuários podem mover streams de áudio e vídeo entre dispositivos usando comandos de voz, o Google Home no app ou em smart displays. A mídia é interrompida em um dispositivo (a fonte) e continua em outro (a destino). Qualquer dispositivo de transmissão com o firmware mais recente pode servir como origem ou destino em um transferência de stream.
O fluxo de eventos para a transferência de stream é:
- No dispositivo de origem:
- A mídia é interrompida.
- O aplicativo receptor da Web recebe um comando para salvar a mídia atual estado.
- O aplicativo receptor da Web foi encerrado.
- No dispositivo de destino:
- O aplicativo receptor da Web está carregado.
- O aplicativo receptor da Web recebe um comando para restaurar a mídia salva estado.
- A mídia será retomada.
Os elementos do estado da mídia incluem:
- Posição ou marcação de tempo específica da música, do vídeo ou do item de mídia.
- É colocado em uma fila maior, como uma playlist ou a rádio de um artista.
- O usuário autenticado.
- o estado da reprodução (por exemplo, em reprodução ou pausada);
Ativando a transferência de stream
Para implementar a transferência de stream para seu receptor da Web:
- Atualizar
supportedMediaCommands
pelo comandoSTREAM_TRANSFER
:playerManager.addSupportedMediaCommands( cast.framework.messages.Command.STREAM_TRANSFER, true);
- Opcionalmente, substitua as mensagens
SESSION_STATE
eRESUME_SESSION
interceptadores, conforme descrito em Como preservar a sessão estado. Modifique-os apenas se os dados personalizados precisarem sejam armazenados como parte do snapshot da sessão. Caso contrário, o padrão implementação para preservar estados de sessão será compatível com a transferência de stream.
Como preservar o estado da sessão
O SDK do receptor da Web oferece uma implementação padrão para que apps receptores da Web preservar os estados da sessão com um snapshot do status atual da mídia, convertendo o status em uma solicitação de carregamento e a retomada da sessão com a solicitação de carregamento.
A solicitação de carregamento gerada pelo Web Receiver pode ser substituída na classe
Interceptador de mensagens SESSION_STATE
, se necessário. Se você quiser adicionar dados personalizados
na solicitação de carregamento, sugerimos colocá-los em
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;
});
Os dados personalizados podem ser recuperados
loadRequestData.customData
no interceptador de mensagens 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;
});
Pré-carregamento de conteúdo
O receptor da Web oferece suporte ao pré-carregamento de itens de mídia após a reprodução atual item na fila.
A operação de pré-carregamento faz o download prévio de vários segmentos do próximos itens. A especificação é feita preloadTime na coluna Objeto QueueItem Se não for informado, o padrão será 20 segundos. O tempo é expresso em segundos, relativo ao final do item em reprodução no momento . Somente valores positivos são válidos. Por exemplo, se o valor for 10 segundos, este item será pré-carregado 10 segundos antes de o item anterior terminar. Se o tempo de pré-carregamento for maior que o tempo restante no currentItem, o pré-carregamento só ocorrerá assim que sempre que possível. Portanto, se um valor muito grande de pré-carregamento for especificado no “queueItem”, um ter o efeito de sempre que estivermos tocando o item atual já carregando o próximo item. No entanto, deixamos a configuração e a escolha ao desenvolvedor, porque esse valor pode afetar a largura de banda e o desempenho do streaming do item em reprodução.
Por padrão, o pré-carregamento funciona para conteúdo de streaming HLS, DASH e Smooth.
Arquivos de vídeo e áudio MP4 comuns, como MP3, não serão pré-carregados como Google Cast oferecem suporte a apenas um elemento de mídia e não podem ser usados para pré-carregamento enquanto um o item de conteúdo existente ainda está sendo reproduzido.
Mensagens personalizadas
A troca de mensagens é o principal método de interação para aplicativos receptores da Web.
Um remetente emite mensagens para um receptor da Web usando as APIs de remetente para o
plataforma executada pelo remetente (Android, iOS, Web). O objeto de evento (que
é a manifestação de uma mensagem) que é passada aos listeners do evento tem uma
elemento de dados (event.data
) em que os dados assumem as propriedades do
um tipo de evento específico.
Um aplicativo receptor da Web pode optar por detectar mensagens em um . Em virtude disso, dizem que o aplicativo receptor da Web dão suporte a esse protocolo de namespace. Dessa forma, os remetentes conectados decidem se comunicar nesse namespace para usar o protocolo apropriado.
Todos os namespaces são definidos por uma string e precisam começar com "urn:x-cast:
"
seguida por qualquer string. Por exemplo:
"urn:x-cast:com.example.cast.mynamespace
".
Este é um snippet de código para o receptor da Web ouvir mensagens personalizadas do remetentes conectados:
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();
Da mesma forma, os aplicativos receptores da Web podem manter os remetentes informados sobre o estado
do receptor da Web ao enviar mensagens para remetentes conectados. Um receptor da Web
aplicativo pode enviar mensagens usando
sendCustomMessage(namespace, senderId, message)
ativado
CastReceiverContext
Um receptor da Web pode enviar mensagens para um remetente individual, seja em resposta a
devido a uma mudança no estado do aplicativo ou a uma mensagem recebida. Além de ponto a ponto
mensagens (com um limite de 64 kb), um receptor da web também pode transmitir mensagens para
todos os remetentes conectados.
Transmissão para dispositivos de áudio
Consulte o guia do Google Cast para dispositivos de áudio para receber suporte relacionado a áudio. somente reprodução.
Android TV
Esta seção discute como o Google Web Receiver usa suas entradas como reprodução, e compatibilidade com Android TV.
Como integrar seu aplicativo com o controle remoto
O Google Web Receiver em execução no dispositivo Android TV converte a entrada de
as entradas de controle do dispositivo (por exemplo, controle remoto portátil) como a reprodução de mídia
definidas para o namespace urn:x-cast:com.google.cast.media
, conforme
descritas em Mensagens de reprodução de mídia. Seu
aplicativo deve suportar essas mensagens para controlar a mídia do aplicativo
a reprodução para permitir o controle básico de reprodução pelo Android TV.
de entrada.
Diretrizes para compatibilidade do Android TV
Aqui estão algumas recomendações e armadilhas comuns a serem evitadas para garantir se o aplicativo é compatível com o Android TV:
- A string do user agent contém tanto "Android" e "Coverride"; alguns sites podem redirecionar para um site somente para dispositivos móveis porque detectam a "Android" rótulo. Não presuma que "Android" na string do user agent indica um usuário de celular.
- A pilha de mídia do Android pode usar GZIP transparente para buscar dados. Confirme se
seus dados de mídia podem responder a
Accept-Encoding: gzip
. - Os eventos de mídia HTML5 do Android TV podem ser acionados em tempos diferentes dos Chromecast, isso pode revelar problemas que estavam ocultos no dispositivo.
- Ao atualizar a mídia, use eventos relacionados à mídia disparados por
<audio>/<video>
elementos, comotimeupdate
,pause
ewaiting
. Evite usar redes eventos relacionados comoprogress
,suspend
estalled
, pois eles tendem a ser dependente da plataforma. Consulte Eventos de mídia. para mais informações sobre como lidar com eventos de mídia no seu receiver. - Ao configurar os certificados HTTPS do site receptor, inclua e certificados de AC intermediários. Consulte a página de teste de SSL da Qualsys para verificar: se o caminho de certificação confiável do seu site inclui uma AC certificado com o rótulo "download extra", talvez ele não carregue em dispositivos plataformas.
- Enquanto o Chromecast exibe a página receptora em um plano gráfico de 720p, outros As plataformas de transmissão, incluindo o Android TV, podem exibir a página em até 1080p. Garanta a página receptora é dimensionada corretamente em diferentes resoluções.