תחילת העבודה עם IMA DAI SDK

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

איך בוחרים את פתרון DAI שמעניין אתכם

הטמעת מודעות דינמיות (DAI) ב-Pod

המדריך הזה מדגים איך להפעיל שידור הצגת פודקאסטים ב-DAI בשביל תוכן בשידור חי או ב-VOD, באמצעות IMA DAI SDK ל-HTML5 עם נגן וידאו שמסתמך על hls.js להפעלה. אם אתם רוצים להציג שילוב לדוגמה מלא או לעקוב אחריו, כולל תמיכה ב-HLS.js וגם ב-Safari Playback, הדוגמה להצגת Pod של HLS. לתמיכה ב-DASH.js, ראו דוגמה להצגת Pod של DASH. אפשר להוריד את האפליקציות לדוגמה מדף ההפצה של HTML5 DAI GitHub.

סקירה כללית – הצגת מודעות Pod ב-DAI

כדי להטמיע הצגת Pod באמצעות IMA DAI SDK יש שני רכיבים עיקריים, שמודגמים במדריך הזה:

  • PodStreamRequest / PodVodStreamRequest: אובייקט שמגדיר בקשה של מקור נתונים לשרתי הפרסום של Google. הבקשות מציינות קוד רשת, וה-PodStreamRequest דורש גם מפתח נכס מותאם אישית ומפתח API אופציונלי. שניהם כוללים פרמטרים אופציונליים אחרים.

  • StreamManager: אובייקט שמטפל בתקשורת בין שידור הווידאו לבין IMA DAI SDK, למשל הפעלת פינגים של מעקב והעברת אירועים של סטרימינג אל בעל התוכן הדיגיטלי.

דרישות מוקדמות

לפני שמתחילים, צריך:

  • שלושה קבצים ריקים:

    • dai.html
    • dai.css
    • dai.js
  • שפת Python שמותקנת במחשב, או בשרת אינטרנט או בסביבת פיתוח מתארחת אחרת למטרות בדיקה

הגדרת סביבת פיתוח

מאחר שה-SDK טוען יחסי תלות באותו פרוטוקול שבו הוא נטען, צריך להשתמש בשרת אינטרנט כדי לבדוק את האפליקציה. דרך מהירה להתחיל לעבוד עם שרת פיתוח מקומי היא להשתמש בשרת המובנה של Python.

  1. באמצעות שורת הפקודה, מהספרייה שמכילה את הקובץ index.html, מריצים אותו:

    python -m http.server 8000
    
  2. בדפדפן אינטרנט, עוברים אל http://localhost:8000/

    אפשר גם להשתמש בכל סביבת פיתוח מתארחת או שרת אינטרנט אחר, כמו שרת HTTP של Apache.

יצירת נגן וידאו פשוט

קודם כול, משנים את dai.html כדי ליצור רכיב וידאו פשוט של HTML5 ו-div כדי להשתמש בו לרכיבים של ממשק המשתמש של המודעות. בנוסף, צריך להוסיף את התגים הנחוצים כדי לטעון את הקבצים dai.css ו-dai.js, וגם כדי לייבא את נגן הווידאו hls.js.

לאחר מכן, משנים את dai.css כך שיציין את הגודל והמיקום של רכיבי הדף. לבסוף, ב-dai.js, מגדירים משתנים ששומרים את הפרטים של בקשת השידור ואת הפונקציה initPlayer() שירוץ כשהדף נטען.

אלה הקבועים של בקשות השידור:

  • BACKUP_STREAM: כתובת ה-URL להפעלת סטרימינג לגיבוי במקרה שתהליך המודעות נתקל בשגיאה חמורה.

  • STREAM_URL: משמש רק בשידורים חיים. כתובת ה-URL של שידור הווידאו שסופקה על ידי הכלי לניהול המניפסט או שותף הצד השלישי באמצעות הצגת Pod. לפני ששולחים בקשה, צריך להזין את מזהה מקור הנתונים שסופק על ידי IMA DAI SDK. במקרה הזה, כתובת ה-URL של מקור הנתונים כוללת placeholder, [[STREAMID]], שיוחלף במזהה מקור הנתונים לפני שליחת הבקשה.

  • NETWORK_CODE: קוד הרשת של חשבון Ad Manager 360.

  • CUSTOM_ASSET_KEY: משמש רק בשידורים חיים. מפתח הנכס בהתאמה אישית שמזהה את אירוע הצגת ה-Pod ב-Ad Manager 360. אפשר ליצור אותו באמצעות הכלי לניהול המניפסט או שותף צד שלישי להצגת pod.

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

dai.html

<html>
<head>
  <script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
  <script src="dai.js"></script>
  <link rel="stylesheet" href="dai.css" type="text/css">
</head>
<body onLoad="initPlayer()">
  <h2>IMA DAI SDK Demo (HLS.JS)</h2>
    <video id="video"></video>
    <div id="ad-ui"></div>
</body>
</html>

dai.css

#video,
#ad-ui {
  width: 640px;
  height: 360px;
  position: absolute;
  top: 35px;
  left: 0;
}

#ad-ui {
  cursor: pointer;
}

dai.js

var BACKUP_STREAM =
    'https://storage.googleapis.com/interactive-media-ads/media/bbb.m3u8'

// Stream Config.
const STREAM_URL = "https://encodersim.sandbox.google.com/masterPlaylist/...&stream_id=[[STREAMID]]";
const NETWORK_CODE = "51636543";
const CUSTOM_ASSET_KEY = "google-sample";
const API_KEY = "";

var hls = new Hls(); // hls.js video player
var videoElement;
var adUiElement;

function initPlayer() {
  videoElement = document.getElementById('video');
  adUiElement = document.getElementById('adUi');
}

טעינת IMA DAI SDK

בשלב הבא, מוסיפים את ה-framework של DAI באמצעות תג סקריפט ב-dai.html, לפני התג של dai.js.

dai.html

<html>
<head>
  <script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
  <script type="text/javascript" src="//imasdk.googleapis.com/js/sdkloader/ima3_dai.js"></script>
  <script src="dai.js"></script>
  <link rel="stylesheet" href="dai.css" type="text/css">
</head>
...

הפעלת StreamManager ושליחת בקשה לשידור חי או ל-VOD

הצגת פודקאסטים בשידור חי

כדי לבקש קבוצה של מודעות, צריך ליצור ima.dai.api.StreamManager, שאחראי על הבקשה והניהול של מקורות הנתונים של DAI. ה-constructor לוקח רכיב וידאו, והמופע שמתקבל לוקח רכיב בממשק המשתמש של המודעה כדי לטפל באינטראקציות עם מודעות.

לאחר מכן, מגדירים פונקציה כדי לבקש שידור חי של הצגת Pod. הפונקציה הזו יוצרת קודם PodStreamRequest, מגדירה אותו עם הפרמטרים StreamRequest שסופקו בשלב 2, ולאחר מכן קוראת ל-streamManager.requestStream() עם אובייקט הבקשה הזה.

dai.js

function initPlayer() {
  videoElement = document.getElementById('video');
  adUiElement = document.getElementById('adUi');
  streamManager = new google.ima.dai.api.StreamManager(videoElement, adUiElement)

  requestLivePodStream(NETWORK_CODE, CUSTOM_ASSET_KEY, API_KEY);
}

function requestLivePodStream(networkCode, customAssetKey, apiKey) {
  // clear HLS.js instance, if in use
  if (hls) {
    hls.destroy();
  }

  // Generate a Pod Serving live Stream Request
  const streamRequest = new google.ima.dai.api.PodStreamRequest();
  streamRequest.networkCode = networkCode;
  streamRequest.customAssetKey = customAssetKey;
  streamRequest.apiKey = apiKey;
  streamRequest.format = 'hls';
  streamManager.requestStream(streamRequest);
}

מילוי בקשות Pod של VOD

כדי לבקש קבוצה של מודעות, צריך ליצור ima.dai.api.StreamManager, שאחראי על הבקשה והניהול של מקורות הנתונים של DAI. ה-constructor לוקח רכיב וידאו, והמופע שמתקבל לוקח רכיב בממשק המשתמש של המודעה כדי לטפל באינטראקציות עם מודעות.

לאחר מכן מגדירים פונקציה שמבקשת את ה-pod שמציג את שידור ה-VOD. הפונקציה הזו יוצרת קודם PodVodStreamRequest, מגדירה אותו עם הפרמטרים StreamRequest שסופקו בשלב 2, ולאחר מכן קוראת ל-streamManager.requestStream() עם אובייקט הבקשה הזה.

dai.js

function initPlayer() {
  videoElement = document.getElementById('video');
  adUiElement = document.getElementById('adUi');
  streamManager = new google.ima.dai.api.StreamManager(videoElement, adUiElement)

  requestVodPodStream(NETWORK_CODE);
}

function requestVodPodStream(networkCode) {
  // clear HLS.js instance, if in use
  if (hls) {
    hls.destroy();
  }

  // Generate a Pod Serving VOD Stream Request
  const streamRequest = new google.ima.dai.api.PodVodStreamRequest();
  streamRequest.networkCode = networkCode;
  streamRequest.format = 'hls';
  streamManager.requestStream(streamRequest);
}

טיפול באירועים שמשודרים בסטרימינג

הצגת פודקאסטים בשידור חי

בשלב הבא, מטמיעים פונקציות event listener לאירועי וידאו גדולים. הדוגמה הזו מטפלת באירועים STREAM_INITIALIZED, ERROR, AD_BREAK_STARTED ו-AD_BREAK_ENDED על ידי שליחת קריאה לפונקציה onStreamEvent(). הפונקציה הזו מטפלת בטעינה של סטרימינג ובשגיאות, וגם משביתה את לחצני הנגן בזמן הצגת מודעה, פעולה שנדרשת על ידי ה-SDK. כשהשידור נטען, נגן הווידאו טוען ומפעיל את כתובת ה-URL שסופקה באמצעות הפונקציה loadStream().

dai.js

var isAdBreak;

function initPlayer() {
  videoElement = document.getElementById('video');
  adUiElement = document.getElementById('adUi');
  streamManager = new google.ima.dai.api.StreamManager(videoElement, adUiElement);
  
  streamManager.addEventListener(
    [google.ima.dai.api.StreamEvent.Type.STREAM_INITIALIZED,
    google.ima.dai.api.StreamEvent.Type.ERROR,
    google.ima.dai.api.StreamEvent.Type.AD_BREAK_STARTED,
    google.ima.dai.api.StreamEvent.Type.AD_BREAK_ENDED],
    onStreamEvent,
    false);
...
function onStreamEvent(e) {
  switch (e.type) {
    case google.ima.dai.api.StreamEvent.Type.STREAM_INITIALIZED:
      console.log('Stream initialized');
      loadStream(e.getStreamData().streamId);
      break;
    case google.ima.dai.api.StreamEvent.Type.ERROR:
      console.log('Error loading stream, playing backup stream.' + e);
      loadStream('');
      break;
    case google.ima.dai.api.StreamEvent.Type.AD_BREAK_STARTED:
      console.log('Ad Break Started');
      isAdBreak = true;
      videoElement.controls = false;
      adUiElement.style.display = 'block';
      break;
    case google.ima.dai.api.StreamEvent.Type.AD_BREAK_ENDED:
      console.log('Ad Break Ended');
      isAdBreak = false;
      videoElement.controls = true;
      adUiElement.style.display = 'none';
      break;
    default:
      break;
  }
}

function loadStream(streamID) {
  var url;
  if(streamID) {
    url = STREAM_URL.replace('[[STREAMID]]', streamID);
  } else {
    console.log('Stream Initialization Failed');
    url = BACKUP_STREAM;
  }
  console.log('Loading:' + url);
  hls.loadSource(url);
  hls.attachMedia(videoElement);
}

מילוי בקשות Pod של VOD

בשלב הבא, מטמיעים פונקציות event listener לאירועי וידאו גדולים. הדוגמה הזו מטפלת באירועים STREAM_INITIALIZED, LOADED, ERROR, AD_BREAK_STARTED ו-AD_BREAK_ENDED על ידי שליחת קריאה לפונקציה onStreamEvent(). הפונקציה הזו מטפלת בטעינה ובשגיאות של השידור, וגם משביתה את לחצני הנגן בזמן הצגת מודעה, בהתאם לדרישות של ה-SDK.

בנוסף, כדי לשדר Pod של VOD, צריך להפעיל StreamManager.loadStreamMetadata() בתגובה לאירוע STREAM_INITIALIZED. בנוסף, אתם צריכים לבקש את כתובת ה-URL של השידור מהשותף שלכם לטכנולוגיית וידאו (VTP). כשהקריאה ל-loadStreamMetadata() מצליחה, היא מפעילה אירוע LOADED, שבו צריך לקרוא לפונקציה loadStream() עם כתובת ה-URL של השידור כדי לטעון ולהפעיל את השידור.

var isAdBreak;

function initPlayer() {
  videoElement = document.getElementById('video');
  adUiElement = document.getElementById('adUi');
  streamManager = new google.ima.dai.api.StreamManager(videoElement, adUiElement);
  
  streamManager.addEventListener(
    [google.ima.dai.api.StreamEvent.Type.STREAM_INITIALIZED,
    google.ima.dai.api.StreamEvent.Type.ERROR,
    google.ima.dai.api.StreamEvent.Type.AD_BREAK_STARTED,
    google.ima.dai.api.StreamEvent.Type.AD_BREAK_ENDED],
    onStreamEvent,
    false);
...
function onStreamEvent(e) {
  switch (e.type) {
    case google.ima.dai.api.StreamEvent.Type.STREAM_INITIALIZED:
      const streamId = e.getStreamData().streamId;
      // 'vtpInterface' is a place holder for your own video technology
      //  partner (VTP) API calls.
      vtpInterface.requestStreamURL({
        'streamId': streamId,
      })
      .then( (vtpStreamUrl) => {
        streamUrl = vtpStreamUrl;
        streamManager.loadStreamMetadata();
      }, (error) => {
        // Handle the error.
      });
      break;
    case google.ima.dai.api.StreamEvent.Type.LOADED:
      loadStream(streamUrl);
      break;
    case google.ima.dai.api.StreamEvent.Type.ERROR:
      console.log('Error loading stream, playing backup stream.' + e);
      loadStream();
      break;
    case google.ima.dai.api.StreamEvent.Type.AD_BREAK_STARTED:
      console.log('Ad Break Started');
      isAdBreak = true;
      videoElement.controls = false;
      adUiElement.style.display = 'block';
      break;
    case google.ima.dai.api.StreamEvent.Type.AD_BREAK_ENDED:
      console.log('Ad Break Ended');
      isAdBreak = false;
      videoElement.controls = true;
      adUiElement.style.display = 'none';
      break;
    default:
      break;
  }
}

function loadStream(url) {
  if(url) {
    console.log('Loading:' + url);
    hls.loadSource(url);
  } else {
    console.log('Stream Initialization Failed');
    hls.loadSource(BACKUP_STREAM);
  }
  hls.attachMedia(videoElement);
}

טיפול במטא-נתונים של השידור

בשלב הזה תטמיעו פונקציות event listener למטא-נתונים שיודיעו ל-SDK כשאירועי מודעות מתרחשים. אופן ההאזנה לאירועי מטא-נתונים של מודעות וידאו In-stream עשוי להשתנות בהתאם לפורמט השידור (HLS או DASH), לסוג השידור (שידור חי או VOD), סוג הנגן וסוג הקצה העורפי של 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'

מעבירים את המטא-נתונים של המזהה 3 ל-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 להפעלה של סטרימינג בשידור חי, תוכלו להשתמש במחרוזת '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 להפעלה של שידור 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);
       }
}

טיפול באירועי שחקן

מוסיפים פונקציות event listener לאירועים pause ו-start של רכיב הווידאו כדי לאפשר למשתמשים להמשיך את ההפעלה כשה-SDK מושהה בזמן ההפסקות למודעות.

function loadStream(streamUrl) {
  ...
  
  videoElement.addEventListener('pause', onStreamPause);
  videoElement.addEventListener('play', onStreamPlay);
}

function onStreamPause() {
  console.log('paused');
  if (isAdBreak) {
    videoElement.controls = true;
    adUiElement.style.display = 'none';
  }
}

function onStreamPlay() {
  console.log('played');
  if (isAdBreak) {
    videoElement.controls = false;
    adUiElement.style.display = 'block';
  }
}

זהו! עכשיו אתם מבקשים ולהציג מודעות בזרם הצגת Pod עם IMA DAI SDK ל-HTML5. מידע נוסף על תכונות SDK מתקדמות יותר מופיע במדריכים הנוספים או בדוגמאות ב-GitHub.