تعتمد حزمة تطوير البرامج (SDK) لتكنولوجيا "إدراج الإعلان الديناميكي" (DAI) من "إعلانات الوسائط التفاعلية" (IMA) على معلومات البيانات الوصفية المضمّنة في مقاطع الوسائط الخاصة بالبث (البيانات الوصفية المضمّنة في البث)، أو في ملف بيان البث (البيانات الوصفية المضمّنة في البيان) لتتبُّع مواضع المشاهدين وأحداث الإعلانات من جهة العميل. يتم إرسال البيانات الوصفية بتنسيقات مختلفة، استنادًا إلى نوع البث الذي يتم تشغيله.
يتلقّى مشغّل الفيديو البيانات الوصفية المحدّدة بوقت على شكل دفعات. اعتمادًا على المشغّل، يمكن عرض البيانات الوصفية في الوقت المحدّد أو على شكل دفعات. يحتوي كل سلسلة بيانات وصفية على طابع زمني للعرض التقديمي (PTS) يشير إلى وقت تشغيلها.
تطبيقك مسؤول عن تسجيل البيانات الوصفية وإعادة توجيهها إلى حزمة تطوير البرامج (SDK) الخاصة بميزة "إعلانات البث المباشر" في IMA. توفّر حزمة تطوير البرامج (SDK) الطرق التالية لتمرير هذه المعلومات:
- onTimedMetadata
تعيد هذه الطريقة توجيه سلاسل البيانات الوصفية الجاهزة للمعالجة إلى حزمة SDK. تتلقّى هذه الدالة وسيطة واحدة:
-
metadata
: عنصر يحتوي على مفتاحTXXX
مع قيمة سلسلة مرتبطة تبدأ بالبادئةgoogle_
.
-
- processMetadata
تجدول هذه الطريقة سلاسل البيانات الوصفية ليتم معالجتها بواسطة حزمة تطوير البرامج بعد وقت عرض الفيديو المحدّد. تتلقّى الدالة الوسيطات التالية:
-
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 شكلاً فريدًا من البيانات الوصفية الموقّتة، كما هو موضّح في الأقسام التالية.
بث MPEG2TS وفق بروتوكول HLS
تستخدم بث DAI خطي بتنسيق HLS يتضمّن مقاطع MPEG2TS لنقل البيانات الوصفية الموقّتة إلى مشغّل الفيديو من خلال علامات ID3 المضمّنة. يتم تضمين علامات ID3 هذه في مقاطع MPEG2TS ويتم منحها اسم الحقل TXXX (للمحتوى النصي المخصّص الذي يحدّده المستخدم).
التشغيل في Safari
تعالج Safari علامات ID3 تلقائيًا كمسار مخفي، لذا يتم تشغيل أحداث cuechange في الوقت الصحيح لمعالجة كل جزء من البيانات الوصفية. لا بأس بتمرير جميع البيانات الوصفية إلى حزمة تطوير البرامج لإعلانات الوسائط التفاعلية (IMA) الخاصة بالإعلانات الديناميكية أثناء البث، بغض النظر عن المحتوى أو النوع. تتم تلقائيًا فلترة البيانات الوصفية غير ذات الصلة.
وفي ما يلي مثال لذلك:
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 غير ذات الصلة، لأنّ حزمة تطوير البرامج لإدراج الإعلان الديناميكي في "إعلانات الوسائط التفاعلية" تنفّذ عملية فك الترميز والفلترة هذه تلقائيًا.
وفي ما يلي مثال لذلك:
hls.on(Hls.Events.FRAG_PARSING_METADATA, (e, data) => {
if (streamManager && data) {
data.samples.forEach((sample) => {
streamManager.processMetadata('ID3', sample.data, sample.pts);
});
}
});
...
فيديوهات البث المباشر بتنسيق CMAF وفق بروتوكول HLS
تستخدم بثات HLS الخاصة بإعلانات DAI الخطية التي تستخدم معيار Common Media Application Framework (CMAF) تمرير البيانات الوصفية الموقّتة من خلال مربّعات eMSGv1 المضمّنة في النطاق وفقًا لمعيار ID3 من خلال CMAF. يتم تضمين مربّعات eMSG هذه في بداية كل جزء من الوسائط، ويحتوي كل eMSG ID3 على PTS بالنسبة إلى آخر انقطاع في البث.
اعتبارًا من الإصدار 1.2.0 من HLS.js، يمرِّر كلا المشغّلين المقترَحيْن بيانات ID3 عبر CMAF إلى المستخدم كما لو كانت علامات ID3. لهذا السبب، تكون الأمثلة التالية مماثلة لأمثلة بث HLS MPEG2TS. ومع ذلك، قد لا يكون هذا هو الحال مع جميع المشغّلات، لذا قد يتطلّب توفير إمكانية تشغيل بث HLS CMAF رمزًا فريدًا لتحليل ID3 من خلال eMSG.
التشغيل في Safari
يتعامل Safari مع ID3 من خلال البيانات الوصفية eMSG كأحداث ID3 زائفة، ويقدّمها على شكل دفعات تلقائيًا كمسار مخفي، وذلك لضمان إطلاق أحداث cuechange في الوقت الصحيح لمعالجة كل جزء من البيانات الوصفية. لا بأس من تمرير جميع البيانات الوصفية إلى حزمة تطوير البرامج الخاصة بإعلانات الوسائط التفاعلية (IMA) في ميزة "الإعلانات الديناميكية أثناء البث" (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) تنفّذ عملية فك الترميز هذه تلقائيًا.
وفي ما يلي مثال لذلك:
hls.on(Hls.Events.FRAG_PARSING_METADATA, (e, data) => {
if (streamManager && data) {
data.samples.forEach((sample) => {
streamManager.processMetadata('ID3', sample.data, sample.pts);
});
}
});
...
مصادر بيانات البث الديناميكي التكيُّفي عبر HTTP (DASH)
تُمرِّر بثات Linear DAI DASH البيانات الوصفية كأحداث بيان في بث أحداث مع القيمة المخصّصة schemeIdUri
urn:google:dai:2018
. يحتوي كل حدث في هذه التدفقات على حمولة نصية وطابع زمني للعرض التقديمي (PTS).
DASH.js
توفّر مكتبة Dash.js معالجات أحداث مخصّصة تحمل اسم قيمة schemeIdUri لكل بث حدث. يتم تنشيط معالجات الأحداث المخصّصة هذه على شكل دفعات، ما يترك لك مهمة معالجة قيمة PTS لتحديد توقيت الحدث بشكلٍ صحيح. يمكن أن تتولّى حزمة تطوير البرامج (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
يعرض Shaka Player الأحداث كجزء من حدث timelineregionenter
. بسبب عدم توافق التنسيق مع Shaka Player، يجب استرداد قيمة البيانات الوصفية بتنسيقها الأولي من خلال السمة detail 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);
}
});
...
عرض الإعلانات المتسلسلة
بالنسبة إلى عرض الإعلانات المتسلسلة، تتوفّر إعدادات مختلفة لنقل البيانات الوصفية المحدّدة بوقت استنادًا إلى المعايير التالية:
- نوع البث المباشر أو الفيديو عند الطلب
- تنسيق البث المباشر وفق بروتوكول HTTP (HLS) أو البث التكيّفي الديناميكي عبر HTTP (DASH)
- نوع المشغّل المستخدَم
- نوع الخلفية المستخدَمة في "إعلانات البث المباشر"
تنسيق البث المباشر وفق بروتوكول HLS (البث المباشر وبث الفيديو عند الطلب، مشغّل HLS.js)
إذا كنت تستخدم مشغّل HLS.js، استمع إلى حدث FRAG_PARSING_METADATA
في HLS.js للحصول على بيانات ID3 الوصفية وتمريرها إلى حزمة تطوير البرامج (SDK) باستخدام StreamManager.processMetadata()
.
لتشغيل الفيديو تلقائيًا بعد تحميل كل المحتوى وتجهيزه، استمع إلى حدث MANIFEST_PARSED
في HLS.js لتفعيل التشغيل.
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، ونوع بث مباشر وفيديو عند الطلب)
إذا كنت تستخدم مشغّل DASH.js، عليك استخدام سلاسل مختلفة للاستماع إلى البيانات الوصفية ID3 لبث مباشر أو بث عند الطلب:
- أحداث البث المباشر:
'https://developer.apple.com/streaming/emsg-id3'
- مصادر الفيديوهات عند الطلب:
'urn:google:dai:2018'
مرِّر البيانات الوصفية ID3 إلى حزمة تطوير البرامج (SDK) باستخدام StreamManager.processMetadata()
.
لعرض عناصر التحكّم في الفيديو تلقائيًا بعد تحميل كل المحتوى وتجهيزه، استمع إلى حدث MANIFEST_LOADED
في DASH.js.
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 Player مع فيديوهات متوفرة عند الطلب (تنسيق فيديوهات DASH)
إذا كنت تستخدم Shaka player لتشغيل بث الفيديو عند الطلب، استخدِم السلسلة '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);
}
}