Manipulador de manifesto para transmissões ao vivo

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 como POD_SERVING_REDIRECT.
  • streamingFormat: defina como HLS ou DASH, 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 evento
  • endDateTime: data e hora programadas para o término deste evento. Esse atributo é obrigatório em caso de unlimitedEndDateTimeis false and ignored ifunlimitedEndDateTimeis 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:
mpd Para transmissões MPEG-DASH
m3u8 Para transmissões HLS
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 1:

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 so estiver ausente, presume-se que todos os segmentos anteriores têm a mesma duração, e o deslocamento de segmento é calculado segment_number e sd.

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}&amp;sd=5000&pd=$$pod-duration$$&amp;cust_params=$$cust_params$$&amp;auth_token=$$token$$" media="$RepresentationID$/$Number$.mp4?stream_id={a-stream-id}&amp;sd=5000&pd=$$pod-duration$$&amp;cust_params=$$cust_params$$&amp;scte35=$$scte35$$&amp;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&amp;sd=5000&pd=$$pod-duration$$&amp;cust_params=$$cust_params$$&amp;auth_token=$$token$$" media="$RepresentationID$/$Number$.mp4?stream_id=ç√&amp;sd=5000&pd=$$pod-duration$$&amp;cust_params=$$cust_params$$&amp;scte35=$$scte35$$&amp;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&amp;sd=5000&amp;pd=30000&amp;cust_params=&amp;auth-token=&amp;scte35=" initialization="$RepresentationID$/init.mp4?stream_id=cc59197a-44c0-4be2-a8cc-9a6fdb80158f:DLS&amp;pd=30000&amp;cust_params=&amp;auth-token=&amp;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&amp;sd=5000&amp;pd=30000&amp;cust_params=&amp;auth-token=&amp;scte35=$$scte35$$" initialization="$RepresentationID$/init.mp4?stream_id=cc59197a-44c0-4be2-a8cc-9a6fdb80158f:DLS&amp;pd=30000&amp;cust_params=&amp;auth-token=&amp;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