A API Pod Serving oferece acesso a conjuntos de anúncios de vídeo de taxa de bits adaptativa preparados de forma que possam ser unidos diretamente a uma lista de reprodução de mídia HLS ou MPEG-DASH voltada ao usuário.
Este guia se concentra na implementação de um servidor básico de manipulação de manifesto de pod para transmissões VOD.
Receber solicitações de manifesto de fluxo
O manipulador de manifesto precisa fornecer um endpoint de API para detectar solicitações de manifesto do app cliente do player de vídeo. No mínimo, esse endpoint precisa coletar um ID de stream do app cliente do player. Esse ID de stream é usado para identificar a sessão de streaming no Ad Manager nas suas solicitações de bloco de anúncios.
Você também precisa 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 de player de vídeo do cliente. | ||||
content_id |
Um ID hipotético correspondente ao vídeo de conteúdo no seu sistema. | ||||
format |
Um parâmetro hipotético correspondente ao formato do fluxo. Uma das seguintes opções:
|
Extrair o stream de conteúdo
Use o ID de conteúdo coletado da solicitação de manifesto para selecionar o fluxo de conteúdo a ser combinado com os anúncios.
Solicitar manifestos de conjuntos de anúncios
Para solicitar anúncios do Ad Manager, seu servidor precisa fazer uma solicitação POST para o endpoint dos pods de anúncios, transmitindo os perfis de codificação e a tag de anúncio solicitados. Essa solicitação também inclui o ID do stream que você coletou na etapa 1.
Em troca, você recebe uma lista de objetos de conjunto de anúncios que contêm 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 precisam ser inseridos no seu 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 de rede do Ad Manager 360 do editor. |
stream_id |
O ID do fluxo do app de player de vídeo do 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 que a reprodução seja o mais tranquila possível, ela precisa corresponder ao conjunto de perfis de codificação usados no 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
inseridos. 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 tempo posição. 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 que estão sendo 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 stream. |
type |
Required |
O tipo de codificação do stream descrito por esse perfil de codificação. Os tipos de conteúdo são: media , iframe e subtitles .
|
container_type |
Required |
O formato do contêiner usado por esse 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 tiver áudio. Somente permitido 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 de codec RFC6381.
Exemplo: |
bitrate |
Required |
Um número inteiro que representa a taxa de bits máxima de vídeo desse 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 a "largura" e a "altura" do vídeo em pixels.
Exemplo: |
Configurações de áudio | ||
codec |
Required |
A string de codec RFC6381.
Exemplo: |
bitrate |
Required |
Um número inteiro que representa a taxa de bits de áudio máxima desse perfil em bytes por
segundo.
Exemplo: |
channels |
Required |
Um número inteiro que representa o número de canais de áudio, incluindo os 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 legenda | ||
format |
Required |
O formato de arquivo usado por legendas na faixa. Os valores aceitos são
webvtt ou ttml .
|
language |
Optional |
O idioma das legendas 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 aos 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 que você pode gastar selecionando anúncios e criando conjuntos de anúncios, em segundos de ponto flutuante. Após esse período, o Ad Manager retorna 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 monitoramento da atividade de streaming. |
Resposta
Parâmetros de resposta | |
---|---|
valid_for |
Duração em que essas playlists de bloco de anúncios são válidas no formato dhms
(dias, horas, minutos, segundos).
|
valid_until |
A data e a hora até que essas playlists de anúncios em bloco são 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 pods de anúncios selecionados para esse stream. |
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 do MPD DASH. |
type |
O tipo de bloco de anúncios. Os tipos de conjunto de anúncios são: pre , mid ou
post .
|
start |
Apenas para conjuntos de anúncios intermediários. A posição no fluxo 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 |
Apenas 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
Este é o conteúdo de request-body.json
referenciado na chamada 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
}
]
}
Inserir conjuntos de anúncios no conteúdo
O processo de unir os conjuntos de anúncios aos fluxos de conteúdo varia de acordo com a implementação, o formato do fluxo e os recursos que você escolhe implementar de acordo com as especificações do formato. Os fluxos de trabalho a seguir são sugestões de como lidar com esse processo. Os detalhes exatos da implementação podem variar de acordo com as necessidades de negócios e os fluxos de conteúdo.
Transmissões HLS
Se você estiver mesclando um fluxo no formato HLS, o fluxo de conteúdo será uma playlist multivariante de links para manifestos de fluxo separados, um para cada perfil de codificação. Seus pods de anúncio precisam ser inseridos em cada um desses manifestos de variantes. Uma maneira de fazer isso é preparar todos os manifestos de variantes e transmiti-los a uma rede de fornecimento de conteúdo (CDN) para hospedagem. A playlist multivariante final é um conjunto de links para esses manifestos hospedados no CDN.
Iterar sobre perfis de codificação
Para cada perfil de codificação, colete todos os manifestos de bloco de anúncios associados da
resposta do Ad Manager, junto com os horários de início associados. Para grupos de anúncios precedentes, defina o horário de início como 0
. Para anúncios pós-rolagem, use a duração do conteúdo como
o horário de início do conjunto de anúncios. Identifique o stream de variante 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, analise 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, envolva 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 pods
de anúncios e streams de variantes sejam processados.
Os manifestos resultantes precisam estar em conformidade com o padrão HLS. Portanto, dependendo dos recursos da especificação que o manifesto de conteúdo incorpora, talvez seja necessário fazer uma passagem final sobre o 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 levar em conta os novos segmentos de anúncios. Depois que todas as discrepâncias com o padrão forem corrigidas, envie cada manifesto de variante específico do usuário para sua CDN para hospedagem.
Se o manifesto de conteúdo estiver criptografado, você precisará 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,
adicione a tag #EXT-X-KEY:METHOD=NONE
para remover a criptografia antes
do primeiro segmento de cada conjunto de anúncios. Por fim, adicione uma cópia da tag #EXT-X-KEY
armazenada antes do primeiro segmento de conteúdo após cada bloco 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 costurada
Esse seria o manifesto da variante costurada resultante, transmitido para o 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 do CDN para cada manifesto de variante concluído, junto com os detalhes do perfil de codificação correspondente, e monte 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
Transmissões MPEG DASH
Se você estiver unindo um stream no formato MPEG DASH, só vai precisar produzir um único arquivo. Isso pode facilitar a junção de transmissões DASH em relação ao HLS.
Um arquivo de descrição de apresentação de mídia (MPD, na sigla em inglês) MPEG DASH preparado corretamente precisa ser composto por vários períodos, cada um com várias representações. Cada representação precisa corresponder a um dos seus perfis de codificação. Cada conjunto de anúncios retornado pelo 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 de cada bloco de anúncios. Para anúncios precedentes, insira os períodos de bloco de anúncios precedentes antes de qualquer período de conteúdo. Para anúncios finais, insira os períodos de conjuntos de anúncios finais após todos os períodos de conteúdo. Itere sobre os períodos no MPD do conteúdo, mantendo o controle do tempo de reprodução de todos os períodos de conteúdo processados. Quando você atingir um limite entre 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 de midroll correspondente nesse limite.
O arquivo MPD costurado final precisa estar totalmente em conformidade com as especificações MPEG_DASH. Portanto, talvez seja necessário iterar sobre o arquivo final mais uma vez para corrigir qualquer tempo de início do período, corrigir a duração da apresentação de mídia para considerar os períodos de anúncios recém-inseridos e resolver outros conflitos que possam ter surgido do processo de costura.
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 do bloco de anúncios
[{
"mpd_uri": "https://{...}pod/1.mpd",
"type": "mid",
"start": 15.0,
"duration": 15.0,
"midroll_index": 1
}]
Exemplo de MPD do conjunto de anúncios
Este é o conteúdo do mpd_uri
do JSON do bloco 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 costurado
Use isso como resposta à solicitação inicial do manifesto de 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>
Outros recursos
- Reprodução de veiculação de pods com o SDK do IMA:
- Reprodução da veiculação de conjunto com a API DAI