טיפול במטא-נתונים מתוזמנים בשידורים לינאריים של הטמעת מודעות דינמיות (DAI)

ה-SDK של מודעות מדיה אינטראקטיביות (IMA) מבוסס על פרטי מטא-נתונים שמוטמעים בפלחי המדיה של השידור (מטא-נתונים בתוך הרצועה), או בקובץ המניפסט של השידור (מטא-נתונים במניפסט) כדי לעקוב אחרי מיקומי הצופים ואירועי מודעות בצד הלקוח. המטא-נתונים נשלחים בפורמטים שונים, בהתאם לסוג השידור שמופעל.

נגן הווידאו מקבל מטא-נתונים מתוזמנים באצוות. בהתאם לנגן, אפשר להציג מטא-נתונים במועד שנקבע, או בקבוצות. לכל מחרוזת של מטא-נתונים יש חותמת זמן של מצגת (PTS) המשויכת למועד שבו צריך להפעיל אותה.

האפליקציה שלכם אחראית לתיעוד המטא-נתונים ולהעברתם ל-IMA DAI SDK. ה-SDK מציע את השיטות הבאות להעברת המידע הזה:

onTimedMetadata

השיטה הזו מעבירה ל-SDK מחרוזות מטא-נתונים שמוכנות לעיבוד. נדרש ארגומנט אחד:

  • metadata: אובייקט שמכיל מפתח של TXXX עם ערך מחרוזת משויך שמתחיל ב-google_.
processMetadata

השיטה הזו מתזמנת מחרוזות מטא-נתונים לעיבוד על ידי ה-SDK אחרי ה-PTS שצוין. הפונקציה לוקחת את הארגומנטים הבאים:

  • type: מחרוזת שמכילה את סוג האירוע שעובר עיבוד. הערכים הקבילים הם ID3 ל-HLS או ל-urn:google:dai:2018 ל-DASH
  • data: ערך מחרוזת עם קידומת google_ או מערך בייטים שמפענח למחרוזת כזו.
  • timestamp: חותמת הזמן בשניות שבה צריך לעבד את הנתונים.

לכל סוג של שידור שנתמך ב-IMA DAI SDK יש צורה ייחודית של מטא-נתונים מתוזמנים, כפי שמתואר בסעיפים הבאים.

שידורי HLS MPEG2TS

שידורים לינאריים של DAI HLS שמשתמשים בקטעי MPEG2TS מעבירים לנגן הווידאו מטא-נתונים מתוזמנים דרך תגי ID3 in-band. תגי 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);
    });
  }
});
...

שידורי CMAF ב-HLS

סטרימינג של DAI HLS לינארי באמצעות Common Media Application Framework (CMAF) מעביר מטא-נתונים מתוזמנים דרך תיבות eMSGv1 בגוף התדרים לפי תקן ID3 עד CMAF. תיבות ה-eMSG האלה מוטמעות בתחילת כל פלח מדיה, כאשר כל מזהה eMSG של ID3 מכיל PTS ביחס להפסקה האחרונה בשידור.

החל מגרסה 1.2.0 של HLS.js, שני השחקנים שהצענו מעבירים את ID3 באמצעות CMAF למשתמש כאילו הם תגי ID3. לכן, הדוגמאות הבאות זהות לדוגמאות של שידורים בפרוטוקול HLS MPEG2TS. עם זאת, יכול להיות שזה לא יהיה המצב אצל כל השחקנים, ולכן ייתכן שיהיה צורך בקוד ייחודי לניתוח ID3 באמצעות eMSG כדי להטמיע תמיכה בשידורי CMAF ב-HLS.

הפעלה ב-Safari

מערכת Safari מתייחסת למטא-נתונים של ID3 באמצעות eMSG כאירועים מסוג pseudo 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 כאירועים מסוג pseudo 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);
    });
  }
});
...

זרמים ב-DASH

שידורי DAI DASH לינאריים מעבירים מטא-נתונים כאירועי מניפסט בסטרימינג של אירוע, עם הערך המותאם אישית schemeIdUri ב-urn:google:dai:2018. כל אירוע בשידורים האלה מכיל מטען ייעודי (payload) של טקסט ואת ה-PTS.

DASH.js

Dash.js מספק רכיבי handler בהתאמה אישית של אירועים, שנקראים על שם ערך schemeIdUri של כל שידור אירועים. רכיבי ה-handler המותאמים אישית האלה מופעלים בכמה קבוצות, ואתם יכולים לעבד את הערך של ה-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

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, חשוב להאזין לאירוע 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().

כדי להציג באופן אוטומטי את פקדי הסרטונים כשהכל נטען ומוכן, מאזינים לאירוע 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)

אם אתם משתמשים בנגן Shaaka להפעלה של שידור חי, השתמשו במחרוזת '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)

אם אתם משתמשים בנגן Shaaka להפעלה של שידור 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);
       }
}