Adicionar recursos principais ao receptor da Web personalizado

Esta página contém snippets de código e descrições dos recursos disponíveis para um app receptor da Web personalizado

  1. Um elemento cast-media-player que representa a interface integrada do player fornecidos com o receptor da Web.
  2. Estilo personalizado semelhante a CSS para o elemento cast-media-player a fim de estilizar vários Elementos da interface, como background-image, splash-image e font-family.
  3. Um elemento de script para carregar o framework do receptor da Web.
  4. Código JavaScript para interceptar mensagens e processar eventos.
  5. Fila para reprodução automática.
  6. Opções para configurar a reprodução.
  7. Opções para definir o contexto do receptor da Web.
  8. Opções para definir comandos compatíveis com o app Web Receiver.
  9. 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 o CastReceiverContext.
  • 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 para getPlaybackConfig(). 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 de contentUrl 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 em contentUrl.

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:

  1. Usando PlayerManager.setSupportedMediaCommands para definir Commands
  2. Adicionar um novo comando usando addSupportedMediaCommands
  3. 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 do MediaInformation 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 é:

  1. No dispositivo de origem:
    1. A mídia é interrompida.
    2. O aplicativo receptor da Web recebe um comando para salvar a mídia atual estado.
    3. O aplicativo receptor da Web foi encerrado.
  2. No dispositivo de destino:
    1. O aplicativo receptor da Web está carregado.
    2. O aplicativo receptor da Web recebe um comando para restaurar a mídia salva estado.
    3. 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:

  1. Atualizar supportedMediaCommands pelo comando STREAM_TRANSFER:
    playerManager.addSupportedMediaCommands(
    cast.framework.messages.Command.STREAM_TRANSFER, true);
  2. Opcionalmente, substitua as mensagens SESSION_STATE e RESUME_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, como timeupdate, pause e waiting. Evite usar redes eventos relacionados como progress, suspend e stalled, 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.