SDK для динамической вставки рекламы (DAI) для интерактивной медиарекламы (IMA) использует метаданные, встроенные в медиасегменты потока (внутриполосные метаданные) или в файл манифеста потока (внутриманифестные метаданные), для отслеживания позиций зрителей и событий показа рекламы на стороне клиента. Метаданные передаются в различных форматах в зависимости от типа воспроизводимого потока.
Видеоплеер получает метаданные с привязкой ко времени пакетами. В зависимости от проигрывателя, метаданные могут отображаться по расписанию или пакетами. Каждая строка метаданных имеет связанную с ней метку времени представления (PTS), указывающую момент её появления.
Ваше приложение отвечает за сбор метаданных и их передачу в IMA DAI SDK. SDK предлагает следующие методы для передачи этой информации:
- onTimedMetadata
Этот метод передаёт строки метаданных, готовые к обработке, в SDK. Он принимает один аргумент:
-
metadata
: объект, содержащий ключTXXX
со связанным строковым значением, которое начинается сgoogle_
.
-
- процессМетаданные
Этот метод планирует обработку строк метаданных SDK после указанной точки PTS. Он принимает следующие аргументы:
-
type
: строка, содержащая тип обрабатываемого события. Допустимые значения:ID3
для HLS илиurn:google:dai:2018
для DASH. -
data
: либо строковое значение с префиксомgoogle_
, либо массив байтов в следующем форматеID3:u\0004u\000u\000u\0000TXXXu\0004u\000u\000u\0000google_xxxxxxxx
. -
timestamp
: временная метка в секундах, когда данные должны быть обработаны.
-
Каждый тип потока, поддерживаемый IMA DAI SDK, использует уникальную форму синхронизированных метаданных, как описано в следующих разделах.
Потоки HLS MPEG2TS
Линейные потоки DAI HLS, использующие сегменты MPEG2TS, передают синхронизированные метаданные в видеоплеер посредством внутриполосных ID3-тегов. Эти ID3-теги встроены в сегменты MPEG2TS и имеют имя поля TXXX (для пользовательского текстового контента).
Воспроизведение в Safari
Safari автоматически обрабатывает ID3-теги как скрытую дорожку, поэтому события cuechange срабатывают в нужный момент для обработки каждого фрагмента метаданных. Вы можете передавать все метаданные в IMA DAI SDK, независимо от их содержания или типа. Нерелевантные метаданные автоматически отфильтровываются.
Вот пример:
videoElement.textTracks.addEventListener('addtrack', (e) => {
const track = e.track;
if (track.kind === 'metadata') {
track.mode = 'hidden';
track.addEventListener('cuechange', () => {
for (const cue of track.activeCues) {
const metadata = {};
metadata[cue.value.key] = cue.value.data;
streamManager.onTimedMetadata(metadata);
}
});
}
});
...
HLS.js
HLS.js предоставляет теги ID3 пакетами через событие FRAG_PARSING_METADATA
в виде массива выборок. HLS.js не преобразует данные ID3 из массивов байтов в строки и не смещает события в соответствующие им PTS. Декодировать данные выборки из массива байтов в строку или отфильтровывать нерелевантные теги ID3 не требуется, поскольку IMA DAI SDK выполняет это декодирование и фильтрацию автоматически.
Вот пример:
hls.on(Hls.Events.FRAG_PARSING_METADATA, (e, data) => {
if (streamManager && data) {
data.samples.forEach((sample) => {
streamManager.processMetadata('ID3', sample.data, sample.pts);
});
}
});
...
Потоки HLS CMAF
Линейные потоки DAI HLS, использующие Common Media Application Framework (CMAF), передают синхронизированные метаданные через внутриполосные блоки eMSGv1 в соответствии со стандартом ID3 через CMAF . Эти блоки eMSG встроены в начало каждого медиасегмента, при этом каждый блок eMSG ID3 содержит метку времени (PTS) относительно последнего разрыва в потоке.
Начиная с версии HLS.js 1.2.0, оба предлагаемых нами плеера передают ID3 пользователю через CMAF, как если бы это были теги ID3. По этой причине следующие примеры аналогичны примерам для потоков HLS MPEG2TS. Однако это может быть не так для всех плееров, поэтому для реализации поддержки потоков HLS CMAF может потребоваться уникальный код для обработки ID3 через eMSG.
Воспроизведение в Safari
Safari обрабатывает метаданные ID3 через eMSG как псевдособытия ID3, автоматически предоставляя их пакетами в виде скрытого трека, благодаря чему события cuechange запускаются в нужное время для обработки каждого фрагмента метаданных. Можно передавать все метаданные в IMA DAI SDK, независимо от того, имеют ли они отношение к синхронизации или нет. Любые метаданные, не относящиеся к DAI, автоматически отфильтровываются.
Вот пример:
videoElement.textTracks.addEventListener('addtrack', (e) => {
const track = e.track;
if (track.kind === 'metadata') {
track.mode = 'hidden';
track.addEventListener('cuechange', () => {
for (const cue of track.activeCues) {
const metadata = {};
metadata[cue.value.key] = cue.value.data;
streamManager.onTimedMetadata(metadata);
}
});
}
});
...
HLS.js
Начиная с версии 1.2.0, HLS.js обрабатывает метаданные ID3 через eMSG как псевдособытия ID3, предоставляя их пакетами через событие FRAG_PARSING_METADATA
в виде массива сэмплов. HLS.js не преобразует данные ID3 из массивов байтов в строки и не смещает события в соответствующие им PTS. Декодировать данные сэмплов из массива байтов в строку не требуется, поскольку IMA DAI SDK выполняет это декодирование автоматически.
Вот пример:
hls.on(Hls.Events.FRAG_PARSING_METADATA, (e, data) => {
if (streamManager && data) {
data.samples.forEach((sample) => {
streamManager.processMetadata('ID3', sample.data, sample.pts);
});
}
});
...
Потоки DASH
Линейные потоки DAI DASH передают метаданные как события манифеста в потоке событий с пользовательским значением schemeIdUri
urn:google:dai:2018
. Каждое событие в этих потоках содержит текстовую полезную нагрузку и PTS.
DASH.js
Dash.js предоставляет настраиваемые обработчики событий, названные по значению schemeIdUri каждого потока событий. Эти настраиваемые обработчики срабатывают пакетами, оставляя вам задачу обработки значения PTS для правильного определения времени события. IMA DAI SDK может сделать это автоматически с помощью метода streamManager processMetadata()
.
Вот пример:
const dash = dashjs.MediaPlayer().create();
dash.on('urn:google:dai:2018', (payload) => {
const mediaId = payload.event.messageData;
const pts = payload.event.calculatedPresentationTime;
streamManager.processMetadata('urn:google:dai:2018', mediaId, pts);
});
...
Шака-плеер
Shaka Player отображает события как часть своего события timelineregionenter
. Из-за несовместимости форматирования с Shaka Player значение метаданных необходимо извлекать в необработанном виде через свойство детализации eventNode.attributes['messageData']
.
Вот пример:
player.addEventListener('timelineregionenter', function(event) {
const detail = event.detail;
if ( detail.eventNode.attributes &&
detail.eventNode.attributes['messageData']) {
const mediaId = detail.eventNode.attributes['messageData'];
const pts = detail.startTime;
streamManager.processMetadata("urn:google:dai:2018", mediaId, pts);
}
});
...
Порция стручков
Для обслуживания Pod существуют различные конфигурации передачи синхронизированных метаданных в зависимости от следующих критериев:
- Тип прямой трансляции или VOD
- Формат потока HLS или DASH
- Тип используемого проигрывателя
- Тип используемого бэкэнда DAI
Формат потока HLS (прямые трансляции и трансляции по запросу, плеер HLS.js)
Если вы используете проигрыватель HLS.js , прослушивайте событие HLS.js FRAG_PARSING_METADATA
, чтобы получить метаданные ID3 и передать их в SDK с помощью StreamManager.processMetadata()
.
Чтобы автоматически воспроизвести видео после того, как все загружено и готово, прослушивайте событие HLS.js MANIFEST_PARSED
для запуска воспроизведения.
function loadStream(streamID) {
hls.loadSource(url);
hls.attachMedia(videoElement);
// Timed metadata is passed HLS stream events to the streamManager.
hls.on(Hls.Events.FRAG_PARSING_METADATA, parseID3Events);
hls.on(Hls.Events.MANIFEST_PARSED, startPlayback);
}
function parseID3Events(event, data) {
if (streamManager && data) {
// For each ID3 tag in the metadata, pass in the type - ID3, the
// tag data (a byte array), and the presentation timestamp (PTS).
data.samples.forEach((sample) => {
streamManager.processMetadata('ID3', sample.data, sample.pts);
});
}
}
function startPlayback() {
console.log('Video Play');
videoElement.play();
}
DASH.js (формат потоков DASH, типы потоков Live и VOD)
Если вы используете проигрыватель DASH.js , вам придется использовать разные строки для прослушивания метаданных ID3 для прямых трансляций или потоков VOD:
- Прямые трансляции:
'https://developer.apple.com/streaming/emsg-id3'
- Потоки VOD:
'urn:google:dai:2018'
Передайте метаданные ID3 в SDK с помощью StreamManager.processMetadata()
.
Чтобы автоматически отобразить элементы управления видео после того, как все загружено и готово, прослушивайте событие DASH.js MANIFEST_LOADED
.
const googleLiveSchema = 'https://developer.apple.com/streaming/emsg-id3';
const googleVodSchema = 'urn:google:dai:2018';
dashPlayer.on(googleLiveSchema, processMetadata);
dashPlayer.on(googleVodSchema, processMetadata);
dashPlayer.on(dashjs.MediaPlayer.events.MANIFEST_LOADED, loadlistener);
function processMetadata(metadataEvent) {
const messageData = metadataEvent.event.messageData;
const timestamp = metadataEvent.event.calculatedPresentationTime;
// Use StreamManager.processMetadata() if your video player provides raw
// ID3 tags, as with dash.js.
streamManager.processMetadata('ID3', messageData, timestamp);
}
function loadlistener() {
showControls();
// This listener must be removed, otherwise it triggers as addional
// manifests are loaded. The manifest is loaded once for the content,
// but additional manifests are loaded for upcoming ad breaks.
dashPlayer.off(dashjs.MediaPlayer.events.MANIFEST_LOADED, loadlistener);
}
Shaka Player с прямыми трансляциями (формат потоков DASH)
Если вы используете проигрыватель Shaka для воспроизведения прямой трансляции, используйте строку 'emsg'
для прослушивания событий метаданных. Затем используйте данные сообщения о событии в вызове StreamManager.onTimedMetadata()
.
shakaPlayer.addEventListener('emsg', (event) => onEmsgEvent(event));
function onEmsgEvent(metadataEvent) {
// Use StreamManager.onTimedMetadata() if your video player provides
// processed metadata, as with Shaka player livestreams.
streamManager.onTimedMetadata({'TXXX': metadataEvent.detail.messageData});
}
Shaka Player с потоками VOD (формат потоков DASH)
Если вы используете плеер Shaka для воспроизведения VOD-потока, используйте строку 'timelineregionenter'
для прослушивания событий метаданных. Затем используйте данные сообщения о событии в вызове StreamManager.processMetadata()
со строкой 'urn:google:dai:2018'
.
shakaPlayer.addEventListener('timelineregionenter', (event) => onTimelineEvent(event));
function onTimelineEvent(metadataEvent) {
const detail = metadataEvent.detail;
if ( detail.eventElement.attributes &&
detail.eventElement.attributes['messageData'] &&
detail.eventElement.attributes['messageData'].value ) {
const mediaId = detail.eventElement.attributes['messageData'].value;
const pts = detail.startTime;
// Use StreamManager.processMetadata() if your video player provides raw
// ID3 tags, as with Shaka player VOD streams.
streamManager.processMetadata('urn:google:dai:2018', mediaId, pts);
}
}