A API Pod Serving dá acesso a segmentos de anúncios codificados e condicionados, preparados para que possam ser integrados diretamente em um HLS voltado para o usuário ou playlist de mídia MPEG-DASH. Para MPEG-DASH, a API Pod Serving também oferece um modelo de manifesto do anúncio para oferecer mais informações e contexto segmentos.
Este guia se concentra na implementação de um servidor básico de manipulação de manifesto de veiculação de conjunto para transmissões ao vivo.
Pré-requisito: configurar eventos de transmissão ao vivo no Google Ad Manager
Antes de fazer solicitações da API de veiculação de conjuntos, você precisa criar um anúncio
para o gerente de cada transmissão processada. É possível criar um
evento de transmissão ao vivo usando o
LiveStreamEventService API
ou o
interface da Web do Google Ad Manager.
Para que um evento de transmissão ao vivo seja usado com a API de fornecimento de pods, é necessário preencher vários atributos do evento:
customAssetKey
: um identificador personalizado a ser usado para este evento. Deve ser único em todos os eventos da rede.adTags
: URL da tag de anúncio principal gerado pelo fluxo de trabalho de programação do Ad Manager.dynamicAdInsertionType
: precisa ser definido comoPOD_SERVING_REDIRECT
.streamingFormat
: defina comoHLS
ouDASH
, de acordo com isso.segmentUrlAuthenticationKeyIds
: pelo menos uma chave HMAC usada para assinar solicitações de segmento de anúncios.daiEncodingProfileIds
: uma lista dos IDs de DAIEncodingProfile ativados para este evento.startDateTime
: a data e a hora de início do eventoendDateTime
: data e hora programadas para o término deste evento. Esse atributo é obrigatório em caso deunlimitedEndDateTime
is false and ignored if
unlimitedEndDateTimeis true.
unlimitedEndDateTime` — booleano. Veja como fazer isso acima.
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 do player de vídeo. No mínimo, esse endpoint precisa coletar um ID de stream do app cliente do player e retornar um manifesto de stream costurado. O código de stream é usado para identificar a sessão de streaming para o anúncio. Administrador.
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 um possível endpoint de solicitação de manifesto
GET /api/video/{asset_key}/manifest.{format}
Host: {your_domain}
Parâmetros de caminho | |||||
---|---|---|---|---|---|
asset_key |
Um ID hipotético correspondente à transmissão ao vivo solicitada no seu sistema. | ||||
format |
Um parâmetro hipotético correspondente ao formato do fluxo. Uma destas opções:
|
Parâmetros de consulta | |
---|---|
stream_id |
O código de stream do Ad Manager do app de player de vídeo cliente. |
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.
Agrupar segmentos de anúncios no fluxo de conteúdo
O agrupamento dos URLs de segmento de anúncio varia de acordo com o formato da transmissão.
Transmissões HLS
Os streams HLS geralmente são veiculados como um manifesto multivariante, que contém conjunto de links para manifestos variantes, que correspondem a cada um dos URLs de perfil.
Observação: para simplificar, este guia pressupõe que sua mídia HLS seja codificada em um formato que combina áudio e vídeo no mesmo arquivo de segmento.
Playlists multivariantes de proxy
Será necessário substituir cada URL da playlist variante na multivariante original. lista de reprodução com outra chamada de endpoint para o manipulador processar a o manifesto da variante selecionada.
As etapas restantes para unir o HLS vão considerar que uma única variante no manifesto está sendo processado.
Exemplo de possível endpoint de solicitação de variante
GET /api/video/{asset_key}/variant/{variant_id}.m3u8
Host: {your_domain}
Parâmetros de caminho | |
---|---|
asset_key |
Um ID hipotético correspondente à transmissão ao vivo solicitada no seu sistema. |
variant |
Um parâmetro hipotético contendo um identificador para a variante específica que estão sendo processados. |
Parâmetros de consulta | |
---|---|
stream_id |
O ID de stream do Ad Manager do app de player de vídeo do cliente. Usado aqui para identificar uma sessão do usuário com o manipulador de manifesto. |
Exemplo de manifesto multivariante não processado
#EXTM3U
#EXT-X-STREAM-INF:BANDWIDTH=5000000,RESOLUTION=1920x1080,CODECS="avc1.4d000c,mp4a.40.5"
https://cdn.{...}/1080p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=2500000,RESOLUTION=1280x720,CODECS="avc1.4d000c,mp4a.40.5"
https://cdn.{...}/720p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=1000000,RESOLUTION=640x360,CODECS="avc1.4d000d,mp4a.40.5"
https://cdn.{...}/360p.m3u8
Exemplo de manifesto de várias variantes com proxy
#EXTM3U
#EXT-X-STREAM-INF:BANDWIDTH=5000000,RESOLUTION=1920x1080,CODECS="avc1.4d000c,mp4a.40.5"
https://{manifest_manipulator}/api/video/tears_of_steel/variant/1080p.m3u8?stream_id=6e69425c-0ac5-43ef-b070-c5143ba68541:CHS
#EXT-X-STREAM-INF:BANDWIDTH=2500000,RESOLUTION=1280x720,CODECS="avc1.4d000c,mp4a.40.5"
https://{manifest_manipulator}/api/video/tears_of_steel/variant/720p.m3u8?stream_id=6e69425c-0ac5-43ef-b070-c5143ba68541:CHS
#EXT-X-STREAM-INF:BANDWIDTH=1000000,RESOLUTION=640x360,CODECS="avc1.4d000d,mp4a.40.5"
https://{manifest_manipulator}/api/video/tears_of_steel/variant/360p.m3u8?stream_id=6e69425c-0ac5-43ef-b070-c5143ba68541:CHS
Identificar segmentos de intervalo de anúncio e inserir descontinuidades
Ao processar o manifesto da variante, acompanhe o horário de início, a duração e índice do próximo intervalo comercial, até que o manifesto dinâmico seja processado contém segmentos que serão substituídos pelo conteúdo do anúncio.
Os intervalos de anúncio podem ser delineados de segmentos de conteúdo de formas diferentes, dependendo
no seu codificador. Uma maneira comum de delinear um intervalo de anúncio é antepor os segmentos
de anúncios com uma tag #EXT-X-CUE-OUT
e seguir com uma tag #EXT-X-CUE-IN
.
Para separar os intervalos de anúncios hospedados pelo Google dos seus segmentos de conteúdo, insira
tags #EXT-X-DISCONTINUITY
no início e no final de cada intervalo. Se essas
de descontinuidade não aparecerem no manifesto final, a reprodução falhará.
Os URIs do segmento de anúncio inserido não estão criptografados. Caso seu conteúdo esteja criptografado,
você também vai precisar remover a criptografia especificando #EXT-X-KEY:METHOD=NONE
antes do primeiro segmento de cada intervalo de anúncio e, em seguida, adicione-o novamente após o
intervalo de anúncio.
Manifesto de exemplo (original)
#EXTM3U
#EXT-X-VERSION:6
#EXT-X-TARGETDURATION:6
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:5.005,
contentorigin.com/1.ts
#EXTINF:5.005,
contentorigin.com/2.ts
#EXT-X-CUE-OUT:15.000
#EXTINF:5.005,
contentorigin.com/3.ts
#EXTINF:5.005,
contentorigin.com/4.ts
#EXTINF:5.005,
contentorigin.com/5.ts
#EXTINF:5.000,d
contentorigin.com/6.ts
#EXT-X-CUE-IN
#EXTINF:5.005,
contentorigin.com/7.mp4
#EXTINF:5.005,
contentorigin.com/8.mp4
Manifesto com descontinuidades inseridas
#EXTM3U
#EXT-X-VERSION:6
#EXT-X-TARGETDURATION:6
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:5.005,
contentorigin.com/1.ts
#EXTINF:5.005,
contentorigin.com/2.ts
#EXTINF:5.005,
#EXT-X-DISCONTINUITY
{... New segments will go here ...}
#EXT-X-DISCONTINUITY
#EXTINF:5.005,
contentorigin.com/7.mp4
#EXTINF:5.005,
contentorigin.com/8.mp4
Processar segmentos de conjuntos de anúncios
Para cada segmento em um conjunto de anúncios, é necessário acompanhar alguns valores adicionais:
segment_number
: segmenta o índice no conjunto de anúncios, começando com zero. Ou “init” para o segmento de inicialização de mp4.segment_duration
: duração do segmento atual em milissegundos. Isso o valor precisa ser o mesmo para todos os segmentos, exceto o último no conjunto.segment_offset
: o deslocamento do segmento é calculado somando a duração do segmento anterior ao deslocamento do segmento em milissegundos.last
: valor booleano que identifica o último segmento em um conjunto de anúncios. Padrões como falso.
Criar URLs de segmentos de anúncios
Substitua cada segmento no intervalo de anúncio por um URL no formato:
/linear/pods/v1/seg/network/{network_code}/custom_asset/{custom_asset_key}/{pod_identifier}/profile/{profile_name}/{segment_number}.(ts|mp4|vtt|aac|ac3|eac3)
Parâmetros de caminho | |
---|---|
network_code
|
É o código da rede do Ad Manager 360 para essa rede. |
custom_asset_key
|
A chave de recurso da transmissão ao vivo personalizada especificada na API LiveStreamEventService ou na página da transmissão ao vivo na interface da Web do Ad Manager 360. |
pod_identifier |
Os seguintes formatos são compatíveis: pod/{integer}
O identificador numérico do intervalo de anúncio atual. Os IDs de conjuntos de anúncios são
atribuído de modo incremental para cada evento de intervalo de anúncio, começando em
ad_break_id/{string}
O identificador de string do intervalo de anúncio atual. |
profile_name
|
Identificador do perfil solicitado. |
segment_number
|
O índice desse segmento no conjunto de anúncios atual, começando em zero. Ao usar o contêiner MP4, o segmento de inicialização pode ser solicitado definindo segment_number como "init". |
Parâmetros de consulta | ||
---|---|---|
stream_id
|
Obrigatório | O parâmetro stream_id do usuário retornado da solicitação de criação de
fluxo.
|
sd
|
Obrigatório | segment_duration
|
so
|
Opcional | segment_offset
Se o atributo |
pd
|
Obrigatório, exceto para eventos com intervalos comerciais sem duração ativados | A duração (em milissegundos) do intervalo de anúncio. Também conhecido como
ad_pod_duration .
|
auth-token
|
Obrigatório | Uma assinatura assinada e codificada por URL Token HMAC para este conjunto de anúncios. |
last
|
Opcional | Booleano que indica o último segmento no intervalo de anúncio. O padrão é "false". |
Os valores dos parâmetros de consulta precisam ser codificados corretamente para serem seguros para URL. Isso é
especialmente importante para o campo auth-token
, já que ele pode conter /
,
+
e =
caracteres.
Manifesto de exemplo (após a substituição do segmento)
#EXTM3U
#EXT-X-VERSION:6
#EXT-X-TARGETDURATION:6
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:5.005,
contentorigin.com/1.ts
#EXTINF:5.005,
contentorigin.com/2.ts
#EXT-X-DISCONTINUITY
#EXTINF:5.005,
https://dai.google.com/linear/pods/v1/seg/network/6062/custom_asset/iYdOkYZdQ1KFULXSN0Gi7g/ad_break_id/adbreak1/profile/devrel4628000/0.ts?sd=5005&so=0&pd=18015&auth-token=ad_break_id%3Dadbreak1~custom_asset_key%3DiYdOkYZdQ1KFULXSN0Gi7g~cust_params%3D~exp%3D1489680000~network_code%3D6062~pd%3D180000~hmac%3D44bf78223c240cbc5bae3cdfd794bfc6971b6583cd296f44ef3a46944605cf9a&stream_id=fe6c9136-09a4-4ff6-862e-daee1dea0e1b:MRN2
#EXTINF:5.005,
https://dai.google.com/linear/pods/v1/seg/network/6062/custom_asset/iYdOkYZdQ1KFULXSN0Gi7g/ad_break_id/adbreak1/profile/devrel4628000/1.ts?sd=5005&so=5005&pd=18015&auth-token=ad_break_id%3Dadbreak1~custom_asset_key%3DiYdOkYZdQ1KFULXSN0Gi7g~cust_params%3D~exp%3D1489680000~network_code%3D6062~pd%3D180000~hmac%3D44bf78223c240cbc5bae3cdfd794bfc6971b6583cd296f44ef3a46944605cf9a&stream_id=fe6c9136-09a4-4ff6-862e-daee1dea0e1b:MRN2
#EXTINF:5.005,
https://dai.google.com/linear/pods/v1/seg/network/6062/custom_asset/iYdOkYZdQ1KFULXSN0Gi7g/ad_break_id/adbreak1/profile/devrel4628000/2.ts?sd=5005&so=10010&pd=18015&auth-token=ad_break_id%3adbreak1~custom_asset_key%3DiYdOkYZdQ1KFULXSN0Gi7g~cust_params%3D~exp%3D1489680000~network_code%3D6062~pd%3D180000~hmac%3D44bf78223c240cbc5bae3cdfd794bfc6971b6583cd296f44ef3a46944605cf9a&stream_id=fe6c9136-09a4-4ff6-862e-daee1dea0e1b:MRN2
#EXTINF:3.000,
https://dai.google.com/linear/pods/v1/seg/network/6062/custom_asset/iYdOkYZdQ1KFULXSN0Gi7g/ad_break_id/adbreak1/profile/devrel4628000/3.ts?sd=3000&so=15015&pd=18015&auth-token=ad_break_id%3Dadbreak1~custom_asset_key%3DiYdOkYZdQ1KFULXSN0Gi7g~cust_params%3D~exp%3D1489680000~network_code%3D6062~pd%3D180000~hmac%3D44bf78223c240cbc5bae3cdfd794bfc6971b6583cd296f44ef3a46944605cf9a&stream_id=fe6c9136-09a4-4ff6-862e-daee1dea0e1b:MRN2&last=true
#EXT-X-DISCONTINUITY
#EXTINF:5.005,
contentorigin.com/7.mp4
#EXTINF:5.005,
contentorigin.com/8.mp4
Parabéns! Agora você está veiculando uma transmissão ao vivo com segmentos de anúncios fornecidos por a API DAI Pod Serving.
Transmissões DASH
Os fluxos DASH são fornecidos como um arquivo MPD, que contém todas as codificações de fluxo em um único arquivo, em que o conteúdo é representado como uma série de períodos.
Modelo do período de solicitação
Solicite um modelo de período do Google Ad Manager. Esse modelo vai se tornar seu período de intervalo de anúncio, depois que as macros que ele contém forem preenchidas.
Solicite esse modelo apenas uma vez por sessão de stream e armazene-o em cache por reutilizar a cada intervalo de anúncio.
Endpointhjf da solicitação do modelo de período
GET /linear/pods/v1/dash/network/{network_code}/custom_asset/{custom_asset}/pods.json
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. |
custom_asset |
A chave de recurso personalizada do evento de transmissão ao vivo no Google Ad Manager. |
Parâmetros de consulta | |
---|---|
stream_id |
O código de stream do Ad Manager do player de vídeo do cliente. |
JSON de resposta | |
---|---|
dash_period_template |
A string XML do modelo de período. |
segment_duration_ms |
A duração de cada segmento de mídia do anúncio no modelo de período de traço, em milésimos de segundo. |
Exemplo de solicitação (cURL)
curl https://dai.google.com/linear/pods/v1/dash/network/21775744923/custom_asset/tears_of_steel/pods.json?stream-id=cc59197a-44c0-4be2-a8cc-9a6fdb80158f:DLS
Exemplo de resposta
{"dash_period_template":"<Period id="adpod-$$pod-id$$" $$period-start$$ $$period-duration$$> <BaseURL>https://dai.google.com/linear/pods/v1/seg/event/{event_code}/pods/$$pod-id$$/profile/</BaseURL>
<SegmentTemplate initialization="$RepresentationID$/init.mp4?stream_id={a-stream-id}&sd=5000&pd=$$pod-duration$$&cust_params=$$cust_params$$&auth_token=$$token$$" media="$RepresentationID$/$Number$.mp4?stream_id={a-stream-id}&sd=5000&pd=$$pod-duration$$&cust_params=$$cust_params$$&scte35=$$scte35$$&auth_token=$$token$$" startNumber="1" presentationTimeOffset="0">
<SegmentTimeline>
<S t="0" d="5" r="$$number-of-repeated-segments$$"/>
</SegmentTimeline>
</SegmentTemplate>
<AdaptationSet id="0" width="1280" height="720" frameRate="30" contentType="video" subsegmentAlignment="true" startWithSAP="1">
<InbandEventStream schemeIdUri="https://developer.apple.com/streaming/emsg-id3"/>
<Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"/>
<Representation mimeType="video/mp4" codecs="avc1.640029" id="a943ff679a2f3e71d9181a21b7542122g" bandwidth="3200000"/>
<Representation mimeType="video/mp4" codecs="avc1.640029" id="abbbd80q4w5ce2fs28308rd1f4g4bat0" bandwidth="1500000"/>
</AdaptationSet>
<AdaptationSet id="1" contentType="audio"> <Representation audioSamplingRate="48000" mimeType="audio/mp4" codecs="mp4a.40.2" id="a87ff679a2f3e71d9181a67b7542122c" bandwidth="95000"/>
<Representation audioSamplingRate="48000" mimeType="audio/mp4" codecs="mp4a.40.2" id="eccbc87e4b5ce2fe28308fd9f2a7baf3" bandwidth="127000"/>
</AdaptationSet>
</Period>",
"segment_duration_ms":5000}
Preencher o modelo de período
O modelo de período contém várias macros que precisam ser substituídas para cada intervalo de anúncio. Todas as macros precisam ser substituídas. Macros não utilizadas devem ser substituídas por uma string vazia ("").
Macro | Descrição | Exemplo |
---|---|---|
$$pod-id$$ |
O índice do conjunto de anúncios que esse período representa. Esse valor precisa ser igual para o mesmo pod em todas as sessões de visualização. | 1 |
$$period-start$$ |
O horário em que o período começa no MPD atual. Um atributo opcional
que precisa ser substituído por start="###" , em que
### é o tempo de apresentação em que o intervalo de anúncio começa. Se
o horário de início do período não for fornecido, esta macro deverá ser substituída
com uma string vazia.
|
start="PT2H33M30S" |
$$period-duration$$ |
A duração de todo o período do anúncio. Um atributo opcional que precisa ser
substituído por duration="###" , em que ### é a
duração do período do anúncio no formato padrão de duração do DASH. Se o
do período não for fornecida, essa macro deverá ser substituída por uma
string vazia.
|
duration="PT15S" |
$$pod-duration$$ |
É a duração esperada dos anúncios para o conjunto em questão, em milésimos de segundo. | 15000 |
$$number-of-repeated-segments$$ |
Esse valor é calculado dividindo a duração do período do anúncio (em milésimos de segundo) pelo valor de segment_duration_ms, e arredondando para para o número inteiro mais próximo. | 3 |
$$cust_params$$ |
Essa macro pode ser substituída pelos parâmetros de segmentação personalizada exclusivos o intervalo de anúncio atual, se. fornecidas. O valor precisa ser formatado conforme descrito neste artigo da Central de Ajuda do Ad Manager. Se nenhum parâmetro personalizado for necessário, essa macro será substituída por uma string vazia. |
&cust_params=section%3Dblog%26anotherKey%3Dvalue1%2Cvalue2
|
$$scte35$$ |
Essa macro precisa ser substituída por um valor scte35 exclusivo para esse intervalo de anúncio, se um for fornecido. Se nenhuma informação de scte35 for necessária, essa macro será substituída por uma string vazia. |
/DAqAAAAAAAA///wDwVAAAT2f0/+ecF1mQABC/8ACgAIQ1VFSQAAAAsuZVlR
|
$$token$$ |
Uma assinatura assinada e codificada por URL Token HMAC. Este token é obrigatório. |
custom_asset_key%3DiYdOkYZdQ1KFULXSN0Gi7g~exp%3D1489680000~network_code%3D6062~pd%3D180000~pod_id%3D5~hmac%3D6a8c44c72e4718ff63ad2284edf2a8b9e319600b430349d31195c99b505858c9
|
Modelo de período bruto, contendo macros
<Period id="adpod-$$pod-id$$" $$period-start$$ $$period-duration$$>
<BaseURL>
https://dai.google.com/linear/pods/v1/seg/event/{event_code}/pods/$$pod-id$$/profile/
</BaseURL>
<SegmentTemplate initialization="$RepresentationID$/init.mp4?stream_id=cc59197a-44c0-4be2-a8cc-9a6fdb80158f:DLS&sd=5000&pd=$$pod-duration$$&cust_params=$$cust_params$$&auth_token=$$token$$" media="$RepresentationID$/$Number$.mp4?stream_id=ç√&sd=5000&pd=$$pod-duration$$&cust_params=$$cust_params$$&scte35=$$scte35$$&auth_token=$$token$$" startNumber="1" presentationTimeOffset="0">
<SegmentTimeline>
<S t="0" d="5" r="$$number-of-repeated-segments$$"/>
</SegmentTimeline>
</SegmentTemplate>
<AdaptationSet id="0" width="1280" height="720" frameRate="30" contentType="video" subsegmentAlignment="true" startWithSAP="1">
<InbandEventStream schemeIdUri="https://developer.apple.com/streaming/emsg-id3"/>
<Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"/>
<Representation mimeType="video/mp4" codecs="avc1.640029" id="a943ff679a2f3e71d9181a21b7542122g" bandwidth="3200000"/>
<Representation mimeType="video/mp4" codecs="avc1.640029" id="abbbd80q4w5ce2fs28308rd1f4g4bat0" bandwidth="1500000"/>
</AdaptationSet>
<AdaptationSet id="1" contentType="audio"> <Representation audioSamplingRate="48000" mimeType="audio/mp4" codecs="mp4a.40.2" id="a87ff679a2f3e71d9181a67b7542122c" bandwidth="95000"/>
<Representation audioSamplingRate="48000" mimeType="audio/mp4" codecs="mp4a.40.2" id="eccbc87e4b5ce2fe28308fd9f2a7baf3" bandwidth="127000"/>
</AdaptationSet>
</Period>
Período de anúncios preenchidos
<Period id="pod-0" start="PT5H50M12S">
<BaseURL>
https://dai.google.com/linear/pods/v1/seg/event/M-nTcApTRTi6CEGIt4GYMw/pod/0/profile/
</BaseURL>
<SegmentTemplate startNumber="0" media="1080p/0.mp4?stream_id=cc59197a-44c0-4be2-a8cc-9a6fdb80158f:DLS&sd=5000&pd=30000&cust_params=&auth-token=&scte35=" initialization="$RepresentationID$/init.mp4?stream_id=cc59197a-44c0-4be2-a8cc-9a6fdb80158f:DLS&pd=30000&cust_params=&auth-token=&scte35=">
<SegmentTimeline>
<S d="5" r="1"/>
</SegmentTimeline>
</SegmentTemplate>
<AdaptationSet mimeType="video/mp4" scanType="progressive" contentType="video">
<Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"/>
<Representation width="768" height="432" frameRate="30" codecs="avc1.42c01e" id="fmp4-video-1200k" bandwidth="1300000">
<InbandEventStream schemeIdUri="https://developer.apple.com/streaming/emsg-id3"/>
</Representation>
</AdaptationSet>
<AdaptationSet mimeType="audio/mp4" scanType="progressive" contentType="audio">
<Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"/>
<Representation audioSamplingRate="48000" codecs="mp4a.40.2" id="fmp4-audio-128kbps" bandwidth="128000">
<AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
</Representation>
</AdaptationSet>
</Period>
Insira o período preenchido no manifesto do DASH
Por fim, substitua o ponto adequado no manifesto bruto pelo novo período de anúncio preenchido e retorna o manifesto integrado final ao cliente de vídeo para reprodução.
Exemplo de manifesto de conteúdo bruto
<?xml version="1.0"?>
<MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:mpeg:DASH:schema:MPD:2011" xsi:schemaLocation="urn:mpeg:DASH:schema:MPD:2011" profiles="urn:mpeg:dash:profile:isoff-main:2011" type="static" mediaPresentationDuration="PT0H9M56.46S">
<BaseURL>
http://example.com/tears_of_steel/
</BaseURL>
<Period start="PT0S">
<AdaptationSet bitstreamSwitching="true">
<Representation id="0" codecs="avc1" mimeType="video/mp4" width="1920" height="1080" startWithSAP="1" bandwidth="500000">
<SegmentBase>
<Initialization sourceURL="segments/1080/1.m4s" range="0-862"/>
</SegmentBase>
<SegmentList duration="15">
<SegmentURL media="segments/1080p/2.m4s" mediaRange="863-7113"/>
<SegmentURL media="segments/1080p/3.m4s" mediaRange="7114-14104"/>
<SegmentURL media="segments/1080p/4.m4s" mediaRange="14105-17990"/>
...
</SegmentList>
</Representation>
<Representation id="1" codecs="avc1" mimeType="video/mp4" width="1280" height="720" startWithSAP="1" bandwidth="250000">
<SegmentBase>
<Initialization sourceURL="segments/720p/1.m4s" range="0-864"/>
</SegmentBase>
<SegmentList duration="15">
<SegmentURL media="segments/720p/2.m4s" mediaRange="865-11523"/>
<SegmentURL media="segments/720p/3.m4s" mediaRange="11524-25621"/>
<SegmentURL media="segments/720p/4.m4s" mediaRange="25622-33693"/>
...
</SegmentList>
</Representation>
<Representation id="1" codecs="avc1" mimeType="video/mp4" width="640" height="480" startWithSAP="1" bandwidth="100000">
<SegmentBase>
<Initialization sourceURL="segment/480p/1.m4s" range="0-865"/>
</SegmentBase>
<SegmentList duration="15">
<SegmentURL media="segment/480p/2.m4s" mediaRange="866-26970"/>
<SegmentURL media="segment/480p/3.m4s" mediaRange="26971-72543"/>
<SegmentURL media="segment/480p/4.m4s" mediaRange="72544-95972"/>
...
</SegmentList>
</Representation>
...
</AdaptationSet>
</Period end>
</MPD>
Exemplo de manifesto integrado
<?xml version="1.0"?>
<MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:mpeg:DASH:schema:MPD:2011" xsi:schemaLocation="urn:mpeg:DASH:schema:MPD:2011" profiles="urn:mpeg:dash:profile:isoff-main:2011" type="static" mediaPresentationDuration="PT0H9M56.46S">
<BaseURL>
http://example.com/tears_of_steel/
</BaseURL>
<Period id="pod-0" start="PT5H50M12S">
<BaseURL>
https://dai.google.com/linear/pods/v1/seg/event/M-nTcApTRTi6CEGIt4GYMw/pod/0/profile/
</BaseURL>
<SegmentTemplate startNumber="0" media="1080p/0.mp4?stream_id=cc59197a-44c0-4be2-a8cc-9a6fdb80158f:DLS&sd=5000&pd=30000&cust_params=&auth-token=&scte35=$$scte35$$" initialization="$RepresentationID$/init.mp4?stream_id=cc59197a-44c0-4be2-a8cc-9a6fdb80158f:DLS&pd=30000&cust_params=&auth-token=&scte35=$$scte35$$">
<SegmentTimeline>
<S d="5" r="1"/>
</SegmentTimeline>
</SegmentTemplate>
<AdaptationSet mimeType="video/mp4" scanType="progressive" contentType="video">
<Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"/>
<Representation width="768" height="432" frameRate="30" codecs="avc1.42c01e" id="fmp4-video-1200k" bandwidth="1300000">
<InbandEventStream schemeIdUri="https://developer.apple.com/streaming/emsg-id3"/>
</Representation>
</AdaptationSet>
<AdaptationSet mimeType="audio/mp4" scanType="progressive" contentType="audio">
<Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"/>
<Representation audioSamplingRate="48000" codecs="mp4a.40.2" id="fmp4-audio-128kbps" bandwidth="128000">
<AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
</Representation>
</AdaptationSet>
</Period>
</MPD>
Parabéns! Agora você está veiculando uma transmissão ao vivo DASH com segmentos de anúncio fornecidos. pela API DAI Pod Serving.
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