Manipulator pliku manifestu w przypadku transmisji na żywo

Interfejs ten zapewnia dostęp do zakodowanych i uwarunkowanych segmentów reklam, które można przygotować w taki sposób, aby można je było połączyć bezpośrednio z udostępnianą użytkownikom playlistę multimediów HLS lub 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 tych segmentów reklam.

Ten przewodnik dotyczy wdrożenia podstawowego serwera manipulacyjnego wyświetlania podów w transmisjach na żywo.

Wymaganie wstępne: skonfiguruj w usłudze Google Ad Manager zdarzenia transmisji na żywo

Przed wysłaniem żądań z interfejsu API do wyświetlania reklam musisz utworzyć zdarzenie transmisji na żywo z Ad Managera dla każdego przetwarzanego strumienia. Wydarzenie z transmisją na żywo możesz utworzyć za pomocą LiveStreamEventService API lub interfejsu internetowego Google Ad Managera.

Aby użyć zdarzenia transmisji na żywo za pomocą interfejsu API obsługującego pody, musisz wypełnić kilka atrybutów zdarzenia:

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

Odbieranie żądań manifestu strumienia

Manipulator manifestu musi udostępniać punkt końcowy interfejsu API nasłuchujący żądań pliku manifestu z aplikacji klienckiej odtwarzacza wideo. Ten punkt końcowy musi przynajmniej zbierać identyfikator strumienia z aplikacji odtwarzacza klienckiego i musi zwracać plik manifestu połączonego strumienia. Identyfikator strumienia danych z Ad Managera identyfikuje sesję strumieniowania.

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. Jedna z tych opcji:
mpd Strumienie MPEG-DASH
m3u8 W przypadku strumieni HLS
Parametry zapytania
stream_id Identyfikator strumienia danych z Ad Managera z klienckiej aplikacji odtwarzacza wideo.

Pobieranie strumienia treści

Użyj identyfikatora treści zebranego w żądaniu pliku manifestu, aby wybrać strumień treści do połączenia z reklamami.

Połącz segmenty reklamy ze strumieniem treści

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

Strumienie HLS

Strumienie HLS są zwykle udostępniane jako plik manifestu z wieloma wariantami, który zawiera zestaw linków do plików manifestu wariantów, które odpowiadają poszczególnym profilom kodowania.

Uwaga: dla uproszczenia w tym przewodniku przyjęto, że multimedia HLS są zakodowane w formacie, który przetwarza dźwięk i obraz do tego samego pliku segmentu.

Proxy z wieloma wariantami

Aby przetworzyć plik manifestu wybranego wariantu, musisz zastąpić adres URL każdej playlisty wariantu w pierwotnej playliście z wieloma wariantami innym wywołaniem punktu końcowego manipulatora.

Pozostałe kroki łączenia HLS będą zakładać, że przetwarzany jest 1 wariant pliku manifestu.

Przykład potencjalnego 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 konkretnego wariantu, który jest przetwarzany.
Parametry zapytania
stream_id Identyfikator strumienia danych z Ad Managera z aplikacji odtwarzacza wideo klienta. Używany w tym miejscu do identyfikowania sesji 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ładowy plik manifestu z wieloma wariantami przez serwer 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

Wskaż segmenty przerwy na reklamę i wstaw nieciągłości

Przetwarzając plik manifestu wariantu, pamiętaj o godzinie rozpoczęcia, czasie trwania i indeksie następnej przerwy na reklamę, dopóki przetwarzany dynamiczny plik manifestu będzie zawierał segmenty, które zostaną zastąpione treścią reklamy.

Przerwy na reklamę można oddzielić od segmentów treści na różne sposoby w zależności od kodera. Jednym z typowych sposobów wyznaczania przerwy na reklamę jest poprzedzanie segmentów reklam tagiem #EXT-X-CUE-OUT, a następnie dodawanie do nich 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 tych tagów nieciągłości w pliku manifestu nie ma, odtwarzanie się nie powiedzie.

Wstawione identyfikatory URI segmentów reklam nie są zaszyfrowane. Jeśli Twoje treści są zaszyfrowane, musisz też usunąć szyfrowanie. W tym celu wskaż #EXT-X-KEY:METHOD=NONE przed pierwszym segmentem każdej przerwy na reklamę, a potem dodaj tę wartość z powrotem po przerwie na reklamę.

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
Plik manifestu 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 reklamowym, zaczynając od zera. Lub „init” w przypadku segmentu inicjowania pliku MP4.
  • segment_duration: czas trwania bieżącego segmentu w milisekundach. Powinna być taka sama we wszystkich segmentach oprócz ostatniego w bloku reklamowym.
  • segment_offset: przesunięcie segmentu obliczane przez dodanie czasu trwania poprzedniego segmentu do przesunięcia segmentu w milisekundach.
  • last: wartość logiczna identyfikują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 takim formacie:

/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)
Parametry ścieżki
network_code Kod sieci Ad Managera 360 danej sieci.
custom_asset_key Klucz zasobu niestandardowej transmisji na żywo określony w interfejsie LiveStreamEventService API lub na stronie transmisji na żywo w interfejsie internetowym Ad Managera 360.
pod_id Identyfikator przerwy na reklamę. Musi być liczbą całkowitą od 1 i rosnącą o 1 przy każdej przerwie na reklamę.

Ta wartość musi być taka sama u wszystkich użytkowników oglądających tę samą przerwę na reklamę w bieżącym zdarzeniu.

profile_name Identyfikator żądanego profilu
segment_number Indeks tego segmentu w bieżącym bloku reklamowym, począwszy od zera.
Jeśli korzystasz z kontenera MP4, żądania segmentu inicjowania można żądać, ustawiając parametr segment_number na „init”.
Parametry zapytania
stream_id Wymagane Parametr stream_id użytkownika został zwrócony z żądania utworzenia strumienia.
sd Wymagane segment_duration
so Opcjonalnie segment_offset

Jeśli brakuje parametru so, zakłada się, że wszystkie poprzednie segmenty mają taki sam czas trwania, a przesunięcie segmentu jest obliczane według wzoru segment_number i sd.

pd Wymagane z wyjątkiem wydarzeń z włączonymi przerwami na reklamę bez czasu trwania Czas trwania przerwy na reklamę (w milisekundach). Nazywany też ad_pod_duration.
auth-token Wymagane Podpisany, zakodowany w adresie URL token HMAC na potrzeby tego bloku reklamowego.
last Opcjonalnie Wartość logiczna wskazująca ostatni segment w przerwie na reklamę. Wartość domyślna to fałsz.

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

Przykładowy plik manifestu (po zastąpieniu 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/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

Gratulacje! Wyświetlasz teraz transmisję na żywo z segmentami reklam dostarczonymi przez interfejs DAI Pod Serving API.

Strumienie DASH

Strumienie DASH są dostarczane w postaci pliku MPD, który zawiera wszystkie kodowanie strumieni w jednym pliku. Treść jest przedstawiona w postaci serii kropek.

Szablon okresu żądania

Poproś Google Ad Managera o szablon miesiączki. Po wypełnieniu zawartych w nim makr stanie się on okresem przerwy na reklamę.

Żądaj tego szablonu tylko raz na sesję strumienia i używaj go w pamięci podręcznej do użytku przy każdej przerwie 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 Ad Managera 360 wydawcy.
custom_asset Niestandardowy klucz zasobu powiązany ze zdarzeniem transmisji na żywo w usłudze Google Ad Manager.
Parametry zapytania
stream_id Identyfikator strumienia danych z Ad Managera z odtwarzacza klienta.
Plik JSON odpowiedzi
dash_period_template Ciąg znaków XML szablonu okresu.
segment_duration_ms Czas trwania każdego segmentu mediów reklamowych w szablonie przedziału czasu (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 przedziału zawiera kilka makr, które musisz zastąpić w każdej przerwie na reklamę. Wszystkie makra należy zastąpić. Nieużywane makra należy zastąpić pustym ciągiem znaków („”).

Makro Opis Przykład
$$pod-id$$ Indeks bloku reklamowego reprezentowanego w tym okresie. Ta wartość musi pasować do tego samego bloku we wszystkich sesjach użytkownika. 1
$$period-start$$ Czas 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 ma się rozpocząć przerwa na reklamę. Jeśli nie podasz czasu rozpoczęcia przedziału, to makro należy zastąpić pustym ciągiem znaków. start="PT2H33M30S"
$$period-duration$$ Czas trwania całego okresu reklamowego. Opcjonalny atrybut, który należy zastąpić wartością duration="###", gdzie ### to czas trwania okresu reklamowego w standardowym formacie DASH. Jeśli nie podano czasu trwania okresu, należy zastąpić to makro pustym ciągiem znaków. duration="PT15S"
$$pod-duration$$ Oczekiwany czas trwania reklam w tym bloku reklamowym (w milisekundach). 15000
$$number-of-repeated-segments$$ Wartość tę oblicza się, dzieląc czas trwania okresu reklamowego (w milisekundach) przez wartość segment_duration_ms i zaokrąglając do najbliższej liczby całkowitej. 3
$$cust_params$$ To makro można zastąpić parametrami kierowania niestandardowego unikalnymi dla bieżącej przerwy na reklamę, jeśli zostały podane. Wartość musi być sformatowana zgodnie z opisem w tym artykule w Centrum pomocy Ad Managera. Jeśli nie są potrzebne żadne parametry niestandardowe, należy zastąpić to makro pustym ciągiem znaków. &cust_params=section%3Dblog%26anotherKey%3Dvalue1%2Cvalue2
$$scte35$$ To makro należy zastąpić wartością scte35 unikalną dla danej przerwy na reklamę, jeśli została podana. Jeśli nie są potrzebne informacje scte35, należy zastąpić to makro pustym ciągiem znaków. /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, który zawiera 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>

Wstaw wypełnioną kropkę do pliku manifestu DASH

Na koniec zastąp odpowiedni okres w nieprzetworzonym pliku manifestu nowo wypełnionym okresem reklamowym i zwróć do klienta wideo, który przesłał żądanie, końcowy połączony plik manifestu, aby mógł go odtworzyć.

Przykładowy plik manifestu nieprzetworzonej treś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ład połączonego pliku 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 teraz transmisję na żywo DASH z segmentami reklam dostarczonymi przez interfejs DAI Pod Serving API.

Dodatkowe materiały