Манифест-манипулятор для прямых трансляций

Pod Serving API предоставляет доступ к закодированным и подготовленным сегментам рекламы, подготовленным таким образом, что их можно вставить непосредственно в пользовательский плейлист мультимедиа HLS или MPEG-DASH. Для MPEG-DASH API обслуживания модулей также предоставляет шаблон манифеста для предоставления дополнительной информации и контекста для этих сегментов рекламы.

Это руководство посвящено реализации базового сервера манипулирования манифестами Pod Serving для прямых трансляций.

Предварительное условие: настройте прямые трансляции в Google Ad Manager.

Прежде чем делать какие-либо запросы к API обслуживания модулей, вы должны создать событие прямой трансляции Менеджера рекламы для каждого обрабатываемого вами потока. Вы можете создать прямую трансляцию с помощью LiveStreamEventService API или веб-интерфейса Google Ad Manager .

Чтобы событие прямой трансляции можно было использовать с API обслуживания модулей, вам необходимо заполнить несколько атрибутов вашего события:

  • customAssetKey — пользовательский идентификатор, который будет использоваться для этого события. Должно быть уникальным для всех событий в сети.
  • adTags – URL основного тега объявления, созданный в процессе управления трафиком Менеджера рекламы.
  • dynamicAdInsertionType — должно быть установлено значение POD_SERVING_REDIRECT .
  • streamingFormat — установите HLS или DASH соответственно.
  • segmentUrlAuthenticationKeyIds – хотя бы один ключ HMAC, используемый для подписи запросов сегмента объявления.
  • daiEncodingProfileIds — список идентификаторов DAIEncodingProfile, включенных для этого события.
  • startDateTime — дата и время начала события.
  • endDateTime — запланированная дата и время окончания этого события. Этот атрибут является обязательным, если unlimitedEndDateTime is false and ignored if «unlimitedEndDateTime» is true. неограниченноеEndDateTime` — логическое значение. См. выше.

Получение запросов манифеста потока

Ваш манипулятор манифеста должен предоставить конечную точку API для прослушивания запросов манифеста от клиентского приложения видеопроигрывателя. Как минимум, эта конечная точка должна получить идентификатор потока из приложения клиентского проигрывателя и вернуть объединенный манифест потока. Идентификатор потока используется для идентификации сеанса потоковой передачи в Менеджере рекламы.

Вам также необходимо собрать некоторую другую информацию для идентификации соответствующего потока контента, например идентификатор контента.

Пример потенциальной конечной точки запроса манифеста

GET /api/video/{asset_key}/manifest.{format}
Host: {your_domain}
Параметры пути
asset_key Гипотетический идентификатор, соответствующий запрошенной прямой трансляции в вашей системе.
format Гипотетический параметр, соответствующий формату потока. Один из следующих вариантов:
mpd Для потоков MPEG-DASH
m3u8 Для HLS-потоков
Параметры запроса
stream_id Идентификатор потока Менеджера рекламы из клиентского видеоплеера.

Получить поток контента

Используйте идентификатор контента, полученный из запроса манифеста, чтобы выбрать поток контента для объединения с рекламой.

Объединение сегментов рекламы в поток контента

URL-адреса сегментов объявлений будут различаться в зависимости от формата вашего потока.

HLS-потоки

Потоки HLS обычно обслуживаются в виде многовариантного манифеста, который будет содержать набор ссылок на варианты манифеста, соответствующие каждому из профилей кодирования.

Примечание. Для простоты в этом руководстве предполагается, что ваш медиафайл HLS закодирован в формате, который объединяет аудио и видео в один и тот же файл сегмента.

Прокси многовариантные плейлисты

Вам нужно будет заменить каждый вариант URL-адреса списка воспроизведения в исходном многовариантном списке воспроизведения другим вызовом конечной точки манипулятора для обработки выбранного варианта манифеста проигрывателя.

Остальные шаги по объединению HLS предполагают, что обрабатывается один вариант манифеста.

Пример потенциальной конечной точки запроса варианта
GET /api/video/{asset_key}/variant/{variant_id}.m3u8
Host: {your_domain}
Параметры пути
asset_key Гипотетический идентификатор, соответствующий запрошенной прямой трансляции в вашей системе.
variant Гипотетический параметр, содержащий идентификатор конкретного обрабатываемого варианта.
Параметры запроса
stream_id Идентификатор потока Менеджера рекламы из клиентского видеоплеера. используется здесь для идентификации сеанса пользователя с манипулятором манифеста.
Пример необработанного многовариантного манифеста
#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
Пример проксированного многовариантного манифеста
#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

Определите сегменты рекламных пауз и вставьте разрывы

При обработке вариантного манифеста отслеживайте время начала, продолжительность и индекс следующей предстоящей рекламной паузы, пока обрабатываемый динамический манифест не будет содержать сегменты, которые будут заменены рекламным контентом.

Рекламные паузы могут быть отделены от сегментов контента по-разному, в зависимости от вашего кодировщика. Один из распространенных способов разграничить рекламную паузу — добавлять перед сегментами рекламы тег #EXT-X-CUE-OUT и следовать за ним тегом #EXT-X-CUE-IN .

Чтобы отделить рекламные паузы, размещенные в Google, от сегментов вашего контента, необходимо вставить теги #EXT-X-DISCONTINUITY в начале и конце каждой рекламной паузы. Если эти теги разрыва не появятся в окончательном манифесте, воспроизведение не удастся.

Вставленные URI сегмента объявления не зашифрованы. Если ваш контент зашифрован, вам также необходимо будет удалить шифрование, указав #EXT-X-KEY:METHOD=NONE перед первым рекламным сегментом каждой рекламной паузы, а затем добавить его обратно после рекламной паузы.

Образец манифеста (оригинал)
#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
Манифест с вставленными разрывами
#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

Обработка сегментов рекламных пакетов

Для каждого сегмента в рекламном пакете необходимо отслеживать несколько дополнительных значений:

  • segment_number : индекс сегмента внутри рекламного модуля, начиная с нуля. Или «init» для сегмента инициализации mp4.
  • segment_duration : продолжительность текущего сегмента в миллисекундах. Это значение должно быть одинаковым для всех сегментов, кроме последнего в модуле.
  • segment_offset : смещение сегмента, рассчитанное путем прибавления продолжительности предыдущего сегмента к смещению его сегмента в миллисекундах.
  • last : логическое значение, определяющее последний сегмент в рекламном пакете. По умолчанию ложь.

Создайте URL-адреса сегментов объявлений

Замените каждый сегмент в рекламной паузе URL-адресом формата:

/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)
Параметры пути
network_code Код сети Менеджера рекламы 360 для этой сети.
custom_asset_key Пользовательский ключ объекта прямой трансляции, указанный в API LiveStreamEventService или на странице прямой трансляции в веб-интерфейсе Менеджера рекламы 360.
pod_identifier

Поддерживаются следующие форматы:

pod/{integer}

Числовой идентификатор текущей рекламной паузы. Идентификаторы рекламных блоков назначаются постепенно для каждой рекламной паузы, начиная с 1 .

ad_break_id/{string}

Строковый идентификатор текущей рекламной паузы.

profile_name Идентификатор запрашиваемого профиля,
segment_number Индекс этого сегмента в текущем рекламном пакете, начиная с нуля.
При использовании контейнера MP4 сегмент инициализации можно запросить, установив для номера_сегмента значение «init».
Параметры запроса
stream_id Необходимый stream_id пользователя, возвращенный из запроса на создание потока.
sd Необходимый segment_duration
so Необязательный segment_offset

Если so отсутствует, предполагается, что все предыдущие сегменты имеют одинаковую продолжительность, а смещение сегмента рассчитывается из segment_number и sd .

pd Обязательно, за исключением мероприятий с включенными бесконечными рекламными паузами. Продолжительность (в миллисекундах) рекламной паузы. Также называется ad_pod_duration .
auth-token Необходимый Подписанный токен HMAC в кодировке URL для этого рекламного модуля.
last Необязательный Логическое значение, указывающее последний сегмент рекламной паузы. По умолчанию ложь.

Значения параметров запроса должны быть правильно закодированы, чтобы обеспечить безопасность URL-адресов. Это особенно важно для поля auth-token , поскольку оно может содержать символы / , + и = .

Образец манифеста (после замены сегмента)
#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

Поздравляем! Теперь вы ведете прямую трансляцию с рекламными сегментами, предоставленными API обслуживания подов DAI.

DASH-стримы

Потоки DASH предоставляются в виде файла MPD, который содержит все кодировки потока в одном файле, где содержимое представлено в виде серии периодов.

Шаблон периода запроса

Запросите шаблон периода в Google Ad Manager. Этот шаблон станет вашим периодом рекламной паузы, как только содержащиеся в нем макросы будут заполнены.

Вам следует запрашивать этот шаблон только один раз за сеанс трансляции и кэшировать его для повторного использования при каждой рекламной паузе.

Запрос шаблона периода endpointhjf
GET /linear/pods/v1/dash/network/{network_code}/custom_asset/{custom_asset}/pods.json
Host: dai.google.com
Content-Type: application/json
Параметры пути
network_code Сетевой код Менеджера рекламы 360 издателя.
custom_asset Пользовательский ключ объекта прямой трансляции в Google Ad Manager.
Параметры запроса
stream_id Идентификатор потока Менеджера рекламы из клиентского видеопроигрывателя.
Ответ в формате JSON
dash_period_template XML-строка шаблона периода.
segment_duration_ms Продолжительность каждого рекламного сегмента в шаблоне периода тире в миллисекундах.
Пример запроса (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
Пример ответа
{"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}

Заполнение шаблона периода

Шаблон периода содержит несколько макросов, которые необходимо заменять для каждой рекламной паузы. Все макросы необходимо заменить. Неиспользуемые макросы следует заменить пустой строкой ("").

Макрос Описание Пример
$$pod-id$$ Индекс рекламного пакета, который представляет этот период. Это значение должно совпадать для одного и того же модуля во всех сеансах просмотра. 1
$$period-start$$ Время начала периода в текущем MPD. Необязательный атрибут, который следует заменить на start="###" , где ### — время презентации, в которое начинается рекламная пауза. Если время начала периода не указано, этот макрос следует заменить пустой строкой. start="PT2H33M30S"
$$period-duration$$ Продолжительность полного рекламного периода. Необязательный атрибут, который следует заменить на duration="###" , где ### — это продолжительность рекламного периода в стандартном формате DASH. Если продолжительность периода не указана, этот макрос следует заменить пустой строкой. duration="PT15S"
$$pod-duration$$ Ожидаемая продолжительность рекламы, которая будет принята для этого пакета, в миллисекундах. 15000
$$number-of-repeated-segments$$ Это значение рассчитывается путем деления продолжительности рекламного периода (в миллисекундах) на значение сегмента_duration_ms и округления до ближайшего целого числа. 3
$$cust_params$$ Этот макрос можно заменить параметрами пользовательского таргетинга, уникальными для текущей рекламной паузы, если. предоставил. Значение должно быть отформатировано, как описано в этой статье Справочного центра Менеджера рекламы . Если пользовательские параметры не требуются, этот макрос следует заменить пустой строкой. &cust_params=section%3Dblog%26anotherKey%3Dvalue1%2Cvalue2
$$scte35$$ Этот макрос необходимо заменить значением scte35, уникальным для этой рекламной паузы, если оно предусмотрено. Если информация scte35 не требуется, этот макрос следует заменить пустой строкой. /DAqAAAAAAAA///wDwVAAAT2f0/+ecF1mQABC/8ACgAIQ1VFSQAAAAsuZVlR
$$token$$ Подписанный токен HMAC с кодировкой URL-адреса. Этот токен является обязательным. custom_asset_key%3DiYdOkYZdQ1KFULXSN0Gi7g~exp%3D1489680000~network_code%3D6062~pd%3D180000~pod_id%3D5~hmac%3D6a8c44c72e4718ff63ad2284edf2a8b9e319600b430349d31195c99b505858c9
Шаблон необработанного периода, содержащий макросы
<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>
Заполненный рекламный период
<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>

Вставьте заполненный период в манифест DASH.

Наконец, замените соответствующий период в необработанном манифесте вновь заполненным рекламным периодом и верните окончательный сшитый манифест запрашивающему видеоклиенту для воспроизведения.

Пример манифеста необработанного контента
<?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>
Пример сшитого манифеста
<?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>

Поздравляем! Теперь вы ведете прямую трансляцию DASH с рекламными сегментами, предоставленными API обслуживания подов DAI.

Дополнительные ресурсы