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

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

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

הטמעת DAI בפודים

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

סקירה כללית של הגשת 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/

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

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

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

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

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

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

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

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

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

  • 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

בשלב הבא, מוסיפים את ה-DAI framework באמצעות תג סקריפט ב-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);
}

הצגת רצף 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);
}

הצגת רצף VOD

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

בנוסף, כדי להציג שידורים חיים של רצף 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'

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

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