Manipulador de manifesto para streams de VOD

A API Pod Serving dá acesso a conjuntos de anúncios em vídeo com taxa de bits adaptável preparados de modo que possam ser integrados diretamente em um HLS voltado para o usuário ou Playlist de mídia MPEG-DASH.

O foco deste guia é a implementação de uma manipulação básica de manifesto da disponibilização de pods para streams de VOD.

Receber solicitações de manifesto de stream

Seu manipulador de manifesto precisa fornecer um endpoint de API para detectar o manifesto do app cliente do player de vídeo. No mínimo, esse endpoint precisa coletar um ID de stream do app do player do cliente. Esse ID de stream é usado para identificar a sessão de streaming para o Ad Manager nas suas solicitações de conjunto de anúncios.

Você também precisa coletar outras informações para identificar os stream de conteúdo, por exemplo, um ID de conteúdo.

Exemplo de endpoint de solicitação de manifesto

GET /api/stream_id/{stream_id}/video/{content_id}.{format}
Host: {your_domain}
Parâmetros de caminho
stream_id O código de stream do Ad Manager do app de player de vídeo cliente.
content_id Um ID hipotético correspondente ao conteúdo de vídeo no seu sistema.
format Um parâmetro hipotético correspondente ao formato de stream. Uma destas opções:
mpd Para streams MPEG-DASH
m3u8 Para transmissões HLS

Recuperar o stream de conteúdo

Usar o Content ID coletado da solicitação de manifesto para selecionar o conteúdo. fazer streaming para agrupar com anúncios.

Solicitar manifestos do conjunto de anúncios

Para solicitar anúncios do Ad Manager, seu servidor precisa fazer uma solicitação POST para o anúncio pods, passando os perfis de codificação solicitados, a tag de anúncio e a segmentação parâmetros. Essa solicitação também inclui o ID do stream coletado na etapa 1:

Em troca, você recebe uma lista de objetos de conjunto de anúncios contendo arquivos de manifesto para os conjuntos de anúncios solicitados pela tag de anúncio do editor e informações sobre quando e onde eles devem ser inseridos no conteúdo.

POST /ondemand/pods/api/v1/network/{network_code}/streams/{stream_id}/adpods
Host: dai.google.com
Content-Type: application/json
Parâmetros de caminho
network_code É o código da rede do Ad Manager 360 do editor.
stream_id O código de stream do app player de vídeo cliente.

Corpo JSON

Parâmetros do corpo
encoding_profiles Required Uma lista de representações JSON dos perfis de codificação que você quer receber para cada intervalo de anúncio. Confira os detalhes abaixo

Para tornar a reprodução o mais perfeita possível, ele deve corresponder ao conjunto de codificando os perfis usados em seu stream de conteúdo.

ad_tag Required Uma tag de anúncio para solicitar anúncios VMAP.
cuepoints Optional Uma lista de pontos de inserção no stream de conteúdo em que os intervalos de anúncios intermediários serão ser inserido. Os pontos de inserção são medidos em segundos de ponto flutuante.

Obrigatório apenas para respostas VMAP que contêm anúncios intermediários usando ajustes de horário posicionais. Isso é incomum.

content_duration_seconds Optional A duração do conteúdo em segundos.

Obrigatório apenas para respostas VMAP que contêm anúncios intermediários usando percentage de ajustes de horário. Isso é incomum.

manifest_type Optional O formato dos streams de anúncios solicitados, hls ou dash. O valor padrão é hls.
dai_options Optional Opções adicionais que controlam aspectos de como os manifestos são renderizados. Confira os detalhes abaixo
Perfil de codificação
profile_name Required Um identificador para esse perfil de codificação. Esse valor pode ser qualquer string que você escolher, mas não é possível ter vários perfis de codificação com o mesmo nome no mesmo fluxo.
type Required O tipo de codificação do fluxo descrito por este perfil de codificação. Conteúdo são: media, iframe e subtitles.
container_type Required O formato de contêiner usado por este perfil de codificação. Os formatos de contêiner são: mpeg2ts, fmp4cmaf e hls_packed_audio
video_settings Optional Obrigatório se o tipo de perfil de codificação for iframe. Caso contrário, só é permitido se o tipo de mídia contém vídeo. Veja detalhes abaixo
audio_settings Optional Obrigatório se o perfil de codificação contiver áudio. Permitido apenas se o tipo for mídia. Confira os detalhes abaixo
subtitle_settings Optional Obrigatório se o perfil de codificação tiver legendas. Confira os detalhes abaixo
Configurações de vídeo
codec Required A string do codec RFC6381.

Exemplo: avc1.4d000c.

bitrate Required Um número inteiro que representa a taxa de bits máxima do vídeo deste perfil em bytes por segundo.
frames_per_second Required O QPS de ponto flutuante do vídeo.
resolution Required Um valor codificado em JSON contendo `width` e `height` do vídeo em pixels.

Exemplo: {"width": 640, "height": 320}.

Configurações de áudio
codec Required A string do codec RFC6381.

Exemplo: mp4a.40.5.

bitrate Required Um número inteiro que representa a taxa de bits máxima de áudio deste perfil em bytes por segundo.

Exemplo: 300000.

channels Required Um número inteiro que representa o número de canais de áudio, incluindo frequência baixa canais.
sample_rate Required Um número inteiro que representa a taxa de amostragem de áudio em hertz.

Exemplo: 4800.

Configurações de legenda
format Required O formato de arquivo usado pelas legendas da banda. Os valores aceitos são webvtt ou ttml.
language Optional O idioma da legenda como uma string de idioma RFC5646. Se fornecido, esse valor só é usado para a renderização DASH.

Exemplo: en-us.

Opções de DAI
dash_profile Optional O perfil MPEG-DASH a ser aplicado aos manifestos do conjunto de anúncios. Essa configuração é usada para Somente manifestos DASH. Os valores permitidos são live ou on-demand. O valor padrão é on-demand.

O valor live corresponde ao perfil MPEG-DASH. "urn:mpeg:dash:profile:isoff-live:2011".

O valor on-demand corresponde ao perfil MPEG-DASH. urn:mpeg:dash:profile:isoff-on-demand:2011.

ad_pod_timeout Optional O tempo máximo gasto selecionando anúncios e criando conjuntos de anúncios, em anúncios flutuantes ponto em segundos. Após esse período, o Ad Manager retorna os anúncios já selecionados na resposta ad_pods e são interrompidos processamento.
sam_id Optional Especifica uma chave de depuração alternativa que pode ser usada para procurar sessões no atividade de transmissão monitor.

Resposta

Parâmetros de resposta
valid_for Duração em que essas playlists de conjuntos de anúncios são válidas em dhms (dias, horas, minutos, segundos).
valid_until A data e a hora até que essas playlists de conjunto de anúncios sejam válidas como um documento ISO8601 string de data e hora, em yyyy-MM-dd'T'hh:mm:ss.sssssssss[+|-]hh:mm .
ad_pods Uma lista de conjuntos de anúncios selecionados para este stream.
Conjunto de anúncios
manifest_uris Apenas para transmissões HLS. Um mapa de códigos de perfil de codificação para URIs de manifesto HLS.
mpd_uri Somente para streams DASH. O URI da MPD do DASH.
type O tipo de conjunto de anúncios. Os tipos de conjuntos de anúncios são: pre, mid ou post
start Somente para conjuntos de anúncios intermediários. A posição no stream em que esse conjunto de anúncios deve ser inserido, em segundos de ponto flutuante.
duration É a duração desse conjunto de anúncios em segundos de ponto flutuante.
midroll_index Somente para conjuntos de anúncios intermediários. O índice do conjunto de anúncios intermediários atual. Indexação começa com 1.

Exemplo de solicitação (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

Exemplo de corpo de solicitação

Este é o conteúdo de request-body.json mencionado na chamada de cURL acima.

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

Exemplo de resposta

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

Agrupar conjuntos de anúncios em conteúdo

O processo para agrupar conjuntos de anúncios nos streams de conteúdo varia de acordo com na implementação, no formato da transmissão e nos recursos escolhidos implementar as especificações do formato. Os fluxos de trabalho a seguir são sugestões de como lidar com esse processo. Os detalhes exatos dos seus pode variar de acordo com as necessidades da empresa e seu conteúdo córregos.

Streams HLS

Se você estiver unindo uma transmissão ao formato HLS, sua transmissão de conteúdo será multivariante playlist de links para manifestos de fluxo separados, um para cada perfil de codificação. Seu anúncio pods precisam ser inseridos em cada um desses manifestos de variantes. Uma forma de isso é preparar todos os manifestos de variantes e transmiti-los para o objeto Content de rede de fornecimento (CDN, na sigla em inglês) para hospedagem na Web. A playlist multivariante final é um conjunto de links para as instâncias de VM manifestos.

Iterar na codificação de perfis

Para cada perfil de codificação, reúna todos os manifestos de conjunto de anúncios associados de da resposta do Ad Manager e os horários de início associados. Para anúncios precedentes pods, defina o horário de início como 0. Para anúncios finais, use a duração do conteúdo como ao horário de início do conjunto de anúncios. Identificar o stream de variantes na multivariante que corresponda às configurações de áudio e vídeo de cada perfil de codificação.

Exemplo de matriz de conjuntos de anúncios
"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
    }
  ]
Exemplo de playlist de conteúdo 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
Exemplo de dados de variantes coletados
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

Inserir anúncios em cada manifesto de variante

Para cada stream de variante, avance pelos segmentos do manifesto de conteúdo, mantendo um total do tempo decorrido do conteúdo. Quando você chegar à posição inicial de um conjunto de anúncios, extraia a lista de segmentos do manifesto do conjunto, una a de segmentos em duas tags #EXT-X-DISCONTINUITY e insira a lista no localização atual no manifesto do conteúdo. Continue esse processo até que todos os pods e streams de variantes foram processados.

Os manifestos resultantes precisam estar em conformidade com o padrão HLS. Portanto, dependendo sobre quais recursos da especificação seu manifesto de conteúdo incorpora, você talvez tenha que fazer uma última transferência no manifesto combinado para corrigir a mídia números de sequência, duração do conteúdo, números de sequência de descontinuidade e quaisquer outras tags que precisam ser atualizadas para levar em consideração os novos segmentos de anúncio. Quando as discrepâncias com o padrão forem reparadas, empurre cada variante específica do usuário à CDN para hospedagem.

Se o manifesto de conteúdo estiver criptografado, será necessário armazenar a última criptografia encontrada antes do início do conjunto de anúncios atual em uma tag #EXT-X-KEY. Depois, você precisa adicionar a tag #EXT-X-KEY:METHOD=NONE para remover a criptografia antes de no primeiro segmento de cada conjunto de anúncios. Por fim, adicione uma cópia dos arquivos tag #EXT-X-KEY antes do primeiro segmento de conteúdo após cada conjunto de anúncios, para restaurar a criptografia do conteúdo.

Exemplo de dados de variantes coletados
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
Exemplo de manifesto de conteúdo

Este é o conteúdo do manifesto https://{...}/1080p.m3u8 listado no dados de variantes coletados.

#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
{...}
Exemplo de manifesto de conjunto de anúncios

Este é o conteúdo do https://dai.google.com/{...}/pod/1/profile/1080p.m3u8 manifesto listado nos dados das variantes coletadas.

#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
Exemplo de manifesto de variante unida

Esse é o manifesto da variante unida resultante, transmitido à CDN e hospedado em 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
{...}

Criar uma playlist multivariante

Colete os endereços do CDN para cada manifesto de variante preenchido, junto com os do perfil de codificação correspondente e reúne os resultados em um novo manifesto multivariante. Esse manifesto específico do usuário é retornado como a resposta à solicitação de manifesto recebida na Etapa 1.

Exemplo de playlist multivariante final
#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

Streams MPEG DASH

Se você estiver agrupando uma transmissão no formato MPEG DASH, você só precisará produzir um único arquivo. Isso torna os streams DASH mais fáceis de unir do que o HLS.

Um arquivo de descrição de apresentação de mídia (MPD, na sigla em inglês) MPEG DASH preparado deve ser consistem em vários pontos, cada um contendo múltiplas representações. Cada deve corresponder a um dos seus perfis de codificação. Cada conjunto de anúncios retornado do Ad Manager também é um arquivo MPD que contém uma sequência de períodos com representações correspondentes.

Para unir esses arquivos MPD, comece anotando os horários de início para cada conjunto de anúncios. Para anúncios precedentes, insira os períodos do conjunto de anúncios precedentes antes de qualquer conteúdo. período Para anúncios finais, insira os períodos do conjunto de anúncios finais depois de todo o conteúdo. períodos. Iterar ao longo dos períodos na MPD do conteúdo, acompanhando o tempo de reprodução decorrido de todos os períodos de conteúdo processados. Quando você atingir um limite entre períodos que correspondem à hora de início de um conjunto de anúncios, insira os períodos do arquivo de MPD do conjunto de anúncios intermediários correspondente nesse limite.

O arquivo MPD agrupado final precisa estar totalmente em conformidade com as especificações MPEG_DASH, portanto, pode ser necessário iterar o arquivo final mais uma vez, corrigindo quaisquer os horários de início do período, corrigindo a duração da apresentação de mídia para considerar períodos de anúncios recém-inseridos e resolver quaisquer outros conflitos que possam ter decorrentes do processo de agrupamento.

Exemplo de MPD de conteúdo

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

Exemplo de JSON de conjunto de anúncios

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

Exemplo de MPD de conjunto de anúncios

Este é o conteúdo de mpd_uri do JSON do conjunto de anúncios acima.

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

Exemplo de MPD agrupado

Veicule isso como sua resposta à solicitação de manifesto inicial do 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>

Outros recursos