Adicionar recursos avançados ao app de remetente da Web

Intervalos de anúncio

O SDK do remetente da Web oferece suporte a intervalos de anúncios e anúncios complementares em um determinado stream de mídia.

Consulte a Visão geral das pausas de anúncios do Web Receiver para mais informações sobre como elas funcionam.

Embora as pausas possam ser especificadas no transmissor e no receptor, é recomendável que elas sejam especificadas no Receptor da Web e no Receptor do Android TV para manter o comportamento consistente em todas as plataformas.

Na Web, especifique os intervalos de anúncios em um comando de carregamento usando BreakClip e Break:

let breakClip1 = new BreakClip('bc0');
breakClip1.title = 'Clip title'
breakClip1.posterUrl = 'https://www.some.url';
breakClip1.duration = 60;
breakClip.whenSKippable = 5;

let breakClip2 = ...
let breakClip3 = ...

let break1 = new Break('b0', ['bc0', 'bc1', 'bc2'], 10);

let mediaInfo = new chrome.cast.media.MediaInfo(<contentId>, '<contentType');
...
mediaInfo.breakClips = [breakClip1, breakClip2, breakClip3];
mediaInfo.breaks = [break1];

let request = new chrome.cast.media.LoadRequest(mediaInfo);

cast.framework.CastContext.getInstance().getCurrentSession().loadMedia(request)

Como usar as APIs de faixas

Uma faixa pode ser um objeto de texto (legenda ou legenda descritiva) ou um objeto de stream de áudio ou vídeo. As APIs Tracks permitem trabalhar com esses objetos no seu app.

Um objeto Track representa uma faixa no SDK. É possível configurar uma faixa e atribuir um ID exclusivo a ela assim:

var englishSubtitle = new chrome.cast.media.Track(1, // track ID
  chrome.cast.media.TrackType.TEXT);
englishSubtitle.trackContentId = 'https://some-url/caption_en.vtt';
englishSubtitle.trackContentType = 'text/vtt';
englishSubtitle.subtype = chrome.cast.media.TextTrackType.SUBTITLES;
englishSubtitle.name = 'English Subtitles';
englishSubtitle.language = 'en-US';
englishSubtitle.customData = null;

var frenchSubtitle = new chrome.cast.media.Track(2, // track ID
  chrome.cast.media.TrackType.TEXT);
frenchSubtitle.trackContentId = 'https://some-url/caption_fr.vtt';
frenchSubtitle.trackContentType = 'text/vtt';
frenchSubtitle.subtype = chrome.cast.media.TextTrackType.SUBTITLES;
frenchSubtitle.name = 'French Subtitles';
frenchSubtitle.language = 'fr';
frenchSubtitle.customData = null;

var frenchAudio = new chrome.cast.media.Track(3, // track ID
  chrome.cast.media.TrackType.AUDIO);
frenchAudio.trackContentId = 'trk0001';
frenchAudio.trackContentType = 'audio/mp3';
frenchAudio.subtype = null;
frenchAudio.name = 'French Audio';
frenchAudio.language = 'fr';
frenchAudio.customData = null;

Um item de mídia pode ter várias faixas. Por exemplo, pode ter vários legendas (cada um para um idioma diferente) ou vários streams de áudio alternativos (para idiomas diferentes).

MediaInfo é a classe que modela um item de mídia. Para associar uma coleção de objetos Track a um item de mídia, atualize a propriedade tracks dele. Essa associação precisa ser feita antes que a mídia seja carregada para o receptor:

var tracks = [englishSubtitle, frenchSubtitle, frenchAudio];
var mediaInfo = new chrome.cast.media.MediaInfo(mediaURL);
mediaInfo.contentType = 'video/mp4';
mediaInfo.metadata = new chrome.cast.media.GenericMediaMetadata();
mediaInfo.customData = null;
mediaInfo.streamType = chrome.cast.media.StreamType.BUFFERED;
mediaInfo.textTrackStyle = new chrome.cast.media.TextTrackStyle();
mediaInfo.duration = null;
mediaInfo.tracks = tracks;

É possível definir as faixas ativas na solicitação activeTrackIds de mídia.

Também é possível ativar uma ou mais faixas associadas ao item de mídia depois que a mídia for carregada, chamando EditTracksInfoRequest(opt_activeTrackIds, opt_textTrackStyle) e transmitindo os IDs das faixas a serem ativadas em opt_activeTrackIds. Os dois parâmetros são opcionais, e você pode escolher quais faixas ou estilos ativos definir. Por exemplo, veja como ativar as legendas em francês (2) e o áudio em francês (3):

var activeTrackIds = [2, 3];
var tracksInfoRequest = new chrome.cast.media.EditTracksInfoRequest(activeTrackIds);
media.editTracksInfo(tracksInfoRequest, successCallback, errorCallback);

Para remover todas as faixas de áudio ou vídeo da mídia atual, defina mediaInfo.tracks=null (uma matriz vazia) e recarregue a mídia.

Para remover todas as faixas de texto da mídia atual (por exemplo, desativando legendas), faça o seguinte:

  • Atualize var activeTrackIds = [2, 3]; (mostrado anteriormente) para que inclua apenas [3], a faixa de áudio.
  • Defina mediaInfo.tracks=null. Não é necessário recarregar a mídia para desativar as legendas de texto (track.hidden). O envio de uma matriz activeTracksId que não contém um trackId ativado desativa a faixa de texto.

Como definir o estilo das faixas de texto

TextTrackStyle é o objeto que encapsula as informações de estilo de uma faixa de texto. Depois de criar ou atualizar um objeto TextTrackStyle, você pode aplicá-lo ao item de mídia em reprodução chamando o método editTrackInfo, como este:

var textTrackStyle = new chrome.cast.media.TextTrackStyle();
var tracksInfoRequest = new chrome.cast.media.EditTracksInfoRequest(textTrackStyle);
media.editTracksInfo(tracksInfoRequest, successCallback, errorCallback);

É possível acompanhar o status da solicitação com o resultado dos callbacks, sucesso ou erro, e atualizar o remetente de origem de acordo com isso.

Os aplicativos precisam permitir que os usuários atualizem o estilo das faixas de texto, usando as configurações fornecidas pelo sistema ou pelo próprio aplicativo.

É possível estilizar os seguintes elementos de estilo de legenda:

  • Cor e opacidade do primeiro plano (texto)
  • Cor e opacidade de segundo plano
  • Tipo de borda
  • Cor da borda
  • Escala da fonte
  • Família de fontes
  • Estilo da fonte

Por exemplo, defina a cor do texto como vermelho com 75% de opacidade da seguinte maneira:

var textTrackStyle = new chrome.cast.media.TextTrackStyle();
textTrackStyle.foregroundColor = '#80FF0000';

Controle do volume

É possível usar RemotePlayer e RemotePlayerController para definir o volume do receptor.

function changeVolume(newVolume) {
  player.volumeLevel = newVolume;
  playerController.setVolumeLevel();
  // Update sender UI to reflect change
}

O app de envio precisa seguir as seguintes diretrizes para controlar o volume:

  • O aplicativo do remetente precisa ser sincronizado com o receptor para que a IU do remetente sempre informe o volume por receptor. Use o callback RemotePlayerEventType.VOLUME_LEVEL_CHANGED e RemotePlayerEventType.IS_MUTED_CHANGED para manter o volume no remetente. Consulte Atualizações de status para mais informações.
  • Os apps de envio não podem definir o nível de volume em um nível específico ou definir o nível de volume para o volume de toque/mídia do dispositivo de envio quando o app é carregado no receptor.

Consulte Controles de volume do remetente na Lista de verificação de design.

Como enviar mensagens de mídia para o destinatário

O Media Messages pode ser enviado pelo remetente ao receptor. Por exemplo, para enviar uma mensagem SKIP_AD ao destinatário:

// Get a handle to the skip button element
const skipButton = document.getElementById('skip');
skipButton.addEventListener("click", function() {
  if (castSession) {
    const media = castSession.getMediaSession();
    castSession.sendMessage('urn:x-cast:com.google.cast.media', {
      type: 'SKIP_AD',
      requestId: 1,
      mediaSessionId: media.mediaSessionId
    });
  }
});

atualizações de status

Quando vários remetentes estão conectados ao mesmo receptor, é importante que cada remetente esteja ciente das mudanças no receptor, mesmo que essas mudanças tenha sido iniciadas por outros remetentes.

Para isso, o aplicativo precisa registrar todos os listeners necessários no RemotePlayerController. Se o TextTrackStyle da mídia atual mudar, todos os remetentes conectados serão notificados e as propriedades correspondentes da sessão de mídia atual, como activeTrackIds e textTrackStyle do campo MediaInfo, serão enviadas aos remetentes em callbacks. Nesse caso, o SDK do receptor não verifica se o novo estilo é diferente do anterior e notifica todos os remetentes conectados.

Indicador de progresso

Mostrar o local de reprodução com um indicador de progresso no remetente é um requisito para a maioria dos apps. As APIs Cast usam o protocolo de mídia Cast, que otimiza o consumo de largura de banda para esse e outros cenários, para que você não precise implementar sua própria sincronização de status. Para a implementação adequada de um indicador de progresso para a reprodução de mídia usando as APIs, consulte o app de exemplo CastVideos-chrome.

Requisitos do CORS

Para streaming de mídia adaptativa, o Google Cast exige a presença de cabeçalhos CORS, mas até mesmo transmissões de mídia mp4 simples exigem CORS se incluírem faixas. Se você quer ativar as faixas para qualquer mídia, ative o CORS para os fluxos de faixas e de mídia. Portanto, se você não tiver cabeçalhos CORS disponíveis para a mídia mp4 simples no servidor e adicionar uma faixa de legenda simples, não será possível transmitir a mídia, a menos que você atualize o servidor para incluir os cabeçalhos CORS apropriados.

Você precisa dos seguintes cabeçalhos: Content-Type, Accept-Encoding e Range. Os dois últimos cabeçalhos, Accept-Encoding e Range, são cabeçalhos adicionais que você talvez não tenha usado antes.

Os caracteres curinga "*" não podem ser usados para o cabeçalho Access-Control-Allow-Origin. Se a página tiver conteúdo de mídia protegido, ela precisará usar um domínio em vez de um coringa.

Retomar uma sessão sem atualizar a página da Web

Para retomar um CastSession existente, use requestSessionById(sessionId) com o sessionId da sessão que você está tentando entrar.

O sessionId pode ser encontrado no CastSession ativo usando getSessionId() depois de chamar loadMedia().

A abordagem recomendada é:

  1. Chame loadMedia() para iniciar a sessão.
  2. Armazenar o sessionId localmente
  3. Volte para a sessão usando requestSessionById(sessionId) quando necessário.
let sessionId;

function rejoinCastSession() {
  chrome.cast.requestSessionById(sessionId);

  // Add any business logic to load new content or only resume the session
}

document.getElementById('play-button').addEventListener(("click"), function() {
  if (sessionId == null) {
    let castSession = cast.framework.CastContext.getInstance().getCurrentSession();
    if (castSession) {
      let mediaInfo = createMediaInfo();
      let request = new chrome.cast.media.LoadRequest(mediaInfo);
      castSession.loadMedia(request)

      sessionId = CastSession.getSessionId();
    } else {
      console.log("Error: Attempting to play media without a Cast Session");
    }
  } else {
    rejoinCastSession();
  }
});

Próximas etapas

Isso conclui os recursos que você pode adicionar ao seu app de envio da Web. Agora você pode criar um app de envio para outra plataforma (Android ou iOS) ou criar um app receptor.