Protocolli di streaming del web player ricevitore

L'SDK Web Receiver supporta oggi tre tipi di protocolli di streaming:

DASH, Live streaming HTTP e Streaming fluido.

Nel presente documento viene elencato il supporto per ciascuno dei protocolli di streaming. Tieni presente che la spiegazione dei tag supportati per ogni protocollo è piuttosto abbreviata rispetto alle specifiche dettagliate del protocollo. L'obiettivo è fornire una rapida panoramica e una comprensione di come utilizzare ogni protocollo e delle funzionalità del protocollo supportate sui dispositivi compatibili con Google Cast per offrire le relative esperienze di streaming.

Streaming adattivo dinamico su HTTP (DASH)

la specifica dettagliata di DASH di ISO.

DASH è un protocollo per lo streaming con velocità in bit adattiva che consente streaming video di alta qualità tramite server HTTP(S). Un file manifest, composto in XML, contiene la maggior parte delle informazioni sui metadati per inizializzare e scaricare i contenuti video. I concetti chiave supportati dal Web Receiver Player sono <Period>, <AdaptationSet>, <Representation>, <SegmentTemplate>, <SegmentList>, <BaseUrl> e <ContentProtection>.

Un manifest DASH inizia con un tag <MPD> principale e all'interno include uno o più tag <Period>, che rappresentano un contenuto per lo streaming. I tag <Period> consentono l'ordinamento di contenuti diversi e vengono spesso utilizzati per separare i contenuti principali da quelli pubblicitari o più video consecutivi.

Un <AdaptationSet> in <MPD> è un insieme di rappresentazioni per un tipo di stream multimediale, nella maggior parte dei casi video, audio o sottotitoli codificati. I tipi MIME più supportati sono "video/mp4", "audio/mp4" e "text/vtt". Un <ContentComponent contentType="$TYPE$"> facoltativo può essere incluso in <AdaptationSet>.

All'interno di ogni <AdaptationSet> dovrebbe essere presente un elenco di tag <Representation> e il ricevitore web userà le informazioni di codecs per inizializzare il buffer di origine dell'MSE e le informazioni di bandwidth per scegliere automaticamente la rappresentazione/la velocità in bit corretta da riprodurre.

Per ogni <Representation>, i segmenti multimediali sono descritti utilizzando <BaseURL> per la rappresentazione di un singolo segmento, <SegmentList> per l'elenco di segmenti (simile a HLS) o <SegmentTemplate>.

Per <SegmentTemplate>, indica in che modo i segmenti di inizializzazione e i contenuti multimediali possono essere rappresentati tramite creazione di modelli. Nell'esempio seguente $Number$ indica il numero del segmento come disponibile dalla CDN. Pertanto, si traduce in seg1.m4, seg2.m4s e così via man mano che la riproduzione 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>

Per un attributo <SegmentTemplate>, è comune utilizzare il tag <SegmentTimeline> per indicare la durata di ogni segmento e i segmenti ripetuti. Spesso una timescale (unità che rappresentano un secondo) è inclusa negli attributi di <SegmentTemplate>, in modo che sia possibile calcolare il tempo del segmento in base a questa unità. Nell'esempio riportato di seguito, il tag <S> indica un tag di segmento, l'attributo d specifica la durata del segmento e l'attributo r specifica quanti segmenti della stessa durata si ripetono affinché $Time$ possa essere calcolato correttamente per il download del segmento multimediale come specificato nell'attributo 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>

Per la rappresentazione con <SegmentList>, ecco un esempio:

<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>

Per un file a segmento singolo, spesso viene utilizzato un <SegmentBase> con richieste di intervallo di byte per specificare quale parte di un file <BaseURL> contiene l'indice, mentre il resto può essere recuperato on demand man mano che la riproduzione prosegue o si verifica. In questo intervallo Initialization viene specificato l'intervallo di metadati init, mentre indexRange specifica l'indice per i segmenti multimediali. Tieni presente che al momento supportiamo solo intervalli di byte consecutivi.

<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>

Indipendentemente dalla rappresentazione utilizzata, se gli stream sono protetti, può essere visualizzata una sezione <ContentProtection> nella sezione <AdaptationSet>, dove schemeIdUri identifica in modo univoco il sistema DRM da utilizzare. Per la crittografia comune è possibile includere un ID chiave facoltativo.

<!-- 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>

Per altri esempi e dettagli, fai riferimento alla specifica MPEG-DASH. Di seguito è riportato un elenco di ulteriori attributi DASH sui tag non menzionati sopra che attualmente supportiamo:

Nome attributo Funzione attributo
durata della presentazione multimediale Durata dei contenuti video.
minimoUpdatePeriod Attributo del tag <MPD>; specifica la frequenza con cui dobbiamo ricaricare il manifest.
digita Attributo del tag <MPD>; "dinamica" per indicare che si tratta di un live streaming.
presentazioneTimeTimeOffset Attributo del tag <SegmentBase>; specifica lo sfasamento della presentazione dall'inizio del periodo.
numeroInizia Specifica il numero del primo segmento multimediale in una presentazione in un periodo. Spesso è usata nei live streaming.

Supportiamo anche il riconoscimento della casella EMSG all'interno di frammenti MP4 per DASH e la fornitura di una EmsgEvent agli sviluppatori.

Sebbene il nostro attuale ricevitore web supporti i principali casi d'uso di DASH, di seguito è riportato un elenco di attributi comuni che la nostra implementazione attuale di DASH ignora o non utilizza. Ciò significa che, indipendentemente dal fatto che il file manifest li contenga, non hanno alcun impatto sull'esperienza di riproduzione dei contenuti.

  • disponibilità
  • allineamento segmento

HTTP Live Streaming (HLS)

La panoramica e le specifiche complete del live streaming HTTP sono disponibili qui.

Uno dei principali punti di forza del player di destinazione web è la possibilità di supportare la riproduzione di HLS in MSE. A differenza di DASH, in cui un manifest viene fornito in un singolo file, HLS invia la playlist principale contenente un elenco di tutte le varianti di stream con il rispettivo URL. La playlist delle varianti è la playlist multimediale. I due tag HLS principali attualmente supportati dal player di ricezione Web nella playlist principale sono:

Nome tag Funzionalità
#EXT-X-STREAM-INF Specifica uno streaming in bit/variante. L'attributo BANDWIDTH è obbligatorio e supporta la selezione di streaming con velocità in bit adattiva. L'attributo CODECS è vivamente consigliato per inizializzare MSE, ad esempio "avc1.42c01e,mp4a.40.2". Se non specificato, la richiesta predefinita è impostata sul video principale H264 3.0 e sui contenuti con codifica audio "mp4a.40.2".
#EXT-X-MEDIA Specifica una playlist multimediale aggiuntiva (nell'attributo URI) che rappresenta i contenuti. Si tratta in genere di stream audio alternativi in altri formati (audio surround 5.1) o in altre lingue. È consentito un attributo TYPE contenente VIDEO, AUDIO, SUBTITLES o CLOSED-CAPTIONS. Se imposti l'attributo DEFAULT su YES, per impostazione predefinita sceglierai questo stream alternativo.

Ecco un elenco di tag HLS attualmente supportati dal web player ricevitore nella playlist multimediale:

Nome tag Funzionalità
#EXTINF Informazioni sul flusso, generalmente seguite dalla durata del segmento in secondi e nella riga successiva l'URL del segmento.
#EXT-X-TARGETDURATA La durata in secondi di ogni segmento. Determina inoltre la frequenza con cui scarichiamo/aggiornamo il manifest della playlist per un live streaming. Il player web di ricezione non supporta durate inferiori a 0,1 secondi.
#SEQUENZA-EXT-X-MEDIA Il numero di sequenza (spesso per un live streaming) rappresentato dal primo segmento di questa playlist.
EXT-X-KEY Informazioni sulla chiave DRM. L'attributo METHOD indica quale sistema chiave utilizzare. Oggi supportiamo AES-128 e SAMPLE-AES .
#EXT-X-BYTERANGE L'intervallo di byte da recuperare per un URL di segmento.
#EXT-X-DISCONTINUITÀ Specifica una discontinuità tra i segmenti consecutivi. Questo avviene spesso con l'inserimento di annunci lato server, dove un segmento annuncio viene visualizzato al centro del flusso principale.
#EXT-X-PROGRAM-DATE-TIME L'ora assoluta del primo campione del segmento successivo, ad esempio 2016-09-21T23:23:52.066Z".
#EXT-X-ENDLIST che si tratti di un VOD o di un live streaming.

Per i live streaming, utilizziamo #EXT-X-PROGRAM-DATE-TIME e #EXT-X-MEDIA-SEQUENCE come fattori chiave per determinare come unire un manifest appena aggiornato. Se presente, l'elemento #EXT-X-PROGRAM-DATE-TIME viene utilizzato per trovare corrispondenze con i segmenti aggiornati. In caso contrario, verrà utilizzato il numero #EXT-X-MEDIA-SEQUENCE. Tieni presente che, secondo le specifiche HLS, non utilizziamo il confronto dei nomi di file per la corrispondenza.

La nostra implementazione HLS supporta la selezione di uno stream audio alternativo, ad esempio l'audio surround 5.1, come riproduzione audio principale. A questo scopo, devi avere un tag #EXT-X-MEDIA con i codec alternativi e fornire il formato di segmento nella configurazione dello stream.

Il ricevitore web prevede un determinato comportamento per specifica. Ad esempio, dopo un tag #EXT-INF, ci aspettiamo un URI. Se non si tratta di un URI, ad esempio un #EXT-X-DISCOUNTINUITY non comporterà l'analisi corretta per la playlist.

Ogni #EXT-X-TARGETDURATION secondi, ricarichiamo la playlist/il manifest per ottenere nuovi elenchi di segmenti e aggiorniamo la nuova rappresentazione interna di tutti i segmenti in quella nuova. Ogni volta che viene richiesta una richiesta, cerchiamo solo nell'intervallo ricercabile. Per i live streaming, consentiamo di cercare soltanto dall'inizio dell'elenco più recente fino alla durata di destinazione prevista fino alla fine. Ad esempio, se hai un elenco di 10 segmenti e ti trovi nel segmento 6, puoi cercare solo fino a 7, ma non 8.

Supporto del formato segmento

L'SDK CAF supporta la riproduzione di contenuti pubblicati in più formati come indicato in HlsSegmentFormat per l'audio e in HlsVideoSegmentFormat per i video. Ciò include il supporto per audio pacchettizzato, come la riproduzione AAC e AC3, sia criptata che non criptata. Devi specificare queste informazioni nel MediaInformation dei LoadRequestData per descrivere correttamente i tuoi contenuti al player. Se non specificata, la configurazione predefinita del player tenterà di riprodurre i contenuti come contenuti in pacchetto Transport Stream. Questa proprietà può essere impostata da qualsiasi mittente nei dati delle richieste di caricamento (Android, iOS e Web) o all'interno del ricevitore tramite intercettatori di messaggi.

Consulta lo snippet di codice di esempio riportato di seguito o la guida Caricamento di contenuti multimediali utilizzando contentId, contentUrl ed entità per ulteriori informazioni su come preparare i contenuti sul ricevitore 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;
    });

Protezione dei contenuti

Come elencato nella sezione dei tag #EXT-X-KEY riportata sopra, l'SDK Cast supporta SAMPLE-AES o SAMPLE-AES-CTR, dove è possibile specificare un URI di inizializzazione per la chiave.

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

Il file KEYFORMAT che supportiamo ora è Widevine e l'URI contiene informazioni DRM con codifica BASE64 XXXXXXX che, quando decodificate, contengono l'ID chiave:

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

La versione 1 definisce i seguenti attributi:

Attributo Esempio Descrizione
KEYFORMATVERSIONS "1" Questa proposta definisce il formato chiave versione 1
KEYFORMAT "urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed" L'UUID è l'UUID Widevine di DASH IF IOP. La stessa stringa esatta viene utilizzata in MPD con gli stream criptati Widevine.
URI "data:text/plain;base64, <base64 encoded PSSH box>" URI dello stream contenente il tipo di dati e la casella PSSH.
METHOD SAMPLE-AES-CTR Indica la crittografia utilizzata per criptare i contenuti. SAMPLE-AES indica che i contenuti sono criptati utilizzando "cbcs". Quest'ultimo indica che i contenuti sono criptati utilizzando uno degli schemi di protezione AES-CTR, ossia "cenc".

Attributi mappati a DASH MPD:

Attributo Descrizione
KEYFORMAT Attributo schemaIdUri dell'elemento ContentProtection.
URI Il contenuto dell'elemento cenc:pssh.
KEYID Stringa esadecimale a 16 byte che codifica l'ID della chiave che ha lo stesso ruolo di default_kid in MPEG DASH. Se utilizzi uno schema di chiavi gerarchico, si tratta della chiave "root".

Esempio di playlist HLS con segnalazione 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

Di seguito è riportato un elenco di funzionalità e tag in HLS che attualmente non utilizziamo o non supportiamo. La loro presenza o assenza non influisce sul comportamento dello streaming.

  • L'attributo RESOLUTION= in #EXT-X-STREAM-INF viene ignorato.
  • L'attributo AUTOSELECT= in #EXT-X-MEDIA non è utilizzato. Preferiamo piuttosto DEFAULT=
  • #EXT-X-I-FRAME-STREAM-INF nella playlist principale viene ignorata.
  • #EXT-X-DISCONTINUITY-SEQUENCE viene ignorato
  • #EXT-X-PLAYLIST-TYPE:EVENT può essere presente in un live streaming e #EXT-X-PLAYLIST-TYPE:VOD può essere presente in uno stream VOD, ma attualmente il nostro Web ricezione ricevitore si basa solo sull'esistenza di #EXT-X-ENDLIST per determinare il live streaming rispetto a VOD.

Streaming fluido

la specifica di Streaming fluida Microsoft ufficiale.

Il flusso fluido fornisce protocollo di streaming adattivo e specifiche XML su HTTP (simile a DASH). A differenza di DASH, Fluid Streaming consiglia solo la pacchettizzazione MPEG-4 per i segmenti multimediali.

Ecco una tabella con gli attributi e i tag più comuni di Fluid Streaming che il Web Receiver supporta oggi. Molti concetti sono già spiegati nella sezione DASH precedente.

Tag/Attributo Utilizzo
<SmoothStreamingMedia> Il tag principale del manifest contiene gli attributi di:
  • TimeScale: numero di unità che rappresentano un secondo, generalmente con incrementi di 10.000.000.
  • Durata: la durata dei contenuti nella scala temporale. Il ricevitore web non supporta durate inferiori a 0,1 s.
  • IsLive: se il manifest è un media dal vivo.
<StreamIndex> Un set di stream, simile all'AdattamentoSet di DASH. Solitamente è di tipo "testo", "video" o "audio". L'attributo URL contiene in genere un URL con frammento basato su modelli che utilizza informazioni quali velocità in bit o ora di inizio.
<LivelloQualità> Ogni tag QualityLevel specifica il bitrate e il codec FourCC. Il codice FourCC è spesso "H264", "AVC1", "AACL" e così via. Per i video, specifica le risoluzioni tramite MaxWidth e MaxHeight. Per l'audio, specifica la relativa frequenza (ad esempio 44100) mediante SamplingRate e il numero di canali.
<c> Elemento Frammento stream. Contiene:
  • d: durata di un frammento.
  • t: tempo multimediale del frammento.
<Protezione> Un tag con l'attributo facoltativo SystemID che elenca l'ID del file DRM di sistema da utilizzare nel tag <SmoothStreamingMedia>.
<Header di protezione> In <Protezione> può contenere un attributo SystemID e dati personalizzati, solitamente codificati in Base64. Per Widevine, conterrà l'ID della chiave, la lunghezza della chiave, l'ID dell'algoritmo, come AESCTR, il LA_URL (URL di acquisizione della licenza), LUI_URL (URL dell'interfaccia utente della licenza) e DS_ID (ID del servizio di dominio).

Protezione dei contenuti

Per codificare correttamente gli ID del sistema di protezione, utilizza la mappatura riportata di seguito.

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

Per <ProtectionHeader>, di seguito è riportato un esempio con dati codificati in Base64. I dati decodificati sono conformi allo stesso formato decodificato descritto nel supporto della protezione dei contenuti DASH riportato sopra.

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

Di seguito è riportato un esempio di manifesto di live streaming fluido con una durata di 3000 secondi dei contenuti:

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

Nell'esempio precedente relativo al video stream, il modello di URL è:

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

Quindi i primi due segmenti (supponendo che siamo al livello di qualità dell'indice 2) saranno i seguenti, con l'ora iniziale estratta da t="80649401378125" sotto il video StreamIndex e l'incremento di 4 secondi * 10000000 per segmento:

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

Di seguito è riportato un elenco di attributi relativi al live streaming che attualmente ignoriamo e che non influiranno sulle esperienze di streaming, indipendentemente dal fatto che vengano forniti:

  • CanSeek, Canpause nel tag <SmoothStreamingMedia>.
  • Chunks, QualitàLevels nel tag <StreamIndex>. Calcoliamo invece il numero di segmenti e il numero di livelli qualitativi in base alle informazioni fornite all'interno di <StreamIndex>, come il tag QualityLevel effettivo e i tag <c>.
  • BitsPerSample, PacketSize non è utilizzato in <QualityLevel>.

Controlla il tipo di visualizzazione

Il metodo canDisplayType verifica le funzionalità video e audio del dispositivo e del display Web ricevendo la convalida dei parametri multimediali trasmessi, restituendo un valore booleano. Tutti i parametri, tranne il primo, sono facoltativi: più parametri includi, più precisa sarà la verifica.

La firma è canDisplayType(<em>mimeType</em>,<em>codecs</em>,<em>width</em>,<em>height</em>,<em>framerate</em>)

Esempi:

Verifica se il dispositivo e il display web ricevitore supportano il mimetype video/mp4 con questo codec, dimensioni e frequenza fotogrammi specifici:

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

Verifica se il dispositivo e il display web ricevono supporto per il formato video 4K per questo codec specificando la larghezza 3840 e l'altezza 2160:

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

Verifica se il dispositivo e il display web ricevono supporto HDR10 per questo codec, dimensioni e frequenza fotogrammi:

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

Verifica se il dispositivo e il display web ricevitore supportano Dolby Vision (DV) per questo codec, dimensioni e frequenza fotogrammi:

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

DRM

Nota: uno dei vantaggi principali dell'utilizzo dell'SDK Ricevitore web è che l'app non deve più caricare MPL e gestire la riproduzione dei contenuti separatamente, perché l'SDK del ricevitore web gestisce questa situazione per conto tuo.

Alcuni contenuti multimediali richiedono la Digital Rights Management (DRM). Per i contenuti multimediali con licenza DRM (e URL della chiave) memorizzati nel file manifest (DASH o HLS), l'SDK Cast gestisce questa richiesta per te. Un sottoinsieme di questi contenuti richiede un elemento licenseUrl necessario per ottenere la chiave di decriptazione. Nel Ricevitore web, puoi utilizzare PlaybackConfig per impostare licenseUrl in base alle tue esigenze.

Il seguente snippet di codice mostra come impostare le informazioni per le richieste di licenza, ad esempio 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 hai un'integrazione dell'Assistente Google, alcune delle informazioni DRM, come le credenziali necessarie per i contenuti, potrebbero essere collegate direttamente al tuo Account Google tramite meccanismi come OAuth/SSO. In questi casi, se i contenuti multimediali vengono caricati tramite comandi vocali o provengono dal cloud, viene richiamato setCredentials dal cloud al dispositivo di trasmissione che fornisce le credenziali. Le applicazioni che scrivono un'app Ricevitore web possono quindi utilizzare le informazioni relative a setCredentials per utilizzare DRM in base alle necessità. Ecco un esempio di utilizzo delle credenziali per creare il contenuto multimediale.

Suggerimento: consulta anche la sezione Caricamento di contenuti multimediali utilizzando contentId, contentUrl ed entità.

Gestione dei canali audio

Quando il player di trasmissione carica i contenuti multimediali, viene configurato un singolo buffer di sorgente audio. Allo stesso tempo, seleziona anche un codec appropriato che deve essere utilizzato dal buffer, in base al tipo MIME della traccia principale. Vengono configurati un nuovo buffer e codec:

  • Quando inizia la riproduzione,
  • a ogni interruzione pubblicitaria
  • ogni volta che riprendono i contenuti principali.

Poiché il buffer utilizza un singolo codec e questo viene scelto in base alla traccia principale, in alcuni casi le tracce secondarie potrebbero essere filtrate e non ascoltate. Ciò può accadere quando la traccia principale di un programma multimediale è in audio surround, ma le tracce audio secondarie utilizzano un audio stereo. Poiché le tracce secondarie vengono spesso utilizzate per offrire contenuti in lingue alternative, fornire contenuti multimediali con tracce diverse può avere un impatto significativo, ad esempio un numero elevato di spettatori che non riesce a sentire i contenuti nella lingua madre.

I seguenti scenari mostrano perché è importante fornire una programmazione in cui le tracce primarie e secondarie contengono lo stesso numero di canali:

Scenario 1: stream multimediale privo di parità di canale tra le tracce principali e secondarie:

  • inglese - AC-3 5.1 canale (principale)
  • svedese - AAC a 2 canali
  • francese - AAC a 2 canali
  • tedesco - AAC a 2 canali

In questo scenario, se la lingua del player è impostata su un valore diverso dall'inglese, l'utente non sente la traccia che si aspetta, in quanto tutte le tracce a due canali vengono filtrate durante la riproduzione. L'unica traccia che poteva essere riprodotta sarebbe l'AC-3 principale a 5.1 canali, quindi solo quando la lingua era impostata sull'inglese.

Scenario 2: stream multimediale con parità di canali tra tracce principali e secondarie:

  • inglese - AC-3 5.1 canale (principale)
  • svedese - AC-3 5.1 canale
  • francese - canale AC-3 5.1
  • tedesco - canale AC-3 5.1

Poiché le tracce di questo stream hanno tutti lo stesso numero di canali, il pubblico ascolterà una traccia a prescindere dalla lingua selezionata.

Gestione dei canali audio Shaka

Per impostazione predefinita, il player di Shaka (DASH) utilizza un numero di canali preferito pari a due, come misura di mitigazione quando si riscontrano contenuti multimediali che non presentano parità tra le tracce audio secondarie.

Se la traccia principale non ha un audio surround (ad esempio, una traccia stereo a due canali), il player di Shaka viene impostato in modo predefinito su due canali e filtra automaticamente tutte le tracce multimediali secondarie con più di due canali.

Puoi anche configurare il numero preferito di canali audio di Shaka impostando preferredAudioChannelCount nella proprietà shakaConfig su cast.framework.RiproduzioneConfig.

Ad esempio:

shakaConfig = { "preferredAudioChannelCount": 6 };

Con preferredAudioChannelCount impostato su 6, Shaka Player controlla se è in grado di supportare i codec audio surround (AC-3 o EC-3) e filtra automaticamente tutte le tracce multimediali non conformi al numero di canali preferito.