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 (برای محتوای متنی سفارشی تعریف شده توسط کاربر) به آنها داده می شود.
پخش در سافاری
سافاری تگهای 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 با استفاده از چارچوب برنامه کاربردی رسانه مشترک (CMAF) ابردادههای زمانبندیشده را از طریق جعبههای eMSGv1 درون باند به دنبال استاندارد ID3 تا CMAF منتقل میکنند. این جعبههای eMSG در ابتدای هر بخش رسانه تعبیه شدهاند و هر ID3 eMSG حاوی یک PTS نسبت به آخرین ناپیوستگی در جریان است.
از زمان انتشار 1.2.0 HLS.js، هر دو بازیکن پیشنهادی ما ID3 را از طریق CMAF به کاربر منتقل می کنند، گویی که برچسب ID3 هستند. به همین دلیل، مثال های زیر مانند جریان های HLS MPEG2TS است. با این حال، ممکن است این مورد در مورد همه بازیکنان صادق نباشد، بنابراین اجرای پشتیبانی از جریان های HLS CMAF می تواند به کد منحصر به فرد برای تجزیه ID3 از طریق eMSG نیاز داشته باشد.
پخش در سافاری
Safari ID3 را از طریق ابرداده eMSG به عنوان رویدادهای ID3 کاذب در نظر میگیرد، و آنها را به صورت دستهای، بهطور خودکار و بهعنوان یک مسیر پنهان ارائه میکند، به طوری که رویدادهای cuechange در زمان مناسب برای پردازش هر تکه ابرداده اجرا میشوند. ارسال همه ابردادهها به کیت توسعه نرمافزار IMA DAI، چه مربوط به زمانبندی باشد و چه نباشد، اشکالی ندارد. هر ابرداده غیر مرتبط با 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، مقدار فراداده باید به صورت خام، از طریق ویژگی جزئیات eventElement.attributes['messageData'].value
بازیابی شود.
در اینجا یک مثال است:
player.addEventListener('timelineregionenter', function(event) {
const detail = event.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;
streamManager.processMetadata("urn:google:dai:2018", mediaId, pts);
}
});
...
سرو غلاف
برای سرویس Pod، بسته به معیارهای زیر، پیکربندیهای مختلفی برای انتقال ابرداده زمانبندی شده وجود دارد:
- نوع پخش زنده یا VOD
- فرمت جریان HLS یا DASH
- نوع پخش کننده مورد استفاده
- نوع باطن DAI مورد استفاده
فرمت جریان HLS (جریان های زنده و VOD، پخش کننده HLS.js)
اگر از پخش کننده HLS.js استفاده می کنید، به رویداد HLS.js FRAG_PARSING_METADATA
گوش دهید تا متادیتا ID3 را دریافت کنید و با StreamManager.processMetadata()
آن را به SDK منتقل کنید.
برای پخش خودکار ویدیو پس از بارگیری و آماده شدن همه چیز، به رویداد 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، نوع پخش زنده و VOD)
اگر از پخش کننده DASH.js استفاده می کنید، باید از رشته های مختلف برای گوش دادن به فراداده ID3 برای جریان های زنده یا VOD استفاده کنید:
- پخش زنده:
'https://developer.apple.com/streaming/emsg-id3'
- جریانهای VOD:
'urn:google:dai:2018'
فراداده ID3 را با StreamManager.processMetadata()
به SDK منتقل کنید.
برای نمایش خودکار کنترلهای ویدیو پس از بارگیری و آماده شدن همه چیز، به رویداد 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);
}
}