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.
O foco deste guia é a implementação de uma manipulação básica de manifesto da disponibilização de pods 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 Pod Serving, você precisa: preencha 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 principal da tag de anúncio gerado pelo tráfego do Ad Manager de desenvolvimento de software.dynamicAdInsertionType
: precisa ser definido comoPOD_SERVING_REDIRECT
.streamingFormat
: defina comoHLS
ouDASH
, de acordo com isso.segmentUrlAuthenticationKeyIds
– pelo menos um Chave HMAC usada para assinar solicitações de segmentos de anúncios.daiEncodingProfileIds
: uma lista dos DAIEncodingProfile IDs ativados para este evento.startDateTime
: data e hora de início do eventoendDateTime
: data e hora programadas para o término deste evento. Este atributo será obrigatório seunlimitedEndDateTime
is false and ignored if
unlimitedEndDateTimeis true.
unlimitedEndDateTime` seja um booleano. Veja como fazer isso acima.
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 e retornar um código manifesto de stream. 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 os stream de conteúdo, 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 de stream. 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.
Streams 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 elementos 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 HLS vão considerar que um único manifesto de variante 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 código de stream do Ad Manager do app de player de vídeo cliente. usado aqui para identificar uma sessão de 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 multivariante 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 é preceder o anúncio
com uma tag #EXT-X-CUE-OUT
e uma tag #EXT-X-CUE-IN
.
Para separar os intervalos de anúncios hospedados pelo Google dos segmentos de conteúdo, insira
Tags #EXT-X-DISCONTINUITY
no início e no final de cada intervalo de anúncio. 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 comercial.
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 conjunto de anúncios
Para cada segmento em um conjunto de anúncios, é preciso 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 trecho atual em milissegundos. Isso o valor precisa ser o mesmo para todos os segmentos, exceto o último no conjunto.segment_offset
: deslocamento de segmento calculado pela adição do item anterior duração do segmento para seu deslocamento de segmento em milissegundoslast
: valor booleano que identifica o último segmento em um conjunto de anúncios. Padrões como falso.
Criar URLs de segmento de anúncio
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/{pod_id}/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. |
custom_asset_key
|
A chave de recurso da transmissão ao vivo personalizada especificada no LiveStreamEventService ou na página da transmissão ao vivo na interface da Web do Ad Manager 360. |
pod_id
|
Identificador do intervalo de anúncio. Deve ser um número inteiro a partir de
1 e aumentando em um para cada intervalo de anúncio.
Esse valor precisa ser o mesmo para todos os usuários que visualizam o mesmo intervalo de anúncio no o evento 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 um contêiner MP4, o segmento de inicialização pode ser solicitado ao definir "segment_number" como "init". |
Parâmetros de consulta | ||
---|---|---|
stream_id
|
Obrigatório | O parâmetro stream_id do usuário retornado da criação de stream
solicitação.
|
sd
|
Obrigatório | segment_duration
|
so
|
Opcional | segment_offset
Se |
pd
|
Obrigatório, exceto para eventos com intervalos de anúncio sem duração ativados | A duração (em milissegundos) do intervalo de anúncio. Também chamados de
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/pod/1/profile/devrel4628000/0.ts?sd=5005&so=0&pd=18015&auth-token=custom_asset_key%3DiYdOkYZdQ1KFULXSN0Gi7g~cust_params%3D~exp%3D1489680000~network_code%3D6062~pd%3D180000~pod_id%3D5~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/pod/1/profile/devrel4628000/1.ts?sd=5005&so=5005&pd=18015&auth-token=custom_asset_key%3DiYdOkYZdQ1KFULXSN0Gi7g~cust_params%3D~exp%3D1489680000~network_code%3D6062~pd%3D180000~pod_id%3D5~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/pod/1/profile/devrel4628000/2.ts?sd=5005&so=10010&pd=18015&auth-token=custom_asset_key%3DiYdOkYZdQ1KFULXSN0Gi7g~cust_params%3D~exp%3D1489680000~network_code%3D6062~pd%3D180000~pod_id%3D5~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/pod/1/profile/devrel4628000/3.ts?sd=3000&so=15015&pd=18015&auth-token=custom_asset_key%3DiYdOkYZdQ1KFULXSN0Gi7g~cust_params%3D~exp%3D1489680000~network_code%3D6062~pd%3D180000~pod_id%3D5~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.
Streams do DASH
Os streams DASH são fornecidos como um arquivo MPD, que contém todas as codificações de stream em um único arquivo, em que o conteúdo é representado como uma série de pontos.
Modelo de período de solicitação
Solicite um modelo de período do Google Ad Manager. Este modelo 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 do recurso personalizado 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 em cada anúncio quebrar. 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 representado por este período. Esse valor precisa corresponder a o mesmo conjunto em todas as sessões de espectador. | 1 |
$$period-start$$ |
A hora em que o período começa na MPD atual. Um atributo opcional
que precisa ser substituído por start="###" , em que
### é o momento da apresentação em que o intervalo comercial 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 deve
será substituído por duration="###" , em que ### é o
do período do anúncio no formato de duração DASH padrão. 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 como descritas neste documento do Ad Manager artigo da Central de Ajuda. Se nenhum parâmetro personalizado for necessário, esta macro deverá ser substituída por um valor vazio fio. |
&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, caso um seja fornecido. Se nenhuma informação scte35 for necessária, essa macro deverá por uma string vazia. |
/DAqAAAAAAAA///wDwVAAAT2f0/+ecF1mQABC/8ACgAIQ1VFSQAAAAsuZVlR
|
$$token$$ |
Uma assinatura assinada e codificada por URL Token HMAC. Esse 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 do anúncio preenchido
<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úncios fornecidos. pela API DAI Pod Serving.
Outros recursos
- Reprodução de veiculação de conjunto com o SDK do IMA:
- Pod que veicula a reprodução com a DAI API