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 oDEFAULT=
#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:
|
<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:
|
<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 tagQualityLevel
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.