Protocolos de transmisión del reproductor de receptor web

En la actualidad, el SDK de Web Receiver admite tres tipos de protocolos de transmisión:

DASH, HTTP de transmisión en vivo y Transmisión fluida.

En este documento, enumeramos nuestra compatibilidad con cada uno de los protocolos de transmisión. Ten en cuenta que la explicación de las etiquetas admitidas para cada protocolo es bastante abreviada en comparación con las especificaciones detalladas del protocolo. El objetivo es proporcionar una visión rápida y comprender cómo usar cada protocolo y qué funciones del protocolo son compatibles con los dispositivos compatibles con Cast para ofrecer sus experiencias de transmisión.

Transmisión adaptable y dinámica a través de HTTP (DASH)

La especificación detallada de DASH de ISO.

DASH es un protocolo de transmisión de tasa de bits adaptable que permite la transmisión de video de alta calidad a través de servidores HTTP(S). Un manifiesto, redactado en XML, contiene la mayor parte de la información de metadatos sobre cómo inicializar y descargar el contenido de video. Los conceptos clave que admite el reproductor web receptor son <Period>, <AdaptationSet>, <Representation>, <SegmentTemplate>, <SegmentList>, <BaseUrl> y <ContentProtection>.

Un manifiesto de DASH comienza con una etiqueta raíz <MPD> y, dentro de ella, incluye una o más etiquetas <Period>, que representan un contenido de transmisión. Las etiquetas <Period> permiten ordenar diferentes piezas de contenido de transmisión y, a menudo, se usan para separar el contenido principal y el anuncio o varios contenidos de video consecutivos.

Un <AdaptationSet> en <MPD> es un conjunto de representaciones para un tipo de transmisión multimedia, en la mayoría de los casos, video, audio o subtítulos. Los tipos de MIME que se suelen admitir son "video/mp4", "audio/mp4" y "text/vtt". Se puede incluir un <ContentComponent contentType="$TYPE$"> opcional en <AdaptationSet>.

Dentro de cada <AdaptationSet>, debe haber una lista de etiquetas <Representation>, y el reproductor web receptor usa la información de codecs para inicializar el búfer de origen de MSE y la información de bandwidth para elegir automáticamente la representación o tasa de bits correctas que se reproducirá.

En cada <Representation>, los segmentos multimedia se describen mediante una <BaseURL> para la representación de un solo segmento, <SegmentList> para la lista de segmentos (similar a HLS) o <SegmentTemplate>.

En el caso de un objeto <SegmentTemplate>, indica cómo los segmentos de inicialización y los segmentos de medios se pueden representar a través de plantillas. En el siguiente ejemplo, $Number$ indica el número de segmento disponible en la CDN. Por lo tanto, se traduce a seg1.m4s, seg2.m4s, etc. a medida que continúa la reproducción.

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

En el caso de un <SegmentTemplate>, es común usar la etiqueta <SegmentTimeline> para indicar la longitud de cada segmento y cuáles se repiten. A menudo, se incluye un timescale (unidades para representar un segundo) como parte de los atributos de <SegmentTemplate>, de modo que podamos calcular el tiempo del segmento en función de esta unidad. En el siguiente ejemplo, la etiqueta <S> significa una etiqueta de segmento, el atributo d especifica la longitud del segmento y el atributo r especifica cuántos segmentos de la misma duración se repiten para que se pueda calcular correctamente $Time$ para descargar el segmento multimedia como se especifica en el 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 la representación que usa <SegmentList>, este es un ejemplo:

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

En el caso de un solo archivo de segmento, se suele usar un <SegmentBase> con solicitudes de rango de bytes para especificar qué parte de un archivo <BaseURL> contiene el índice, y el resto se puede recuperar a pedido mientras continúa la reproducción o se produce una búsqueda. Aquí, el rango Initialization especifica el rango de metadatos init y indexRange especifica el índice para los segmentos multimedia. Ten en cuenta que, por el momento, solo admitimos rangos 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>

Independientemente de la representación que se use, si las transmisiones están protegidas, puede aparecer una sección <ContentProtection> en <AdaptationSet>, en la que un schemeIdUri identifica de forma única el sistema DRM que se usará. Se puede incluir un ID de clave opcional para la encriptación común.

<!-- 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 obtener más detalles y ejemplos, consulta la especificación MPEG-DASH. A continuación, se muestra una lista de atributos DASH adicionales en las etiquetas que no se mencionaron anteriormente y que admitimos actualmente:

Nombre del atributo Función del atributo
mediaPresentationDuration La duración del contenido del video
minimumUpdatePeriod Atributo de la etiqueta <MPD>; especifica la frecuencia con la que debemos volver a cargar el manifiesto.
tipo Atributo de la etiqueta <MPD>; es "dinámico" para indicar que se trata de una transmisión en vivo.
presentationTimeOffset Atributo de la etiqueta <SegmentBase>; especifica el desfase de tiempo de presentación desde el principio del período.
startNumber Especifica la cantidad del primer segmento multimedia en una presentación en un período. Suele usarse en las transmisiones en vivo.

También admitimos el reconocimiento de la caja EMSG dentro de los fragmentos MP4 para DASH y proporcionamos un EmsgEvent a los desarrolladores.

Si bien nuestro reproductor web receptor actual admite los principales casos de uso de DASH, a continuación se incluye una lista de atributos comunes que nuestra implementación actual de DASH ignora o no usa. Eso significa que, independientemente de si el manifiesto los contiene, no afectan la experiencia de reproducción del contenido.

  • availabilityStartTime
  • segmentAlignment

HTTP Live Streaming (HLS)

Puedes obtener la descripción general y la especificación completa de la transmisión HTTP en vivo aquí.

Una de las principales ventajas del reproductor web receptor es su capacidad de admitir la reproducción de HLS en ECM. A diferencia de DASH, en el que un manifiesto viene en un solo archivo, HLS envía la lista de reproducción principal que contiene una lista de todas las transmisiones de variantes con su respectiva URL. La playlist de variantes es la playlist de contenido multimedia. Las dos etiquetas HLS principales que admite el reproductor web receptor en la lista de reproducción principal son las siguientes:

Nombre de la etiqueta Funcionalidad
#EXT-X-STREAM-INF Especifica una transmisión de variantes o tasa de bits. Se requiere el atributo BANDWIDTH, que admite la selección de transmisión de tasa de bits adaptable. Se recomienda el atributo CODECS para inicializar el ECM, como "avc1.42c01e,mp4a.40.2". Si no se especifica, la sentencia case predeterminada se establece en el video del perfil principal 3.0 de H264 y en el contenido de audio "mp4a.40.2".
#EXT-X-MEDIA Especifica la lista de reproducción multimedia adicional (en el atributo URI) que representa el contenido. Por lo general, son transmisiones de audio alternativas en otro formato (sonido envolvente 5.1) o idioma. Se permite un atributo de TYPE que contenga VIDEO, AUDIO, SUBTITLES o CLOSED-CAPTIONS. Si configuras el atributo DEFAULT en YES, se indicará que se elige esta transmisión alternativa de forma predeterminada.

A continuación, se muestra una lista de etiquetas HLS que el reproductor web receptor admite actualmente en la lista de reproducción de contenido multimedia:

Nombre de la etiqueta Funcionalidad
#EXTINF Información de transmisión, generalmente seguida de la duración del segmento en segundos y, en la línea siguiente, la URL del segmento.
#EXT-X-TARGETDURATION La duración en segundos de cada segmento. Esto también determina la frecuencia con la que descargamos o actualizamos el manifiesto de la playlist para una transmisión en vivo. El reproductor web receptor no admite duraciones inferiores a 0.1 s.
#EXT-X-MEDIA-SEQUENCE Es el número de secuencia (a menudo para una transmisión en vivo) que representa el primer segmento de esta playlist.
#EXT-X-KEY Información clave de DRM. El atributo METHOD nos indica qué sistema de claves usar. Hoy admitimos AES-128 y SAMPLE-AES.
#EXT-X-BYTERANGE Es el rango de bytes que se debe recuperar para la URL de un segmento.
#EXT-X-DISCONTINUITY Especifica una discontinuidad entre segmentos consecutivos. Esto se suele observar con la inserción de anuncios del servidor, en la que aparece un segmento de anuncios en el medio de la transmisión principal.
#EXT-X-PROGRAM-DATE-TIME Tiempo absoluto de la primera muestra del siguiente segmento (por ejemplo, “2016-09-21T23:23:52.066Z”).
#EXT-X-ENDLIST Indica si se trata de un VOD o de una transmisión en vivo.

Para la transmisión en vivo, usamos #EXT-X-PROGRAM-DATE-TIME y #EXT-X-MEDIA-SEQUENCE como factores clave a fin de determinar cómo combinar un manifiesto recién actualizado. Si está presente, se usa #EXT-X-PROGRAM-DATE-TIME para hacer coincidir los segmentos actualizados. De lo contrario, se usará el número #EXT-X-MEDIA-SEQUENCE. Ten en cuenta que, según la especificación HLS, no usamos la comparación de nombres de archivos para la coincidencia.

Nuestra implementación de HLS admite la selección de una transmisión de audio alternativa, por ejemplo, sonido envolvente 5.1, como la reproducción de audio principal. Esto se puede lograr con una etiqueta #EXT-X-MEDIA con los códecs alternativos y proporcionando el formato del segmento en la configuración de la transmisión.

El reproductor web receptor espera cierto comportamiento según las especificaciones. Por ejemplo, después de una etiqueta #EXT-INF, se espera un URI. Si no es un URI, por ejemplo, #EXT-X-DISCOUNTINUITY, hará que falle el análisis de la lista de reproducción.

Cada #EXT-X-TARGETDURATION segundos, vuelvemos a cargar la playlist o el manifiesto para obtener nuevas listas de segmentos, y actualizamos la representación interna nueva de todos los segmentos al nuevo. Cada vez que se solicita una búsqueda, solo lo hacemos dentro del rango de búsqueda. Para las transmisiones en vivo, solo permitimos buscar desde el comienzo de la lista más reciente hasta una duración objetivo de tres desde el final. Por ejemplo, si tienes una lista de 10 segmentos y estás en el segmento 6, solo puedes buscar hasta 7, pero no 8.

Compatibilidad con formatos de segmentos

El SDK de CAF admite la reproducción de contenido entregado en varios formatos, como se hace en HlsSegmentFormat para audio y HlsVideoSegmentFormat para video. Esto incluye compatibilidad con audio empaquetado, como la reproducción en AAC y AC3, tanto encriptada como no encriptada. Es necesario especificar esta información en el MediaInformation de LoadRequestData para describir correctamente tu contenido al reproductor. Si no se especifica, la configuración predeterminada del reproductor intentará reproducir el contenido como contenido empaquetado de Transport Stream. Esta propiedad se puede configurar desde cualquiera de los remitentes en los datos de solicitudes de carga (Android, iOS y Web) o en el receptor mediante interceptores de mensajes.

Consulta el siguiente fragmento de código de muestra o la guía Cómo cargar contenido multimedia con contentId, contentUrl y entidad para obtener más información sobre cómo preparar contenido en el receptor 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;
    });

Protección de contenido

Como se indica en la sección de etiquetas #EXT-X-KEY anterior, el SDK de Cast admite SAMPLE-AES o SAMPLE-AES-CTR, donde se puede especificar un URI para la clave y un vector de inicialización:

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

El objeto KEYFORMAT que ahora admitimos es Widevine y el URI contiene información de DRM codificada en BASE64 XXXXXXX que, cuando se decodifica, contiene el ID de clave:

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

La versión 1 define los siguientes atributos:

Atributo Ejemplo Descripción
KEYFORMATVERSIONS "1" Esta propuesta define la versión 1 del formato de clave
KEYFORMAT "urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed" El UUID es el UUID de Widevine de DASH IF IOP. Se usa la misma cadena en MPD con las transmisiones encriptadas con Widevine.
URI "data:text/plain;base64, <base64 encoded PSSH box>" El URI de la transmisión que contiene el tipo de datos y el cuadro PSSH.
METHOD SAMPLE-AES-CTR Indica el algoritmo de cifrado de encriptación que se usó para encriptar el contenido. SAMPLE-AES indica que el contenido está encriptado con "cbcs". SAMPLE-AES-CTR indica que el contenido está encriptado con uno de los esquemas de protección de AES-CTR, denominado "cenc".

Atributos asignados a la MPD de DASH:

Atributo Descripción
KEYFORMAT Atributo schemaIdUri del elemento ContentProtection.
URI El contenido del elemento cenc:pssh.
KEYID Cadena hexadecimal de 16 bytes que codifica el ID de clave que tiene el mismo rol que default_kid en MPEG DASH. Si se usa un esquema de claves jerárquicas, esta sería la clave “raíz”.

Ejemplo de lista de reproducción de HLS con señalización 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

A continuación, se muestra una lista de características y etiquetas en HLS que no usamos ni admitimos en la actualidad. Su presencia o ausencia no afectan el comportamiento de la transmisión.

  • Se ignora el atributo RESOLUTION= en #EXT-X-STREAM-INF.
  • No se usa el atributo AUTOSELECT= en #EXT-X-MEDIA. En cambio, nos basamos en DEFAULT=
  • Se ignora #EXT-X-I-FRAME-STREAM-INF en la playlist principal.
  • Se ignora #EXT-X-DISCONTINUITY-SEQUENCE
  • #EXT-X-PLAYLIST-TYPE:EVENT puede estar presente en una transmisión en vivo y #EXT-X-PLAYLIST-TYPE:VOD puede estar en una transmisión de VOD. Sin embargo, por el momento, nuestro reproductor receptor web solo se basa en la existencia de #EXT-X-ENDLIST para determinar en comparación con VOD en vivo.

Transmisión fluida

Especificaciones de transmisión fluida oficiales de Microsoft

La transmisión fluida proporciona un protocolo de transmisión adaptable y una especificación XML a través de HTTP (similar a DASH). A diferencia de DASH, Smooth Streaming solo recomienda el empaquetado MPEG-4 para los segmentos de medios.

A continuación, se muestra una tabla de las etiquetas y los atributos más comunes de Smooth Streaming que admite el reproductor web receptora en la actualidad. Muchos conceptos ya se explican en la sección anterior de DASH.

Etiqueta o atributo Uso
<SmoothStreamingMedia> Etiqueta principal del manifiesto. Contiene los siguientes atributos:
  • TimeScale: Cantidad de unidades para representar un segundo, por lo general, un incremento de 10,000,000.
  • Duración: Muestra la duración del contenido en una escala de tiempo. El reproductor web receptor no admite duraciones inferiores a 0.1 s.
  • IsLive: Indica si el manifiesto es un medio en vivo.
<StreamIndex> Un conjunto de transmisiones, similar al AdaptationSet de DASH. El tipo suele ser "texto", "video" o "audio". Por lo general, el atributo Url contiene una URL de fragmento con plantilla que usa información como la tasa de bits o la hora de inicio.
<QualityLevel> Cada etiqueta QualityLevel especifica su tasa de bits y un códec FourCC. El código FourCC suele ser "H264", "AVC1", "AACL", etc. En el caso de los videos, especifica sus resoluciones mediante MaxWidth y MaxHeight. En el caso del audio, especifica su frecuencia (por ejemplo, 44100) a través de SamplingRate y la cantidad de canales.
<c> Elemento de fragmento de transmisión. Contiene lo siguiente:
  • d: la duración de un fragmento.
  • t: Tiempo de medios del fragmento
<Protección> Es una etiqueta con el atributo opcional SystemID que enumera el ID del sistema DRM que se usará en la etiqueta <SmoothStreamingMedia>.
<ProtectionHeader> En <Protection>, puede contener un atributo de SystemID y datos personalizados, generalmente codificados en Base64. Para Widevine, contendrá el ID de clave, la longitud de la clave, el ID de algoritmo, como AESCTR, LA_URL (URL de adquisición de licencia), LUI_URL (URL de interfaz de usuario de licencia) y DS_ID (ID de servicio de dominio).

Protección de contenido

Para codificar los IDs del sistema de protección correctamente, usa la siguiente asignación:

  • WIDEVINE: "EDEF8BA9-79D6-4ACE-A3C8-27DCD51D21ED".
  • CLAVE CERRADA: "1077EFEC-C0B2-4D02-ACE3-3C1E52E2FB4B"
  • MPEG_DASH_MP4PROTECCIÓN: 'URN:MPEG:DASH:MP4PROTECTION:2011'

Para <ProtectionHeader>, a continuación se muestra un ejemplo con datos codificados en Base64. Cuando los datos se decodifican, cumplen con el mismo formato decodificado que se describe en la compatibilidad de la protección de contenido DASH más arriba.

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

A continuación, se muestra un ejemplo de un manifiesto de transmisión Smooth en vivo con una duración de contenido 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>

En el ejemplo anterior para la transmisión de video por Internet, la plantilla de URL es:

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

Por lo tanto, los dos primeros segmentos (suponiendo que estamos en el nivel de calidad del índice 2) serán los siguientes, con el tiempo inicial extraído de t="80649401378125" bajo el StreamIndex de video y el incremento de tiempo de 4 segundos × 10000000 por segmento:

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

A continuación, se muestra una lista de atributos de Smooth Streaming que ignoramos actualmente y no tienen efecto en las experiencias de transmisión, independientemente de que se proporcionen o no:

  • CanSeek y CanPause en la etiqueta <SmoothStreamingMedia>.
  • Segmentación, niveles de calidad en la etiqueta <StreamIndex> En cambio, calculamos la cantidad de segmentos y niveles de calidad en función de la información proporcionada dentro de <StreamIndex>, como la etiqueta QualityLevel real y las etiquetas <c>.
  • BitsPerSample, no se usa PacketSize en <QualityLevel>.

Cómo verificar el tipo de pantalla

El método canDisplayType verifica las capacidades de audio y video del dispositivo receptor web y la visualización. Para ello, valida los parámetros multimedia que se pasaron y muestra un valor booleano. Todos los parámetros, excepto los primeros, son opcionales. Cuantos más parámetros incluyas, más precisa será la verificación.

Su firma es canDisplayType(<em>mimeType</em>,<em>codecs</em>,<em>width</em>,<em>height</em>,<em>framerate</em>).

Ejemplos:

Comprueba si el dispositivo y la pantalla del receptor web admiten el tipo de MIME de video/mp4 con este códec, dimensiones y velocidad de fotogramas en particular:

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

Comprueba si el dispositivo y la pantalla del receptor web admiten el formato de video 4K para este códec. Para ello, especifica el ancho de 3840 y la altura de 2160:

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

Comprueba si el dispositivo y la pantalla del receptor web admiten HDR10 para este códec, dimensiones y velocidad de fotogramas:

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

Comprueba si el dispositivo y la pantalla del receptor web admiten Dolby Vision (DV) para este códec, las dimensiones y la velocidad de fotogramas:

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

DRM

Parte del contenido multimedia requiere administración de derechos digitales (DRM). En el caso del contenido multimedia que tiene su licencia DRM (y URL clave) almacenada en su manifiesto (DASH o HLS), el SDK de Cast se encarga de este caso por ti. Un subconjunto de ese contenido requiere una licenseUrl, que se necesita para obtener la clave de desencriptación. En Web Receiver, puedes usar PlaybackConfig para configurar licenseUrl según sea necesario.

En el siguiente fragmento de código, se muestra cómo configurar información de solicitudes para solicitudes de licencia, 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;
});

Si tienes una integración con Asistente de Google, es posible que parte de la información de la DRM, como las credenciales necesarias para el contenido, se vincule directamente a tu Cuenta de Google mediante mecanismos como OAuth/SSO. En esos casos, si el contenido multimedia se carga con la voz o proviene de la nube, se invoca un setCredentials desde la nube al dispositivo de transmisión que proporciona esas credenciales. Luego, las aplicaciones que escriben una app receptora web pueden usar la información de setCredentials para operar la DRM según sea necesario. Este es un ejemplo de cómo usar la credencial para crear el contenido multimedia.

Sugerencia: Consulta también Cómo cargar contenido multimedia con contentId, contentUrl y entidad.

Manejo de canales de audio

Cuando el reproductor de Cast carga contenido multimedia, configura un único búfer de fuente de audio. Al mismo tiempo, también selecciona un códec apropiado que el búfer usará, según el tipo de MIME de la pista principal. Se configuran un nuevo búfer y códec:

  • cuando comience la reproducción
  • en cada pausa publicitaria
  • cada vez que se reanuda el contenido principal.

Debido a que el búfer utiliza un solo códec y que el códec se elige en función de la pista principal, hay situaciones en las que las pistas secundarias se pueden filtrar y no escuchar. Esto puede suceder cuando la pista principal de un programa multimedia está en sonido envolvente, pero las pistas de audio secundarias usan sonido estéreo. Debido a que las pistas secundarias suelen usarse para ofrecer contenido en idiomas alternativos, proporcionar contenido multimedia con diferentes cantidades de pistas puede tener un impacto significativo (por ejemplo, que un gran número de usuarios no pueda escuchar el contenido en su idioma nativo).

En las siguientes situaciones, se ilustra por qué es importante proporcionar programación en la que las pistas principales y secundarias contengan la misma cantidad de canales:

Situación 1: Transmisión de contenido multimedia sin paridad de canales entre las pistas principales y secundarias:

  • inglés - AC-3 canal 5.1 (principal)
  • sueco - AAC de 2 canales
  • francés - AAC de 2 canales
  • alemán - AAC de 2 canales

En este caso, si el idioma del reproductor no es inglés, el usuario no escuchará la pista que espera, ya que las pistas de dos canales se filtran durante la reproducción. La única pista que se podría reproducir sería el canal principal AC-3 5.1, y solo cuando el idioma esté configurado en inglés.

Situación 2: Transmisión de contenido multimedia con paridad de canal entre pistas principales y secundarias:

  • inglés - AC-3 canal 5.1 (principal)
  • sueco - AC-3 5.1 canal
  • francés - AC-3 canal 5.1
  • alemán - AC-3 canal 5.1

Debido a que todas las pistas de esta transmisión tienen la misma cantidad de canales, el público escuchará una pista independientemente del idioma seleccionado.

Manejo de canales de audio Shaka

De forma predeterminada, el reproductor Shaka (DASH) tiene un recuento de dos canales preferidos, como medida de mitigación cuando se encuentra contenido multimedia que carece de paridad entre las pistas de audio secundarias.

Si la pista principal no es sonido envolvente (por ejemplo, una pista estéreo de dos canales), el reproductor Shaka usará dos canales de forma predeterminada y filtrará automáticamente las pistas multimedia secundarias que tengan más de dos canales.

La cantidad preferida de canales de audio de Shaka también se puede configurar configurando el preferredAudioChannelCount en la propiedad shakaConfig de cast.framework.PlaybackConfig.

Por ejemplo:

shakaConfig = { "preferredAudioChannelCount": 6 };

Con preferredAudioChannelCount establecido en 6, Shaka Player comprueba si puede admitir los códecs de sonido envolvente (AC-3 o EC-3) y filtra automáticamente las pistas multimedia que no cumplen con la cantidad preferida de canales.