La API de Publicación de grupos de anuncios proporciona acceso a grupos de anuncios de video con tasa de bits adaptable preparados de manera tal que se puedan unir directamente a una playlist de contenido multimedia HLS o MPEG-DASH para usuarios.
Esta guía se enfoca en implementar un servidor básico de manipulación de manifiestos de Pod Serving para transmisiones de VOD.
Cómo recibir solicitudes de manifiesto de transmisión
Tu manipulador de manifiestos debe proporcionar un extremo de API para escuchar solicitudes de manifiestos 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. Este ID de transmisión se usa para identificar la sesión de transmisión en Ad Manager en tus solicitudes de grupos de anuncios.
También debes recopilar otra información para identificar el flujo de contenido adecuado, por ejemplo, un ID de contenido.
Ejemplo de extremo de solicitud de manifiesto
GET /api/stream_id/{stream_id}/video/{content_id}.{format}
Host: {your_domain}
Parámetros de ruta | |||||
---|---|---|---|---|---|
stream_id |
El ID de transmisión de Ad Manager de la app del reproductor de video cliente | ||||
content_id |
Un ID hipotético que corresponde al video de contenido de tu sistema. | ||||
format |
Es un parámetro hipotético que corresponde al formato de transmisión. Una de las siguientes opciones:
|
Cómo recuperar la transmisión de contenido
Usa el ID de contenido recopilado de la solicitud de manifiesto para seleccionar la transmisión de contenido que se unirá con los anuncios.
Solicita manifiestos de grupos de anuncios
Para solicitar anuncios de Ad Manager, tu servidor debe realizar una solicitud POST al extremo de los grupos de anuncios y pasar los perfiles de codificación y la etiqueta de anuncio solicitados. Esta solicitud también incluye el ID de transmisión que recopilaste en el paso 1.
A cambio, recibes una lista de objetos de grupo de anuncios que contienen archivos de manifiesto para los grupos de anuncios solicitados por la etiqueta de anuncio del publicador y la información sobre cuándo y dónde se deben insertar en tu contenido.
POST /ondemand/pods/api/v1/network/{network_code}/streams/{stream_id}/adpods
Host: dai.google.com
Content-Type: application/json
Parámetros de ruta | |
---|---|
network_code |
El código de red de Ad Manager 360 del publicador |
stream_id |
Es el ID de flujo de la app de reproductor de video cliente. |
Cuerpo JSON
Parámetros del cuerpo | ||
---|---|---|
encoding_profiles |
Required |
Es una lista de representaciones JSON de los perfiles de codificación que deseas recibir para cada pausa publicitaria. Sigue leyendo para conocer más detalles
Para que la reproducción sea lo más fluida posible, debe coincidir con el conjunto de perfiles de codificación que se usan en tu transmisión de contenido. |
ad_tag |
Required |
Una etiqueta de anuncio para solicitar anuncios de VMAP. |
cuepoints |
Optional |
Es una lista de puntos de inserción dentro de la transmisión de contenido en los que se insertarán las pausas publicitarias durante el video. Los puntos de inserción se miden en segundos de punto flotante.
Es obligatorio solo para las respuestas de VMAP que contienen anuncios durante el video con compensaciones de tiempo posicionales. Esto no es común. |
content_duration_seconds |
Optional |
Es la duración del contenido en segundos.
Es obligatorio solo para las respuestas de VMAP que contienen anuncios durante el video con compensaciones de tiempo de porcentaje. Esto no es común. |
manifest_type |
Optional |
Es el formato de las transmisiones de anuncios que se solicitan, ya sea hls o dash . El valor predeterminado es hls .
|
dai_options |
Optional |
Son opciones adicionales que controlan aspectos de cómo se renderizan los manifiestos. Sigue leyendo para conocer más detalles |
Perfil de codificación | ||
profile_name |
Required |
Es un identificador para este perfil de codificación. Este valor puede ser cualquier cadena que elijas, pero no puedes tener varios perfiles de codificación con el mismo nombre en la misma transmisión. |
type |
Required |
Es el tipo de codificación de la transmisión que describe este perfil de codificación. Los tipos de contenido son media , iframe y subtitles .
|
container_type |
Required |
Es el formato de contenedor que usa este perfil de codificación. Los formatos de contenedor son los siguientes: mpeg2ts , fmp4cmaf y hls_packed_audio .
|
video_settings |
Optional |
Es obligatorio si el tipo de perfil de codificación es iframe. De lo contrario, solo se permite si el tipo de contenido multimedia contiene video. Consulta los detalles a continuación |
audio_settings |
Optional |
Obligatorio si el perfil de codificación contiene audio. Solo se permite si el tipo es media. Sigue leyendo para conocer más detalles |
subtitle_settings |
Optional |
Obligatorio si el perfil de codificación contiene subtítulos. Sigue leyendo para conocer más detalles |
Configuración de video | ||
codec |
Required |
La cadena de códec RFC6381.
Ejemplo: |
bitrate |
Required |
Es un número entero que representa la tasa de bits de video máxima de este perfil en bytes por segundo. |
frames_per_second |
Required |
Los FPS de punto flotante del video. |
resolution |
Required |
Es un valor con codificación JSON que contiene el "ancho" y la "altura" del video en píxeles.
Ejemplo: |
Configuración de audio | ||
codec |
Required |
La cadena de códec RFC6381.
Ejemplo: |
bitrate |
Required |
Es un número entero que representa la tasa de bits de audio máxima de este perfil en bytes por segundo.
Ejemplo: |
channels |
Required |
Es un número entero que representa la cantidad de canales de audio, incluidos los canales de baja frecuencia. |
sample_rate |
Required |
Es un número entero que representa la tasa de muestreo de audio en hercios.
Ejemplo: |
Configuración de subtítulos | ||
format |
Required |
Es el formato de archivo que usan los subtítulos integrados en la transmisión. Los valores admitidos son webvtt o ttml .
|
language |
Optional |
Es el idioma de los subtítulos como una cadena de idioma RFC5646. Si se proporciona, este valor solo se usa para la renderización de DASH.
Ejemplo: |
Opciones de DAI | ||
dash_profile |
Optional |
Es el perfil de MPEG-DASH que se aplicará a los manifiestos de grupos de anuncios. Este parámetro de configuración solo se usa para manifiestos DASH. Los valores permitidos son live o on-demand . El valor predeterminado es on-demand .
El valor
El valor |
ad_pod_timeout |
Optional |
Es el tiempo máximo que se puede dedicar a seleccionar anuncios y crear grupos de anuncios, expresado en segundos de punto flotante. Una vez transcurrido este tiempo, Ad Manager muestra los anuncios que ya se seleccionaron en la respuesta ad_pods y detiene el procesamiento.
|
sam_id |
Optional |
Especifica una clave de depuración alternativa que se puede usar para buscar sesiones en el supervisor de actividad de transmisión. |
Respuesta
Parámetros de respuesta | |
---|---|
valid_for |
Es la duración durante la cual estas playlists de grupos de anuncios son válidas en formato dhms (días, horas, minutos y segundos).
|
valid_until |
Es la fecha y hora hasta la que estas playlists de grupos de anuncios son válidas como una cadena de fecha y hora ISO8601, en formato yyyy-MM-dd'T'hh:mm:ss.sssssssss[+|-]hh:mm .
|
ad_pods |
Es una lista de grupos de anuncios seleccionados para esta transmisión. |
Grupo de anuncios | |
manifest_uris |
Solo para transmisiones HLS. Un mapa de IDs de perfiles de codificación a URIs de manifiestos de HLS. |
mpd_uri |
Solo para transmisiones DASH. Es el URI del MPD de DASH. |
type |
Es el tipo de grupo de anuncios. Los tipos de grupos de anuncios son pre , mid o post .
|
start |
Solo para grupos de anuncios durante el video. Es la posición en la transmisión en la que se debe insertar este grupo de anuncios, en segundos de punto flotante. |
duration |
Es la duración de este grupo de anuncios en segundos de punto flotante. |
midroll_index |
Solo para grupos de anuncios durante el video. Es el índice del grupo de anuncios durante el video actual. El indexado comienza con 1 .
|
Ejemplo de solicitud (cURL)
curl -X POST \
-d '@request-body.json' \
-H 'Content-Type: application/json' \
https://dai.google.com/ondemand/pods/api/v1/network/21775744923/streams/6e69425c-0ac5-43ef-b070-c5143ba68541:CHS/adpods
Ejemplo de cuerpo de la solicitud
Este es el contenido de request-body.json
al que se hace referencia en la llamada a cURL anterior.
{
"encoding_profiles": [
{
"profile_name": "1080p",
"type": "media",
"container_type": "mpeg2ts",
"video_settings": {
"codec": "avc1.4d000c",
"bitrate": 5000000,
"frames_per_second": 30.0,
"resolution": {
"width": 1920,
"height": 1080
}
},
"audio_settings": {
"codec": "mp4a.40.5",
"bitrate": 300000,
"channels": 2,
"sample_rate": 48000
}
},
{
"profile_name": "360p",
"type": "media",
"container_type": "mpeg2ts",
"video_settings": {
"codec": "avc1.4d000d",
"bitrate": 1000000,
"frames_per_second": 30.0,
"resolution": {
"width": 640,
"height": 360
}
},
"audio_settings": {
"codec": "mp4a.40.5",
"bitrate": 64000,
"channels": 2,
"sample_rate": 48000
}
},
{
"profile_name": "subtitles-webvtt",
"type": "subtitles",
"subtitle_settings": {
"format": "webvtt"
}
}
],
"ad_tag": "https://pubads.g.doubleclick.net/gampad/ads?...",
"manifest_type": "hls"
}
Ejemplo de respuesta
{
"valid_for": "8h0m0s",
"valid_until": "2023-03-24T08:30:26.839717986-07:00",
"ad_pods": [
{
"manifest_urls":{
"1080p": "https://{...}/pod/0/profile/1080p.m3u8",
"360p": "https://{...}/pod/0/profile.m3u8",
"subtitles-webvtt": "https://{...}/pod/0/profile/subtitles-en.vtt"
},
"type": "pre",
"duration": 10.0
},
{
"manifest_urls":{
"1080p": "https://{...}/pod/1/profile/1080p.m3u8",
"360p": "https://{...}/pod/1/profile.m3u8",
"subtitles-webvtt": "https://{...}/pod/1/profile/subtitles-en.vtt"
},
"type": "mid",
"start": 15.0,
"duration": 15.0,
"midroll_index": 1
},
{
"manifest_urls":{
]"1080p": "https://{...}/pod/2/profile/1080p.m3u8",
"360p": "https://{...}/pod/2/profile.m3u8",
"subtitles-webvtt": "https://{...}/pod/0/profile/subtitles-en.vtt""
},
"type": "post",
"duration": 10.0
}
]
}
Cómo unir grupos de anuncios al contenido
El proceso de unir grupos de anuncios a tus transmisiones de contenido varía según la implementación, el formato de la transmisión y las funciones que elijas implementar a partir de las especificaciones del formato. Los siguientes flujos de trabajo son sugerencias para controlar este proceso. Los detalles precisos de la implementación pueden variar según las necesidades de tu empresa y tus flujos de contenido.
Transmisiones HLS
Si unes una transmisión en formato HLS, tu transmisión de contenido será una playlist multivariante de vínculos a manifiestos de transmisión independientes, uno para cada perfil de codificación. Tus grupos de anuncios deben insertarse en cada uno de estos manifiestos de variantes. Una forma de hacerlo es preparar todos los manifiestos de variantes y pasarlos a una red de distribución de contenidos (CDN) para su alojamiento. La playlist de múltiples variantes final es un conjunto de vínculos a estos manifiestos alojados en la CDN.
Iteración sobre perfiles de codificación
Para cada perfil de codificación, recopila todos los manifiestos de grupos de anuncios asociados de la respuesta de Ad Manager, junto con sus horas de inicio asociadas. Para los grupos de anuncios previos al video, establece la hora de inicio en 0
. Para los anuncios al final del video, usa la duración del contenido como la hora de inicio del grupo de anuncios. Identifica la transmisión de variante en la playlist de varias variantes que coincida con la configuración de audio y video de cada perfil de codificación.
Ejemplo de array de grupos de anuncios
"ad_pods": [
{
"manifest_urls":{
"1080p": "https://{...}/pod/0/profile/1080p.m3u8",
"360p": "https://{...}/pod/0/profile/360p.m3u8",
"subtitles-en": "https://{...}/pod/0/profile/subitles-en.vtt"
},
"type": "pre",
"duration": 10.0
},
{
"manifest_urls":{
"1080p": "https://{...}/pod/1/profile/1080p.m3u8",
"360p": "https://{...}/pod/1/profile/360p.m3u8",
"subtitles-en": "https://{...}/pod/1/profile/subitles-en.vtt"
},
"type": "mid",
"start": 15.0,
"duration": 15.0,
"midroll_index": 1
},
{
"manifest_urls":{
"1080p": "https://{...}/pod/2/profile/1080p.m3u8",
"360p": "https://{...}/pod/2/profile/360p.m3u8",
"subtitles-en": "https://{...}/pod/2/profile/subitles-en.vtt"
},
"type": "post",
"duration": 10.0
}
]
Ejemplo de playlist de contenido de múltiples variantes
#EXTM3U
#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subs0",LANGUAGE="en",NAME="English",AUTOSELECT=YES,DEFAULT=YES,URI="https://{...}/subitles-en.vtt"
#EXT-X-STREAM-INF:BANDWIDTH=5000000,RESOLUTION=1920x1080,CODECS="avc1.4d000c,mp4a.40.5"
https://{...}/1080p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=1000000,RESOLUTION=640x360,CODECS="avc1.4d000d,mp4a.40.5"
https://{...}/360p.m3u8
Ejemplo de datos de variantes recopilados
Encoding profile: "1080p"
Profile settings: {...}
Content manifest: https://{...}/1080p.m3u8
Ad pods (start time -> manifest):
0 -> https://{...}/pod/0/profile/1080p.m3u8
15 -> https://{...}/pod/1/profile/1080p.m3u8
600 -> https://{...}/pod/2/profile/1080p.m3u8
Cómo insertar anuncios en cada manifiesto de variante
Para cada transmisión de variantes, revisa los segmentos del manifiesto de contenido y mantén un total general del tiempo de contenido transcurrido. Cuando llegues a la posición de inicio de un grupo de anuncios, extrae la lista de segmentos del manifiesto del grupo de anuncios, une la lista de segmentos en dos etiquetas #EXT-X-DISCONTINUITY
y, luego, insértala en la ubicación actual del manifiesto de contenido. Continúa con este proceso hasta que se hayan procesado todos los grupos de anuncios y los flujos de variantes.
Los manifiestos resultantes deben cumplir con el estándar HLS. Por lo tanto, según las funciones de la especificación que incorpore tu manifiesto de contenido, es posible que debas realizar un pase final por el manifiesto combinado para corregir los números de secuencia de contenido multimedia, la duración del contenido, los números de secuencia de discontinuidad y cualquier otra etiqueta que deba actualizarse para tener en cuenta los nuevos segmentos de anuncios. Una vez que se hayan corregido las discrepancias con el estándar, envía cada manifiesto de variante específica del usuario a tu CDN para su alojamiento.
Si el manifiesto de contenido está encriptado, debes almacenar la última clave de encriptación que se encontró antes del inicio del grupo de anuncios actual en una etiqueta #EXT-X-KEY
. Luego, debes agregar la etiqueta #EXT-X-KEY:METHOD=NONE
para quitar la encriptación antes del primer segmento de cada grupo de anuncios. Por último, debes agregar una copia de la etiqueta #EXT-X-KEY
almacenada antes del primer segmento de contenido después de cada grupo de anuncios para restablecer la encriptación del contenido.
Ejemplo de datos de variantes recopilados
Encoding profile: "1080p"
Content manifest: https://{...}/1080p.m3u8
Ad pods (start time -> manifest):
0 -> https://dai.google.com/{...}pod/0/profile/1080p.m3u8
15 -> https://dai.google.com/{...}pod/1/profile/1080p.m3u8
600 -> https://dai.google.com/{...}pod/2/profile/1080p.m3u8
Ejemplo de manifiesto de contenido
Este es el contenido del manifiesto https://{...}/1080p.m3u8
que se indica en los datos de variantes recopilados.
#EXTM3U
{...}
#EXTINF:5.000,
https://{...}/1080p/content-segment-0.ts
#EXTINF:5.000,
https://{...}/1080p/content-segment-1.ts
#EXTINF:5.000,
https://{...}/1080p/content-segment-2.ts
#EXTINF:5.000,
https://{...}/1080p/content-segment-3.ts
#EXTINF:5.000,
https://{...}/1080p/content-segment-4.ts
#EXTINF:5.000,
https://{...}/1080p/content-segment-5.ts
{...}
Ejemplo de manifiesto de grupo de anuncios
Este es el contenido del manifiesto https://dai.google.com/{...}/pod/1/profile/1080p.m3u8
que se indica en los datos de variantes recopilados.
#EXTM3U
{...}
#EXTINF:5.000,
https://dai.google.com/{...}/0.ts
#EXTINF:5.000,
https://dai.google.com/{...}/1.ts
#EXTINF:5.000,
https://dai.google.com/{...}/2.ts
Ejemplo de manifiesto de variante cosida
Este sería el manifiesto de variante cosida resultante, que se pasa a la CDN y se aloja en https://cdn.{...}/{userid}/1080p.m3u8
.
#EXTM3U
{...}
#EXTINF:5.000,
https://{...}/1080p/content-segment-0.ts
#EXTINF:5.000,
https://{...}/1080p/content-segment-1.ts
#EXTINF:5.000,
https://{...}/1080p/content-segment-2.ts
#EXT-X-DISCONTINUITY
#EXTINF:5.000,
https://dai.google.com/{...}/0.ts
#EXTINF:5.000,
https://dai.google.com/{...}/1.ts
#EXTINF:5.000,
https://dai.google.com/{...}/2.ts
#EXT-X-DISCONTINUITY
#EXTINF:5.000,
https://{...}/1080p/content-segment-3.ts
#EXTINF:5.000,
https://{...}/1080p/content-segment-4.ts
#EXTINF:5.000,
https://{...}/1080p/content-segment-5.ts
{...}
Cómo crear una playlist de múltiples variantes
Recopila las direcciones de CDN de cada manifiesto de variante completado, junto con los detalles del perfil de codificación coincidentes, y reúne los resultados en un nuevo manifiesto multivariante. Este manifiesto específico del usuario se muestra como la respuesta a la solicitud de manifiesto que recibiste en el paso 1.
Ejemplo de playlist de múltiples variantes final
#EXTM3U
#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subs0",LANGUAGE="en",NAME="English",AUTOSELECT=YES,DEFAULT=YES,URI="https://cdn.{...}-subitles-en.vtt"
#EXT-X-STREAM-INF:BANDWIDTH=5000000,RESOLUTION=1920x1080,CODECS="avc1.4d000c,mp4a.40.5"
https://cdn.{...}/{userid}/1080p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=1000000,RESOLUTION=640x360,CODECS="avc1.4d000d,mp4a.40.5"
https://cdn.{...}/{userid}/360p.m3u8
Transmisiones de MPEG DASH
Si unes una transmisión en formato MPEG DASH, solo debes producir un archivo. Esto puede facilitar la unión de transmisiones DASH en comparación con HLS.
Un archivo de descripción de presentación multimedia (MPD) de MPEG DASH preparado de forma correcta debe consistir en varios períodos, cada uno de los cuales contiene varias representaciones. Cada representación debe coincidir con uno de tus perfiles de codificación. Cada grupo de anuncios que se muestra desde Ad Manager también es un archivo MPD que contiene una secuencia de períodos con representaciones coincidentes.
Para unir estos archivos MPD, primero toma nota de las horas de inicio de cada grupo de anuncios. Para los anuncios previos al video, inserta los períodos de los grupos de anuncios previos al video antes de cualquier período de contenido. Para los anuncios al final del video, inserta los períodos de los grupos de anuncios al final del video después de todos los períodos del contenido. Itera sobre los períodos del MPD de contenido y haz un seguimiento del tiempo de reproducción transcurrido de todos los períodos de contenido procesados. Cuando llegues a un límite entre períodos que corresponda a la hora de inicio de un grupo de anuncios, inserta los períodos del archivo MPD del grupo de anuncios durante el video coincidente en ese límite.
El archivo MPD final debe cumplir por completo con las especificaciones de MPEG_DASH, por lo que es posible que debas iterar sobre el archivo final una vez más para corregir los tiempos de inicio de los períodos, fijar la duración de la presentación multimedia para tener en cuenta los períodos de anuncios insertados recientemente y resolver cualquier otro conflicto que pueda haber surgido del proceso de unión.
MPD de ejemplo de contenido
<?xml version="1.0" encoding="UTF-8"?>
<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" minBufferTime="PT1.500000S" type="static" mediaPresentationDuration="PT0H10M00.000S" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011">
<ProgramInformation moreInformationURL="http://.../info">
<Title>Example Stream</Title>
</ProgramInformation>
<Period duration="PT0H0M15.000S" id="content-period-1">
...
</Period>
<Period duration="PT0H0M15.000S" id="content-period-2">
...
</Period>
<Period duration="PT0H0M15.000S" id="content-period-3">
...
</Period>
...
</MPD>
Ejemplo de JSON de grupo de anuncios
[{
"mpd_uri": "https://{...}pod/1.mpd",
"type": "mid",
"start": 15.0,
"duration": 15.0,
"midroll_index": 1
}]
Ejemplo de MPD de grupo de anuncios
Este es el contenido de mpd_uri
del JSON del grupo de anuncios anterior.
<?xml version="1.0" encoding="UTF-8"?>
<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" minBufferTime="PT1.500000S" type="static" mediaPresentationDuration="PT0H0M15.000S" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011">
<ProgramInformation moreInformationURL="http://.../info">
<Title>Ad Pod 1</Title>
</ProgramInformation>
<Period duration="PT0H0M5.000S" id="ad-pod-1-period-1">
...
</Period>
<Period duration="PT0H0M5.000S" id="ad-pod-1-period-2">
...
</Period>
<Period duration="PT0H0M5.000S" id="ad-pod-1-period-3">
...
</Period>
...
</MPD>
Ejemplo de MPD unido
Envía esto como respuesta a la solicitud inicial del manifiesto de transmisión.
<?xml version="1.0" encoding="UTF-8"?>
<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" minBufferTime="PT1.500000S" type="static" mediaPresentationDuration="PT0H10M15.000S" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011">
<ProgramInformation moreInformationURL="http://.../info">
<Title>Example Stream</Title>
</ProgramInformation>
<Period duration="PT0H0M15.000S" id="content-period-1">
...
</Period>
<Period duration="PT0H0M5.000S" id="ad-pod-1-period-1">
...
</Period>
<Period duration="PT0H0M5.000S" id="ad-pod-1-period-2">
...
</Period>
<Period duration="PT0H0M5.000S" id="ad-pod-1-period-3">
...
</Period>
<Period duration="PT0H0M15.000S" id="content-period-2">
...
</Period>
<Period duration="PT0H0M15.000S" id="content-period-3">
...
</Period>
...
</MPD>
Recursos adicionales
- Reproducción de la publicación de grupos con el SDK de IMA:
- Reproducción de la publicación de grupos de anuncios con la API de DAI