A API Pod Serving fornece acesso a conjuntos de anúncios em vídeo com taxa de bits adaptável preparados para que possam ser agrupados diretamente em uma playlist de mídia HLS ou MPEG-DASH voltada para o usuário.
O foco deste guia é implementar um servidor básico de manipulação de manifesto de disponibilização de pod para fluxos de VOD.
Receber solicitações de manifesto de stream
O manipulador de manifesto precisa fornecer um endpoint de API para detectar solicitações de manifesto do app cliente de player de vídeo. No mínimo, esse endpoint precisa coletar um ID de stream do app do player cliente. Esse ID de stream é usado para identificar a sessão de streaming para o Ad Manager nas solicitações de conjunto de anúncios.
Também é necessário coletar outras informações para identificar o fluxo de conteúdo adequado, 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 ID do stream do Ad Manager do app do player de vídeo do 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 das seguintes opções:
|
Recuperar o stream de conteúdo
Use o ID do conteúdo coletado na solicitação do manifesto para selecionar o stream de conteúdo a ser agrupado com os anúncios.
Solicitar manifestos de conjunto de anúncios
Para solicitar anúncios do Ad Manager, seu servidor precisa fazer uma solicitação POST para o endpoint dos conjuntos de anúncios, transmitindo os perfis de codificação, a tag de anúncio e os parâmetros de segmentação solicitados. Essa solicitação também inclui o ID do fluxo coletado na Etapa 1.
Em troca, você recebe uma lista de objetos de conjuntos de anúncios que contêm arquivos de manifesto para os conjuntos solicitados pela tag de anúncio do editor, além de informações sobre quando e onde eles precisam 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 ID de stream do app de player de vídeo do cliente. |
Corpo JSON
Parâmetros de 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. Veja os detalhes abaixo
Para que a reprodução seja o mais perfeita possível, ela precisa corresponder ao conjunto de perfis de codificação usados no seu stream de conteúdo. |
ad_tag |
Required |
Uma tag 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
inseridos. Os pontos de inserção são medidos em segundos de ponto flutuante.
Necessá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 ajustes de horário de porcentagem. Isso é incomum. |
manifest_type |
Optional |
É o formato dos fluxos de anúncios solicitados, hls ou
dash . O valor padrão é hls .
|
dai_options |
Optional |
Outras opções que controlam aspectos de como os manifestos são renderizados. Veja 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 stream. |
type |
Required |
O tipo de codificação do stream descrito por este perfil de codificação. Os tipos de conteúdo são: media , iframe , subtitles .
|
container_type |
Required |
O formato do contêiner usado por este perfil de codificação. Os formatos de contêiner são: mpeg2ts , fmp4cmaf , 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 tiver vídeo. Confira os detalhes abaixo |
audio_settings |
Optional |
Obrigatório se o perfil de codificação contiver áudio. Permitido apenas se o tipo for mídia. Veja os detalhes abaixo |
subtitle_settings |
Optional |
Obrigatório se o perfil de codificação tiver legendas. Veja os detalhes abaixo |
Configurações de vídeo | ||
codec |
Required |
String do codec RFC6381.
Exemplo: |
bitrate |
Required |
Um número inteiro que representa a taxa de bits máxima de 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 que contém `width` e `height` do vídeo em pixels.
Exemplo: |
Configurações de áudio | ||
codec |
Required |
String do codec RFC6381.
Exemplo: |
bitrate |
Required |
Um número inteiro que representa a taxa de bits máxima de áudio deste perfil em bytes por
segundo.
Exemplo: |
channels |
Required |
Um número inteiro que representa o número de canais de áudio, incluindo canais de baixa frequência. |
sample_rate |
Required |
Um número inteiro que representa a taxa de amostragem de áudio em hertz.
Exemplo: |
Configurações de legendas | ||
format |
Required |
Formato de arquivo usado por legendas em 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
é usado apenas para renderização DASH.
Exemplo: |
Opções da DAI | ||
dash_profile |
Optional |
O perfil MPEG-DASH a ser aplicado a manifestos de conjuntos de anúncios. Essa configuração é usada apenas para
manifestos DASH. Os valores permitidos são live ou
on-demand . O valor padrão é on-demand .
O valor
O valor |
ad_pod_timeout |
Optional |
O tempo máximo para gastar na seleção de anúncios e na criação de conjuntos de anúncios, em segundos de ponto flutuante. Após esse tempo, o Ad Manager retorna todos os
anúncios já selecionados na resposta ad_pods e interrompe
o processamento.
|
sam_id |
Optional |
Especifica uma chave de depuração alternativa que pode ser usada para procurar sessões no monitor de atividade de streaming. |
Resposta
Parâmetros de resposta | |
---|---|
valid_for |
Duração das playlists de conjunto de anúncios válidas no formato 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 uma string de data e hora ISO8601, no formato yyyy-MM-dd'T'hh:mm:ss.sssssssss[+|-]hh:mm .
|
ad_pods |
Uma lista de conjuntos de anúncios selecionados para este fluxo. |
Conjunto de anúncios | |
manifest_uris |
Somente para transmissões HLS. Um mapa de IDs de perfil de codificação para URIs de manifesto HLS. |
mpd_uri |
Somente para transmissões DASH. O URI da MPD DASH. |
type |
É o tipo de conjunto de anúncios. Os tipos de conjunto 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 precisa 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. A 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 da solicitação
Esse é 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
}
]
}
Agrupe os conjuntos de anúncios no conteúdo
O processo de unir conjuntos de anúncios nos streams de conteúdo varia de acordo com a implementação, o formato do stream e os recursos escolhidos para as especificações do formato. Os fluxos de trabalho a seguir são sugestões sobre como lidar com esse processo. Os detalhes exatos da sua implementação podem variar de acordo com as necessidades da sua empresa e os streams de conteúdo.
Streams HLS
Se você estiver agrupando um stream no formato HLS, o stream de conteúdo será uma playlist multivariante de links para manifestos de stream separados, um para cada perfil de codificação. Seus conjuntos de anúncios precisam ser inseridos em cada um desses manifestos de variantes. Uma maneira de fazer isso é preparar todos os manifestos de variantes e transmiti-los para uma rede de fornecimento de conteúdo (CDN, na sigla em inglês) para hospedagem. A playlist multivariante final é um conjunto de links para esses manifestos hospedados pela CDN.
Iterar em perfis de codificação
Para cada perfil de codificação, reúna todos os manifestos de conjuntos de anúncios associados da
resposta do Ad Manager, além dos horários de início associados. Para conjuntos de anúncios precedentes, defina o horário de início como 0
. Para anúncios finais, use a duração do conteúdo como o horário de início do conjunto de anúncios. Identifique o stream de variantes na playlist
multivariante que corresponde à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, percorra os segmentos do manifesto de conteúdo, mantendo um
total em execução do tempo de conteúdo decorrido. Quando você chegar à posição inicial
de um conjunto de anúncios, extraia a lista de segmentos do manifesto do conjunto de anúncios, una a
lista de segmentos em duas tags #EXT-X-DISCONTINUITY
e insira a lista no
local atual no manifesto de conteúdo. Continue esse processo até que todos os conjuntos de anúncios e streams de variantes tenham sido processados.
Os manifestos resultantes precisam estar em conformidade com o padrão HLS. Portanto, dependendo dos recursos da especificação incorporados pelo manifesto de conteúdo, pode ser necessário fazer uma passagem final no manifesto combinado para corrigir os números de sequência de mídia, a duração do conteúdo, os números de sequência de descontinuidade e outras tags que precisam ser atualizadas para considerar os novos segmentos de anúncios. Depois que as discrepâncias com o padrão forem reparadas, envie cada manifesto de variante específica do usuário à CDN para hospedagem.
Se o manifesto de conteúdo estiver criptografado, será necessário armazenar a última chave de criptografia
encontrada antes do início do conjunto de anúncios atual em uma tag #EXT-X-KEY
. Em seguida, é necessário adicionar a tag #EXT-X-KEY:METHOD=NONE
para remover a criptografia antes do primeiro segmento de cada conjunto de anúncios. Por fim, você precisa adicionar uma cópia da tag
#EXT-X-KEY
armazenada 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
Esse é o conteúdo do manifesto https://{...}/1080p.m3u8
listado nos
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
Esse é o conteúdo do manifesto
https://dai.google.com/{...}/pod/1/profile/1080p.m3u8
listado nos dados de variantes coletados.
#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 agrupada
Esse seria o manifesto da variante integrada resultante, transmitido para a 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 playlist multivariante
Colete os endereços da CDN de cada manifesto de variante concluído, com os detalhes do perfil de codificação correspondentes, e reúna os resultados em um novo manifesto multivariante. Esse manifesto específico do usuário é retornado como a resposta à solicitação de manifesto que você recebeu 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 combinando um stream no formato MPEG DASH, precisará produzir apenas um arquivo. Isso pode facilitar o agrupamento de streams DASH do que de HLS.
Um arquivo de descrição de apresentação de mídia (MPD, na sigla em inglês) MPEG DASH devidamente preparado precisa ter vários períodos, cada um contendo várias representações. Cada representação precisa 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 pontos com representações correspondentes.
Para unir esses arquivos MPD, comece anotando os horários de início de cada conjunto de anúncios. Para anúncios precedentes, insira os períodos do conjunto de anúncios precedentes antes de qualquer período de conteúdo. Para anúncios finais, insira os períodos do conjunto de anúncios finais após todos os períodos de conteúdo. Itere ao longo dos períodos na MPD de conteúdo, monitorando o tempo de reprodução decorrido para todos os períodos de conteúdo processado. Quando você atingir um limite entre os períodos que correspondem ao horário de início de um conjunto de anúncios, insira os períodos do arquivo 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. Talvez seja necessário iterar o arquivo final mais uma vez corrigindo os horários de início do período, corrigindo a duração da apresentação de mídia para considerar os períodos de anúncio recém-inseridos e resolvendo quaisquer outros conflitos que possam ter surgido com o processo de agrupamento.
Exemplo de conteúdo de MPD
<?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
Esse é 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 montada
Servir como sua resposta à solicitação inicial de manifesto de 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
- Reprodução de veiculação de conjuntos com o SDK do IMA:
- Veiculação de pods com a API DAI