Actualmente, el SDK de receptor web admite tres tipos de protocolos de transmisión:
DASH, Transmisión en vivo HTTP y Transmisión fluida
En este documento, detallamos nuestra asistencia para cada uno de los protocolos de transmisión. Ten en cuenta que la explicación de las etiquetas compatibles para cada protocolo es muy 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é características 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)
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 videos de alta calidad a través de servidores HTTP(S). Un manifiesto, compuesto en XML, contiene la mayoría de la información de metadatos sobre cómo inicializar y descargar el contenido del video. Los conceptos clave que admite el reproductor receptor web son <Period>
, <AdaptationSet>
, <Representation>
, <SegmentTemplate>
, <SegmentList>
, <BaseUrl>
y <ContentProtection>
.
Un manifiesto DASH comienza con una etiqueta raíz <MPD>
y, dentro de él, se incluyen una o más etiquetas <Period>
, que representan un contenido de transmisión.
Las etiquetas <Period>
permiten ordenar distintos tipos de contenido de transmisión y, a menudo, se usan para separar contenido principal y publicidad o varios videos 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 MIME más compatibles son "video/mp4", "audio/mp4" y "text/vtt". Se puede incluir un <ContentComponent contentType="$TYPE$">
opcional en <AdaptationSet>
.
Dentro de cada <AdaptationSet>
, debería haber una lista de etiquetas <Representation>
, y el reproductor web receptor utiliza la información codecs
para inicializar el búfer de fuentes del ECM y la información bandwidth
a fin de elegir automáticamente la representación o tasa de bits correctas que se reproducirá.
Para cada <Representation>
, los segmentos multimedia se describen mediante un <BaseURL>
para la representación de un solo segmento, <SegmentList>
para una lista de segmentos (similar a HLS) o <SegmentTemplate>
.
Para una <SegmentTemplate>
, indica cómo se pueden representar el segmento de inicialización y los segmentos multimedia a través de plantillas. En el siguiente ejemplo, $Number$
indica el número de segmento como 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>
Para una <SegmentTemplate>
, es común usar la etiqueta <SegmentTimeline>
a fin de indicar cuánto dura cada segmento y qué segmentos se repiten. Un timescale
(unidades que representan un segundo) a menudo se incluye como parte de los atributos de <SegmentTemplate>
para que podamos calcular el tiempo del segmento según esta unidad. En el siguiente ejemplo, la etiqueta <S>
significa una etiqueta de segmento, el atributo d
especifica cuánto dura el segmento y el atributo r
especifica cuántos segmentos de la misma duración se repiten para que $Time$
se pueda calcular correctamente a fin de 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>
A continuación, se muestra un ejemplo de la representación mediante <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>
Para un solo archivo de segmento, se suele usar un <SegmentBase>
con solicitudes de rango de bytes a fin de especificar qué parte de un archivo <BaseURL>
contiene el índice, y se puede recuperar el resto a pedido a medida que continúa la reproducción o se produce una búsqueda. Aquí, el rango Initialization
especifica el rango de metadatos init y el indexRange
especifica el índice de los segmentos multimedia. Ten en cuenta que, en este 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>
Sin importar qué representación se use, si las transmisiones están protegidas, una sección <ContentProtection>
puede aparecer en <AdaptationSet>
, en la que 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 ejemplos y detalles, consulta la especificación de MPEG-DASH. A continuación, se muestra una lista de atributos DASH adicionales en etiquetas no mencionadas anteriormente que actualmente admitimos:
Nombre del atributo | Función de atributos |
---|---|
Duración de presentación multimedia | La duración del contenido de video |
período mínimodeactualización | Atributo de la etiqueta <MPD> ; especifica la frecuencia con la que necesitamos volver a cargar el manifiesto. |
type | Atributo de la etiqueta <MPD> ; "dinámico" para indicar que esta es una transmisión en vivo. |
presentaciónTimeTimeset | Atributo de la etiqueta <SegmentBase> . Especifica el desplazamiento del tiempo de presentación desde el comienzo del período. |
númerodeinicio | Especifica la cantidad del primer segmento multimedia de una presentación en un período. Este suele usarse en las transmisiones en vivo. |
También se admite el reconocimiento del cuadro EMSG dentro de fragmentos MP4 para DASH y se proporciona una EmsgEvent
a los desarrolladores.
Si bien nuestro reproductor web receptor actualmente admite los principales casos de uso de DASH, aquí hay una lista de atributos comunes que nuestra implementación actual de DASH ignora o no usa. Esto significa que, sin importar si el manifiesto los contiene, no afectan la experiencia de reproducción del contenido.
- availabilityStartTime.
- Alineación de segmentos
HTTP Live Streaming (HLS)
Puedes obtener la descripción general y la especificación completa de la transmisión en vivo HTTP aquí.
Una de las ventajas clave del reproductor web de receptores 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 lista de reproducción de variantes es la lista de reproducción de contenido multimedia. Las dos etiquetas HLS principales que el reproductor receptor web admite en la lista de reproducción principal son las siguientes:
Nombre de la etiqueta | Funcionalidad |
---|---|
#EXT‐X‐STREAM‐INF | Especifica un flujo de tasa de bits o variante. El atributo BANDWIDTH es obligatorio, ya 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, el caso predeterminado se establece en el video principal 3.0 de perfil principal H264 y el contenido de audio "mp4a.40.2" codificado. |
#EXT‐X‐MEDIA | Especifica la lista de reproducción de contenido multimedia adicional (en el atributo URI ) que representa el contenido. Estas suelen ser 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 . Establecer el atributo DEFAULT en YES indicará que elegiste esta transmisión alternativa de forma predeterminada. |
A continuación, se muestra una lista de etiquetas HLS que el reproductor receptor web admite en la lista de reproducción de contenido multimedia:
Nombre de la etiqueta | Funcionalidad |
---|---|
#EXTINF | La información de la transmisión, por lo general, seguida de la duración del segmento en segundos y en la siguiente línea de 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 lista de reproducción para una transmisión en vivo. El reproductor receptor web no admite duraciones de menos de 0.1 s. |
#EXT-X-MEDIA-SEQUENCE | Número de secuencia (a menudo para una transmisión en vivo) que representa el primer segmento en esta lista de reproducción. |
#EXT-X-KEY. | Información de la clave DRM El atributo METHOD nos indica qué sistema clave usar. Actualmente, admitimos AES-128 y SAMPLE-AES . |
#EXT‐X‐BYTERANGE | El rango de bytes que se debe recuperar para la URL de un segmento. |
#EXT-X-CONCONTINUIDAD | Especifica una discontinuidad entre segmentos consecutivos. Esto se suele ver con la inserción de anuncios del servidor, en la que un segmento de anuncio aparece en el medio de la transmisión principal. |
#EXT-X-PROGRAM-DATE-TIME | Hora absoluta de la primera muestra del siguiente segmento, por ejemplo, “2016-09-21T23:23:52.066Z”. |
#EXT-X-ENDLIST. | Si es una transmisión en vivo o VOD |
En las transmisiones en vivo, usamos #EXT-X-PROGRAM-DATE-TIME
y #EXT-X-MEDIA-SEQUENCE
como factores clave para determinar cómo combinar un manifiesto recién actualizado. Si está presente, #EXT-X-PROGRAM-DATE-TIME
se usa para hacer coincidir los segmentos actualizados.
De lo contrario, se usará el número #EXT-X-MEDIA-SEQUENCE
. Ten en cuenta que, según las especificaciones de 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, como el sonido envolvente 5.1, como reproducción de audio principal. Esto se puede lograr si tienes una etiqueta #EXT-X-MEDIA
con los códecs alternativos y se proporciona el formato del segmento en la configuración de la transmisión.
El reproductor receptor web espera cierto comportamiento por especificación. Por ejemplo, después de una etiqueta #EXT-INF
, se espera un URI. Si no es un URI, por ejemplo, un #EXT-X-DISCOUNTINUITY
hará que falle el análisis de la lista de reproducción.
Cada #EXT-X-TARGETDURATION
segundos, se vuelve a cargar la lista de reproducción o el manifiesto para obtener nuevas listas de segmentos y se actualiza la representación interna nueva de todos los segmentos al nuevo. Cada vez que se solicita una búsqueda, solo buscamos dentro del rango que se puede buscar. En el caso de las transmisiones en vivo, solo permitimos buscar desde el principio de la lista más reciente hasta una duración objetivo 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 indica en la documentación sobre HlsSegmentFormat
para audio y HlsVideoSegmentFormat
para video. Esto incluye la compatibilidad con audio empaquetado, como la reproducción de AAC y AC3, encriptada y no encriptada. Es obligatorio especificar esta información en el MediaInformation
de la LoadRequestData
a fin de describir correctamente el contenido al jugador. 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 la solicitud de carga (Android, iOS y Web) o dentro del receptor por medio de 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 la entidad para obtener más información sobre cómo preparar el 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 mencionó en la sección de etiquetas #EXT-X-KEY
anterior, el SDK de Cast admite SAMPLE-AES
o SAMPLE-AES-CTR
, en los que 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 KEYFORMAT
que ahora admitimos es Widevine, y el URI contiene una información 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 del DASH IF IOP. La misma string se usa en MPD con transmisiones encriptadas con Widevine. |
URI |
"data:text/plain;base64, <base64 encoded PSSH box>" |
URI de la transmisión que contiene el tipo de datos y el cuadro PSSH. |
METHOD |
SAMPLE-AES-CTR |
Indica el cifrado 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 protecciones de AES-CTR, es decir, "cenc". |
Atributos asignados a MPD de DASH:
Atributo | Descripción |
---|---|
KEYFORMAT |
Atributo schemaIdUri del elemento ContentProtection. |
URI |
El contenido del elemento cenc:pssh. |
KEYID |
La string hexadecimal de 16 bytes codifica la ID de la clave que tiene la misma función que default_kid en el DASH de MPEG. Si se utiliza un esquema de clave jerárquica, esta será 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 las características y etiquetas de HLS que actualmente no usamos ni admitimos. Su presencia o ausencia no afectan el comportamiento de la transmisión.
- Se ignora el atributo
RESOLUTION=
de#EXT-X-STREAM-INF
. - No se usa el atributo
AUTOSELECT=
en#EXT-X-MEDIA
. En su lugar, nos basamos enDEFAULT=
- Se ignorará
#EXT-X-I-FRAME-STREAM-INF
en la lista de reproducción 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, pero actualmente nuestro Receptor web solo depende de la existencia de#EXT-X-ENDLIST
para determinar en comparación con VOD en vivo.
Transmisión sin interrupciones
Especificaciones de transmisión fluida de Microsoft
La transmisión fluida proporciona un protocolo de transmisión adaptable y una especificación XML en HTTP (similar a DASH). A diferencia de DASH, Smooth Streaming recomienda solo paquetes de MPEG-4 para los segmentos multimedia.
Esta es una tabla de las etiquetas y los atributos más comunes en Smooth Streaming que admite el reproductor web receptor: Muchos conceptos ya se explican en la sección DASH anterior.
Etiqueta/atributo | Uso |
---|---|
<SmoothStreamingMedia> | La etiqueta principal del manifiesto contiene los siguientes atributos:
|
<StreamIndex> | Un conjunto de transmisiones, similar al AdaptationSet de DASH. Por lo general, el tipo es "texto", "video" o "audio". Por lo general, el atributo URL contiene una URL de fragmento de plantilla que usa información como la tasa de bits o la hora de inicio. |
<Nivel de calidad> | Cada etiqueta QualityQuality especifica su tasa de bits y un códec FourCC. El código de FourCC suele ser "H264", "AVC1", "AACL", etc. Para los videos, especifica sus resoluciones a través de MaxWidth y MaxHeight. Para el audio, especifica su frecuencia (como 44100) a través de SamplingRate y la cantidad de canales. |
<c> | Elemento del fragmento de transmisión Contiene los siguientes elementos:
|
<Protección> | Una etiqueta con el atributo opcional de SystemID que muestra el ID de la DRM del sistema para usar en la etiqueta <SmoothStreamingMedia> |
<ProtectionHeader> | En <Protección>, puede contener un atributo de ID del sistema y datos personalizados, generalmente codificados en Base64. Para Widevine, contendrá el ID de la clave, su longitud, el ID del 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 correctamente los ID del sistema de protección, usa la siguiente asignación:
- WIDEVINE: 'EDEF8BA9-79D6-4ACE-A3C8-27DCD51D21ED',
- CLAVE CLAVE: '1077EFEC-C0B2-4D02-ACE3-3C1E52E2FB4B',
- MPEG_DASH_MP4PROTECCIÓN: 'URN:MPEG:DASH:MP4PROTECCIÓN:2011'
Para <ProtectionHeader>
, a continuación, se muestra un ejemplo con datos codificados en Base64. Los datos, cuando se decodifican, se ajustan al mismo formato decodificado que se describe en la asistencia de protección de contenido DASH anterior.
<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 de Smooth Live 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 primeros dos segmentos (suponiendo que nos encontramos en el nivel de calidad de índice 2) serán los siguientes, con la hora inicial extraída de t="80649401378125" en la sección StreamStream de video y el incremento de tiempo de 4 segundos * 1,000,000 por segmento:
QualityLevels(2)/Fragments(video=80649401378125) QualityLevels(2)/Fragments(video=80649441378125) ...
Esta es una lista de los atributos de Smooth Streaming que actualmente ignoramos y no afectan las experiencias de transmisión, sin importar si se proporcionan:
- CanSeek, CanPause en la etiqueta
<SmoothStreamingMedia>
. - Chunks y QualityLevels en la etiqueta
<StreamIndex>
. En su lugar, calculamos la cantidad de segmentos y niveles de calidad según la información proporcionada dentro de<StreamIndex>
, como la etiqueta realQualityLevel
y las etiquetas<c>
. - No se usa BitsPerSample ni PacketSize en
<QualityLevel>
.
Verifica el tipo de pantalla
El método canDisplayType
verifica las capacidades de audio y video del dispositivo del receptor web y la pantalla mediante la validación de los parámetros multimedia pasados y muestra un valor booleano. Todos los parámetros, excepto el primero, 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 del receptor web y la pantalla admiten el tipo 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)
Para verificar si el dispositivo y la pantalla del receptor web admiten el formato de video 4K para este códec, 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, las dimensiones y la velocidad de fotogramas:
canDisplayType("video/mp4", "hev1.2.6.L150", 3840, 2160, 30)
Comprueba si el dispositivo del receptor web y la pantalla admiten Dolby Vision (DV) para este códec, dimensiones y velocidad de fotogramas:
canDisplayType("video/mp4", "dvhe.04.06", 1920, 1080, 30)
DRM
Nota: Uno de los beneficios clave de usar el SDK de receptor web es que tu app ya no necesita cargar MPL ni controlar la reproducción de contenido multimedia por separado, ya que el SDK de receptor web lo hace por ti.
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 un licenseUrl
, que se necesita para obtener la clave de desencriptación. En el receptor web, puedes usar PlaybackConfig
para configurar licenseUrl
según sea necesario.
En el siguiente fragmento de código, se muestra cómo puedes configurar la información de la solicitud 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, parte de la información de DRM, como las credenciales necesarias para el contenido, podría vincularse directamente a tu Cuenta de Google a través de mecanismos como OAuth o SSO. En esos casos, si el contenido multimedia se carga a través de voz o proviene de la nube, se invoca un setCredentials
desde la nube hasta el dispositivo de transmisión que proporciona esas credenciales. Las aplicaciones que escriben una app de recepción web pueden usar la información de setCredentials
para operar con DRM según sea necesario. Aquí hay un ejemplo del uso de la credencial para construir los medios.
Sugerencia: Consulta también Carga contenido multimedia con contentId, contentUrl y la entidad.
Manejo de canales de audio
Cuando el reproductor de Cast carga contenido multimedia, configura un solo búfer de fuente de audio. Al mismo tiempo, selecciona un códec apropiado para que use el búfer, según el tipo de MIME de la pista principal. Se configuran un nuevo búfer y códec:
- cuando comienza la reproducción
- en cada pausa para anuncios.
- cada vez que se reanude el contenido principal.
Debido a que el búfer usa un solo códec y el códec se elige en función de la pista principal, existen situaciones en las que las pistas secundarias pueden filtrarse y no escucharse. Esto puede suceder cuando la pista principal de un programa de medios está en sonido envolvente, pero las pistas de audio secundarias usan sonido estéreo. Debido a que las pistas secundarias se usan con frecuencia para ofrecer contenido en idiomas alternativos, proporcionar contenido multimedia con diferentes números de pistas puede tener un impacto sustancial, como una gran cantidad de usuarios que no pueden escuchar el contenido en su idioma nativo.
Las siguientes situaciones ilustran por qué es importante proporcionar una programación en la que las pistas principales y secundarias contengan la misma cantidad de canales:
Situación 1: Falta la paridad de canal en las pistas principal y secundaria:
- Inglés - AC-3 Canal 5.1 (principal)
- sueco: AAC, 2-channel
- francés - AAC 2-channel
- alemán - AAC 2-channel
En este caso, si el idioma del reproductor no es inglés, el usuario no escuchará la pista que espera oír, ya que todas las pistas de dos canales se filtran durante la reproducción. La única pista que se podría reproducir es el canal AC-3 5.1 principal, y solo cuando el idioma está configurado en inglés.
Situación 2: Transmisión de medios con paridad de canal en las pistas primaria y secundaria:
- Inglés - AC-3 Canal 5.1 (principal)
- sueco: AC-3 5.1 canal
- francés: AC-3 5.1 channel
- canal alemán AC-3 5.1
Debido a que todas las pistas de esta transmisión tienen la misma cantidad de canales, un público escuchará una pista sin importar el idioma seleccionado.
Manejo de canales de audio de Shaka
El reproductor Shaka (DASH) tiene como valor predeterminado un recuento de canales preferido de dos, como medida de mitigación cuando se encuentra contenido multimedia que carece de paridad en pistas de audio secundarias.
Si la pista principal no tiene sonido envolvente (por ejemplo, una pista estéreo de dos canales), el reproductor Shaka usará de manera predeterminada dos canales y filtrará automáticamente las pistas multimedia secundarias que tengan más de dos canales.
La cantidad preferida de canales de audio de Shaka se puede configurar si se establece preferredAudioChannelCount
en la propiedad shakaConfig
, en cast.framework.PlaybackConfig.
Por ejemplo:
shakaConfig = { "preferredAudioChannelCount": 6 };
Si preferredAudioChannelCount
está configurado en 6, Shaka Player verifica si admite los códecs de sonido envolvente (AC-3
o EC-3
) y filtra automáticamente las pistas multimedia que no se ajusten a la cantidad de canales preferida.