کیت توسعه نرمافزاری درج پویای تبلیغات رسانههای تعاملی (IMA) یا DAI، برای ردیابی موقعیت بینندگان و رویدادهای تبلیغاتی سمت کلاینت، به اطلاعات فراداده تعبیهشده در بخشهای رسانهای استریم (فراداده درونباند) یا در فایل مانیفست استریم (فراداده درونمانیفست) متکی است. فرادادهها بسته به نوع استریم در حال پخش، در قالبهای مختلفی ارسال میشوند.
پخشکنندهی ویدیو، فرادادههای زمانبندیشده را بهصورت دستهای دریافت میکند. بسته به پخشکننده، فرادادهها میتوانند در زمان برنامهریزیشده یا بهصورت دستهای نمایش داده شوند. هر رشتهی فراداده دارای یک مهر زمانی ارائه (PTS) مرتبط است که نشان میدهد چه زمانی باید فعال شود.
برنامه شما مسئول دریافت فراداده و ارسال آن به IMA DAI SDK است. SDK روشهای زیر را برای ارسال این اطلاعات ارائه میدهد:
- فرادادهی زمانبندیشده
این متد رشتههای متادیتایی را که آماده پردازش هستند به SDK ارسال میکند. این متد یک آرگومان واحد میگیرد:
-
metadata: شیءای حاوی کلیدTXXXبا مقدار رشتهای مرتبط که با پیشوندgoogle_شروع میشود.
-
- فراداده فرآیند
این متد، رشتههای متادیتا را برای پردازش توسط SDK پس از PTS مشخصشده، زمانبندی میکند. این متد آرگومانهای زیر را دریافت میکند:
-
type: رشتهای که شامل نوع رویداد در حال پردازش است. مقادیر پذیرفته شده برای HLS،ID3یا برای DASH،urn:google:dai:2018هستند. -
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 در ابتدای هر بخش رسانهای تعبیه شدهاند و هر eMSG ID3 حاوی یک PTS نسبت به آخرین ناپیوستگی در جریان است.
از زمان انتشار نسخه ۱.۲.۰ HLS.js، هر دو پخشکننده پیشنهادی ما، ID3 را از طریق CMAF به کاربر منتقل میکنند، گویی که تگهای ID3 هستند. به همین دلیل، مثالهای زیر مشابه مثالهای مربوط به جریانهای HLS MPEG2TS هستند. با این حال، ممکن است این مورد در مورد همه پخشکنندهها صدق نکند، بنابراین پیادهسازی پشتیبانی از جریانهای HLS CMAF میتواند به کد منحصر به فردی برای تجزیه ID3 از طریق eMSG نیاز داشته باشد.
پخش در سافاری
سافاری با متادیتای 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
از نسخه ۱.۲.۰، 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 منتقل میکنند. هر رویداد در این جریانها شامل یک payload متنی و PTS است.
دش.جیاس
Dash.js کنترلکنندههای رویداد سفارشی را ارائه میدهد که نامشان از مقدار schemeIdUri هر جریان رویداد گرفته شده است. این کنترلکنندههای سفارشی به صورت دستهای اجرا میشوند و پردازش مقدار PTS برای زمانبندی صحیح رویداد را به شما واگذار میکنند. کیت توسعه نرمافزار IMA DAI میتواند این کار را برای شما با متد 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);
}
});
...
سرو غلاف
برای سرویسدهی پاد، بسته به معیارهای زیر، پیکربندیهای مختلفی برای ارسال فرادادههای زمانبندیشده وجود دارد:
- نوع پخش زنده یا VOD
- فرمت جریان HLS یا DASH
- نوع پخش کننده مورد استفاده
- نوع بکاند DAI مورد استفاده
قالب پخش HLS (پخش زنده و VOD، پخشکننده HLS.js)
اگر از پخشکنندهی HLS.js استفاده میکنید، به رویداد FRAG_PARSING_METADATA در HLS.js گوش دهید تا متادیتای 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 player برای پخش زنده استفاده میکنید، از رشته '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 با پخشهای VOD (فرمت پخشهای DASH)
اگر از Shaka player برای پخش جریان 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);
}
}