Manifestatore per gli stream VOD

L'API Pod Serving fornisce l'accesso a pod di annunci video con velocità in bit adattabili preparati in modo da poter essere uniti direttamente a una playlist media HLS o MPEG-DASH rivolta agli utenti.

Questa guida si concentra sull'implementazione di un server di manipolazione del manifest per la pubblicazione di pod di base per gli stream VOD.

Ricevere richieste di manifest dello stream

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

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

Esempio di endpoint di richiesta 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 client.
content_id Un ID ipotetico corrispondente al video dei contenuti nel tuo sistema.
format Un parametro ipotetico corrispondente al formato dello stream. Uno dei seguenti:
mpd Per gli stream MPEG-DASH
m3u8 Per gli stream HLS

Recuperare lo stream di contenuti

Utilizza l'ID contenuto raccolto dalla richiesta 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 inviare una richiesta POST all'endpoint dei pod di annunci, passando i profili di codifica e il tag annuncio richiesti. Questa richiesta include anche l'ID stream raccolto nel passaggio 1.

In cambio, ricevi un elenco di oggetti pod di annunci contenenti file manifest per i pod di annunci richiesti dal tag annuncio del publisher e 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 dall'app di riproduzione video del client.

Corpo JSON

Parametri del 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, deve corrispondere all'insieme di profili di codifica utilizzati nello 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 con virgola mobile.

Obbligatorio solo per le risposte VMAP che contengono mid-roll che utilizzano offset temporali posizionali. Questo non è comune.

content_duration_seconds Optional La durata dei contenuti in secondi.

Obbligatorio solo per le risposte VMAP che contengono mid-roll che utilizzano offset temporali in percentuale. Questo non è comune.

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 del rendering dei manifest. Consulta i dettagli di seguito
Profilo di codifica
profile_name Required Un identificatore per questo profilo di codifica. Questo valore può essere qualsiasi stringa che scegli, ma non puoi 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 contenitore 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. Consentito solo se il tipo è media. 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 video massima di questo profilo in byte al secondo.
frames_per_second Required La frequenza fotogrammi in virgola mobile del video.
resolution Required Un valore con codifica JSON contenente la "larghezza" e l'"altezza" 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 audio massima 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 sottotitoli
format Required Il formato del 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 specificato, 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 per selezionare gli annunci e creare i pod di annunci, in secondi con virgola mobile. Trascorso questo tempo, Ad Manager restituisce 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 La durata per cui queste playlist di pod di annunci sono valide nel formato dhms (giorni, ore, minuti, secondi).
valid_until La data e l'ora fino a cui queste playlist di pod di annunci sono valide come stringa data/ora ISO8601, nel 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 dell'MPD DASH.
type Il tipo di pod di annunci. I tipi di pod di annunci sono: pre, mid o post.
start Solo per i pod di annunci mid-roll. La posizione nello stream in cui deve essere inserito questo pod di annunci, in secondi con virgola mobile.
duration La durata di questo pod di annunci in secondi con virgola mobile.
midroll_index Solo per i 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

Esempio di corpo della richiesta

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

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

Inserire i pod di annunci nei contenuti

Il processo di unione dei pod di annunci agli stream di contenuti varia a seconda dell'implementazione, del formato dello stream e delle funzionalità che scegli di implementare dalle 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 della tua attività e ai tuoi stream di contenuti.

Stream HLS

Se stai unendo uno stream nel formato HLS, lo stream di contenuti sarà una playlist multivariante di link a manifest di stream separati, uno per ogni profilo di codifica. I pod di annunci devono essere inseriti in ciascuno di questi manifest delle varianti. Un modo per farlo è preparare tutti i manifest delle varianti e trasmetterli a una rete CDN (Content Delivery Network) per l'hosting. La playlist multivariante finale è un insieme di link a questi manifest ospitati su 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 relative ore di inizio. 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 con più varianti che corrisponde alle impostazioni audio e video di ciascun profilo di codifica.

Array di pod di annunci di esempio
"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 sulle 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 in ogni manifest della variante

Per ogni stream di variante, esamina i segmenti del manifest dei contenuti, mantenendo un totale corrente del tempo dei contenuti trascorso. Quando raggiungi la posizione iniziale di un pod di annunci, estrai l'elenco dei segmenti dal manifest del pod di annunci, inseriscilo in due tag #EXT-X-DISCONTINUITY e inserisci l'elenco nella posizione corrente nel manifest dei contenuti. Continua questa procedura finché non sono stati elaborati tutti i pod di annunci e gli stream di varianti.

I manifest risultanti devono essere conformi allo standard HLS. Pertanto, a seconda delle funzionalità della specifica incorporate nel manifest dei contenuti, potrebbe essere necessario eseguire un'ultima passata sul manifest combinato per correggere i numeri di sequenza dei contenuti multimediali, la durata dei contenuti, i numeri di sequenza delle interruzioni e qualsiasi altro tag che deve essere aggiornato per tenere conto dei nuovi segmenti di annunci. Una volta corrette eventuali discrepanze con lo standard, carica ogni manifest della variante specifica per utente sulla tua CDN per l'hosting.

Se il manifest dei contenuti è criptato, devi memorizzare 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 sulle 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
Manifest dei contenuti di esempio

Si tratta dei contenuti del file 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

Si tratta dei contenuti del https://dai.google.com/{...}/pod/1/profile/1080p.m3u8 manifest 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 manifest delle varianti unite

Si tratta del 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
{...}

Creare una playlist multivariante

Raccogliere gli indirizzi CDN per ogni manifest della variante completato, insieme ai dettagli del profilo di codifica corrispondente, e assemblare 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 stai unendo uno stream nel formato MPEG DASH, devi produrre solo un singolo file. In questo modo, gli stream DASH possono essere uniti più facilmente rispetto a quelli HLS.

Un file MPD (Media Presentation Description) MPEG DASH preparato correttamente deve essere costituito da più periodi, ciascuno contenente più rappresentazioni. Ogni representation 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 periodi con rappresentazioni corrispondenti.

Per unire questi file MPD, inizia prendendo nota dell'ora 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 contenuti. Per i post-roll, inserisci i periodi dei pod di annunci post-roll dopo tutti i periodi dei contenuti. Esegui l'iterazione sui periodi nell'MPD dei contenuti, tenendo traccia del tempo di riproduzione trascorso per tutti i periodi di contenuti elaborati. Quando raggiungi un confine tra periodi corrispondente all'ora di inizio di un pod di annunci, inserisci i periodi del file MPD del pod di annunci mid-roll corrispondente in quel confine.

Il file MPD cucito finale deve essere completamente conforme alle specifiche MPEG_DASH, pertanto potrebbe essere necessario eseguire un'altra iterazione sul file finale per correggere eventuali orari di inizio del periodo, correggere la durata della presentazione multimediale in base ai periodi degli annunci appena inseriti e risolvere eventuali altri conflitti che potrebbero essere sorti durante il processo di cucitura.

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

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

MPD di pod di annunci di esempio

Questi sono i contenuti di mpd_uri dal 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 MPD cucito

Utilizzalo come risposta alla richiesta iniziale del 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