La API de Pod Serving proporciona acceso a segmentos de anuncios codificados y condicionados, preparados de modo que se puedan unir directamente en una lista de reproducción de contenido multimedia HLS o MPEG-DASH para el usuario. En el caso de MPEG-DASH, la API de Pod Serving también proporciona una plantilla de manifiesto para brindar información y contexto adicionales para estos segmentos de anuncios.
Esta guía se enfoca en la implementación de un servidor básico de manipulación de manifiestos de la entrega de Pods para las transmisiones en vivo.
Requisito previo: Configura eventos de transmisión en vivo en Google Ad Manager
Antes de realizar solicitudes desde la API de entrega de Pods, debes crear un evento de transmisión en vivo de Ad Manager para cada transmisión que proceses. Puedes crear un evento de transmisión en vivo mediante LiveStreamEventService API
o la interfaz web de Google Ad Manager.
Para usar un evento de transmisión en vivo con la API de entrega de pods, deberás propagar varios atributos de tu evento:
customAssetKey
: Es un identificador personalizado que se usará para este evento. Debe ser único en todos los eventos de la red.adTags
: Es la URL principal de la etiqueta de anuncio que genera el flujo de trabajo de coordinación de anuncios de Ad Manager.dynamicAdInsertionType
: Se debe configurar comoPOD_SERVING_REDIRECT
.streamingFormat
: Se establece enHLS
oDASH
según corresponda.segmentUrlAuthenticationKeyIds
: Se usa al menos una clave HMAC para firmar solicitudes de segmentos de anuncios.daiEncodingProfileIds
: Es una lista de los ID DAIEncodingProfile habilitados para este evento.startDateTime
: Fecha y hora de inicio del eventoendDateTime
: Es la fecha y hora de finalización programadas de este evento. Este atributo es obligatorio siunlimitedEndDateTime
is false and ignored if
unlimitedEndDateTimeis true.
unlimitedEndDateTime` - Booleano. Consulta la descripción anterior.
Cómo recibir solicitudes del manifiesto de transmisión
Tu manipulador de manifiestos debe proporcionar un extremo de API para que escuche las solicitudes de manifiesto de la app cliente del reproductor de video. Como mínimo, este extremo debe recopilar un ID de transmisión de la app del reproductor cliente y debe mostrar un manifiesto de transmisión unido. El ID de transmisión se usa para identificar la sesión de transmisión en Ad Manager.
También debes recopilar otra información para identificar la transmisión de contenido adecuada, por ejemplo, un ID de contenido.
Ejemplo de un posible extremo de solicitud de manifiesto
GET /api/video/{asset_key}/manifest.{format}
Host: {your_domain}
Parámetros de ruta de acceso | |||||
---|---|---|---|---|---|
asset_key |
Un ID hipotético correspondiente a la transmisión en vivo solicitada en tu sistema. | ||||
format |
Es un parámetro hipotético que corresponde al formato de transmisión. Una de las siguientes opciones:
|
Parámetros de consulta | |
---|---|
stream_id |
El ID de transmisión de Ad Manager de la app cliente de reproductor de video |
Cómo recuperar la transmisión de contenido
Usa el Content ID recopilado de la solicitud del manifiesto para seleccionar el flujo de contenido que deseas unir con los anuncios.
Une segmentos de anuncios en la transmisión de contenido
La unión de las URLs de los segmentos de anuncios variará según el formato de transmisión.
Transmisiones HLS
Por lo general, las transmisiones HLS se entregan como un manifiesto de múltiples variantes, que contendrá un conjunto de vínculos a manifiestos de variantes, que corresponden a cada uno de los perfiles de codificación.
Nota: Para simplificar, en esta guía, se supone que tu medio HLS está codificado en un formato que combina audio y video en el mismo archivo de segmentos.
Playlists de múltiples variantes de proxy
Deberás reemplazar la URL de la playlist de cada variante en la playlist original de múltiples variantes por otra llamada de extremo al manipulador para procesar el manifiesto de la variante seleccionada del reproductor.
En los pasos restantes para unir HLS, se asumirá que se está procesando un manifiesto de una sola variante.
Ejemplo de un posible extremo de solicitud de variante
GET /api/video/{asset_key}/variant/{variant_id}.m3u8
Host: {your_domain}
Parámetros de ruta de acceso | |
---|---|
asset_key |
Un ID hipotético correspondiente a la transmisión en vivo solicitada en tu sistema. |
variant |
Es un parámetro hipotético que contiene un identificador para la variante específica que se procesa. |
Parámetros de consulta | |
---|---|
stream_id |
El ID de transmisión de Ad Manager de la app de reproductor de video del cliente que se usa aquí para identificar una sesión de usuario con el manipulador de manifiestos. |
Ejemplo de manifiesto de múltiples variantes sin procesar
#EXTM3U
#EXT-X-STREAM-INF:BANDWIDTH=5000000,RESOLUTION=1920x1080,CODECS="avc1.4d000c,mp4a.40.5"
https://cdn.{...}/1080p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=2500000,RESOLUTION=1280x720,CODECS="avc1.4d000c,mp4a.40.5"
https://cdn.{...}/720p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=1000000,RESOLUTION=640x360,CODECS="avc1.4d000d,mp4a.40.5"
https://cdn.{...}/360p.m3u8
Ejemplo de manifiesto de múltiples variantes con proxy
#EXTM3U
#EXT-X-STREAM-INF:BANDWIDTH=5000000,RESOLUTION=1920x1080,CODECS="avc1.4d000c,mp4a.40.5"
https://{manifest_manipulator}/api/video/tears_of_steel/variant/1080p.m3u8?stream_id=6e69425c-0ac5-43ef-b070-c5143ba68541:CHS
#EXT-X-STREAM-INF:BANDWIDTH=2500000,RESOLUTION=1280x720,CODECS="avc1.4d000c,mp4a.40.5"
https://{manifest_manipulator}/api/video/tears_of_steel/variant/720p.m3u8?stream_id=6e69425c-0ac5-43ef-b070-c5143ba68541:CHS
#EXT-X-STREAM-INF:BANDWIDTH=1000000,RESOLUTION=640x360,CODECS="avc1.4d000d,mp4a.40.5"
https://{manifest_manipulator}/api/video/tears_of_steel/variant/360p.m3u8?stream_id=6e69425c-0ac5-43ef-b070-c5143ba68541:CHS
Identifica segmentos de pausas publicitarias e inserta discontinuidades
A medida que proceses el manifiesto de la variante, haz un seguimiento de la hora de inicio, la duración y el índice de la próxima pausa publicitaria hasta que el manifiesto dinámico que se procesa contenga segmentos que se reemplazarán por el contenido del anuncio.
Según tu codificador, las pausas publicitarias se pueden delimitar de los segmentos de contenido de diferentes maneras. Una forma común de definir una pausa publicitaria es anteponer una etiqueta #EXT-X-CUE-OUT
a los segmentos de anuncios y seguirlos con una etiqueta #EXT-X-CUE-IN
.
Para separar las pausas publicitarias alojadas en Google de los segmentos de contenido, debes insertar etiquetas #EXT-X-DISCONTINUITY
al comienzo y al final de cada pausa publicitaria. Si estas etiquetas de discontinuidad no aparecen en el manifiesto final, la reproducción fallará.
Los URI de segmento de anuncio insertados no están encriptados. Si tu contenido está encriptado, también deberás quitar la encriptación. Para ello, especifica #EXT-X-KEY:METHOD=NONE
antes del primer segmento publicitario de cada pausa publicitaria y, luego, vuelve a agregarla después de la pausa.
Manifiesto de muestra (original)
#EXTM3U
#EXT-X-VERSION:6
#EXT-X-TARGETDURATION:6
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:5.005,
contentorigin.com/1.ts
#EXTINF:5.005,
contentorigin.com/2.ts
#EXT-X-CUE-OUT:15.000
#EXTINF:5.005,
contentorigin.com/3.ts
#EXTINF:5.005,
contentorigin.com/4.ts
#EXTINF:5.005,
contentorigin.com/5.ts
#EXTINF:5.000,d
contentorigin.com/6.ts
#EXT-X-CUE-IN
#EXTINF:5.005,
contentorigin.com/7.mp4
#EXTINF:5.005,
contentorigin.com/8.mp4
Manifiesto con discontinuidades insertadas
#EXTM3U
#EXT-X-VERSION:6
#EXT-X-TARGETDURATION:6
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:5.005,
contentorigin.com/1.ts
#EXTINF:5.005,
contentorigin.com/2.ts
#EXTINF:5.005,
#EXT-X-DISCONTINUITY
{... New segments will go here ...}
#EXT-X-DISCONTINUITY
#EXTINF:5.005,
contentorigin.com/7.mp4
#EXTINF:5.005,
contentorigin.com/8.mp4
Procesa segmentos de grupos de anuncios
Para cada segmento dentro de un grupo de anuncios, debes hacer un seguimiento de algunos valores adicionales:
segment_number
: Índice del segmento dentro del grupo de anuncios, que comienza con cero. O "init" para el segmento de inicialización de mp4.segment_duration
: Duración del segmento actual en milisegundos. Este valor debe ser el mismo para todos los segmentos, excepto el último del Pod.segment_offset
: El desplazamiento del segmento se calcula agregando la duración del segmento anterior a su desplazamiento en milisegundos.last
: Valor booleano que identifica el último segmento de un grupo de anuncios. La configuración predeterminada es false.
Crear URLs de segmentos de anuncios
Reemplaza cada segmento dentro de la pausa publicitaria por una URL del siguiente formato:
/linear/pods/v1/seg/network/{network_code}/custom_asset/{custom_asset_key}/pod/{pod_id}/profile/{profile_name}/{segment_number}.(ts|mp4|vtt|aac|ac3|eac3)
Parámetros de ruta de acceso | |
---|---|
network_code
|
Es el código de red de Ad Manager 360 correspondiente a esta red. |
custom_asset_key
|
Es la clave del elemento de transmisión en vivo personalizada que se especifica en la API de LiveStreamEventService o en la página de la transmisión en vivo, en la interfaz web de Ad Manager 360. |
pod_id
|
Es el identificador de la pausa publicitaria. Debe ser un número entero que comience en 1 y aumente de a uno para cada pausa publicitaria.
Este valor debe ser el mismo para todos los usuarios que vean la misma pausa publicitaria en el evento actual. |
profile_name
|
Es el identificador del perfil que se solicita. |
segment_number
|
El índice de este segmento dentro del grupo de anuncios actual, a partir de cero. Cuando se usa el contenedor MP4, el segmento de inicialización se puede solicitar estableciendo segment_number como "init". |
Parámetros de consulta | ||
---|---|---|
stream_id
|
Obligatorio | El parámetro stream_id del usuario que se muestra en la solicitud de creación de transmisión
|
sd
|
Obligatorio | segment_duration
|
so
|
Opcional | segment_offset
Si falta |
pd
|
Obligatorio, excepto para los eventos en los que se habilitaron las pausas publicitarias sin duración | Es la duración (en milisegundos) de la pausa publicitaria. También se conoce como ad_pod_duration .
|
auth-token
|
Obligatorio | Un token HMAC firmado y con codificación URL para este grupo de anuncios. |
last
|
Opcional | Es un valor booleano que indica el último segmento de la pausa publicitaria. La configuración predeterminada es "false". |
Los valores de los parámetros de consulta deben estar correctamente codificados para que sean seguros para las URL. Esto es en especial importante para el campo auth-token
, ya que podría contener caracteres /
, +
y =
.
Manifiesto de muestra (después del reemplazo del segmento)
#EXTM3U
#EXT-X-VERSION:6
#EXT-X-TARGETDURATION:6
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:5.005,
contentorigin.com/1.ts
#EXTINF:5.005,
contentorigin.com/2.ts
#EXT-X-DISCONTINUITY
#EXTINF:5.005,
https://dai.google.com/linear/pods/v1/seg/network/6062/custom_asset/iYdOkYZdQ1KFULXSN0Gi7g/pod/1/profile/devrel4628000/0.ts?sd=5005&so=0&pd=18015&auth-token=custom_asset_key%3DiYdOkYZdQ1KFULXSN0Gi7g~cust_params%3D~exp%3D1489680000~network_code%3D6062~pd%3D180000~pod_id%3D5~hmac%3D44bf78223c240cbc5bae3cdfd794bfc6971b6583cd296f44ef3a46944605cf9a&stream_id=fe6c9136-09a4-4ff6-862e-daee1dea0e1b:MRN2
#EXTINF:5.005,
https://dai.google.com/linear/pods/v1/seg/network/6062/custom_asset/iYdOkYZdQ1KFULXSN0Gi7g/pod/1/profile/devrel4628000/1.ts?sd=5005&so=5005&pd=18015&auth-token=custom_asset_key%3DiYdOkYZdQ1KFULXSN0Gi7g~cust_params%3D~exp%3D1489680000~network_code%3D6062~pd%3D180000~pod_id%3D5~hmac%3D44bf78223c240cbc5bae3cdfd794bfc6971b6583cd296f44ef3a46944605cf9a&stream_id=fe6c9136-09a4-4ff6-862e-daee1dea0e1b:MRN2
#EXTINF:5.005,
https://dai.google.com/linear/pods/v1/seg/network/6062/custom_asset/iYdOkYZdQ1KFULXSN0Gi7g/pod/1/profile/devrel4628000/2.ts?sd=5005&so=10010&pd=18015&auth-token=custom_asset_key%3DiYdOkYZdQ1KFULXSN0Gi7g~cust_params%3D~exp%3D1489680000~network_code%3D6062~pd%3D180000~pod_id%3D5~hmac%3D44bf78223c240cbc5bae3cdfd794bfc6971b6583cd296f44ef3a46944605cf9a&stream_id=fe6c9136-09a4-4ff6-862e-daee1dea0e1b:MRN2
#EXTINF:3.000,
https://dai.google.com/linear/pods/v1/seg/network/6062/custom_asset/iYdOkYZdQ1KFULXSN0Gi7g/pod/1/profile/devrel4628000/3.ts?sd=3000&so=15015&pd=18015&auth-token=custom_asset_key%3DiYdOkYZdQ1KFULXSN0Gi7g~cust_params%3D~exp%3D1489680000~network_code%3D6062~pd%3D180000~pod_id%3D5~hmac%3D44bf78223c240cbc5bae3cdfd794bfc6971b6583cd296f44ef3a46944605cf9a&stream_id=fe6c9136-09a4-4ff6-862e-daee1dea0e1b:MRN2&last=true
#EXT-X-DISCONTINUITY
#EXTINF:5.005,
contentorigin.com/7.mp4
#EXTINF:5.005,
contentorigin.com/8.mp4
¡Felicitaciones! Ahora estás publicando una transmisión en vivo con segmentos de anuncios que proporciona la API de Pod Serving de DAI.
Transmisiones DASH
Las transmisiones de DASH se proporcionan como un archivo MPD, que contiene todas las codificaciones de transmisión en un solo archivo, en el que el contenido se representa como una serie de puntos.
Plantilla de período de solicitud
Solicita una plantilla de período de Google Ad Manager. Esta plantilla se convertirá en tu período de pausa publicitaria, una vez que se propaguen las macros que contiene.
Solo debes solicitar esta plantilla una vez por sesión de transmisión y almacenarla en caché para reutilizarla con cada pausa publicitaria.
Extremo de solicitud de plantilla de período
GET /linear/pods/v1/dash/network/{network_code}/custom_asset/{custom_asset}/pods.json
Host: dai.google.com
Content-Type: application/json
Parámetros de ruta de acceso | |
---|---|
network_code |
El código de red de Ad Manager 360 del publicador. |
custom_asset |
La clave del elemento personalizada del evento de transmisión en vivo en Google Ad Manager. |
Parámetros de consulta | |
---|---|
stream_id |
El ID de transmisión de Ad Manager del reproductor de video del cliente. |
Respuesta JSON | |
---|---|
dash_period_template |
Es la cadena XML de la plantilla de punto. |
segment_duration_ms |
Es la duración de cada segmento multimedia del anuncio en la plantilla del período de guion, en milisegundos. |
Ejemplo de solicitud (cURL)
curl https://dai.google.com/linear/pods/v1/dash/network/21775744923/custom_asset/tears_of_steel/pods.json?stream-id=cc59197a-44c0-4be2-a8cc-9a6fdb80158f:DLS
Ejemplo de respuesta
{"dash_period_template":"<Period id="adpod-$$pod-id$$" $$period-start$$ $$period-duration$$> <BaseURL>https://dai.google.com/linear/pods/v1/seg/event/{event_code}/pods/$$pod-id$$/profile/</BaseURL>
<SegmentTemplate initialization="$RepresentationID$/init.mp4?stream_id={a-stream-id}&sd=5000&pd=$$pod-duration$$&cust_params=$$cust_params$$&auth_token=$$token$$" media="$RepresentationID$/$Number$.mp4?stream_id={a-stream-id}&sd=5000&pd=$$pod-duration$$&cust_params=$$cust_params$$&scte35=$$scte35$$&auth_token=$$token$$" startNumber="1" presentationTimeOffset="0">
<SegmentTimeline>
<S t="0" d="5" r="$$number-of-repeated-segments$$"/>
</SegmentTimeline>
</SegmentTemplate>
<AdaptationSet id="0" width="1280" height="720" frameRate="30" contentType="video" subsegmentAlignment="true" startWithSAP="1">
<InbandEventStream schemeIdUri="https://developer.apple.com/streaming/emsg-id3"/>
<Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"/>
<Representation mimeType="video/mp4" codecs="avc1.640029" id="a943ff679a2f3e71d9181a21b7542122g" bandwidth="3200000"/>
<Representation mimeType="video/mp4" codecs="avc1.640029" id="abbbd80q4w5ce2fs28308rd1f4g4bat0" bandwidth="1500000"/>
</AdaptationSet>
<AdaptationSet id="1" contentType="audio"> <Representation audioSamplingRate="48000" mimeType="audio/mp4" codecs="mp4a.40.2" id="a87ff679a2f3e71d9181a67b7542122c" bandwidth="95000"/>
<Representation audioSamplingRate="48000" mimeType="audio/mp4" codecs="mp4a.40.2" id="eccbc87e4b5ce2fe28308fd9f2a7baf3" bandwidth="127000"/>
</AdaptationSet>
</Period>",
"segment_duration_ms":5000}
Propaga la plantilla del período
La plantilla de período contiene varias macros que debes reemplazar en cada pausa publicitaria. Se deben reemplazar todas las macros. Las macros no utilizadas se deben reemplazar por una string vacía ("").
Macro | Descripción | Ejemplo |
---|---|---|
$$pod-id$$ |
Es el índice del grupo de anuncios que representa este período. Este valor debe coincidir con el mismo grupo de anuncios en todas las sesiones de visualizador. | 1 |
$$period-start$$ |
Es el tiempo en el que comienza el período en la MPD actual. Atributo opcional que se debe reemplazar por start="###" , en el que ### es la hora de presentación en la que comienza la pausa publicitaria. Si no se proporciona la hora de inicio del período, esta macro se debe reemplazar por una string vacía.
|
start="PT2H33M30S" |
$$period-duration$$ |
Es la duración del período completo del anuncio. Un atributo opcional que se debe reemplazar por duration="###" , en el que ### es la duración del período del anuncio en el formato de duración de DASH estándar. Si no se proporciona la duración del período, esta macro se debe reemplazar por una string vacía.
|
duration="PT15S" |
$$pod-duration$$ |
Es la duración esperada de los anuncios que se tomarán para este grupo, en milisegundos. | 15000 |
$$number-of-repeated-segments$$ |
Para calcular este valor, se divide la duración del período del anuncio (en milisegundos) por el valor de segment_duration_ms y se redondea al número entero más cercano. | 3 |
$$cust_params$$ |
Esta macro se puede reemplazar por los parámetros de segmentación personalizados únicos de la pausa publicitaria actual, si se proporciona. El valor debe tener el formato que se describe en este artículo del Centro de ayuda de Ad Manager. Si no se necesitan parámetros personalizados, esta macro se debe reemplazar por una string vacía. |
&cust_params=section%3Dblog%26anotherKey%3Dvalue1%2Cvalue2
|
$$scte35$$ |
Esta macro debe reemplazarse por un valor scte35 único para esa pausa publicitaria, si se proporciona. Si no se necesita información de scte35, esta macro se debe reemplazar por una string vacía. |
/DAqAAAAAAAA///wDwVAAAT2f0/+ecF1mQABC/8ACgAIQ1VFSQAAAAsuZVlR
|
$$token$$ |
Un token HMAC firmado y con codificación URL Este token es obligatorio. |
custom_asset_key%3DiYdOkYZdQ1KFULXSN0Gi7g~exp%3D1489680000~network_code%3D6062~pd%3D180000~pod_id%3D5~hmac%3D6a8c44c72e4718ff63ad2284edf2a8b9e319600b430349d31195c99b505858c9
|
Plantilla de período sin procesar, que contiene macros
<Period id="adpod-$$pod-id$$" $$period-start$$ $$period-duration$$>
<BaseURL>
https://dai.google.com/linear/pods/v1/seg/event/{event_code}/pods/$$pod-id$$/profile/
</BaseURL>
<SegmentTemplate initialization="$RepresentationID$/init.mp4?stream_id=cc59197a-44c0-4be2-a8cc-9a6fdb80158f:DLS&sd=5000&pd=$$pod-duration$$&cust_params=$$cust_params$$&auth_token=$$token$$" media="$RepresentationID$/$Number$.mp4?stream_id=ç√&sd=5000&pd=$$pod-duration$$&cust_params=$$cust_params$$&scte35=$$scte35$$&auth_token=$$token$$" startNumber="1" presentationTimeOffset="0">
<SegmentTimeline>
<S t="0" d="5" r="$$number-of-repeated-segments$$"/>
</SegmentTimeline>
</SegmentTemplate>
<AdaptationSet id="0" width="1280" height="720" frameRate="30" contentType="video" subsegmentAlignment="true" startWithSAP="1">
<InbandEventStream schemeIdUri="https://developer.apple.com/streaming/emsg-id3"/>
<Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"/>
<Representation mimeType="video/mp4" codecs="avc1.640029" id="a943ff679a2f3e71d9181a21b7542122g" bandwidth="3200000"/>
<Representation mimeType="video/mp4" codecs="avc1.640029" id="abbbd80q4w5ce2fs28308rd1f4g4bat0" bandwidth="1500000"/>
</AdaptationSet>
<AdaptationSet id="1" contentType="audio"> <Representation audioSamplingRate="48000" mimeType="audio/mp4" codecs="mp4a.40.2" id="a87ff679a2f3e71d9181a67b7542122c" bandwidth="95000"/>
<Representation audioSamplingRate="48000" mimeType="audio/mp4" codecs="mp4a.40.2" id="eccbc87e4b5ce2fe28308fd9f2a7baf3" bandwidth="127000"/>
</AdaptationSet>
</Period>
Período del anuncio propagado
<Period id="pod-0" start="PT5H50M12S">
<BaseURL>
https://dai.google.com/linear/pods/v1/seg/event/M-nTcApTRTi6CEGIt4GYMw/pod/0/profile/
</BaseURL>
<SegmentTemplate startNumber="0" media="1080p/0.mp4?stream_id=cc59197a-44c0-4be2-a8cc-9a6fdb80158f:DLS&sd=5000&pd=30000&cust_params=&auth-token=&scte35=" initialization="$RepresentationID$/init.mp4?stream_id=cc59197a-44c0-4be2-a8cc-9a6fdb80158f:DLS&pd=30000&cust_params=&auth-token=&scte35=">
<SegmentTimeline>
<S d="5" r="1"/>
</SegmentTimeline>
</SegmentTemplate>
<AdaptationSet mimeType="video/mp4" scanType="progressive" contentType="video">
<Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"/>
<Representation width="768" height="432" frameRate="30" codecs="avc1.42c01e" id="fmp4-video-1200k" bandwidth="1300000">
<InbandEventStream schemeIdUri="https://developer.apple.com/streaming/emsg-id3"/>
</Representation>
</AdaptationSet>
<AdaptationSet mimeType="audio/mp4" scanType="progressive" contentType="audio">
<Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"/>
<Representation audioSamplingRate="48000" codecs="mp4a.40.2" id="fmp4-audio-128kbps" bandwidth="128000">
<AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
</Representation>
</AdaptationSet>
</Period>
Inserta el período propagado en el manifiesto de DASH
Por último, reemplaza el período apropiado en tu manifiesto sin procesar con el período del anuncio recién propagado y muestra el manifiesto unido final al cliente de video solicitante para su reproducción.
Ejemplo de manifiesto de contenido sin procesar
<?xml version="1.0"?>
<MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:mpeg:DASH:schema:MPD:2011" xsi:schemaLocation="urn:mpeg:DASH:schema:MPD:2011" profiles="urn:mpeg:dash:profile:isoff-main:2011" type="static" mediaPresentationDuration="PT0H9M56.46S">
<BaseURL>
http://example.com/tears_of_steel/
</BaseURL>
<Period start="PT0S">
<AdaptationSet bitstreamSwitching="true">
<Representation id="0" codecs="avc1" mimeType="video/mp4" width="1920" height="1080" startWithSAP="1" bandwidth="500000">
<SegmentBase>
<Initialization sourceURL="segments/1080/1.m4s" range="0-862"/>
</SegmentBase>
<SegmentList duration="15">
<SegmentURL media="segments/1080p/2.m4s" mediaRange="863-7113"/>
<SegmentURL media="segments/1080p/3.m4s" mediaRange="7114-14104"/>
<SegmentURL media="segments/1080p/4.m4s" mediaRange="14105-17990"/>
...
</SegmentList>
</Representation>
<Representation id="1" codecs="avc1" mimeType="video/mp4" width="1280" height="720" startWithSAP="1" bandwidth="250000">
<SegmentBase>
<Initialization sourceURL="segments/720p/1.m4s" range="0-864"/>
</SegmentBase>
<SegmentList duration="15">
<SegmentURL media="segments/720p/2.m4s" mediaRange="865-11523"/>
<SegmentURL media="segments/720p/3.m4s" mediaRange="11524-25621"/>
<SegmentURL media="segments/720p/4.m4s" mediaRange="25622-33693"/>
...
</SegmentList>
</Representation>
<Representation id="1" codecs="avc1" mimeType="video/mp4" width="640" height="480" startWithSAP="1" bandwidth="100000">
<SegmentBase>
<Initialization sourceURL="segment/480p/1.m4s" range="0-865"/>
</SegmentBase>
<SegmentList duration="15">
<SegmentURL media="segment/480p/2.m4s" mediaRange="866-26970"/>
<SegmentURL media="segment/480p/3.m4s" mediaRange="26971-72543"/>
<SegmentURL media="segment/480p/4.m4s" mediaRange="72544-95972"/>
...
</SegmentList>
</Representation>
...
</AdaptationSet>
</Period end>
</MPD>
Ejemplo de manifiesto unido
<?xml version="1.0"?>
<MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:mpeg:DASH:schema:MPD:2011" xsi:schemaLocation="urn:mpeg:DASH:schema:MPD:2011" profiles="urn:mpeg:dash:profile:isoff-main:2011" type="static" mediaPresentationDuration="PT0H9M56.46S">
<BaseURL>
http://example.com/tears_of_steel/
</BaseURL>
<Period id="pod-0" start="PT5H50M12S">
<BaseURL>
https://dai.google.com/linear/pods/v1/seg/event/M-nTcApTRTi6CEGIt4GYMw/pod/0/profile/
</BaseURL>
<SegmentTemplate startNumber="0" media="1080p/0.mp4?stream_id=cc59197a-44c0-4be2-a8cc-9a6fdb80158f:DLS&sd=5000&pd=30000&cust_params=&auth-token=&scte35=$$scte35$$" initialization="$RepresentationID$/init.mp4?stream_id=cc59197a-44c0-4be2-a8cc-9a6fdb80158f:DLS&pd=30000&cust_params=&auth-token=&scte35=$$scte35$$">
<SegmentTimeline>
<S d="5" r="1"/>
</SegmentTimeline>
</SegmentTemplate>
<AdaptationSet mimeType="video/mp4" scanType="progressive" contentType="video">
<Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"/>
<Representation width="768" height="432" frameRate="30" codecs="avc1.42c01e" id="fmp4-video-1200k" bandwidth="1300000">
<InbandEventStream schemeIdUri="https://developer.apple.com/streaming/emsg-id3"/>
</Representation>
</AdaptationSet>
<AdaptationSet mimeType="audio/mp4" scanType="progressive" contentType="audio">
<Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"/>
<Representation audioSamplingRate="48000" codecs="mp4a.40.2" id="fmp4-audio-128kbps" bandwidth="128000">
<AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
</Representation>
</AdaptationSet>
</Period>
</MPD>
¡Felicitaciones! Ahora estás publicando una transmisión en vivo de DASH con segmentos de anuncios que proporciona la API de DAI Pod Serving.
Recursos adicionales
- Reproducción de Pods con el SDK de IMA:
- Reproducción de un Pod con la API de DAI