Protocolos de streaming do player 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.

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

Streaming adaptável dinâmico sobre HTTP (DASH)

Especificação detalhada de DASH da ISO.

O DASH é um protocolo de streaming com taxa de bits adaptável que permite o streaming de vídeo de alta qualidade por meio de 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 compatíveis com o player receptor da Web são <Period>, <AdaptationSet>, <Representation>, <SegmentTemplate>, <SegmentList>, <BaseUrl> e <ContentProtection>.

Um manifesto DASH começa com uma tag <MPD> raiz e inclui uma ou mais tags <Period>, que representam um conteúdo de streaming. As tags <Period> permitem a ordenação de diferentes partes do conteúdo de streaming e geralmente são 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 com suporte 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 player receptor da Web usa as informações codecs para inicializar o buffer de origem do 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>, ele 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 como disponível na CDN. Portanto, ela é convertida 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 quais segmentos 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 trecho com base nessa unidade. No exemplo abaixo, a tag <S> indica uma tag de segmento. O atributo d especifica a duração do segmento, e o atributo r indica quantos segmentos com a mesma duração se repetem para que $Time$ possa ser calculado corretamente para 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. 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. Observe que, no momento, só oferecemos suporte a 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 forem protegidos, uma seção <ContentProtection> poderá aparecer em <AdaptationSet>, em que um schemeIdUri identifica exclusivamente o sistema DRM a ser usado. É possível incluir um ID de chave opcional 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 MPEG-DASH. Veja abaixo uma lista de outros atributos DASH em tags não mencionadas acima que têm suporte atualmente:

Nome do atributo Função do atributo
mediaPresentationDuration A duração do conteúdo do vídeo.
minimumUpdatePeriod Atributo da tag <MPD>. Especifica a frequência com que precisamos atualizar o manifesto.
digitar Atributo da tag <MPD>: "dinâmico" para indicar que esta é uma transmissão ao vivo.
presentationTimeOffset Atributo da tag <SegmentBase>. Especifica o intervalo de horário da apresentação a partir do início do período.
startNumber 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 aceitamos o reconhecimento da caixa EMSG dentro de fragmentos MP4 para DASH e fornecemos um EmsgEvent para os desenvolvedores.

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

  • availabilityStartTime
  • segmentAlignment

HTTP Live Streaming (HLS)

Acesse a visão geral e as especificações completas de HTTP Live Streaming aqui.

Uma das principais vantagens do player receptor da Web é 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 com uma lista de todos os streams de variantes com o respectivo URL. A playlist da variante é a playlist de mídia. As duas principais tags HLS que o player receptor da Web oferece suporte atualmente na playlist principal são:

Nome da tag Funcionalidade
#EXT-X-STREAM-INF Especifica um fluxo de variantes/taxa de bits. O atributo BANDWIDTH é obrigatório, porque oferece suporte à seleção de streaming de taxa de bits adaptável. O atributo CODECS é altamente recomendado para inicializar um MSE, como "avc1.42c01e,mp4a.40.2". Se não for especificado, o caso padrão será definido como conteúdo de vídeo 3.0 do perfil principal H264 e conteúdo codificado de áudio "mp4a.40.2".
#EXT-X-MEDIA Especifica uma playlist de mídia adicional (no atributo URI) que representa o conteúdo. Geralmente, são streams de áudio alternativos em outro formato (som surround 5.1) ou idioma. É permitido usar um atributo de TYPE contendo VIDEO, AUDIO, SUBTITLES ou CLOSED-CAPTIONS. Definir o atributo DEFAULT como YES indica a escolha desse fluxo alternativo por padrão.

Veja uma lista de tags HLS com suporte atualmente pelo player 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 tem. Isso também determina a frequência com que fazemos o download/atualização do manifesto de playlist para uma transmissão ao vivo. O player de receptor da Web não oferece suporte a durações menores que 0,1 segundo.
#EXT-X-MEDIA-SEQUENCE O número de sequência (geralmente para uma transmissão ao vivo) que o primeiro segmento dessa playlist representa.
#EXT-X-KEY Informações sobre a chave DRM. O atributo METHOD informa qual sistema de chaves usar. Atualmente, oferecemos suporte a AES-128 e SAMPLE-AES.
#EXT-X-BYTERANGE O intervalo de bytes a ser buscado para um URL de segmento.
#EXT-X-DISCONTINUITY Especifica uma descontinuidade entre segmentos consecutivos. Isso geralmente é observado com a inserção de anúncios do lado do servidor, em que um segmento de anúncio aparece no meio do stream principal.
#EXT-X-PROGRAM-DATE-TIME Tempo absoluto da primeira amostra do próximo segmento, por exemplo, "2016-09-21T23:23:52.066Z".
#EXT-X-ENDLIST Seja um VOD ou uma transmissão ao vivo.

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

Nossa implementação de HLS oferece suporte à seleção de um stream de áudio alternativo, como som surround 5.1, como a reprodução de áudio principal. Isso pode ser feito tendo uma tag #EXT-X-MEDIA com os codecs alternativos, além de fornecer o formato de segmento na configuração do stream.

O player do receptor da Web espera um comportamento específico de acordo com a especificação. Por exemplo, após uma tag #EXT-INF, esperamos um URI. Se não for um URI, por exemplo, um #EXT-X-DISCOUNTINUITY fará com que a análise da playlist falhe.

A cada #EXT-X-TARGETDURATION segundos, recarregamos a playlist/manifesto para receber novas listas de segmentos. Além disso, atualizamos a nova representação interna de todos os segmentos para a nova. Sempre que uma busca é solicitada, buscamos somente dentro do intervalo pesquisável. Para a busca em tempo real, só permitimos a busca a partir do início da lista mais recente até uma duração desejada de três a partir do fim. Por exemplo, se você tiver uma lista de dez segmentos e estiver no segmento 6, poderá buscar até sete, mas não oito.

Suporte a formatos de segmentos

O SDK CAF oferece suporte à reprodução de conteúdo entregue em vários formatos, conforme mencionado em HlsSegmentFormat para áudio e HlsVideoSegmentFormat para vídeo. Isso inclui suporte a áudio compactado, como reprodução AAC e AC3, tanto criptografado quanto não criptografado. É necessário especificar essas informações no MediaInformation do LoadRequestData para descrever corretamente seu conteúdo para o jogador. Se não for especificada, a configuração padrão do player tentará reproduzir o conteúdo como conteúdo empacotado do Transport Stream. Essa propriedade pode ser definida a partir de qualquer um dos remetentes nos dados da solicitação de carregamento (Android, iOS e Web) ou no receptor, por meio de interceptadores de mensagens.

Confira o exemplo de snippet de código abaixo ou o guia Como carregar mídia usando contentId, contentUrl and 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 de tag #EXT-X-KEY acima, o SDK do Cast oferece suporte a SAMPLE-AES ou SAMPLE-AES-CTR, em que um URI para a 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"

A KEYFORMAT com suporte agora é Widevine, e o URI contém uma informação de DRM 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 é 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 o código de criptografia usado ao criptografar o conteúdo. SUMMARY-AES sinaliza que o conteúdo está criptografado usando "cbcs". SAMPLE-AES-CTR sinaliza que o conteúdo foi criptografado usando um dos esquemas de proteção do AES-CTR, chamado "cenc".

Atributos mapeados para MPD DASH:

Atributo Descrição
KEYFORMAT O atributo schemeIdUri 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 default_kid em MPEG DASH. Se estiver usando um esquema de chave hierárquica, 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 no HLS que não são usados nem compatíveis atualmente. 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, usamos o DEFAULT=
  • #EXT-X-I-FRAME-STREAM-INF na playlist principal é ignorado.
  • #EXT-X-DISCONTINUITY-SEQUENCE é ignorado
  • #EXT-X-PLAYLIST-TYPE:EVENT pode estar presente em uma transmissão ao vivo, e #EXT-X-PLAYLIST-TYPE:VOD pode estar em uma transmissão de VOD, mas atualmente nosso player receptor da Web depende apenas da existência de #EXT-X-ENDLIST para determinar os eventos ao vivo e VOD.

Streaming sem falhas

Especificação oficial do Smooth Streaming da Microsoft.

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

Esta é uma tabela com as tags e os atributos mais comuns no Smooth Streaming que o player receptor da Web oferece suporte atualmente. Muitos conceitos já são explicados na seção DASH acima.

Tag/atributo Uso
<SmoothStreamingMedia> A tag principal do manifesto contém atributos de:
  • TimeScale: número de unidades para representar um segundo, normalmente com incremento de 10.000.000.
  • Duração: a duração do conteúdo em uma escala de tempo. O player receptor da Web não é compatível com durações menores que 0,1 segundo.
  • IsLive: indica se o manifesto é uma mídia ativa.
<StreamIndex> Um conjunto de transmissões, semelhante ao AdaptationSet do DASH. O tipo geralmente é "texto", "vídeo" ou "áudio". O atributo "Url" geralmente contém um URL de fragmento modelado usando informações como taxa de bits ou horário de início.
<QualityLevel> Cada tag QualityLevel especifica a respectiva taxa de bits e um codec FourCC. O código FourCC costuma ser H264, AVC1, AACL etc. Para vídeos, ele especifica as resoluções por meio de MaxWidth e MaxHeight. Para áudio, ele especifica a frequência (como 44100) por meio de SampleRate e número de canais.
<c> Elemento de fragmento do stream. 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. Para o Widevine, ele conterá o ID da chave, o comprimento da chave, o ID do algoritmo, como AESCTR, o LA_URL (URL de aquisição de licença), LUI_URL (URL da interface do usuário da licença) e DS_ID (ID de serviço do domínio).

Proteção de conteúdo

Para codificar os IDs do sistema de proteção corretamente, use o mapeamento abaixo:

  • WIDEVINE: 'EDEF8BA9-79D6-4ACE-A3C8-27DCD51D21ED',
  • CLEARKEY: '1077EFEC-C0B2-4D02-ACE3-3C1E52E2FB4B',
  • MPEG_DASH_MP4PROTECTION: 'URN:MPEG:DASH:MP4PROTECTION:2011' (link em inglês)

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 DASH acima.

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

Confira abaixo um exemplo de manifesto de streaming Smooth ao vivo com conteúdo de 3.000 segundos:

<?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})

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

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

Veja uma lista de atributos do Smooth Streaming que ignoramos no momento e que não afetam as experiências de streaming, independente de serem fornecidos ou não:

  • CanSeek, CanPause na tag <SmoothStreamingMedia>.
  • Chunks e QualityLevels na tag <StreamIndex>. Em vez disso, calculamos o número de segmentos e de níveis de qualidade com base nas informações fornecidas em <StreamIndex>, como a tag QualityLevel real e as tags <c>.
  • BitsPerSample e 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 receptor da Web e a exibição validando os parâmetros de mídia transmitidos, retornando um booleano. Todos os parâmetros, exceto os primeiros, são opcionais. 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 da Web e a tela oferecem suporte ao tipo MIME 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 da Web e a tela são compatíveis com o formato de vídeo 4K para esse codec 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 da Web e a tela 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 da Web e a tela são compatíveis com Dolby Vision (DV) para este codec, as dimensões e o frame rate:

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

DRM

Alguns conteúdos de mídia exigem gerenciamento de direitos digitais (DRM, na sigla em inglês). Se o conteúdo de mídia tem a licença DRM (e o URL da chave) armazenado no manifesto (DASH ou HLS), o SDK do Cast processa esse caso para você. Um subconjunto desse conteúdo requer um licenseUrl, 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 de solicitação 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 com o 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 OAuth/SSO. Nesses casos, se o conteúdo de mídia for carregado usando a voz ou vier da nuvem, um setCredentials será invocado da nuvem para o dispositivo de transmissão que fornece essas credenciais. Os aplicativos que programam um app receptor da Web podem usar as informações do setCredentials para operar o DRM conforme necessário. Confira um exemplo de uso da credencial para criar a mídia:

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

Gerenciamento de canais de áudio

Quando o player do Cast 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 começar,
  • em cada intervalo de anúncio, e
  • sempre que o conteúdo principal for retomado.

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

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

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

  • Inglês - AC-3 Canal 5.1 (principal)
  • sueco – AAC em dois canais
  • francês - AAC em dois canais
  • alemão - AAC em dois canais

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

Cenário 2: stream de mídia com paridade de canal nas faixas primária e secundária:

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

Como todas as faixas dessa transmissão têm o mesmo número de canais, o público vai ouvir uma música independentemente do idioma selecionado.

Processamento de canais de áudio Shaka

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

Se a faixa principal não for de som surround (por exemplo, uma faixa estéreo de dois canais), o player Shaka vai usar dois canais por padrão e filtrar automaticamente todas as faixas de mídia secundárias que tenham mais de dois canais.

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

Exemplo:

shakaConfig = { "preferredAudioChannelCount": 6 };

Com a preferredAudioChannelCount definida como 6, o Shaka Player verifica se oferece suporte aos codecs de som surround (AC-3 ou EC-3) e filtra automaticamente todas as faixas de mídia que não estão em conformidade com o número preferido de canais.