Protocolos de streaming do receptor da Web

Atualmente, o SDK do receptor da Web é compatível com três tipos de protocolos de streaming:

DASH, HTTP Live Streaming e Smooth Streaming (links em inglês).

Neste documento, listamos nosso suporte para cada um dos protocolos de streaming. A explicação de tags compatíveis para cada protocolo é muito abreviada em comparação com a especificação detalhada do protocolo. O objetivo é fornecer uma visão rápida e entender como usar cada protocolo e quais recursos do protocolo são compatíveis com dispositivos compatíveis com Cast para fornecer as experiências de streaming deles.

Streaming adaptativo dinâmico por HTTP (DASH)

A especificação detalhada do DASH (link em inglês) da ISO.

O DASH é um protocolo de streaming de taxa de bits adaptável que permite streaming de vídeo de alta qualidade por servidores HTTP(S). Um manifesto, composto em XML, contém a maioria das informações de metadados sobre como inicializar e fazer o download do conteúdo de vídeo. Os principais conceitos aceitos pelo Web Receiver Player são <Period>, <AdaptationSet>, <Representation>, <SegmentTemplate>, <SegmentList>, <BaseUrl> e <ContentProtection>.

Um manifesto DASH começa com uma tag <MPD> raiz. Já o interior inclui uma ou mais tags <Period>, que representam um conteúdo de streaming. As tags <Period> permitem ordenar diferentes tipos de conteúdo de streaming e costumam ser usadas para separar o conteúdo principal e o anúncio ou vários conteúdos de vídeo consecutivos.

Um <AdaptationSet> em <MPD> é um conjunto de representações para um tipo de stream de mídia, na maioria dos casos, vídeo, áudio ou legendas. Os tipos MIME mais comumente suportados são "video/mp4", "audio/mp4" e "text/vtt". Um <ContentComponent contentType="$TYPE$"> opcional pode ser incluído em <AdaptationSet>.

Dentro de cada <AdaptationSet>, uma lista de tags <Representation> precisa estar presente, e o Web Receiver Player usa as informações de codecs para inicializar o buffer de origem da MSE e as informações de bandwidth para escolher automaticamente a representação/taxa de bits correta a ser reproduzida.

Para cada <Representation>, os segmentos de mídia são descritos usando um <BaseURL> para representação de segmento único, <SegmentList> para lista de segmentos (semelhante a HLS) ou <SegmentTemplate>.

Para um <SegmentTemplate>, indica como o segmento de inicialização e os segmentos de mídia podem ser representados por modelos. No exemplo abaixo, $Number$ indica o número do segmento conforme disponível na CDN. Isso se traduz em seg1.m4s, seg2.m4s etc. à medida que a reprodução continua.

<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" xmlns:ns2="http://www.w3.org/1999/xlink"
  profiles="urn:mpeg:dash:profile:isoff-live:2011,http://dashif.org/guidelines/dash264" type="static"
  publishTime="2016-10-05T22:07:14.859Z" mediaPresentationDuration="P1DT0H0M0.000S" minBufferTime="P0DT0H0M7.500S">
  <Period id="P0">
    <AdaptationSet lang="en" segmentAlignment="true">
      <ContentComponent id="1" contentType="audio"/>
      <SegmentTemplate media="seg$Number$.m4s" initialization="seginit.mp4"
        duration="10000" startNumber="1" timescale="1000" presentationTimeOffset="0"/>
      <Representation id="1" bandwidth="150123" audioSamplingRate="44100"
        mimeType="audio/mp4" codecs="mp4a.40.2" startWithSAP="1">
        <AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
        <BaseURL>http://www.google.com/testVideo</BaseURL>
      </Representation>
    </AdaptationSet>
    <AdaptationSet segmentAlignment="true">
      <ContentComponent id="1" contentType="video"/>
      <SegmentTemplate media="seg$Number$.m4s" initialization="seginit.mp4"
        duration="10000" startNumber="1" timescale="1000" presentationTimeOffset="0"/>
      <Representation id="1" bandwidth="212191" width="384" height="208" sar="26:27"
        frameRate="25" mimeType="video/mp4" codecs="avc1.42c01f" startWithSAP="1">
        <BaseURL>http://www.google.com/testVideo/bitrate1/</BaseURL>
      </Representation>
      <Representation id="1" bandwidth="366954" width="512" height="288" sar="1:1"
        frameRate="25" mimeType="video/mp4" codecs="avc1.42c01f" startWithSAP="1">
        <BaseURL>http://www.google.com/testVideo/bitrate2/</BaseURL>
      </Representation>
      <Representation id="1" bandwidth="673914" width="640" height="352" sar="44:45"
        frameRate="25" mimeType="video/mp4" codecs="avc1.42c01f" startWithSAP="1">
        <BaseURL>http://www.google.com/testVideo/bitrate3/</BaseURL>
      </Representation>
    </AdaptationSet>
  </Period>
</MPD>

Para um <SegmentTemplate>, é comum usar a tag <SegmentTimeline> para indicar quanto tempo cada segmento tem e que se repetem. Um timescale (unidades para representar um segundo) geralmente é incluído como parte dos atributos de <SegmentTemplate> para que possamos calcular o tempo do segmento com base nessa unidade. No exemplo abaixo, a tag <S> indica uma tag de segmento, o atributo d especifica quanto tempo o segmento tem, e o atributo r especifica quantos segmentos com a mesma duração são repetidos para que $Time$ seja calculado corretamente para fazer o download do segmento de mídia conforme especificado no atributo media.

<SegmentTemplate>
  timescale="48000"
  initialization="$RepresentationID$-init.dash"
  media="$RepresentationID$-$Time$.dash"
    startNumber="1">
    <SegmentTimeline>
      <S t="0" d="96256" r="2" />
      <S d="95232" />
      <S d="96256" r="2" />
      <S d="95232" />
      <S d="96256" r="2" />
   </SegmentTimeline>
</SegmentTemplate>

Para representação usando <SegmentList>, veja um exemplo:

<Representation id="FirstRep" bandwidth="2000000" width="1280"
  height="720">
  <BaseURL>FirstRep/</BaseURL>
  <SegmentList timescale="90000" duration="270000">
     <RepresentationIndex sourceURL="representation-index.sidx"/>
     <SegmentURL media="seg-1.ts"/>
     <SegmentURL media="seg-2.ts"/>
     <SegmentURL media="seg-3.ts"/>
  </SegmentList>
</Representation>

Para um único arquivo de segmento, um <SegmentBase> geralmente é usado com solicitações de intervalo de bytes para especificar qual parte de um arquivo <BaseURL> contém o índice, e o restante pode ser buscado sob demanda à medida que a reprodução continua ou uma busca ocorre. Aqui, o intervalo Initialization especifica o intervalo de metadados init e o indexRange especifica o índice dos segmentos de mídia. No momento, só há suporte para intervalos de bytes consecutivos.

<Representation bandwidth="4190760" codecs="avc1.640028"
  height="1080" id="1" mimeType="video/mp4" width="1920">
  <BaseURL>video.mp4<BaseURL>
  <SegmentBase indexRange="674-1149">
    <Initialization range="0-673" />
  </SegmentBase>
</Representation>

Independentemente da representação usada, se os streams estiverem protegidos, uma seção <ContentProtection> poderá aparecer em <AdaptationSet>, em que um schemeIdUri identifica exclusivamente o sistema DRM a ser usado. Um ID de chave opcional pode ser incluído para criptografia comum.

<!-- Common Encryption -->
<ContentProtection
  schemeIdUri="urn:mpeg:dash:mp4protection:2011"
  value="cenc"
  cenc:default_KID="7D2714D0-552D-41F5-AD56-8DD9592FF891">
</ContentProtection>

<!-- Widevine -->
<ContentProtection
  schemeIdUri="urn:uuid:EDEF8BA9-79D6-4ACE-A3C8-27DCD51D21ED">
</ContentProtection>

Para mais exemplos e detalhes, consulte a especificação de MPEG-DASH. Veja abaixo uma lista de atributos adicionais de DASH em tags não mencionadas acima:

Nome do atributo Função de atributos
Duração da apresentação de mídia O tempo do conteúdo de vídeo.
Período de atualização mínimo Atributo da tag <MPD>. Especifica com que frequência precisamos recarregar o manifesto.
tipo Atributo da tag <MPD>. É "dinâmico" para indicar que esta é uma transmissão ao vivo.
CompensaçãoTimeTime Atributo da tag <SegmentBase>. Especifica o deslocamento de tempo da apresentação desde o início do período.
Número de início Especifica o número do primeiro segmento de mídia em uma apresentação em um período. Isso é muito usado em transmissões ao vivo.

Também é possível reconhecer a caixa EMSG dentro de fragmentos MP4 para DASH e fornecer um EmsgEvent para desenvolvedores.

Embora nosso player do receptor da Web atual ofereça suporte aos principais casos de uso do DASH, esta é uma lista de atributos comuns que nossa implementação atual do DASH ignora ou não usa. Isso significa que, independentemente do manifesto, não haverá impacto na experiência de reprodução do conteúdo.

  • disponibilidadeInício
  • Alinhamento de segmentos

HTTP Live Streaming (HLS)

A visão geral e a especificação completa da transmissão ao vivo HTTP podem ser encontradas aqui.

Um dos pontos fortes do Web Receiver Player é a capacidade de oferecer suporte à reprodução de HLS no MSE. Ao contrário do DASH, em que um manifesto vem em um único arquivo, o HLS envia a playlist principal que contém uma lista de todos os streams de variantes com o respectivo URL. A playlist variante é a playlist de mídia. As duas principais tags HLS atualmente compatíveis com o player de receptor da Web na playlist principal são:

Nome da tag Funcionalidade
#EXT-X-STREAM-INF Especifica um stream de taxa/taxa de bits. O atributo BANDWIDTH é necessário e é compatível com a seleção de streaming com taxa de bits adaptável. O atributo CODECS é altamente recomendado para inicializar o MSE, como "avc1.42c01e,mp4a.40.2". Se não for especificado, o caso padrão será definido para o vídeo do perfil principal 3.0 H264 e o conteúdo codificado por áudio "mp4a.40.2".
#EXT-X-MEDIA Especifica mais uma playlist de mídia (no atributo URI) que representa o conteúdo. Normalmente são streamings de áudio alternativos em outro formato (som surround 5.1) ou idioma. Um atributo de TYPE contendo VIDEO, AUDIO, SUBTITLES ou CLOSED-CAPTIONS é permitido. Definir o atributo DEFAULT como YES indica que você vai escolher esse fluxo alternativo por padrão.

Veja uma lista de tags HLS atualmente compatíveis com o player de receptor da Web na playlist de mídia:

Nome da tag Funcionalidade
#EXTINF Informações de stream, geralmente seguidas pela duração do segmento em segundos e, na próxima linha, o URL do segmento.
#EXT-X-TARGETDURATION Quanto tempo em segundos cada segmento é. Isso também determina com que frequência fazemos o download/atualização do manifesto da playlist para uma transmissão ao vivo. O Web Receiver Player não oferece suporte para durações menores que 0,1 s.
#EXT-X-MEDIA-SEQUENCE O número sequencial (geralmente para uma transmissão ao vivo) que o primeiro segmento desta playlist representa.
#EXT-X-KEY Informações da chave DRM. O atributo METHOD indica qual sistema de chaves usar. Atualmente, aceitamos AES-128 e SAMPLE-AES.
#EXT-X-BYTERANGE O intervalo de bytes a ser buscado para um URL de segmento.
#EXT-X-DESCONTINUAÇÃO Especifica uma descontinuidade entre segmentos consecutivos. Isso geralmente é visto com a inserção de anúncios do lado do servidor, em que um segmento aparece no meio do fluxo principal.
#EXT-X-PROGRAMA-DATA-HORA Tempo absoluto da primeira amostra do próximo segmento, por exemplo, "2016-09-21T23:23:52.066Z".
#EXT-X-ENDLIST Se é um VOD ou transmissão ao vivo.

Para transmissão ao vivo, usamos #EXT-X-PROGRAM-DATE-TIME e #EXT-X-MEDIA-SEQUENCE como os principais fatores para determinar como mesclar um manifesto recém-atualizado. Se presente, o #EXT-X-PROGRAM-DATE-TIME é usado para corresponder aos segmentos atualizados. Caso contrário, o número #EXT-X-MEDIA-SEQUENCE será usado. Observe que, de acordo com a especificação HLS, não usamos a comparação de nomes de arquivo para correspondência.

Nossa implementação de HLS é compatível com a seleção de um stream de áudio alternativo, como o som surround 5.1, como a reprodução de áudio principal. Para isso, use uma tag #EXT-X-MEDIA com os codecs alternativos e forneça o formato do segmento na configuração do stream.

O player de receptor da Web espera determinado comportamento por especificação. Por exemplo, depois de uma tag #EXT-INF, esperamos um URI. Se não for um URI, por exemplo, uma #EXT-X-DISCOUNTINUITY vai causar uma falha na análise da playlist.

A cada #EXT-X-TARGETDURATION segundos, recarregamos a playlist/manifesto para receber novas listas de segmentos e atualizamos a nova representação interna de todos os segmentos para o novo. Sempre que uma busca é solicitada, buscamos apenas dentro do intervalo pesquisável. Para transmissões ao vivo, permitimos a busca do início da lista mais recente até a duração de três destinos. Por exemplo, se você tiver uma lista de 10 segmentos e estiver no segmento 6, só poderá buscar até 7, mas não 8.

Compatibilidade com o formato do segmento

O SDK do CAF é compatível com a reprodução de conteúdo enviado em vários formatos, conforme mencionado em HlsSegmentFormat para áudio e HlsVideoSegmentFormat para vídeo. Isso inclui compatibilidade com áudio em pacote, como reprodução AAC e AC3, criptografadas e não criptografadas. É necessário especificar essas informações no MediaInformation do LoadRequestData para descrever corretamente seu conteúdo para o player. Se não for especificado, a configuração padrão do player vai tentar reproduzir o conteúdo como um conteúdo empacotado do Transport Stream. Essa propriedade pode ser definida de qualquer um dos remetentes nos dados de solicitação de carregamento (Android, iOS e Web) ou dentro do receptor por interceptadores de mensagens.

Confira o snippet de código de exemplo abaixo ou o guia Como carregar mídia usando contentId, contentUrl e entity para mais informações sobre como preparar conteúdo no receptor da Web.

playerManager.setMessageInterceptor(
    cast.framework.messages.MessageType.LOAD, loadRequestData => {
      ...
      // Specify segment format for an HLS stream playing CMAF packaged content.
      loadRequestData.media.contentType = 'application/x-mpegurl';
      loadRequestData.media.hlsSegmentFormat = cast.framework.messages.HlsSegmentFormat.FMP4;
      loadRequestData.media.hlsVideoSegmentFormat = cast.framework.messages.HlsVideoSegmentFormat.FMP4;
      ...
      return loadRequestData;
    });

Proteção de conteúdo

Conforme listado na seção da tag #EXT-X-KEY acima, o SDK do Google Cast é compatível com SAMPLE-AES ou SAMPLE-AES-CTR, em que um URI da chave de um vetor de inicialização pode ser especificado:

EXT-X-KEY: METHOD=SAMPLE-AES, \
URI="data:text/plain;base64,XXXXXX", \
IV=0x6df49213a781e338628d0e9c812d328e, \
KEYFORMAT="com.widevine", \
KEYFORMATVERSIONS="1"

O KEYFORMAT que aceitamos agora é o Widevine, e o URI contém uma informações de DRM codificada em Base64 XXXXXXX que, quando decodificada, contém o ID da chave:

{
   "content_id": "MTQ1NjkzNzM1NDgxNA==",
   "key_ids": [
      "xxxxxxxxxxxxxxxx"
   ]
}

A versão 1 define os seguintes atributos:

Atributo Exemplo Descrição
KEYFORMATVERSIONS "1" Esta proposta define a versão 1 do formato da chave
KEYFORMAT "urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed" O UUID é o UUID Widevine do DASH IF IOP. A mesma string exata é usada na MPD com streams criptografados Widevine.
URI "data:text/plain;base64, <base64 encoded PSSH box>" URI do stream que contém o tipo de dados e a caixa PSSH.
METHOD SAMPLE-AES-CTR Indica a criptografia usada ao criptografar o conteúdo. SAMPLE-AES sinaliza que o conteúdo é criptografado usando "cbcs", enquanto SAMPLE-AES-CTR sinaliza que o conteúdo é criptografado usando um dos esquemas de proteção AES-CTR, ou seja, "cenc".

Atributos mapeados para a MPD DASH:

Atributo Descrição
KEYFORMAT Atributo do schemaIdUri do elemento ContentProtection.
URI O conteúdo do elemento cenc:pssh.
KEYID String hexadecimal de 16 bytes que codifica o ID da chave, que tem o mesmo papel que o default_kid no MPEG DASH. Se estiver usando um esquema de chave hierárquica, essa seria a chave "raiz".

Exemplo de playlist HLS com sinalização V2:

#EXTM3U
#EXT-X-VERSION:6
#EXT-X-TARGETDURATION:2
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-MAP:URI="init_segment.mp4"
#EXTINF:1.001,
output_video-1.mp4
#EXT-X-DISCONTINUITY
#EXT-X-KEY:METHOD=SAMPLE-AES,URI="data:text/plain;base64,AAAAPXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAB0aDXdpZGV2aW5lX3Rlc3QiDHRlc3QgY29udGVudA==",KEYID=0x112233445566778899001122334455,KEYFORMAT="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed",KEYFORMATVERSION="1"
#EXTINF:1.001,
output_video-2.mp4
#EXTINF:0.734,
output_video-3.mp4
#EXT-X-ENDLIST

Veja abaixo uma lista de recursos e tags em HLS que não usamos nem oferecemos suporte no momento. A presença ou ausência delas não afeta o comportamento de streaming.

  • O atributo RESOLUTION= em #EXT-X-STREAM-INF é ignorado.
  • O atributo AUTOSELECT= em #EXT-X-MEDIA não é usado. Em vez disso, confiamos em DEFAULT=.
  • #EXT-X-I-FRAME-STREAM-INF na playlist principal é ignorado.
  • #EXT-X-DISCONTINUITY-SEQUENCE foi ignorado
  • #EXT-X-PLAYLIST-TYPE:EVENT pode estar presente em uma transmissão ao vivo, e #EXT-X-PLAYLIST-TYPE:VOD pode estar presente em uma transmissão de VOD, mas atualmente nosso Web Receiver Player depende apenas da existência de #EXT-X-ENDLIST para determinar o VOD ao vivo.

Streaming suave

A especificação Smooth Streaming oficial da Microsoft

O Smooth Streaming fornece um protocolo de streaming adaptável e especificação de XML sobre HTTP (semelhante ao DASH). Ao contrário do DASH, o Smooth Streaming recomenda apenas o empacotamento MPEG-4 para os segmentos de mídia.

Esta é uma tabela das tags e dos atributos mais comuns no Smooth Streaming que oferece suporte ao player de receptor da Web atualmente. Muitos conceitos já foram explicados na seção DASH acima.

Tag/atributo Uso
<SmoothStreamingMedia>. Tag principal do manifesto, contém atributos de:
  • TimeScale: número de unidades que representam um segundo, normalmente um aumento de 10.000.000.
  • Duração: duração do conteúdo em escala de tempo. O Web Receiver Player não é compatível com durações menores que 0,1 s.
  • IsLive: se o manifesto é uma mídia ativa.
<StreamIndex> Um conjunto de streams, semelhante ao AdaptationSet do DASH. O tipo geralmente é "texto", "vídeo" ou "áudio". O atributo de URL geralmente contém um URL de fragmento modelado que usa informações como taxa de bits ou horário de início.
<QualityLevel> Cada tag QualityLevel especifica a taxa de bits e um codec FourCC. O código FourCC geralmente é "H264", "AVC1", "AACL" etc. Para vídeo, ele especifica suas resoluções por meio de MaxWidth e MaxHeight. Para áudio, ele especifica a frequência (como 44100) por meio da SampleRate e número de canais.
<c> Elemento Stream Fragment. Contém:
  • d: duração de um fragmento.
  • t: Tempo de mídia do fragmento.
<Proteção> Uma tag com o atributo opcional SystemID listando o ID do DRM do sistema a ser usado na tag <SmoothStreamingMedia>.
<ProtectionHeader> Em <Protection>, pode conter um atributo de SystemID e dados personalizados, geralmente codificados em Base64. No caso do Widevine, ele conterá o ID da chave, o comprimento da chave, o ID do algoritmo, como AESCTR, LA_URL (URL de aquisição de licença), LUI_URL (URL da interface do usuário de licença) e DS_ID (ID de serviço do domínio).

Proteção de conteúdo

Para codificar os IDs dos sistemas de proteção corretamente, use o mapeamento abaixo:

  • WIDEVINE: 'EDEF8BA9-79D6-4ACE-A3C8-27DCD51D21ED',
  • CLEANKEY: '1077EFEC-C0B2-4D02-ACE3-3C1E52E2FB4B',
  • MPEG_DASH_MP4PROTECTION: 'URN:MPEG:DASH:MP4PROTECTION:2011'

Para <ProtectionHeader>, veja abaixo um exemplo com dados codificados em Base64. Os dados, quando decodificados, estão em conformidade com o mesmo formato decodificado, conforme descrito no suporte à proteção de conteúdo do DASH acima.

<Protection>
  <ProtectionHeader SystemID="9a04f079-9840-4286-ab92-e65be0885f95">
    $BASE64ENCODED_DATA
  </ProtectionHeader>
</Protection>

Veja abaixo um exemplo de um manifesto de transmissão suave ao vivo com uma duração de 3.000 segundos de conteúdo:

<?xml version="1.0"?>
  <SmoothStreamingMedia MajorVersion="2" MinorVersion="0" Duration="3000000000"
    TimeScale="10000000" IsLive="TRUE" LookAheadFragmentCount="2" DVRWindowLength="600000000" CanSeek="TRUE" CanPause="TRUE">
    <StreamIndex Type="text" Name="textstream301_swe" Language="swe" Subtype="CAPT" Chunks="0"
      TimeScale="10000000" Url="QualityLevels({bitrate})/Fragments(textstream301_swe={start time})">
      <QualityLevel Index="0" Bitrate="20000" CodecPrivateData="" FourCC="DFXP"/>
        <c d="40000000" t="80649382288125"/>
        <c d="39980000"/>
        <c d="40020000"/>
    </StreamIndex>
    <Protection>
      <ProtectionHeader> SystemID="$BASE64ENCODEDDRMDATA$"</ProtectionHeader>
    </Protection>
    <StreamIndex Type="audio" Name="audio101_eng" Language="eng" Subtype="AACL" Chunks="0"
      TimeScale="10000000" Url="QualityLevels({bitrate})/Fragments(audio101_eng={start time})">
      <QualityLevel Index="0" Bitrate="128000" CodecPrivateData="1290" FourCC="AACL" AudioTag="255"
        Channels="2" SamplingRate="32000" BitsPerSample="16" PacketSize="4"/>
      <c d="40000000" t="80649401327500"/>
      <c d="40000000"/>
      <c d="40000000"/>
    </StreamIndex>
    <StreamIndex Type="video" Name="video" Subtype="AVC1" Chunks="0" TimeScale="10000000"
      Url="QualityLevels({bitrate})/Fragments(video={start time})">
      <QualityLevel Index="0" Bitrate="400000" CodecPrivateData="000000016742E01596540C0EFCB808140000000168CE3880"
        FourCC="AVC1" MaxWidth="384" MaxHeight="216"/>
      <QualityLevel Index="1" Bitrate="800000" CodecPrivateData="00000001674D401E965281004B6020500000000168EF3880"
        FourCC="AVC1" MaxWidth="512" MaxHeight="288"/>
      <QualityLevel Index="2" Bitrate="1600000" CodecPrivateData="00000001674D401E965281B07BCDE020500000000168EF3880"
        FourCC="AVC1" MaxWidth="854" MaxHeight="480"/>
      <QualityLevel Index="3" Bitrate="2200000" CodecPrivateData="00000001674D401F96528080093602050000000168EF3880"
        FourCC="AVC1" MaxWidth="1024" MaxHeight="576"/>
      <c d="40000000" t="80649401378125"/>
      <c d="40000000"/>
      <c d="40000000"/>
    </StreamIndex>
  </SmoothStreamingMedia>

No exemplo acima para o stream de vídeo, o modelo de URL é:

QualityLevels({bitrate})/Fragments(video={start time})

Portanto, os dois primeiros segmentos, supondo que estejamos no nível de qualidade do índice 2, serão os seguintes, com o tempo inicial extraído de t="80649401378125" no StreamIndex do vídeo e o incremento de tempo de 4 segundos * 1.000.000 por segmento:

QualityLevels(2)/Fragments(video=80649401378125)
QualityLevels(2)/Fragments(video=80649441378125)
...

Veja uma lista de atributos do Smooth Streaming que ignoramos e não influenciam as experiências de streaming, independentemente de serem fornecidas ou não:

  • CanSeek e CanPause na tag <SmoothStreamingMedia>.
  • Chunks, QualityLevels na tag <StreamIndex>. Em vez disso, calculamos o número de segmentos e o número de níveis de qualidade com base em informações fornecidas em <StreamIndex>, como a tag QualityLevel real e as tags <c>.
  • BitsPerSample, PacketSize em <QualityLevel> não é usado.

Verificar o tipo de exibição

O método canDisplayType verifica os recursos de vídeo e áudio do dispositivo Web Receiver e mostra a validação dos parâmetros de mídia transmitidos, retornando um booleano. Todos os parâmetros são opcionais, e quanto mais parâmetros você incluir, mais precisa será a verificação.

A assinatura é canDisplayType(<em>mimeType</em>,<em>codecs</em>,<em>width</em>,<em>height</em>,<em>framerate</em>)

Exemplos:

Verifica se o dispositivo receptor e a tela da Web são compatíveis com o tipo de vídeo/mp4 com este codec, dimensões e frame rate específicos:

canDisplayType("video/mp4", "avc1.42e015,mp4a.40.5", 1920, 1080, 30)

Verifica se o dispositivo receptor e a tela da Web são compatíveis com o formato de vídeo em 4K especificando a largura de 3.840 e a altura de 2.160:

canDisplayType("video/mp4", "hev1.1.2.L150", 3840, 2160)

Verifica se o dispositivo receptor e a tela da Web oferecem suporte a HDR10 para este codec, dimensões e frame rate:

canDisplayType("video/mp4", "hev1.2.6.L150", 3840, 2160, 30)

Verifica se o dispositivo receptor e a tela da Web oferecem suporte ao Dolby Vision (DV) para esse codec, dimensões e frame rate:

canDisplayType("video/mp4", "dvhe.04.06", 1920, 1080, 30)

DRM

Observação: um dos principais benefícios de usar o SDK do receptor da Web é que seu app não precisa mais carregar o MPL e processar a reprodução de mídia separadamente, porque o SDK do receptor da Web processa isso para você.

Alguns conteúdos de mídia exigem o Gerenciamento de direitos digitais (DRM, na sigla em inglês). Para conteúdo de mídia que tenha a licença DRM (e o URL da chave) armazenados no manifesto (DASH ou HLS), o SDK do Cast trata esse caso para você. Um subconjunto desse conteúdo requer um licenseUrl, que é necessário para conseguir a chave de descriptografia. No receptor da Web, você pode usar PlaybackConfig para definir o licenseUrl conforme necessário.

O snippet de código a seguir mostra como definir informações sobre solicitações de licença, como withCredentials:

const context = cast.framework.CastReceiverContext.getInstance();
const playbackConfig = new cast.framework.PlaybackConfig();
// Customize the license url for playback
playbackConfig.licenseUrl = 'http://widevine/yourLicenseServer';
playbackConfig.protectionSystem = cast.framework.ContentProtection.WIDEVINE;
playbackConfig.licenseRequestHandler = requestInfo => {
  requestInfo.withCredentials = true;
};
context.start({playbackConfig: playbackConfig});

// Update playback config licenseUrl according to provided value in load request.
context.getPlayerManager().setMediaPlaybackInfoHandler((loadRequest, playbackConfig) => {
  if (loadRequest.media.customData && loadRequest.media.customData.licenseUrl) {
    playbackConfig.licenseUrl = loadRequest.media.customData.licenseUrl;
  }
  return playbackConfig;
});

Se você tiver uma integração do Google Assistente, algumas das informações de DRM, como as credenciais necessárias para o conteúdo, poderão ser vinculadas diretamente à sua Conta do Google por mecanismos como o OAuth/SSO. Nesses casos, se o conteúdo de mídia for carregado por voz ou proveniente da nuvem, um setCredentials será invocado da nuvem para o dispositivo de transmissão que fornece essas credenciais. Aplicativos que gravam um app receptor da Web podem usar as informações de setCredentials para operar o DRM conforme necessário. Veja um exemplo de como usar a credencial para criar a mídia.

Dica: consulte também Como carregar mídia usando contentId, contentUrl e entity.

Gerenciamento do canal de áudio

Quando o player de transmissão carrega mídia, ele configura um único buffer de origem de áudio. Ao mesmo tempo, ele também seleciona um codec apropriado para ser usado pelo buffer, com base no tipo MIME da faixa principal. Um novo buffer e codec são configurados:

  • quando a reprodução é iniciada,
  • em cada intervalo de anúncio
  • sempre que o conteúdo principal for retomado.

Como o buffer usa um único codec e o codec é escolhido com base na faixa principal, há situações em que as faixas secundárias podem ser filtradas e não são ouvidas. Isso pode acontecer quando a faixa principal de um programa está em som surround, mas as faixas de áudio secundárias usam som estéreo. Como as faixas secundárias são usadas com frequência para oferecer conteúdo em idiomas alternativos, fornecer mídia contendo diferentes números de faixas pode ter um impacto significativo, como um grande número de espectadores que não conseguem ouvir conteúdo no idioma nativo.

Os cenários a seguir ilustram por que é importante fornecer programação em que as faixas primária e secundária contêm o mesmo número de canais:

Cenário 1: stream de mídia sem paridade de canal nas faixas primárias e secundárias:

  • Inglês - canal AC-3 5.1 (principal)
  • swedish - 2 canais AAC
  • Francês: 2 canais de AAC
  • alemão - 2 canais AAC

Nesse cenário, se o idioma do jogador estiver definido como algo diferente do inglês, o usuário não vai ouvir a faixa esperada, porque todas as faixas de dois canais são filtradas durante a reprodução. A única faixa que poderia ser reproduzida seria o canal AC-3 5.1 principal e somente quando o idioma estiver definido como inglês.

Cenário 2: streaming de mídia com paridade de canais nas faixas primárias e secundárias:

  • Inglês - canal AC-3 5.1 (principal)
  • sueco - canal AC-3 5.1
  • Francês: canal AC-3 5.1
  • alemão: canal AC-3 5.1

Como todas as faixas desse stream têm o mesmo número de canais, um público-alvo ouvirá uma faixa independente do idioma selecionado.

Tratamento do canal de áudio Shaka

O player kaka (DASH) tem como padrão uma contagem de canais preferencial de dois, como uma medida de mitigação ao encontrar mídia que não tem paridade entre faixas de áudio secundárias.

Se a faixa principal não for o som surround (por exemplo, uma faixa estéreo de dois canais), o player Shaka usará como padrão dois canais e filtrará automaticamente qualquer faixa de mídia secundária que tenha mais de dois canais.

O número preferencial de canais de áudio de Shaka também pode ser configurado configurando o preferredAudioChannelCount na propriedade shakaConfig em cast.framework.PlaybackConfig.

Exemplo:

shakaConfig = { "preferredAudioChannelCount": 6 };

Com o preferredAudioChannelCount definido como 6, o Shaka Player verifica se ele é compatível com os codecs de som surround (AC-3 ou EC-3) e filtra automaticamente qualquer faixa de mídia que não esteja em conformidade com o número preferencial de canais.