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.

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 como POD_SERVING_REDIRECT.
  • streamingFormat: defina como HLS ou DASH, 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 evento
  • endDateTime: data e hora programadas para o término deste evento. Este atributo será obrigatório se unlimitedEndDateTimeis false and ignored ifunlimitedEndDateTimeis 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:
mpd Para streams 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.

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 milissegundos
  • last: 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 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 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}&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 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&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 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&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úncios fornecidos. pela API DAI Pod Serving.

Outros recursos