Manifestatore per gli stream VOD

L'API Pod Serving fornisce l'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 si concentra sull'implementazione di un server di manipolazione del manifest di pubblicazione dei pod di base per i flussi VOD.

Ricevi richieste manifest del flusso

Il manipolatore del manifest deve fornire un endpoint API per ascoltare le richieste di manifest dall'app client del video player. Questo endpoint deve almeno raccogliere un ID streaming 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 anche raccogliere altre informazioni per identificare lo stream di contenuti appropriato, ad esempio un ID contenuti.

Esempio di endpoint di richiesta del manifest

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 valori:
mpd Per stream MPEG-DASH
m3u8 Per i flussi HLS

Recuperare lo stream di contenuti

Utilizza l'ID contenuti 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 dei pod di annunci, passando 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.

In cambio, ricevi un elenco di oggetti pod di annunci contenenti i file manifest per i pod di annunci richiesti dal tag annuncio del publisher, oltre a informazioni su quando e dove devono essere inseriti nei tuoi 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 rendere la riproduzione il più fluida possibile, questo deve 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 vengono misurati in secondi in virgola mobile.

Obbligatorio solo per le risposte VMAP che contengono mid-roll che utilizzano offset temporali posizionali. È raro.

content_duration_seconds Optional La durata dei contenuti in secondi.

Obbligatorio solo per le risposte VMAP che contengono mid-roll con offset temporali percentuale. È raro.

manifest_type Optional Il formato degli stream di annunci richiesti, hls o dash. Il valore predefinito è hls.
dai_options Optional Opzioni aggiuntive che controllano aspetti della modalità di 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 è possibile avere più profili di codifica con lo stesso nome nello stesso stream.
type Required Il tipo di codifica dello stream descritto da questo profilo di codifica. I tipi di contenuti sono: media, iframe, subtitles.
container_type Required Il formato del contenitore utilizzato da questo profilo di codifica. I formati dei contenitori sono: mpeg2ts, fmp4cmaf, hls_packed_audio
video_settings Optional Obbligatorio se il tipo di profilo di codifica è iframe. Altrimenti, consentito solo se il tipo multimediale contiene video. Consulta i dettagli di seguito
audio_settings Optional Obbligatorio se il profilo di codifica contiene audio. Consentito 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 i valori "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 quelli 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 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 interrompe l'elaborazione.
sam_id Optional Specifica una chiave di debug alternativa che può essere utilizzata per cercare le sessioni nel Monitoraggio attività di streaming.

Risposta

Parametri di risposta
valid_for Durata per la quale queste playlist di pod di annunci sono valide in 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 stream HLS. Una mappa della codifica degli ID profilo agli URI del file 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 con rappresentazione 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.

Esempio di richiesta (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

Esempio di corpo della richiesta

Questi sono i contenuti di request_body.json a cui si fa 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 pod di annunci nei contenuti

Il processo di stitching di pod di annunci nei flussi 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 questo processo. I dettagli precisi dell'implementazione possono variare in base alle esigenze aziendali e ai flussi di contenuti.

Flussi HLS

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

Ripetizione 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 della variante 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 multivariante
#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 file manifest di ogni variante

Per ogni stream delle varianti, esamina i segmenti del manifest dei contenuti, mantenendo un totale complessivo del tempo trascorso per i contenuti. Quando arrivi alla posizione iniziale di un pod di annunci, estrai l'elenco di segmenti dal relativo file manifest, 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 i pod di annunci e gli stream delle varianti.

I file manifest risultanti devono essere conformi allo standard HLS. Di conseguenza, a seconda delle funzionalità della specifica incorporate nel file manifest dei contenuti, potresti dover eseguire un passaggio finale al file manifest combinato per correggere i numeri della sequenza multimediale, la durata dei contenuti, i numeri delle sequenze di discontinuità ed eventuali altri tag che devono essere aggiornati per tenere conto dei nuovi segmenti di annunci. Una volta risolte eventuali discrepanze con lo standard, invia ogni manifest delle varianti specifiche dell'utente alla tua 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 memorizzato 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 elencati 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 del pod di annunci

Questi sono i contenuti del manifest di https://dai.google.com/{...}/pod/1/profile/1080p.m3u8 elencati 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 file manifest delle varianti con unione

Questo sarebbe il manifest della variante unita risultante, passato alla CDN e ospitato all'indirizzo 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 del 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 stai eseguendo lo stitching di uno stream nel formato MPEG DASH, devi solo produrre un singolo file. In questo modo gli stream DASH sono più facili da unire rispetto a HLS.

Un file MPD (Media Presentation Description) MPEG DASH preparato correttamente deve essere composto da più punti, ciascuno con più rappresentazioni. Ogni rappresentazione deve corrispondere a uno dei 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 prendendo nota dell'ora di inizio di ogni pod di annunci. Per gli annunci pre-roll, inserisci i periodi del 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. Ripeti i passaggi per i periodi nel file 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 punti dal file MPD del pod di annunci mid-roll corrispondente in corrispondenza di quel limite.

Il file MPD finale accoppiato 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 in base ai periodi degli annunci appena inseriti e risolvendo eventuali altri conflitti che potrebbero derivare dal processo di stitching.

MPD dei contenuti 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 di pod di annunci

Questi sono i contenuti di mpd_uri del file JSON del 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 unito

Da pubblicare come risposta alla richiesta iniziale del manifest dello streaming.

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