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 | Гипотетический параметр, соответствующий формату потока. Один из следующих вариантов:
|
Параметры запроса | |
---|---|
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} Числовой идентификатор текущей рекламной паузы. Идентификаторы рекламных блоков назначаются постепенно для каждой рекламной паузы, начиная с ad_break_id/{string} Строковый идентификатор текущей рекламной паузы. |
profile_name | Идентификатор запрашиваемого профиля, |
segment_number | Индекс этого сегмента в текущем рекламном пакете, начиная с нуля. При использовании контейнера MP4 сегмент инициализации можно запросить, установив для номера_сегмента значение «init». |
Параметры запроса | ||
---|---|---|
stream_id | Необходимый | stream_id пользователя, возвращенный из запроса на создание потока. |
sd | Необходимый | segment_duration |
so | Необязательный | segment_offset Если |
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}&sd=5000&pd=$$pod-duration$$&cust_params=$$cust_params$$&auth_token=$$token$$" media="$RepresentationID$/$Number$.mp4?stream_id={a-stream-id}&sd=5000&pd=$$pod-duration$$&cust_params=$$cust_params$$&scte35=$$scte35$$&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&sd=5000&pd=$$pod-duration$$&cust_params=$$cust_params$$&auth_token=$$token$$" media="$RepresentationID$/$Number$.mp4?stream_id=ç√&sd=5000&pd=$$pod-duration$$&cust_params=$$cust_params$$&scte35=$$scte35$$&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&sd=5000&pd=30000&cust_params=&auth-token=&scte35=" initialization="$RepresentationID$/init.mp4?stream_id=cc59197a-44c0-4be2-a8cc-9a6fdb80158f:DLS&pd=30000&cust_params=&auth-token=&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&sd=5000&pd=30000&cust_params=&auth-token=&scte35=$$scte35$$" initialization="$RepresentationID$/init.mp4?stream_id=cc59197a-44c0-4be2-a8cc-9a6fdb80158f:DLS&pd=30000&cust_params=&auth-token=&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.
Дополнительные ресурсы
- Модуль для воспроизведения с помощью IMA SDK:
- Модуль для воспроизведения с помощью DAI API