Outil de manipulation du fichier manifeste pour les diffusions en direct

L'API Pod Serving permet d'accéder à des segments d'annonces encodés et conditionnés, préparés de telle sorte qu'ils puissent être assemblés directement dans un HLS destiné à l'utilisateur ; ou MPEG-DASH. Pour MPEG-DASH, l'API Pod Serving fournit également un modèle de fichier manifeste pour fournir des informations et un contexte supplémentaires sur ces segments d'annonces.

Ce guide est axé sur l'implémentation d'une manipulation de base du fichier manifeste pour la diffusion de séries d'annonces. pour les diffusions en direct.

Condition préalable : Configurer des événements de diffusion en direct dans Google Ad Manager

Avant d'effectuer des requêtes à partir de l'API de diffusion de séries d'annonces, vous devez créer un événement de diffusion en direct Ad Manager pour chaque flux que vous traitez. Vous pouvez créer un événement de streaming en direct à l'aide de LiveStreamEventService API ou de l'interface Web Google Ad Manager.

Pour qu'un événement de diffusion en direct puisse être utilisé avec l'API de diffusion de séries d'annonces, vous devez renseigner plusieurs attributs de votre événement :

  • customAssetKey : identifiant personnalisé à utiliser pour cet événement. Doit être unique pour tous les événements du réseau.
  • adTags – URL du tag d'emplacement publicitaire principal générée par le trafficking dans Ad Manager du workflow.
  • dynamicAdInsertionType : doit être défini sur POD_SERVING_REDIRECT.
  • streamingFormat : à définir sur HLS ou DASH en conséquence.
  • segmentUrlAuthenticationKeyIds - au moins un Clé HMAC servant à signer les demandes de segments d'annonces.
  • daiEncodingProfileIds : liste des ID DAIEncodingProfile activés pour cet événement.
  • startDateTime : date et heure de début de l'événement
  • endDateTime : date et heure de fin planifiées de cet événement. Cet attribut est obligatoire si unlimitedEndDateTimeis false and ignored ifunlimitedEndDateTimeis true.unlimitedEndDateTime` : booléen. Voir ci-dessus

Recevoir des requêtes de fichier manifeste de flux

Votre outil de manipulation du fichier manifeste doit fournir un point de terminaison d'API pour écouter le fichier manifeste à partir de l'application cliente du lecteur vidéo. Ce point de terminaison doit au minimum collecter un ID de flux à partir de l'application du lecteur client et renvoyer un le fichier manifeste de flux. L'ID de flux permet d'identifier la session de streaming dans Ad Manager.

Vous devez également collecter d'autres informations pour identifier le flux de contenu approprié, par exemple un ID de contenu.

Exemple de point de terminaison de requête de fichier manifeste potentiel

GET /api/video/{asset_key}/manifest.{format}
Host: {your_domain}
Paramètres de chemin d'accès
asset_key Un ID fictif correspondant à la diffusion en direct demandée dans votre système
format Paramètre hypothétique correspondant au format du flux. L'un des éléments suivants :
mpd Pour les flux MPEG-DASH
m3u8 Pour les flux HLS
Paramètres de requête
stream_id ID de flux Ad Manager provenant de l'application de lecteur vidéo cliente.

Récupérer le flux de contenu

Utilisez l'ID de contenu collecté à partir de la requête de fichier manifeste pour sélectionner le flux de contenu à assembler avec les annonces.

Insérer des segments d'annonces dans le flux de contenu

L'association des URL de segments d'annonces varie en fonction du format de votre flux.

Flux HLS

Les flux HLS sont généralement diffusés sous la forme d'un fichier manifeste multivariante, qui contient une Ensemble de liens vers des fichiers manifestes de variantes, qui correspondent à chacun des types d'encodage profils.

Remarque : Pour simplifier, ce guide suppose que vos contenus multimédias HLS sont encodés dans un format qui muxe l'audio et la vidéo dans le même fichier de segment.

Playlists de multivariantes proxy

Vous devez remplacer l'URL de la playlist de chaque variante dans la multivariante d'origine playlist avec un autre appel du point de terminaison au manipulateur pour traiter les fichier manifeste de la variante sélectionnée.

Les étapes restantes pour assembler HLS supposent qu'un seul fichier manifeste de variante est en cours de traitement.

Exemple de point de terminaison de requête de variante potentiel
GET /api/video/{asset_key}/variant/{variant_id}.m3u8
Host: {your_domain}
Paramètres de chemin d'accès
asset_key Un ID fictif correspondant à la diffusion en direct demandée dans votre système
variant Paramètre fictif contenant un identifiant pour la variante spécifique en cours de traitement.
Paramètres de requête
stream_id ID de flux Ad Manager de l'application de lecteur vidéo client, utilisé ici pour identifier une session utilisateur avec le manipulateur de fichier manifeste.
Exemple de fichier manifeste de multivariantes non traités
#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
Exemple de fichier manifeste multivariante avec 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

Identifier les segments de coupure publicitaire et insérer les discontinuités

Lorsque vous traitez le fichier manifeste de la variante, gardez une trace de l'heure de début, de la durée et de l'indice de la prochaine coupure publicitaire à venir, jusqu'à ce que le fichier manifeste dynamique en cours de traitement contienne des segments qui seront remplacés par le contenu de l'annonce.

Les coupures publicitaires peuvent être délimitées des segments de contenu de différentes manières, en fonction de votre encodeur. Une méthode courante pour délimiter une coupure publicitaire consiste à placer une balise #EXT-X-CUE-OUT avant les segments d'annonces, puis à la suivre d'une balise #EXT-X-CUE-IN.

Pour séparer les coupures publicitaires hébergées par Google de vos segments de contenu, vous devez insérer Des tags #EXT-X-DISCONTINUITY au début et à la fin de chaque coupure publicitaire. Si ces les balises de discontinuité n'apparaissent pas dans le fichier manifeste final, la lecture échouera.

Les URI des segments d'annonces insérés ne sont pas chiffrés. Si votre contenu est chiffré, vous devrez également supprimer le chiffrement en spécifiant #EXT-X-KEY:METHOD=NONE avant le premier segment d'annonces de chaque coupure publicitaire, puis ajoutez-le de nouveau après la la coupure publicitaire.

Exemple de fichier manifeste (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
Fichier manifeste avec des discontinuités insérées
#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

Traiter les segments de séries d'annonces

Pour chaque segment d'un bloc d'annonces, vous devez suivre quelques valeurs supplémentaires :

  • segment_number : index du segment dans le bloc d'annonces, commençant par zéro. Ou "init" pour le segment d'initialisation MP4.
  • segment_duration: durée du segment actuel en millisecondes. Cette valeur doit être identique pour tous les segments, à l'exception du dernier du pod.
  • segment_offset: décalage du segment calculé en ajoutant les valeurs durée du segment par rapport au décalage de son segment en millisecondes
  • last: valeur booléenne identifiant le dernier segment d'une série d'annonces. Valeurs par défaut sur "false".

Créer des URL de segment d'annonces

Remplacez chaque segment de la coupure publicitaire par une URL au format suivant:

/linear/pods/v1/seg/network/{network_code}/custom_asset/{custom_asset_key}/{pod_identifier}/profile/{profile_name}/{segment_number}.(ts|mp4|vtt|aac|ac3|eac3)
Paramètres de chemin d'accès
network_code Code de réseau Ad Manager 360 de ce réseau.
custom_asset_key Clé de l'élément de diffusion en direct personnalisée spécifiée dans LiveStreamEventService ou sur la page de diffusion en direct dans l'interface Web d'Ad Manager 360.
pod_identifier

Les formats suivants sont acceptés :

pod/{integer}

Identifiant numérique de la coupure publicitaire en cours. Les ID de séries d'annonces sont attribués de manière incrémentielle pour chaque événement de coupure publicitaire, à partir de 1.

ad_break_id/{string}

Identifiant de chaîne de la coupure publicitaire en cours.

profile_name Identifiant du profil demandé,
segment_number Index de ce segment dans la série d'annonces actuelle, à partir de zéro.
Lorsque vous utilisez un conteneur MP4, vous pouvez demander le segment d'initialisation en définissant segment_number sur "init".
Paramètres de requête
stream_id Obligatoire Paramètre stream_id de l'utilisateur renvoyé par la fonctionnalité de création de flux requête.
sd Obligatoire segment_duration
so Facultatif segment_offset

Si so n'est pas indiqué, le système considère que les segments précédents ont la même durée et le décalage du segment est calculé à partir de segment_number et sd.

pd Obligatoire, sauf pour les événements pour lesquels des coupures publicitaires sans durée sont activées Durée de la coupure publicitaire (en millisecondes). Également appelé ad_pod_duration.
auth-token Obligatoire Jeton HMAC signé et encodé au format URL pour ce bloc d'annonces.
last Facultatif Valeur booléenne indiquant le dernier segment de la coupure publicitaire. Valeur par défaut : "false".

Les valeurs des paramètres de requête doivent être correctement encodées pour pouvoir être utilisées sans risque pour les URL. Cela est particulièrement important pour le champ auth-token, car il peut contenir des caractères /, + et =.

Exemple de fichier manifeste (après le remplacement d'un segment)
#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/ad_break_id/adbreak1/profile/devrel4628000/0.ts?sd=5005&so=0&pd=18015&auth-token=ad_break_id%3Dadbreak1~custom_asset_key%3DiYdOkYZdQ1KFULXSN0Gi7g~cust_params%3D~exp%3D1489680000~network_code%3D6062~pd%3D180000~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/ad_break_id/adbreak1/profile/devrel4628000/1.ts?sd=5005&so=5005&pd=18015&auth-token=ad_break_id%3Dadbreak1~custom_asset_key%3DiYdOkYZdQ1KFULXSN0Gi7g~cust_params%3D~exp%3D1489680000~network_code%3D6062~pd%3D180000~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/ad_break_id/adbreak1/profile/devrel4628000/2.ts?sd=5005&so=10010&pd=18015&auth-token=ad_break_id%3adbreak1~custom_asset_key%3DiYdOkYZdQ1KFULXSN0Gi7g~cust_params%3D~exp%3D1489680000~network_code%3D6062~pd%3D180000~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/ad_break_id/adbreak1/profile/devrel4628000/3.ts?sd=3000&so=15015&pd=18015&auth-token=ad_break_id%3Dadbreak1~custom_asset_key%3DiYdOkYZdQ1KFULXSN0Gi7g~cust_params%3D~exp%3D1489680000~network_code%3D6062~pd%3D180000~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

Félicitations ! Vous diffusez maintenant une diffusion en direct avec des segments d'annonces fournis par l'API d'insertion dynamique de pods.

Flux DASH

Les flux DASH sont fournis sous la forme d'un fichier MPD contenant tous les encodages de flux au format dans un fichier unique, dans lequel le contenu est représenté par une série de points.

Modèle de période de demande

Demandez un modèle de période à Google Ad Manager. Ce modèle deviendra votre de la coupure publicitaire, une fois que les macros qu'elle contient ont été insérées.

Vous ne devez demander ce modèle qu'une seule fois par session de diffusion et le mettre en cache pour à réutiliser avec chaque coupure publicitaire.

Point de terminaison de la requête du modèle de période
GET /linear/pods/v1/dash/network/{network_code}/custom_asset/{custom_asset}/pods.json
Host: dai.google.com
Content-Type: application/json
Paramètres de chemin d'accès
network_code Le code de réseau Ad Manager 360 de l'éditeur.
custom_asset Clé d'élément personnalisé de l'événement en direct dans Google Ad Manager.
Paramètres de requête
stream_id ID de flux Ad Manager indiqué dans le lecteur vidéo client.
Réponse JSON
dash_period_template Chaîne XML du modèle de période.
segment_duration_ms Durée de chaque segment de contenu publicitaire dans le modèle de période de tiret, en millisecondes.
Exemple de requête (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
Exemple de réponse
{"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}

Insérer des valeurs dans le modèle de période

Le modèle de période contient plusieurs macros que vous devez remplacer pour chaque coupure publicitaire. Toutes les macros doivent être remplacées. Les macros inutilisées doivent être remplacées par Chaîne vide ("").

Macro Description Exemple
$$pod-id$$ Indice de la série d'annonces que représente cette période. Cette valeur doit être identique pour le même pod dans toutes les sessions de visionnage. 1
$$period-start$$ Heure à laquelle la période commence dans la description de la présentation du média actuelle. Un attribut facultatif qui doit être remplacé par start="###", où ### correspond à l'heure de présentation à laquelle la coupure publicitaire commence. Si l'heure de début de la période n'est pas fournie, cette macro doit être remplacée par une chaîne vide. start="PT2H33M30S"
$$period-duration$$ Durée de la période publicitaire complète. Un attribut facultatif qui doit être remplacé par duration="###", où ### est le durée de la période de l'annonce au format de durée standard DASH. Si la durée de la période n'est pas fournie, cette macro doit être remplacée par une chaîne vide. duration="PT15S"
$$pod-duration$$ Durée attendue des annonces à sélectionner pour cette série d'annonces, en millisecondes. 15000
$$number-of-repeated-segments$$ Cette valeur est calculée en divisant la durée de la période de l'annonce (en millisecondes) par la valeur de segment_duration_ms, et en arrondissant à le nombre entier le plus proche. 3
$$cust_params$$ Cette macro peut être remplacée par les paramètres de ciblage personnalisés propres à la coupure publicitaire en cours, le cas échéant. La valeur doit respecter le format décrit dans cette documentation Ad Manager cet article du Centre d'aide. Si aucun paramètre personnalisé n'est nécessaire, cette macro doit être remplacée par une chaîne vide. &cust_params=section%3Dblog%26anotherKey%3Dvalue1%2Cvalue2
$$scte35$$ Cette macro doit être remplacée par une valeur scte35 propre à cette coupure publicitaire, le cas échéant. Si aucune information scte35 n'est nécessaire, cette macro doit être remplacée par une chaîne vide. /DAqAAAAAAAA///wDwVAAAT2f0/+ecF1mQABC/8ACgAIQ1VFSQAAAAsuZVlR
$$token$$ Jeton HMAC signé et encodé au format URL. Veuillez indiquer ce jeton. custom_asset_key%3DiYdOkYZdQ1KFULXSN0Gi7g~exp%3D1489680000~network_code%3D6062~pd%3D180000~pod_id%3D5~hmac%3D6a8c44c72e4718ff63ad2284edf2a8b9e319600b430349d31195c99b505858c9
Modèle de période brut, contenant des 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>
Période d'annonce renseignée
<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>

Insérer la période renseignée dans le fichier manifeste DASH

Enfin, remplacez le point approprié dans votre fichier manifeste brut par le nouveau d'une période d'annonce insérée, puis renvoyer le fichier manifeste assemblé final à la demande pour la lecture.

Exemple de fichier manifeste de contenu brut
<?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>
Exemple de fichier manifeste assemblé
<?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>

Félicitations ! Vous diffusez désormais une diffusion en direct DASH avec des segments d'annonces par l'API d'insertion dynamique de pods.

Ressources supplémentaires