Protokoły strumieniowego przesyłania danych z odbiornika internetowego

Pakiet Web pickupr SDK obsługuje obecnie 3 typy protokołów strumieniowania:

DASH, HTTP Live Streaming i Smooth Streaming.

W tym dokumencie opisujemy, jakie obsługujemy poszczególne protokoły strumieniowania. Pamiętaj, że wyjaśnienie obsługiwanych tagów dla każdego protokołu jest dość skrócone w porównaniu do szczegółowej specyfikacji protokołu. Celem jest szybkie przedstawienie i zrozumienie sposobów korzystania z poszczególnych protokołów oraz tego, które funkcje tego protokołu są obsługiwane na urządzeniach obsługujących Cast, aby umożliwić strumieniowanie.

Dynamiczne adaptacyjne strumieniowe przesyłanie danych przez HTTP (DASH)

Szczegółowa specyfikacja ISO.

DASH to protokół strumieniowania z adaptacyjną szybkością transmisji bitów, który umożliwia strumieniowe przesyłanie wideo wysokiej jakości przez serwery HTTP(S). Plik manifestu w formacie XML zawiera większość metadanych potrzebnych do inicjowania i pobierania treści wideo. Odtwarzacz internetowy obsługuje najważniejsze koncepcje <Period>, <AdaptationSet>, <Representation>, <SegmentTemplate>, <SegmentList>, <BaseUrl> i <ContentProtection>.

Plik manifestu DASH zaczyna się od głównego tagu <MPD>, a w środku znajduje się co najmniej 1 tag <Period>, który reprezentuje 1 transmisję treści. Tagi <Period> umożliwiają uporządkowanie różnych elementów przesyłanych strumieniowo i często są używane do oddzielania treści głównych od reklam lub wielu następujących po sobie treści wideo.

Element <AdaptationSet> w kolumnie <MPD> to zbiór reprezentacji jednego typu strumienia multimediów – w większości przypadków wideo, audio i napisy. Najczęściej obsługiwane MIME to „video/mp4”, „audio/mp4” i „text/vtt”. W polu <AdaptationSet> można umieścić opcjonalny element <ContentComponent contentType="$TYPE$">.

W każdym elemencie <AdaptationSet> powinna znajdować się lista tagów <Representation>, a odtwarzacz Web pickupr Player używa informacji z codecs do inicjowania bufora źródłowego MSE oraz informacji bandwidth, aby automatycznie wybrać odpowiednią reprezentację/szybkość transmisji bitów do odtwarzania.

W przypadku każdego elementu typu <Representation> segmenty multimediów są opisywane za pomocą atrybutu <BaseURL> (reprezentacja pojedynczego segmentu), <SegmentList> – listy segmentów (podobnych do HLS) lub <SegmentTemplate>.

W przypadku właściwości <SegmentTemplate> wskazuje, jak segmenty inicjowania i segmenty multimediów mogą być reprezentowane za pomocą szablonów. W tym przykładzie $Number$ wskazuje numer segmentu dostępny w sieci CDN. W miarę dalszego odtwarzania przekłada się to na seg1.m4s, seg2.m4s itp.

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

W przypadku właściwości <SegmentTemplate> często używane jest tag <SegmentTimeline> do wskazywania, jak długo trwa każdy segment i które segmenty się powtarzają. timescale (jednostki reprezentujące jedną sekundę) jest często dołączany do atrybutów właściwości <SegmentTemplate>, dzięki czemu możemy obliczyć czas segmentu na podstawie tej jednostki. W przykładzie poniżej tag <S> oznacza tag segmentu, atrybut d określa długość segmentu, a atrybut r – liczbę powtórzeń segmentów o tym samym czasie trwania. Dzięki temu można prawidłowo obliczyć wartość $Time$ na potrzeby pobrania segmentu multimediów zgodnie z atrybutem 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>

Oto przykład z użyciem parametru <SegmentList>:

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

W przypadku pliku z pojedynczym segmentem właściwość <SegmentBase> jest często używana z żądaniami zakresu bajtów do określenia, która część pliku <BaseURL> zawiera indeks. Reszta może zostać pobrana na żądanie w miarę dalszego odtwarzania lub wyszukiwania. W tym przypadku zakres Initialization określa zakres metadanych rozpoczęcia, a indexRange – indeks segmentów multimediów. Obecnie obsługujemy tylko kolejne zakresy bajtów.

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

Niezależnie od użytej metody, jeśli strumienie są chronione, sekcja <ContentProtection> może pojawić się w polu <AdaptationSet>, gdzie schemeIdUri jednoznacznie identyfikuje system DRM. Można dołączyć opcjonalny identyfikator klucza na potrzeby popularnego szyfrowania.

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

Więcej przykładów i szczegółów znajdziesz w specyfikacji MPEG-DASH. Poniżej znajduje się lista dodatkowych atrybutów DASH w tagach niewymienionych powyżej, które są obecnie obsługiwane:

Nazwa atrybutu Funkcja atrybutu
mediaPresentationDuration Czas trwania treści wideo.
minimumUpdatePeriod Atrybut tagu <MPD>. Określa, jak często musimy ponownie wczytywać plik manifestu.
typ Atrybut tagu <MPD>; „dynamiczny” wskazujący, że jest to transmisja na żywo.
presentationTimeOffset Atrybut tagu <SegmentBase>; określa przesunięcie czasu prezentacji od początku okresu.
startNumber Określa numer pierwszego segmentu multimediów w prezentacji w danym okresie. Często jest on używany w transmisjach na żywo.

Obsługujemy też rozpoznawanie pola EMSG we fragmentach MP4 na potrzeby DASH i udostępniamy deweloperom EmsgEvent.

Choć nasz obecny odtwarzacz internetowy DASH obsługuje główne przypadki użycia DASH, poniżej znajdziesz listę typowych atrybutów, które są ignorowane lub nieużywane przez naszą obecną implementację. Oznacza to, że niezależnie od tego, czy plik manifestu je zawiera, nie mają one wpływu na odtwarzanie treści.

  • availabilityStartTime
  • segmentAlignment

Transmisja na żywo przez HTTP (HLS)

Omówienie i pełną specyfikację transmisji na żywo przez HTTP znajdziesz tutaj.

Jedną z głównych zalet odtwarzacza Web Receivedr Player jest możliwość odtwarzania HLS w MSE. W przeciwieństwie do DASH, gdzie manifest znajduje się w 1 pliku, HLS wysyła playlistę reklamy nadrzędnej zawierającą listę wszystkich strumieni wariantów z odpowiednimi adresami URL. Playlista wariantu to playlista multimediów. Dwa główne tagi HLS, które obecnie obsługuje odtwarzacz sieci Web na głównej playliście, to:

Nazwa tagu Funkcje
#EXT-X-STREAM-INF Określa szybkość transmisji bitów/strumień wariantu. Wymagany jest atrybut BANDWIDTH, który obsługuje wybór strumieniowania z adaptacyjną szybkością transmisji bitów. Do inicjowania MSE, np. "avc1.42c01e,mp4a.40.2", zdecydowanie zalecamy użycie atrybutu CODECS. Jeśli ich nie określisz, domyślnie zostaną użyte treści wideo z profilu głównego H264 w wersji 3.0 i treści zakodowane w formacie audio "mp4a.40.2".
#EXT-X-MEDIA Określa dodatkową playlistę multimediów (w atrybucie URI), która reprezentuje treści. Są to zwykle alternatywne strumienie audio w innym formacie (dźwięk przestrzenny 5.1) lub w innym języku. Dozwolony jest atrybut TYPE zawierający VIDEO, AUDIO, SUBTITLES lub CLOSED-CAPTIONS. Ustawienie atrybutu DEFAULT na YES wskazuje, że ten strumień alternatywny jest domyślnie wybierany.

Oto lista tagów HLS, które obecnie obsługuje Web Odbieranier Player na playliście multimediów:

Nazwa tagu Funkcje
#EXTINF Informacje o strumieniu, po których następują zwykle czas trwania segmentu w sekundach, a w następnym wierszu adres URL segmentu.
#EXT-X-TARGETDURATION Czas trwania poszczególnych segmentów (w sekundach). Określa też, jak często pobieramy/odświeżamy plik manifestu playlisty w przypadku transmisji na żywo. Odtwarzacz internetowy nie obsługuje czasów trwania krótszych niż 0,1 s.
#EXT-X-MEDIA-SEQUENCE Numer sekwencyjny (często w przypadku transmisji na żywo), który reprezentuje pierwszy segment playlisty.
#EXT-X-KEY Informacje o kluczu DRM. Atrybut METHOD informuje nas, którego systemu kluczy mamy użyć. Dziś obsługujemy AES-128 i SAMPLE-AES.
#EXT-X-BYTERANGE Zakres bajtów do pobrania dla adresu URL segmentu.
#EXT-X-DISCONTINUITY Określa nieciągłość między kolejnymi segmentami. Widać to często przy wstawianiu reklam po stronie serwera, gdy segment reklam pojawia się pośrodku głównego strumienia.
#EXT-X-PROGRAM-DATE-TIME Czas bezwzględny pierwszej próbki następnego segmentu, np. „2016-09-21T23:23:52.066Z”.
#EXT-X-ENDLIST Określa, czy jest to film na żądanie czy transmisja na żywo.

W przypadku transmisji na żywo używamy #EXT-X-PROGRAM-DATE-TIME i #EXT-X-MEDIA-SEQUENCE jako kluczowych czynników, które decydują o tym, jak scalić nowo odświeżony plik manifestu. Jeśli jest podany, do dopasowywania odświeżanych segmentów służy #EXT-X-PROGRAM-DATE-TIME. W przeciwnym razie będzie używany numer #EXT-X-MEDIA-SEQUENCE. Pamiętaj, że zgodnie ze specyfikacją HLS nie używamy porównania nazw plików do dopasowywania.

Nasza implementacja HLS umożliwia wybór alternatywnego strumienia audio, takiego jak dźwięk przestrzenny 5.1, jako głównego odtwarzania dźwięku. Możesz to zrobić, używając tagu #EXT-X-MEDIA z alternatywnymi kodekami oraz podając format segmentu w konfiguracji strumienia.

Odtwarzacz internetowy wymaga pewnego działania zależnie od specyfikacji. Na przykład po tagu #EXT-INF oczekujemy identyfikatora URI. Jeśli na przykład nie jest to identyfikator URI, dyrektywa #EXT-X-DISCOUNTINUITY uniemożliwi analizowanie playlisty.

Co #EXT-X-TARGETDURATION sekundy odświeżamy playlistę lub plik manifestu, aby uzyskać nowe listy segmentów. Następnie aktualizujemy nową wewnętrzną reprezentację wszystkich segmentów. Za każdym razem, gdy żądane jest wyszukiwanie, wyszukiwanie uwzględnia tylko zakres możliwy do wyszukania. W przypadku transmisji na żywo zezwalamy tylko na przewijanie od początku najnowszej listy do czasu trwania docelowego wynoszącego 3 elementy od końca. Na przykład jeśli na liście 10 segmentów jest 6 segment, możesz wyszukać tylko 7, a nie 8.

Obsługa formatu segmentu

Pakiet SDK CAF obsługuje odtwarzanie treści dźwiękowych w wielu formatach, jak w przypadku HlsSegmentFormat (audio) i HlsVideoSegmentFormat (wideo). Obejmuje to obsługę skompresowanego dźwięku, np. odtwarzania plików AAC i AC3, zarówno w przypadku szyfrowania, jak i niezaszyfrowanego. Podanie tych informacji w sekcji MediaInformation jest wymagane w przypadku LoadRequestData, aby można było poprawnie opisać treści odtwarzaczowi. Jeśli nie podasz żadnej wartości, domyślna konfiguracja odtwarzacza spróbuje odtworzyć zawartość jako zawartość w pakiecie Transport Stream. Tę właściwość można ustawić od dowolnego nadawcy w danych żądania wczytania (Android, iOS i internet) lub w odbiorniku za pomocą funkcji przechwytywania wiadomości.

Zapoznaj się z przykładowym fragmentem kodu poniżej lub z przewodnikiem Wczytywanie multimediów przy użyciu parametru contentId, contentUrl and entity, aby uzyskać więcej informacji o przygotowywaniu treści w odbiorniku internetowym.

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

Ochrona treści

Jak podano w sekcji dotyczącej tagu #EXT-X-KEY powyżej, pakiet SDK Cast obsługuje SAMPLE-AES lub SAMPLE-AES-CTR, gdzie można określić identyfikator URI klucza wektora inicjującego:

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

KEYFORMAT, który obsługujemy obecnie, to Widevine. Identyfikator URI zawiera informacje DRM w formacie BASE64 XXXXXXX, które po zdekodowaniu zawierają identyfikator klucza:

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

Wersja 1 zawiera te atrybuty:

Atrybut Przykład Opis
KEYFORMATVERSIONS "1" Ta oferta pakietowa określa format klucza w wersji 1
KEYFORMAT "urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed" Identyfikator UUID to identyfikator Widevine UUID z DASH IF IOP. Ten sam ciąg znaków jest używany w MPD ze strumieniami zaszyfrowanymi Widevine.
URI "data:text/plain;base64, <base64 encoded PSSH box>" Identyfikator URI strumienia zawierającego typ danych i pole PSSH.
METHOD SAMPLE-AES-CTR Wskazuje mechanizm szyfrowania używany podczas szyfrowania treści. SAMPLE-AES sygnalizuje, że treści są szyfrowane za pomocą parametru „cbcs”. SAMPLE-AES-CTR sygnalizuje, że treści są szyfrowane za pomocą jednego ze schematów zabezpieczeń AES-CTR, czyli „cenc”.

Atrybuty zmapowane na MPD DASH:

Atrybut Opis
KEYFORMAT Atrybut schemaIdUri elementu ContentProtection.
URI Zawartość elementu cenc:pssh.
KEYID 16-bajtowy ciąg szesnastkowy kodujący identyfikator klucza, który ma tę samą rolę co default_kid w MPEG DASH. Jeśli używasz hierarchicznego schematu kluczy, będzie to klucz „root”.

Przykładowa playlista HLS z sygnałem 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

Poniżej znajdziesz listę funkcji i tagów HLS, których obecnie nie używamy ani nie obsługujemy. Ich obecność lub nieobecność nie ma wpływu na zachowanie transmisji.

  • Atrybut RESOLUTION= w dyrektywie #EXT-X-STREAM-INF jest ignorowany.
  • Atrybut AUTOSELECT= w zasobniku #EXT-X-MEDIA nie jest używany. Zamiast tego polegamy na DEFAULT=
  • Element #EXT-X-I-FRAME-STREAM-INF na playliście reklamy nadrzędnej jest ignorowany.
  • #EXT-X-DISCONTINUITY-SEQUENCE jest ignorowany(a)
  • Element #EXT-X-PLAYLIST-TYPE:EVENT może występować w transmisji na żywo, a element #EXT-X-PLAYLIST-TYPE:VOD – w strumieniu VOD, ale obecnie nasz odtwarzacz internetowy korzysta tylko z parametru #EXT-X-ENDLIST do określenia transmisji na żywo z treściami na żądanie (VOD).

Płynne strumieniowanie

Oficjalna specyfikacja Smooth Streaming firmy Microsoft.

Płynne strumieniowanie zapewnia adaptacyjny protokół strumieniowego przesyłania danych i specyfikację XML przez HTTP (podobnie jak DASH). W odróżnieniu od DASH funkcja Smooth Streaming rekomenduje w przypadku segmentów multimedialnych tylko format MPEG-4.

Oto tabela z najpopularniejszymi tagami i atrybutami w funkcji Smooth Streaming, które obecnie obsługuje odtwarzacz Web Receivedr Player. Wiele pojęć zostało już wyjaśnionych w sekcji DASH powyżej.

Tag/atrybut Wykorzystanie
<SmoothStreamingMedia> Główny tag pliku manifestu; zawiera atrybuty:
  • Skala czasu: liczba jednostek reprezentująca 1 sekundę, zwykle przyrost co 10 000 000.
  • Czas trwania: długość treści w skali czasowej. Odtwarzacz internetowy nie obsługuje czasów trwania krótszych niż 0,1 s.
  • IsLive: określa, czy plik manifestu jest aktywny.
<StreamIndex> Jeden zestaw strumieni, podobny do AdaptationSet w DASH. Jego typ to zwykle „tekst”, „wideo” lub „audio”. Atrybut URL zwykle zawiera szablonowy adres URL z fragmentem z informacjami takimi jak szybkość transmisji bitów czy czas rozpoczęcia.
<QualityLevel> Każdy tag QualityLevel określa swoją szybkość transmisji bitów i kodek FourCC. Kody FourCC to często „H264”, „AVC1”, „AACL” itp. W przypadku filmów określa się ich rozdzielczości za pomocą wartości MaxRange i MaxHeight. W przypadku audio określa częstotliwość (np. 44100) przez częstotliwość próbkowania i liczbę kanałów.
<c> Element Stream Fragment. Zawiera:
  • d: czas trwania fragmentu.
  • T: czas mediów we fragmencie.
<Zabezpieczenie> Tag z opcjonalnym atrybutem SystemID zawierający identyfikator systemu DRM, który ma być używany w tagu <SmoothStreamingMedia>.
<ProtectionHeader> W polu <Protection> może zawierać atrybut SystemID oraz dane niestandardowe, zwykle zakodowane w standardzie Base64. W przypadku Widevine zawiera on identyfikator klucza, długość klucza, identyfikator algorytmu, np. AESCTR, LA_URL (adres URL pozyskiwania licencji), LUI_URL (adres URL interfejsu licencji) i DS_ID (identyfikator usługi domeny).

Ochrona treści

Aby prawidłowo zakodować identyfikatory systemu ochrony, użyj tego mapowania:

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

W przypadku formatu <ProtectionHeader> poniżej znajdziesz przykład danych zakodowanych w standardzie Base64. Po zdekodowaniu dane po zdekodowaniu mają taki sam format jak opisano w opisie powyżej w sekcji dotyczącej ochrony treści DASH.

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

Poniżej znajdziesz przykład pliku manifestu do sprawnego transmitowania na żywo z 3000-sekundowym czasem trwania treści:

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

W powyższym przykładzie strumienia wideo szablon URL to:

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

Zatem pierwsze 2 segmenty (zakładając, że mamy poziom jakości indeksu 2) będą następujące. Czas początkowy jest wyodrębniany z parametru t="80649401378125" w ramach wskaźnika StreamIndex (Video StreamIndex) z przyrostem czasu wynoszącym 4 sekundy × 10000000 na segment:

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

Oto lista atrybutów Smooth Streaming, które obecnie ignorujemy i nie mają one wpływu na strumieniowanie danych, niezależnie od tego, czy są one podane:

  • CanSeek i CanPause w tagu <SmoothStreamingMedia>.
  • Chunks i QualityLevels w tagu <StreamIndex>. Zamiast tego liczbę segmentów i poziomów jakości obliczamy na podstawie informacji podanych w elemencie <StreamIndex>, takich jak rzeczywisty tag QualityLevel i tagi <c>.
  • Kolumny BitsPerSample i PacketSize w komponencie <QualityLevel> nie są używane.

Sprawdź typ wyświetlacza

Metoda canDisplayType sprawdza możliwości wideo i audio odbiornika internetowego, a następnie wyświetla, weryfikując przekazane parametry multimediów i zwracając wartość logiczną. Wszystkie parametry – pierwszy z nich jest opcjonalny – im więcej parametrów dodasz, tym dokładniejsze będzie sprawdzenie.

Podpis: canDisplayType(<em>mimeType</em>,<em>codecs</em>,<em>width</em>,<em>height</em>,<em>framerate</em>)

Przykłady:

Sprawdza, czy odbiornik i wyświetlacz internetowy obsługują typ MIME wideo/mp4 z tym konkretnym kodekiem, wymiarami i liczbą klatek na sekundę:

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

Sprawdza, czy odbiornik i wyświetlacz obsługują format wideo 4K dla tego kodeka, określając szerokość 3840 i wysokość 2160:

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

Sprawdza, czy odbiornik i wyświetlacz obsługują HDR10 w przypadku tego kodeka, wymiarów i liczby klatek:

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

Sprawdza, czy odbiornik i wyświetlacz WWW obsługują Dolby Vision (DV) w przypadku tego kodeka, wymiarów i liczby klatek na sekundę:

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

zarządzanie prawami cyfrowymi

Niektóre treści multimedialne wymagają systemu zarządzania prawami cyfrowymi (DRM). W przypadku treści multimedialnych, które mają licencję DRM (i adres URL klucza) zapisane w pliku manifestu (DASH lub HLS), pakiet SDK Cast zajmuje się tym za Ciebie. Podzbiór tych treści wymaga licenseUrl, który jest potrzebny do uzyskania klucza odszyfrowywania. W odbiorniku internetowym możesz użyć PlaybackConfig, aby odpowiednio ustawić licenseUrl.

Ten fragment kodu pozwala ustawić informacje na potrzeby żądań licencji, takich jak 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;
});

Jeśli masz integrację z Asystentem Google, niektóre informacje DRM, np. dane uwierzytelniające niezbędne do treści, mogą być bezpośrednio powiązane z Twoim kontem Google za pomocą takich mechanizmów jak OAuth/SSO. W takich przypadkach, jeśli treści multimedialne są ładowane głosowo lub pobierane z chmury, na urządzeniu przesyłającym dostarczającym dane jest wywoływany setCredentials z chmury. Aplikacje utworzone za pomocą aplikacji Web Detectr mogą w razie potrzeby używać informacji setCredentials do obsługi DRM. Oto przykład użycia danych logowania do utworzenia mediów.

Wskazówka: zobacz też Wczytywanie multimediów przy użyciu parametru contentId, contentUrl i encji.

Obsługa kanałów audio

Gdy odtwarzacz przesyłający wczytuje multimedia, konfiguruje pojedynczy bufor źródła dźwięku. Jednocześnie wybiera odpowiedni kodek do użycia przez bufor na podstawie typu MIME ścieżki głównej. Skonfigurowano nowy bufor i kodek:

  • po rozpoczęciu odtwarzania,
  • przy każdej przerwie na reklamę.
  • za każdym razem, gdy wznowimy główną część treści.

Ponieważ bufor używa jednego kodeka, a kodek jest wybierany na podstawie ścieżki podstawowej, są sytuacje, w których ścieżki dodatkowe mogą zostać odfiltrowane i nie będą słyszane. Może się tak zdarzyć, gdy główna ścieżka programu multimediów jest z dźwiękiem przestrzennym, a dodatkowe ścieżki audio wykorzystują dźwięk stereo. Ścieżki dodatkowe są często wykorzystywane do udostępniania treści w innych językach, więc przesyłanie multimediów z różną liczbą utworów może mieć istotny wpływ, ponieważ duża liczba widzów nie słyszy treści w ich języku ojczystym.

Poniższe scenariusze ilustrują, dlaczego ważne jest dostarczanie treści programowych, gdy ścieżki główne i dodatkowe zawierają tę samą liczbę kanałów:

Scenariusz 1 – w strumieniu multimediów brakuje spójności między ścieżkami głównymi i dodatkowymi:

  • angielski – kanał AC-3 5.1 (podstawowy)
  • szwedzki – 2-kanałowy AAC
  • francuski – 2-kanałowy AAC
  • niemiecki – 2-kanałowy AAC

W takiej sytuacji, gdy język odtwarzacza jest ustawiony na inny niż angielski, użytkownik nie słyszy utworu, którego się spodziewał, ponieważ podczas odtwarzania wszystkie ścieżki dwukanałowe są odfiltrowywane. Jedynym utworem, który można odtworzyć, był główny kanał AC-3 5.1 – i tylko wtedy, gdy język jest ustawiony na angielski.

Scenariusz 2 – strumień multimediów ze spójnością kanałów na ścieżkach głównych i dodatkowych:

  • angielski – kanał AC-3 5.1 (podstawowy)
  • szwedzki – kanał AC-3 5.1
  • francuski – kanał AC-3 5.1
  • niemiecki – kanał AC-3 5.1

Ponieważ wszystkie ścieżki z tej transmisji mają taką samą liczbę kanałów, odbiorcy usłyszą utwór niezależnie od wybranego języka.

Obsługa kanałów audio Shaka

Odtwarzacz Shaka (DASH) domyślnie ustawia preferowaną liczbę kanałów równą 2. Jest to środek łagodzący, gdy natrafisz na multimedia, które nie mają spójności między dodatkowymi ścieżkami audio.

Jeśli główna ścieżka nie jest dźwiękiem przestrzennym (na przykład dwukanałową ścieżką stereo), odtwarzacz Shaka domyślnie ustawi dwa kanały i automatycznie odfiltruje dodatkowe ścieżki multimedialne, które mają więcej niż 2 kanały.

Preferowaną przez Shaka liczbę kanałów audio można też skonfigurować, ustawiając właściwość preferredAudioChannelCount we właściwości shakaConfig w pliku cast.framework.PlaybackConfig.

Na przykład:

shakaConfig = { "preferredAudioChannelCount": 6 };

Gdy preferredAudioChannelCount ma wartość 6, Shaka Player sprawdza, czy obsługuje kodeki dźwięku przestrzennego (AC-3 lub EC-3), i automatycznie odfiltrowuje wszystkie ścieżki multimedialne, które nie są zgodne z preferowaną liczbą kanałów.