ערכת ה-SDK להטמעת מודעות דינמיות (DAI) של מודעות המדיה האינטראקטיביות (IMA) מסתמכת על פרטי המטא-נתונים שמוטמעים בפלחי המדיה של הסטרימינג (מטא-נתונים בפס), או בקובץ המניפסט של הסטרימינג (מטא-נתונים בתוך המניפסט) כדי לעקוב אחרי המיקומים של הצופים ואירועי המודעות בצד הלקוח. המטא-נתונים נשלחים בפורמטים שונים, בהתאם לסוג הסטרימינג שמופעל.
נגן הווידאו מקבל מטא-נתונים מתוזמנים בקבוצות. בהתאם לנגן, המטא-נתונים יכולים להופיע בזמן המתוזמן או בקבוצות. לכל מחרוזת מטא-נתונים יש חותמת זמן של הצגה (PTS) שמשויכת אליה, שמציינת מתי היא צריכה להופיע.
האפליקציה אחראית לתעד מטא-נתונים ולהעביר אותם ל-IMA DAI SDK. ה-SDK מציע את השיטות הבאות להעברת המידע הזה:
- onTimedMetadata
השיטה הזו מעבירה מחרוזות של מטא-נתונים שמוכנות לעיבוד ל-SDK. הוא מקבל ארגומנט יחיד:
metadata
: אובייקט שמכיל מפתח מסוגTXXX
עם ערך מחרוזת משויך שמתחיל ב-google_
.
- processMetadata
השיטה הזו מתזמנת מחרוזות של מטא-נתונים לעיבוד על ידי ה-SDK אחרי הערך שצוין ב-PTS. הפונקציה מקבלת את הארגומנטים הבאים:
type
: מחרוזת שמכילה את סוג האירוע שעובד. הערכים הקבילים הםID3
עבור HLS אוurn:google:dai:2018
עבור DASHdata
: ערך מחרוזת עם הקידומתgoogle_
או מערך בייטים לפי הפורמט הזהID3:u\0004u\000u\000u\0000TXXXu\0004u\000u\000u\0000google_xxxxxxxx
.timestamp
: חותמת הזמן בשניות שבה צריך לעבד את הנתונים.
כל סוג של שידור שנתמך על ידי IMA DAI SDK משתמש בצורה ייחודית של מטא-נתונים מתוזמנים, כפי שמתואר בקטעים הבאים.
מקורות נתונים מסוג HLS MPEG2TS
בשידורי HLS לינארי עם DAI שמשתמשים בפלחים MPEG2TS, המטא-נתונים המתוזמנים מועברים לנגן הווידאו באמצעות תגי ID3 בפס. תגי ה-ID3 האלה מוטמעים בקטעי ה-MPEG2TS ומקבלים את שם השדה TXXX (לתכנים מותאמים אישית של טקסט).
הפעלה ב-Safari
תגי ה-ID3 עוברים עיבוד באופן אוטומטי ב-Safari כטראק מוסתר, כך שאירועי שינוי קטעים יופעלו בזמן הנכון כדי לעבד כל מקטע של מטא-נתונים. מותר להעביר את כל המטא-נתונים ל-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
בשידורי 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 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
בשידורי DASH עם DAI לינארי, המטא-נתונים מועברים כאירועי מניפסט במקור אירועים עם הערך המותאם אישית 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
אירועים מוצגים ב-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
להצגת Pod יש הגדרות שונות להעברת מטא-נתונים מתוזמנים, בהתאם לקריטריונים הבאים:
- סוג השידור: חי או VOD
- פורמט הסטרימינג: HLS או DASH
- סוג הנגן שבו נעשה שימוש
- סוג הקצה העורפי של DAI שבו נעשה שימוש
פורמט של שידור HLS (שידורים חיים ושידורי VOD, נגן 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, סוג של שידור חי ו-VOD)
אם אתם משתמשים בנגן DASH.js, עליכם להשתמש במחרוזות שונות כדי להאזין למטא-נתונים של ID3 בסטרימינג בשידור חי או בסטרימינג של VOD:
- שידורים חיים:
'https://developer.apple.com/streaming/emsg-id3'
- שידורי VOD:
'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 עם שידורים חיים (פורמט של שידורי 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);
}
}