Manipulator pliku manifestu w przypadku transmisji na żywo

Interfejs Pod Serving API zapewnia dostęp do zakodowanych i uwarunkowanych segmentów reklam, przygotowane w taki sposób, że można je połączyć bezpośrednio z plikiem HLS przeznaczonym dla użytkowników lub playlistę MPEG-DASH. W przypadku MPEG-DASH interfejs Pod Serving API udostępnia też szablon pliku manifestu, który zawiera dodatkowe informacje i kontekst dotyczący tej reklamy segmentów niestandardowych.

Ten przewodnik skupia się na wdrożeniu podstawowego serwera manipulującego plikiem manifestu wyświetlania bloków reklamowych w przypadku transmisji na żywo.

Warunek wstępny: skonfiguruj wydarzenia na żywo w usłudze Google Ad Manager

Przed wysłaniem żądań z interfejsu API bloków reklamowych do wyświetlania reklam musisz utworzyć Zdarzenie na żywo w ramach menedżera każdej transmisji, którą przetwarzasz. Możesz utworzyć za pomocą funkcji LiveStreamEventService API lub Interfejs internetowy Google Ad Managera.

Aby użyć zdarzenia transmisji na żywo z interfejsem API do wyświetlania bloków reklamowych, musisz wypełnić kilka atrybutów tego zdarzenia:

  • customAssetKey – identyfikator niestandardowy używany w przypadku tego zdarzenia. Musi być unikalny wśród wszystkich zdarzeń w sieci.
  • adTags – główny adres URL tagu reklamy wygenerowany w ramach procesu trafikowania w usłudze Ad Manager.
  • dynamicAdInsertionType – musi być ustawiony na POD_SERVING_REDIRECT.
  • streamingFormat – ustaw odpowiednio HLS lub DASH.
  • segmentUrlAuthenticationKeyIds – co najmniej 1 klucz HMAC używany do podpisywania żądań dotyczących segmentów reklam.
  • daiEncodingProfileIds – lista identyfikatorów DAIEncodingProfile włączonych w przypadku tego zdarzenia.
  • startDateTime – data i godzina rozpoczęcia zdarzenia.
  • endDateTime – zaplanowana data i godzina zakończenia wydarzenia. Ten atrybut jest wymagany, jeśli wartość logiczna jest następująca: unlimitedEndDateTimeis false and ignored ifunlimitedEndDateTimeis true.unlimitedEndDateTime` Patrz wyżej.

Odbieranie żądań pliku manifestu strumienia

Manipulujący plik manifestu musi udostępnić punkt końcowy interfejsu API, który będzie nasłuchiwać żądań pliku manifestu z aplikacji klienta odtwarzacza. Punkt końcowy musi co najmniej pobierać identyfikator strumienia z aplikacji klienta odtwarzacza i zwracać zszyty plik manifestu strumienia. Identyfikator strumienia służy do identyfikowania sesji strumieniowej w usłudze Ad Manager.

Musisz też zebrać inne informacje, aby zidentyfikować odpowiedni strumień treści, np. identyfikator treści.

Przykład potencjalnego punktu końcowego żądania pliku manifestu

GET /api/video/{asset_key}/manifest.{format}
Host: {your_domain}
Parametry ścieżki
asset_key Hipotetyczny identyfikator odpowiadający żądanej transmisji na żywo w Twoim systemie.
format Hipotetyczny parametr odpowiadający formatowi strumienia. Wybierz jedną z tych opcji:
mpd Strumienie MPEG-DASH
m3u8 W przypadku strumieni HLS
Parametry zapytania
stream_id Identyfikator strumienia Ad Managera z aplikacji klienta odtwarzacza wideo.

Pobieranie strumienia treści

Użyj identyfikatora treści zebranego z żądania pliku manifestu, aby wybrać strumień treści, który ma być zszyty z reklamami.

Łączenie segmentów reklam ze strumieniem treści

Łączenie adresów URL segmentów reklam będzie się różnić w zależności od formatu strumienia.

strumienie HLS,

Strumienie HLS są zwykle dostarczane jako pliki manifestu wielowariantowego, które zawierają zestaw linków do plików manifestu wariantów odpowiadających poszczególnym profilom kodowania.

Uwaga: dla uproszczenia w tym przewodniku przyjęto, że multimedia HLS są zakodowane który łączy dźwięk i obraz w jeden plik segmentu.

Playlisty z wieloma wariantami na serwerach proxy

Musisz zastąpić adres URL każdej playlisty wariantu w pierwotnym wielowariancie. z innym wywołaniem punktu końcowego do manipulatora, wybranego pliku manifestu wariantu.

W pozostałych krokach łączenia HLS zakłada się, że pojedynczy plik manifestu wariantu jest przetwarzany.

Przykład punktu końcowego żądania wariantu
GET /api/video/{asset_key}/variant/{variant_id}.m3u8
Host: {your_domain}
Parametry ścieżki
asset_key Hipotetyczny identyfikator odpowiadający żądanej transmisji na żywo w Twoim systemie.
variant Hipotetyczny parametr zawierający identyfikator konkretnej wersji, która jest przetwarzana.
Parametry zapytania
stream_id Identyfikator strumienia Ad Managera z aplikacji odtwarzacza wideo klienta. co tutaj wskazać sesję użytkownika za pomocą manipulatora pliku manifestu.
Przykładowy nieprzetworzony plik manifestu z wieloma wariantami
#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
Przykład zastępczego pliku manifestu z wieloma wariantami
#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

Określ segmenty przerw na reklamę i wstaw nieciągłości

Podczas przetwarzania pliku manifestu wariantu śledź czas rozpoczęcia, czas trwania i indeks następnej nadchodzącej przerwy na reklamę, aż przetwarzany plik manifestu dynamicznego będzie zawierać segmenty, które zostaną zastąpione treścią reklamy.

Przerwy na reklamy mogą być oddzielone od segmentów treści na różne sposoby, w zależności w koderze. Jednym z popularnych sposobów na wyznaczenie przerwy na reklamę jest poprzedzanie segmentów reklam tagiem #EXT-X-CUE-OUT, a następnie dodawanie tagu #EXT-X-CUE-IN.

Aby oddzielić przerwy na reklamę hostowane przez Google od segmentów treści, musisz wstawić Tagi #EXT-X-DISCONTINUITY na początku i na końcu każdej przerwy na reklamę. Jeśli W ostatecznej wersji pliku manifestu nie ma tagów nieciągłości, odtwarzanie się nie uda.

Wstawione identyfikatory URI segmentu reklam nie są zaszyfrowane. Jeśli Twoje treści są zaszyfrowane, musisz też usunąć szyfrowanie, podając wartość #EXT-X-KEY:METHOD=NONE przed pierwszym segmentem reklamy w każdej przerwie na reklamę, a następnie ponownie dodać szyfrowanie po przerwie.

Przykładowy plik manifestu (pierwotny)
#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
Manifest z wstawionymi nieciągłościami
#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

Przetwarzanie segmentów bloków reklamowych

W przypadku każdego segmentu w bloku reklamowym musisz śledzić kilka dodatkowych wartości:

  • segment_number: indeks segmentu w bloku reklam, zaczynający się od zera. Lub „init” dla segmentu inicjowania pliku mp4.
  • segment_duration: czas trwania bieżącego segmentu w milisekundach. Ta wartość powinna być taka sama dla wszystkich segmentów z wyjątkiem ostatniego w podzie.
  • segment_offset: przesunięcie segmentu obliczone przez dodanie poprzedniej wartości czas trwania segmentu do przesunięcia segmentu w milisekundach
  • last: wartość logiczna określająca ostatni segment w bloku reklamowym. Wartość domyślna to fałsz.

Tworzenie adresów URL segmentów reklam

Zastąp każdy segment w przerwie na reklamę adresem URL w formacie:

/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)
Parametry ścieżki
network_code Kod sieci Ad Managera 360 dla tej sieci.
custom_asset_key Klucz pliku niestandardowej transmisji na żywo określony w interfejsie API LiveStreamEventService lub na stronie transmisji na żywo w interfejsie internetowym Ad Managera 360.
pod_identifier

Obsługiwane formaty:

pod/{integer}

Identyfikator numeryczny bieżącej przerwy na reklamę. Identyfikatory podsegmentów reklamy są przypisywane stopniowo do każdego zdarzenia przerwy na reklamę, zaczynając od 1.

ad_break_id/{string}

Identyfikator ciągu znaków bieżącej przerwy na reklamę.

profile_name identyfikator żądanego profilu;
segment_number Indeks tego segmentu w bieżącym podgrupie reklam, zaczynając od zera.
Podczas korzystania z kontenera MP4 można poprosić o utworzenie segmentu inicjalizacji, ustawiając parametr segment_number na „init”.
Parametry zapytania
stream_id Wymagane Parametr stream_id użytkownika zwrócony z narzędzia Stream Create użytkownika.
sd Wymagane segment_duration
so Opcjonalnie segment_offset

Jeśli brakuje parametru so, przyjmuje się, że wszystkie poprzednie segmenty mają tę samą długość, a przesunięcie segmentu jest obliczane na podstawie parametrów segment_number i sd.

pd Wymagane z wyjątkiem zdarzeń z włączonymi bezterminowymi przerwami na reklamę Czas trwania przerwy na reklamę (w milisekundach). Inna nazwa: ad_pod_duration
auth-token Wymagane Podpisany, zakodowany w formacie URL token HMAC dla tego podsegmentu reklamy.
last Opcjonalnie Wartość logiczna wskazująca ostatni segment w przerwie na reklamę. Wartość domyślna to fałsz.

Aby wartości parametrów zapytania były bezpieczne w adresach URL, muszą być odpowiednio zakodowane. Jest to szczególnie ważne w przypadku pola auth-token, ponieważ może ono zawierać znaki /, +=.

Przykładowy plik manifestu (po wymianie segmentu)
#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

Gratulacje! Obecnie wyświetlasz transmisję na żywo z segmentami reklamowymi udostępnianymi przez interfejs DAI Pod Serving API.

Strumienie DASH

Strumienie DASH są dostarczane w postaci pliku MPD, który zawiera wszystkie kodowanie strumieni w w pojedynczym pliku, w którym treść jest przedstawiona jako seria kropek.

Szablon okresu żądania

Poproś o szablon okresu w Google Ad Managerze. Ten szablon stanie się okresem przerwy na reklamę, gdy zostaną wypełnione zawarte w nim makra.

Wysyłaj ten szablon tylko raz na sesję strumienia i buforuj go przez z każdą przerwą na reklamę.

Punkt końcowy żądania szablonu okresu
GET /linear/pods/v1/dash/network/{network_code}/custom_asset/{custom_asset}/pods.json
Host: dai.google.com
Content-Type: application/json
Parametry ścieżki
network_code Kod sieci wydawcy Ad Managera 360.
custom_asset Niestandardowy klucz zasobu zdarzenia transmisji na żywo w Google Ad Manager.
Parametry zapytania
stream_id Identyfikator strumienia Ad Managera z odtwarzacza wideo klienta.
Odpowiedź JSON
dash_period_template Ciąg znaków XML szablonu okresu.
segment_duration_ms Czas trwania każdego segmentu treści reklamowych w szablonie okresu danych w milisekundach.
Przykładowe żądanie (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
Przykładowa odpowiedź
{"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}

Wypełnij szablon okresu

Szablon kropki zawiera kilka makr, które musisz zastąpić w każdej reklamie przerwania. Trzeba zastąpić wszystkie makra. Nieużywane makra należy zastąpić tagiem pusty ciąg znaków („”).

Makro Opis Przykład
$$pod-id$$ Indeks bloku reklamowego w tym okresie. Ta wartość musi być taka sama w przypadku wszystkich sesji widzów w ramach tego samego podzbioru. 1
$$period-start$$ Godzina rozpoczęcia okresu w bieżącym MPD. Opcjonalny atrybut, który należy zastąpić wartością start="###", gdzie ### to czas prezentacji, w którym rozpoczyna się przerwa na reklamę. Jeśli czas rozpoczęcia okresu nie jest podany, należy zastąpić to makro pustym ciągiem znaków. start="PT2H33M30S"
$$period-duration$$ Czas trwania całego okresu reklamowego. Opcjonalny atrybut, który powinien zostać zastąpiony przez duration="###", gdzie ### to czas trwania okresu reklamy w standardowym formacie czasu DASH. Jeśli nie podano czasu trwania okresu, to makro należy zastąpić pustym ciągiem. duration="PT15S"
$$pod-duration$$ Przewidywany czas trwania reklam, które mają być wybrane w tym bloku reklamowym (w milisekundach). 15000
$$number-of-repeated-segments$$ Wartość tę oblicza się, dzieląc czas trwania okresu reklamowego (w milisekund) przez wartość segment_duration_ms i zaokrąglone w górę do najbliższą liczbą całkowitą. 3
$$cust_params$$ To makro może zostać zastąpione przez niestandardowe parametry kierowania, które są unikalne dla bieżącej przerwy na reklamę (jeśli są dostępne). Wartość musi mieć format opisany w tym artykule w Centrum pomocy Ad Managera. Jeśli nie są potrzebne żadne parametry niestandardowe, makro należy zastąpić pustym ciągu znaków. &cust_params=section%3Dblog%26anotherKey%3Dvalue1%2Cvalue2
$$scte35$$ To makro należy zastąpić wartością scte35, która jest unikalna dla danej przerwy na reklamę (jeśli została podana). Jeśli nie są potrzebne żadne informacje scte35, to makro należy zastąpić pustym ciągiem. /DAqAAAAAAAA///wDwVAAAT2f0/+ecF1mQABC/8ACgAIQ1VFSQAAAAsuZVlR
$$token$$ Podpisany, zakodowany w adresie URL Token HMAC. Ten token jest wymagany. custom_asset_key%3DiYdOkYZdQ1KFULXSN0Gi7g~exp%3D1489680000~network_code%3D6062~pd%3D180000~pod_id%3D5~hmac%3D6a8c44c72e4718ff63ad2284edf2a8b9e319600b430349d31195c99b505858c9
Szablon nieprzetworzonego okresu zawierający makra
<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>
Wypełniony okres reklamy
<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>

Wstawianie wypełnionego okresu do pliku manifestu DASH

Na koniec zastąp odpowiedni przedział czasu w nieprzetworzonym pliku manifestu nowym wypełnionego okresu reklamy i wysyłanie ostatecznego połączonego pliku manifestu do żądania klienta wideo.

Przykład pliku manifestu z nieprzetworzoną zawartością
<?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>
Przykładowy połączony plik manifestu
<?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>

Gratulacje! Wyświetlasz transmisję na żywo DASH z dostarczonymi segmentami reklam za pomocą DAI Pod Serving API.

Dodatkowe materiały