Manipulador de manifiestos para transmisiones en vivo

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 como POD_SERVING_REDIRECT.
  • streamingFormat: Se establece en HLS o DASH 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 evento
  • endDateTime: Es la fecha y hora de finalización programadas de este evento. Este atributo es obligatorio si unlimitedEndDateTimeis false and ignored ifunlimitedEndDateTimeis 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:
mpd Para transmisiones MPEG-DASH
m3u8 Para transmisiones HLS
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 so, se supone que todos los segmentos anteriores tienen la misma duración, y el desplazamiento del segmento se calcula a partir de segment_number y sd.

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}&amp;sd=5000&pd=$$pod-duration$$&amp;cust_params=$$cust_params$$&amp;auth_token=$$token$$" media="$RepresentationID$/$Number$.mp4?stream_id={a-stream-id}&amp;sd=5000&pd=$$pod-duration$$&amp;cust_params=$$cust_params$$&amp;scte35=$$scte35$$&amp;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&amp;sd=5000&pd=$$pod-duration$$&amp;cust_params=$$cust_params$$&amp;auth_token=$$token$$" media="$RepresentationID$/$Number$.mp4?stream_id=ç√&amp;sd=5000&pd=$$pod-duration$$&amp;cust_params=$$cust_params$$&amp;scte35=$$scte35$$&amp;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&amp;sd=5000&amp;pd=30000&amp;cust_params=&amp;auth-token=&amp;scte35=" initialization="$RepresentationID$/init.mp4?stream_id=cc59197a-44c0-4be2-a8cc-9a6fdb80158f:DLS&amp;pd=30000&amp;cust_params=&amp;auth-token=&amp;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&amp;sd=5000&amp;pd=30000&amp;cust_params=&amp;auth-token=&amp;scte35=$$scte35$$" initialization="$RepresentationID$/init.mp4?stream_id=cc59197a-44c0-4be2-a8cc-9a6fdb80158f:DLS&amp;pd=30000&amp;cust_params=&amp;auth-token=&amp;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