Протоколы потоковой передачи веб-приемника проигрывателя

Web Receiver SDK на сегодняшний день поддерживает три типа протоколов потоковой передачи:

DASH , HTTP Live Streaming и Smooth Streaming .

В этом документе мы перечисляем нашу поддержку для каждого из протоколов потоковой передачи. Обратите внимание, что объяснение поддерживаемых тегов для каждого протокола весьма сокращено по сравнению с подробной спецификацией протокола. Цель состоит в том, чтобы дать краткое представление и понимание того, как использовать каждый протокол и какие функции протокола поддерживаются на устройствах с поддержкой Cast для обеспечения потоковой передачи.

Динамическая адаптивная потоковая передача через HTTP (DASH)

Подробная спецификация DASH по стандарту ISO.

DASH — это протокол потоковой передачи с адаптивным битрейтом, который обеспечивает высококачественную потоковую передачу видео через HTTP(S)-серверы. Манифест, составленный в формате XML, содержит большую часть метаданных, необходимых для инициализации и загрузки видеоконтента. Ключевыми понятиями, которые поддерживает проигрыватель Web-приемника, являются <Period> , <AdaptationSet> , <Representation> , <SegmentTemplate> , <SegmentList> , <BaseUrl> и <ContentProtection> .

Манифест DASH начинается с корневого тега <MPD> и включает в себя один или несколько тегов <Period> , которые представляют один потоковый контент. Теги <Period> позволяют упорядочивать различные части потокового контента и часто используются для разделения основного контента и рекламы или нескольких последовательных видеоконтентов.

<AdaptationSet> в <MPD> — это набор представлений для одного типа медиапотока, в большинстве случаев видео, аудио или субтитров. Наиболее часто поддерживаемыми типами mime являются «video/mp4», «audio/mp4» и «text/vtt». Необязательный <ContentComponent contentType="$TYPE$"> можно включить в <AdaptationSet> .

Внутри каждого <AdaptationSet> должен присутствовать список тегов <Representation> , и проигрыватель веб-приемника использует информацию codecs для инициализации исходного буфера MSE и информацию о bandwidth для автоматического выбора правильного представления/битрейта для воспроизведения.

Для каждого <Representation> медиасегменты описываются либо с помощью <BaseURL> для представления одного сегмента, <SegmentList> для списка сегментов (аналогично HLS), либо <SegmentTemplate> .

Для <SegmentTemplate> он указывает, как сегмент инициализации и медиа-сегменты могут быть представлены с помощью шаблонов. В приведенном ниже примере $Number$ указывает номер сегмента, доступный в CDN. Таким образом, по мере продолжения воспроизведения он преобразуется в seg1.m4s, seg2.m4s и т. д.

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

Для <SegmentTemplate> обычно используется тег <SegmentTimeline> , чтобы указать длину каждого сегмента и какие сегменты повторяются. timescale (единицы измерения, обозначающие одну секунду) часто включается как часть атрибутов <SegmentTemplate> , чтобы мы могли вычислить время сегмента на основе этой единицы. В приведенном ниже примере тег <S> обозначает тег сегмента, атрибут d указывает длину сегмента, а атрибут r указывает, сколько сегментов одинаковой продолжительности повторяется, чтобы можно было правильно рассчитать $Time$ для загрузки мультимедиа. сегмент, как указано в атрибуте 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>

Ниже приведен пример представления с использованием <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>

Для файла с одним сегментом <SegmentBase> часто используется с запросами диапазона байтов, чтобы указать, какая часть файла <BaseURL> содержит индекс, а остальная часть может быть получена по требованию по мере продолжения воспроизведения или поиска. Здесь диапазон Initialization указывает диапазон метаданных инициализации, а indexRange указывает индекс для медиа-сегментов. Обратите внимание, что сейчас мы поддерживаем только последовательные диапазоны байтов.

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

Независимо от того, какое представление используется, если потоки защищены, раздел <ContentProtection> может появиться в разделе <AdaptationSet> , где schemeIdUri однозначно идентифицирует используемую систему DRM. Для общего шифрования можно включить дополнительный идентификатор ключа.

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

Дополнительные примеры и подробную информацию см. в спецификации MPEG-DASH. Ниже приведен список дополнительных атрибутов DASH в тегах, не упомянутых выше, которые мы в настоящее время поддерживаем:

имя атрибута Атрибут Функция
СМИПрезентацияПродолжительность Продолжительность видеоконтента.
Минимальный период обновления Атрибут тега <MPD> ; указывает, как часто нам нужно перезагружать манифест.
тип Атрибут тега <MPD> ; «динамический», чтобы указать, что это прямая трансляция.
презентацияTimeOffset Атрибут тега <SegmentBase> ; задает смещение времени представления от начала периода.
стартовый номер Указывает номер первого медиасегмента в презентации за период. Это часто используется в прямом эфире.

Мы также поддерживаем распознавание блока EMSG внутри фрагментов MP4 для DASH и предоставляем разработчикам EmsgEvent .

Хотя наш текущий проигрыватель Web-приемник поддерживает основные варианты использования DASH, вот список общих атрибутов, которые наша текущая реализация DASH игнорирует или не использует. Это означает, что независимо от того, содержатся ли они в манифесте, они не влияют на качество воспроизведения контента.

  • доступностьStartTime
  • сегментВыравнивание

Прямая трансляция HTTP (HLS)

Обзор и полную спецификацию потокового вещания по протоколу HTTP можно получить здесь .

Одной из ключевых сильных сторон Web Receiver Player является его способность поддерживать воспроизведение HLS в MSE. В отличие от DASH, где манифест поставляется в одном файле, HLS отправляет основной список воспроизведения, содержащий список всех вариантов потоков с соответствующими URL-адресами. Вариант списка воспроизведения представляет собой список воспроизведения мультимедиа. Два основных тега HLS, которые в настоящее время поддерживаются Web-ресивером в основном списке воспроизведения:

Название тэга Функциональность
#EXT-X-STREAM-INF Указывает битрейт/вариант потока. Требуется атрибут BANDWIDTH , который поддерживает выбор потоковой передачи с адаптивным битрейтом. Атрибут CODECS настоятельно рекомендуется использовать для инициализации MSE, например "avc1.42c01e,mp4a.40.2" . Если не указано, по умолчанию устанавливается видео основного профиля H264 3.0 и аудиоконтент в кодировке "mp4a.40.2" .
#EXT-X-MEDIA Указывает дополнительный список воспроизведения мультимедиа (в атрибуте URI ), представляющий содержимое. Обычно это альтернативные аудиопотоки в другом формате (объемный звук 5.1) или на другом языке. Допускается атрибут TYPE содержащий VIDEO , AUDIO , SUBTITLES или CLOSED-CAPTIONS . Установка атрибута DEFAULT в YES будет указывать на выбор этого альтернативного потока по умолчанию.

Вот список тегов HLS, которые в настоящее время поддерживает проигрыватель Web-ресивера в списке воспроизведения мультимедиа:

Название тэга Функциональность
#EXTINF Информация о потоке, за которой обычно следует продолжительность сегмента в секундах, а в следующей строке — URL-адрес сегмента.
#EXT-X-TARGETDURATION Продолжительность каждого сегмента в секундах. Это также определяет, как часто мы загружаем/обновляем манифест плейлиста для прямой трансляции. Проигрыватель веб-приемника не поддерживает продолжительность менее 0,1 секунды.
#EXT-X-MEDIA-SEQUENCE Порядковый номер (часто для прямой трансляции), который представляет первый сегмент в этом списке воспроизведения.
#EXT-X-KEY Ключевая информация DRM. Атрибут METHOD сообщает нам, какую систему ключей использовать. Сегодня мы поддерживаем AES-128 и SAMPLE-AES .
#EXT-X-BYTERANGE Диапазон байтов для выборки URL-адреса сегмента.
#EXT-X-ПРЕРЫВАНИЕ Указывает разрыв между последовательными сегментами. Это часто наблюдается при вставке рекламы на стороне сервера, когда сегмент рекламы появляется в середине основного потока.
#EXT-X-ПРОГРАММА-ДАТА-ВРЕМЯ Абсолютное время первой выборки следующего сегмента, например «2016-09-21T23:23:52.066Z».
#EXT-X-ENDLIST Будь то VOD или прямая трансляция.

Для прямой трансляции мы используем #EXT-X-PROGRAM-DATE-TIME и #EXT-X-MEDIA-SEQUENCE в качестве ключевых факторов для определения того, как объединить недавно обновленный манифест. Если присутствует, #EXT-X-PROGRAM-DATE-TIME используется для сопоставления обновленных сегментов. В противном случае будет использоваться номер #EXT-X-MEDIA-SEQUENCE . Обратите внимание, что согласно спецификации HLS мы не используем сравнение имен файлов для сопоставления.

Наша реализация HLS поддерживает выбор альтернативного аудиопотока, например объемного звука 5.1, в качестве основного воспроизведения звука. Этого можно добиться, используя тег #EXT-X-MEDIA с альтернативными кодеками, а также указав формат сегмента в конфигурации потока.

Проигрыватель веб-приемника ожидает определенного поведения в зависимости от спецификации. Например, после тега #EXT-INF мы ожидаем URI. Если это не URI, например #EXT-X-DISCOUNTINUITY это приведет к сбою анализа списка воспроизведения.

Каждые #EXT-X-TARGETDURATION секунд мы перезагружаем список воспроизведения/манифест, чтобы получить новые списки сегментов, и обновляем новое внутреннее представление всех сегментов до нового. Каждый раз, когда запрашивается поиск, мы ищем только в пределах диапазона поиска. В режиме реального времени мы разрешаем поиск только от начала новейшего списка до трех целевых значений от конца. Например, если у вас есть список из 10 сегментов и вы находитесь в сегменте 6, вы можете искать только до 7, но не до 8.

Поддержка формата сегмента

CAF SDK поддерживает воспроизведение контента, доставленного в нескольких форматах, как указано в HlsSegmentFormat для аудио и HlsVideoSegmentFormat для видео. Сюда входит поддержка упакованного аудио , такого как воспроизведение AAC и AC3, как зашифрованного, так и незашифрованного. Необходимо указать эту информацию в MediaInformation LoadRequestData , чтобы правильно описать ваш контент проигрывателю. Если не указано, конфигурация проигрывателя по умолчанию попытается воспроизвести содержимое как упакованное содержимое Транспортного потока. Это свойство можно установить у любого отправителя в данных запроса загрузки ( Android , iOS и Web ) или внутри получателя через перехватчики сообщений.

Ознакомьтесь с приведенным ниже примером фрагмента кода или руководством по загрузке мультимедиа с использованием contentId, contentUrl и сущности для получения дополнительной информации о том, как подготовить контент в веб-приемнике.

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

Защита контента

Как указано в разделе тега #EXT-X-KEY выше, Cast SDK поддерживает SAMPLE-AES или SAMPLE-AES-CTR , где можно указать URI ключа и вектор инициализации:

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

Сейчас мы поддерживаем KEYFORMAT — Widevine, а URI содержит информацию DRM XXXXXXX в кодировке BASE64, которая при декодировании содержит идентификатор ключа:

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

Версия 1 определяет следующие атрибуты:

Атрибут Пример Описание
KEYFORMATVERSIONS "1" Это предложение определяет версию 1 формата ключа.
KEYFORMAT "urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed" UUID — это UUID Widevine из DASH IF IOP. Та же самая строка используется в MPD с зашифрованными потоками Widevine.
URI "data:text/plain;base64, <base64 encoded PSSH box>" URI потока, содержащий тип данных и поле PSSH.
METHOD SAMPLE-AES-CTR Указывает шифр шифрования, используемый при шифровании содержимого. SAMPLE-AES сигнализирует о том, что контент зашифрован с использованием «cbcs». SAMPLE-AES-CTR сигнализирует о том, что контент зашифрован с использованием одной из схем защиты AES-CTR, а именно «cenc».

Атрибуты, сопоставленные с DASH MPD:

Атрибут Описание
KEYFORMAT Атрибут SchemIdUri элемента ContentProtection.
URI Содержимое элемента centc:pssh.
KEYID 16-байтовая шестнадцатеричная строка, кодирующая идентификатор ключа, который играет ту же роль, что и default_kid в MPEG DASH. При использовании иерархической схемы ключей это будет «корневой» ключ.

Пример плейлиста HLS с сигнализацией 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

Ниже приведен список функций и тегов HLS, которые мы в настоящее время не используем и не поддерживаем. Их наличие или отсутствие не влияет на поведение потоковой передачи.

  • Атрибут RESOLUTION= в #EXT-X-STREAM-INF игнорируется.
  • Атрибут AUTOSELECT= в #EXT-X-MEDIA не используется. Вместо этого мы полагаемся на DEFAULT=
  • #EXT-XI-FRAME-STREAM-INF в основном списке воспроизведения игнорируется.
  • #EXT-X-DISCONTINUITY-SEQUENCE игнорируется.
  • #EXT-X-PLAYLIST-TYPE:EVENT может присутствовать в прямой трансляции, а #EXT-X-PLAYLIST-TYPE:VOD может присутствовать в потоке VOD, но в настоящее время наш веб-плеер-приемник полагается только на наличие #EXT-X-ENDLIST , чтобы определить прямую трансляцию или VOD.

Плавная потоковая передача

Официальная спецификация Smooth Streaming от Microsoft.

Плавная потоковая передача обеспечивает адаптивный протокол потоковой передачи и спецификацию XML через HTTP (аналогично DASH). В отличие от DASH, Smooth Streaming рекомендует для медиа-сегментов только упаковку MPEG-4.

Ниже приведена таблица наиболее распространенных тегов и атрибутов Smooth Streaming, которые сегодня поддерживает Web Receiver Player. Многие концепции уже объяснены в разделе DASH выше.

Тег/Атрибут Применение
<СмузСтримингМедиа> Главный тег манифеста содержит атрибуты:
  • TimeScale: количество единиц, представляющих одну секунду, обычно с шагом 10 000 000.
  • Продолжительность: продолжительность контента во временной шкале. Проигрыватель веб-приемника не поддерживает продолжительность менее 0,1 секунды.
  • IsLive: является ли манифест живым носителем.
<Индекс Стрима> Один набор потоков, аналогичный AdaptationSet в DASH. Обычно это «текст», «видео» или «аудио». Атрибут Url обычно содержит шаблонный URL-адрес фрагмента с использованием такой информации, как битрейт или время начала.
<Уровень Качества> Каждый тег QualityLevel указывает свой битрейт и кодек FourCC. Кодом FourCC часто являются «H264», «AVC1», «AACL» и т. д. Для видео он определяет разрешение через MaxWidth и MaxHeight. Для звука он определяет его частоту (например, 44100) через SamplingRate и количество каналов.
<с> Элемент фрагмента потока. Содержит:
  • d: продолжительность фрагмента.
  • t: Медиа-время фрагмента.
<Защита> Тег с необязательным атрибутом SystemID, в котором указан идентификатор системного DRM, который будет использоваться в теге <SmoothStreamingMedia>.
<ЗаголовокЗащиты> В разделе <Защита> может содержать атрибут SystemID и пользовательские данные, обычно в кодировке Base64. Для Widevine он будет содержать идентификатор ключа, длину ключа, идентификатор алгоритма, например AESCTR, LA_URL (URL-адрес получения лицензии), LUI_URL (URL-адрес пользовательского интерфейса лицензии) и DS_ID (идентификатор службы домена).

Защита контента

Чтобы правильно закодировать идентификаторы системы защиты, используйте приведенное ниже сопоставление:

  • ШИРОКАЯ ЛОЗА: 'EDEF8BA9-79D6-4ACE-A3C8-27DCD51D21ED',
  • ЧИСТЫЙ КЛЮЧ: '1077EFEC-C0B2-4D02-ACE3-3C1E52E2FB4B',
  • MPEG_DASH_MP4PROTECTION: 'URN:MPEG:DASH:MP4PROTECTION:2011'

Для <ProtectionHeader> ниже приведен пример данных в кодировке Base64. Данные при декодировании соответствуют тому же декодированному формату, который описан выше в разделе о поддержке защиты контента DASH.

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

Ниже приведен пример манифеста потоковой передачи Smooth с длительностью контента 3000 секунд:

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

В приведенном выше примере видеопотока шаблон URL-адреса:

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

Таким образом, первые два сегмента (при условии, что мы находимся на уровне качества индекса 2) будут следующими: начальное время будет извлечено из t="80649401378125" под видео StreamIndex и шагом времени 4 секунды * 10000000 на сегмент:

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

Вот список атрибутов Smooth Streaming, которые мы в настоящее время игнорируем и не оказываем никакого влияния на потоковую передачу независимо от того, предоставлены ли они:

  • CanSeek , CanPause в теге <SmoothStreamingMedia> .
  • Chunks , QualityLevels в теге <StreamIndex> . Вместо этого мы рассчитываем количество сегментов и количество уровней качества на основе информации, предоставленной внутри <StreamIndex> , такой как фактический тег QualityLevel и теги <c> .
  • BitsPerSample , PacketSize в <QualityLevel> не используется.

Проверьте тип дисплея

Метод canDisplayType проверяет возможности видео и аудио устройства веб-приемника и отображает их, проверяя переданные параметры мультимедиа и возвращая логическое значение. Все параметры, кроме первого, являются необязательными — чем больше параметров вы включите, тем точнее будет проверка.

Его подпись canDisplayType(<em>mimeType</em>,<em>codecs</em>,<em>width</em>,<em>height</em>,<em>framerate</em>)

Примеры:

Проверяет, поддерживает ли устройство веб-приемника и дисплей mime-тип видео/mp4 с этим конкретным кодеком, размерами и частотой кадров:

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

Проверяет, поддерживает ли устройство веб-приемника и дисплей формат видео 4K для этого кодека, указав ширину 3840 и высоту 2160:

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

Проверяет, поддерживает ли устройство веб-приемника и дисплей HDR10 для этого кодека, размеры и частоту кадров:

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

Проверяет, поддерживает ли устройство веб-приемника и дисплей Dolby Vision (DV) для этого кодека, размеры и частоту кадров:

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

УЦП

Для некоторого медиаконтента требуется управление цифровыми правами (DRM). Для медиа-контента, лицензия DRM (и URL-адрес ключа которого хранится в манифесте (DASH или HLS), Cast SDK обрабатывает этот случай за вас. Для части этого контента требуется licenseUrl , необходимый для получения ключа дешифрования. В веб-приемнике вы можете использовать PlaybackConfig , чтобы при необходимости установить licenseUrl .

В следующем фрагменте кода показано, как можно задать информацию для запросов лицензий, таких как 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;
});

Если у вас есть интеграция с Google Assistant, некоторая информация DRM, такая как учетные данные, необходимые для контента, может быть связана непосредственно с вашей учетной записью Google с помощью таких механизмов, как OAuth/SSO. В тех случаях, если медиаконтент загружается посредством голоса или поступает из облака, setCredentials вызывается из облака на устройство Cast, предоставляющее эти учетные данные. Приложения, создающие приложение веб-приемника, могут затем использовать информацию setCredentials для управления DRM по мере необходимости. Вот пример использования учетных данных для создания носителя.

Совет . См. также раздел Загрузка мультимедиа с использованием contentId, contentUrl иentity .

Обработка аудиоканала

Когда проигрыватель Cast загружает медиафайлы, он устанавливает один буфер источника звука. В то же время он также выбирает подходящий кодек для использования буфером на основе типа MIME основной дорожки. Устанавливаются новый буфер и кодек:

  • когда начнется воспроизведение,
  • во время каждой рекламной паузы и
  • каждый раз, когда возобновляется основной контент.

Поскольку в буфере используется один кодек и поскольку кодек выбирается на основе основной дорожки, бывают ситуации, когда второстепенные дорожки могут быть отфильтрованы и не услышаны. Это может произойти, если основная дорожка мультимедийной программы имеет объемный звук, а вторичные звуковые дорожки используют стереозвук. Поскольку второстепенные треки часто используются для предложения контента на альтернативных языках, предоставление носителей, содержащих разное количество треков, может иметь существенное влияние, например, когда большое количество зрителей не смогут слышать контент на своем родном языке.

Следующие сценарии иллюстрируют, почему важно обеспечивать программы, в которых первичные и вторичные дорожки содержат одинаковое количество каналов:

Сценарий 1 — медиапоток без четности каналов на первичном и вторичном каналах:

  • английский — канал AC-3 5.1 (основной)
  • шведский — AAC, 2 канала
  • французский — AAC, 2 канала
  • немецкий - AAC 2-канальный

В этом сценарии, если в качестве языка проигрывателя установлено любое значение, кроме английского, пользователь не слышит дорожку, которую он ожидает услышать, поскольку все двухканальные дорожки отфильтровываются во время воспроизведения. Единственная дорожка, которую можно воспроизводить, — это основной 5.1-канальный AC-3, и то только тогда, когда в качестве языка установлен английский.

Сценарий 2 — медиапоток с четностью каналов на первичном и вторичном треках:

  • английский — канал AC-3 5.1 (основной)
  • шведский - канал AC-3 5.1
  • французский - канал AC-3 5.1
  • немецкий - AC-3 5.1 канал

Поскольку все треки этого потока имеют одинаковое количество каналов, аудитория услышит трек независимо от выбранного языка.

Обработка аудиоканала Shaka

Проигрыватель Shaka (DASH) по умолчанию использует предпочтительное количество каналов, равное двум, в качестве меры по снижению риска при обнаружении мультимедиа, которому не хватает четности на вторичных звуковых дорожках.

Если основная дорожка не является объемным звуком (например, двухканальная стереодорожка), то проигрыватель Shaka по умолчанию использует два канала и автоматически отфильтровывает любые второстепенные мультимедийные дорожки, имеющие более двух каналов.

Предпочитаемое количество аудиоканалов Shaka также можно настроить, установив preferredAudioChannelCount в свойстве shakaConfig в cast.framework.PlaybackConfig .

Например:

shakaConfig = { "preferredAudioChannelCount": 6 };

Если для preferredAudioChannelCount установлено значение 6, Shaka Player проверяет, поддерживает ли он кодеки объемного звука ( AC-3 или EC-3 ), и автоматически отфильтровывает любые мультимедийные дорожки, которые не соответствуют предпочтительному количеству каналов.