Manifestatore per gli stream VOD

L'API Pod Serving fornisce accesso a pod di annunci video con velocità in bit adattiva preparati in modo da poter essere uniti direttamente a una playlist multimediale HLS o MPEG-DASH rivolta all'utente.

Questa guida è incentrata sull'implementazione di un server di manipolazione del manifest per la pubblicazione di pod di base per i flussi VOD.

Ricevi richieste relative al manifest del flusso

Il manipolatore del manifest deve fornire un endpoint API per ascoltare le richieste di manifest dall'app client del video player. Come minimo, questo endpoint deve raccogliere un ID stream dall'app del player client. Questo ID stream viene utilizzato per identificare la sessione di streaming per Ad Manager nelle richieste di pod di annunci.

Devi raccogliere anche altre informazioni per identificare lo stream di contenuti appropriato, ad esempio un Content ID.

Endpoint di richiesta manifest di esempio

GET /api/stream_id/{stream_id}/video/{content_id}.{format}
Host: {your_domain}
Parametri del percorso
stream_id L'ID stream di Ad Manager dall'app del video player del client.
content_id Un ID ipotetico corrispondente ai contenuti video nel tuo sistema.
format Un parametro ipotetico corrispondente al formato dello stream. Uno dei seguenti:
mpd Per stream MPEG-DASH
m3u8 Per gli stream HLS

Recuperare lo stream di contenuti

Utilizza l'ID contenuto raccolto dalla richiesta del file manifest per selezionare lo stream di contenuti da unire agli annunci.

Richiedi manifest dei pod di annunci

Per richiedere annunci da Ad Manager, il server deve effettuare una richiesta POST all'endpoint ad pods, trasmettendo i profili di codifica, il tag annuncio e i parametri di targeting richiesti. Questa richiesta include anche l'ID stream che hai raccolto nel passaggio 1.

Riceverai un elenco di oggetti pod di annunci contenenti file manifest per i pod di annunci richiesti dal tag annuncio del publisher, oltre a informazioni su quando e dove devono essere inseriti nei contenuti.

POST /ondemand/pods/api/v1/network/{network_code}/streams/{stream_id}/adpods
Host: dai.google.com
Content-Type: application/json
Parametri del percorso
network_code Il codice di rete Ad Manager 360 del publisher.
stream_id L'ID stream dell'app del video player del client.

Corpo JSON

Parametri corpo
encoding_profiles Required Un elenco di rappresentazioni JSON dei profili di codifica che vuoi ricevere per ogni interruzione pubblicitaria. Consulta i dettagli di seguito

Per garantire la massima fluidità della riproduzione, questi dati devono corrispondere all'insieme di profili di codifica utilizzati nel tuo stream di contenuti.

ad_tag Required Un tag annuncio per richiedere annunci VMAP.
cuepoints Optional Un elenco di cue point all'interno dello stream di contenuti in cui verranno inserite le interruzioni pubblicitarie mid-roll. I cue point sono misurati in secondi in virgola mobile.

Obbligatorio solo per le risposte VMAP che contengono mid-roll che utilizzano scarti temporali posizionali. Si tratta di una situazione rara.

content_duration_seconds Optional La durata dei contenuti in secondi.

Obbligatorio solo per le risposte VMAP che contengono mid-roll con scarti temporali percentuale. Si tratta di una situazione rara.

manifest_type Optional Il formato degli stream di annunci richiesti, hls o dash. Il valore predefinito è hls.
dai_options Optional Opzioni aggiuntive che controllano gli aspetti del rendering dei manifest. Consulta i dettagli di seguito
Profilo di codifica
profile_name Required Un identificatore del profilo di codifica. Questo valore può essere qualsiasi stringa tu scelga, ma non puoi avere più profili di codifica con lo stesso nome nello stesso stream.
type Required Il tipo di codifica del flusso descritto da questo profilo di codifica. I tipi di contenuti sono: media, iframe e subtitles.
container_type Required Il formato del contenitore utilizzato da questo profilo di codifica. I formati dei container sono: mpeg2ts, fmp4cmaf, hls_packed_audio
video_settings Optional Obbligatorio se il tipo di profilo di codifica è iframe. In caso contrario, consentito solo se il tipo di media contiene video. Consulta i dettagli di seguito
audio_settings Optional Obbligatorio se il profilo di codifica contiene audio. Consentita solo se il tipo è multimediale. Consulta i dettagli di seguito
subtitle_settings Optional Obbligatorio se il profilo di codifica contiene sottotitoli. Consulta i dettagli di seguito
Impostazioni video
codec Required La stringa del codec RFC6381.

Esempio: avc1.4d000c

bitrate Required Un numero intero che rappresenta la velocità in bit massima del video di questo profilo in byte al secondo.
frames_per_second Required L'f/s in virgola mobile del video.
resolution Required Un valore con codifica JSON contenente il valore "width" e "height" del video in pixel.

Esempio: {"width": 640, "height": 320}

Impostazioni audio
codec Required La stringa del codec RFC6381.

Esempio: mp4a.40.5

bitrate Required Un numero intero che rappresenta la velocità in bit massima dell'audio di questo profilo in byte al secondo.

Esempio: 300000

channels Required Un numero intero che rappresenta il numero di canali audio, inclusi i canali a bassa frequenza.
sample_rate Required Un numero intero che rappresenta la frequenza di campionamento audio in Hertz.

Esempio: 4800

Impostazioni dei sottotitoli
format Required Il formato file utilizzato dai sottotitoli in banda. I valori supportati sono webvtt o ttml.
language Optional La lingua dei sottotitoli come stringa di lingua RFC5646. Se fornito, questo valore viene utilizzato solo per il rendering DASH.

Esempio: en-us

Opzioni DAI
dash_profile Optional Il profilo MPEG-DASH da applicare ai manifest dei pod di annunci. Questa impostazione viene utilizzata solo per i manifest DASH. I valori consentiti sono live o on-demand. Il valore predefinito è on-demand.

Il valore live corrisponde al profilo MPEG-DASH "urn:mpeg:dash:profile:isoff-live:2011".

Il valore on-demand corrisponde al profilo MPEG-DASH urn:mpeg:dash:profile:isoff-on-demand:2011.

ad_pod_timeout Optional Il tempo massimo da dedicare alla selezione degli annunci e alla creazione dei pod di annunci, in secondi in virgola mobile. Una volta trascorso questo tempo, Ad Manager restituisce tutti gli annunci già selezionati nella risposta ad_pods e ne interrompe l'elaborazione.
sam_id Optional Specifica una chiave di debug alternativa che può essere utilizzata per cercare sessioni nel monitoraggio dell'attività di streaming.

Risposta

Parametri di risposta
valid_for Durata per la quale queste playlist di pod di annunci sono valide nel formato dhms (giorni, ore, minuti, secondi).
valid_until La data e l'ora di validità di queste playlist di pod di annunci come stringa data/ora ISO8601 in formato yyyy-MM-dd'T'hh:mm:ss.sssssssss[+|-]hh:mm.
ad_pods Un elenco di pod di annunci selezionati per questo stream.
Pod di annunci
manifest_uris Solo per gli stream HLS. Una mappa degli ID profilo di codifica agli URI del manifest HLS.
mpd_uri Solo per stream DASH. L'URI del DASH MPD.
type Il tipo di pod di annunci. I tipi di pod di annunci sono: pre, mid o post.
start Solo per pod di annunci mid-roll. La posizione, espressa in secondi in virgola mobile, nello stream in cui deve essere inserito il pod di annunci.
duration La durata di questo pod di annunci in secondi in virgola mobile.
midroll_index Solo per pod di annunci mid-roll. L'indice del pod di annunci mid-roll corrente. L'indicizzazione inizia con 1.

Richiesta di esempio (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

Corpo della richiesta di esempio

Questi sono i contenuti di request-body.json a cui viene fatto riferimento nella chiamata cURL sopra riportata.

{
  "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"
}

Esempio di risposta

{
  "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
    }
  ]
}

Unisci i pod di annunci nei contenuti

Il processo di stitching dei pod di annunci nei tuoi stream di contenuti varia a seconda dell'implementazione, del formato dello stream e delle funzionalità che scegli di implementare in base alle specifiche del formato. I seguenti flussi di lavoro sono suggerimenti su come gestire questa procedura. I dettagli precisi dell'implementazione possono variare in base alle esigenze aziendali e ai flussi di contenuti.

Flussi HLS

Se devi unire uno stream nel formato HLS, lo stream di contenuti sarà una playlist multivariante di link a file manifest dello stream separati, uno per ogni profilo di codifica. I tuoi pod di annunci devono essere inseriti in ognuno di questi manifest delle varianti. Un modo per farlo è preparare tutti i manifest delle varianti e passarli a una rete CDN (Content Delivery Network) per l'hosting. La playlist multivariante finale è un insieme di link a questi manifest ospitati da CDN.

Esegui l'iterazione sui profili di codifica

Per ogni profilo di codifica, raccogli tutti i manifest dei pod di annunci associati dalla risposta di Ad Manager, insieme alle ore di inizio associate. Per i pod di annunci pre-roll, imposta l'ora di inizio su 0. Per i post-roll, utilizza la durata dei contenuti come ora di inizio del pod di annunci. Identifica lo stream delle varianti nella playlist multivariante che corrisponde alle impostazioni audio e video di ogni profilo di codifica.

Esempio di array di pod di annunci
"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
    }
  ]
Esempio di playlist di contenuti multivarianti
#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
Esempio di dati delle varianti raccolti
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

Inserisci gli annunci nel manifest di ogni variante

Per ogni stream delle varianti, esamina i segmenti del manifest dei contenuti, mantenendo un totale complessivo del tempo trascorso nei contenuti. Quando arrivi alla posizione iniziale di un pod di annunci, estrai l'elenco di segmenti dal file manifest del pod stesso, aggrega l'elenco di segmenti in due tag #EXT-X-DISCONTINUITY e inserisci l'elenco nella posizione corrente nel manifest dei contenuti. Continua questa procedura finché non saranno stati elaborati tutti gli stream di annunci e le varianti.

I manifest risultanti devono essere conformi allo standard HLS. Di conseguenza, a seconda delle funzionalità della specifica incorporate dal file manifest dei contenuti, potresti dover eseguire un passaggio finale del file manifest combinato per correggere i numeri delle sequenze multimediali, la durata dei contenuti, i numeri delle sequenze di interruzioni e tutti gli altri tag che devono essere aggiornati per tenere conto dei nuovi segmenti di annunci. Una volta risolte le discrepanze con lo standard, invia il manifest di ogni variante specifica dell'utente alla rete CDN per l'hosting.

Se il manifest dei contenuti è criptato, devi archiviare l'ultima chiave di crittografia trovata prima dell'inizio del pod di annunci corrente in un tag #EXT-X-KEY. Poi, devi aggiungere il tag #EXT-X-KEY:METHOD=NONE per rimuovere la crittografia prima del primo segmento di ogni pod di annunci. Infine, devi aggiungere una copia del tag #EXT-X-KEY archiviato prima del primo segmento di contenuti dopo ogni pod di annunci per ripristinare la crittografia dei contenuti.

Esempio di dati delle varianti raccolti
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
Esempio di file manifest dei contenuti

Questi sono i contenuti del manifest https://{...}/1080p.m3u8 elencato nei dati delle varianti raccolti.

#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
{...}
Esempio di manifest dei pod di annunci

Questi sono i contenuti del manifest https://dai.google.com/{...}/pod/1/profile/1080p.m3u8 elencato nei dati delle varianti raccolti.

#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
Esempio di manifest delle varianti con unione

Si tratta del manifest della variante unita risultante, passato alla CDN e ospitato al momento 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
{...}

Crea una playlist multivariante

Raccogli gli indirizzi CDN per ogni manifest delle varianti completato, insieme ai dettagli del profilo di codifica corrispondente e assembla i risultati in un nuovo manifest multivariante. Questo manifest specifico per l'utente viene restituito come risposta alla richiesta di manifest che hai ricevuto nel passaggio 1.

Esempio di playlist multivariante finale
#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

Stream MPEG DASH

Se vuoi unire uno stream nel formato MPEG DASH, devi produrre un solo file. In questo modo gli stream DASH sono più facili da unire rispetto a HLS.

Un file MPD (Media Presentazione) MPEG DASH preparato correttamente deve essere composto da più periodi, ciascuno contenente più rappresentazioni. Ogni rappresentazione deve corrispondere a uno dei tuoi profili di codifica. Ogni pod di annunci restituito da Ad Manager è anche un file MPD contenente una sequenza di punti con rappresentazioni corrispondenti.

Per unire questi file MPD, inizia a prendere nota delle ore di inizio di ogni pod di annunci. Per i pre-roll, inserisci i periodi dei pod di annunci pre-roll prima di qualsiasi periodo di contenuto. Per i post-roll, inserisci i periodi del pod di annunci post-roll dopo tutti i periodi dei contenuti. Esegui l'iterazione nei periodi nell'MPD dei contenuti, tenendo traccia del tempo di riproduzione trascorso per tutti i periodi dei contenuti elaborati. Quando raggiungi un limite tra i periodi che corrisponde all'ora di inizio di un pod di annunci, inserisci i periodi dal file MPD del pod di annunci mid-roll corrispondente in corrispondenza di quel limite.

Il file MPD finale unito deve essere completamente conforme alle specifiche MPEG_DASH, quindi potresti dover ripetere l'iterazione del file finale ancora una volta correggendo gli orari di inizio dei periodi, la durata della presentazione multimediale per tenere conto dei periodi degli annunci appena inseriti e risolvendo eventuali altri conflitti che potrebbero essersi verificati dal processo di unione.

File MPD di esempio

<?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>

Esempio di JSON di pod di annunci

[{
  "mpd_uri": "https://{...}pod/1.mpd",
  "type": "mid",
  "start": 15.0,
  "duration": 15.0,
  "midroll_index": 1
}]

Esempio di MPD pod di annunci

Questo è il contenuto dell'elemento mpd_uri del file JSON dei pod di annunci riportato sopra.

<?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>

Esempio di file MPD con unione

Pubblica questa risposta come risposta alla richiesta iniziale del file manifest dello stream.

<?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>

Risorse aggiuntive