הגדרת מחלקת השחקנים

ב-video_player.js, מגדירים מחלקה של wrapper לנגן וידאו כדי להפעיל ולשלוט בנגן dash.js.

הגדרת הנגן של פס רחב

כדי להגדיר איפה באפליקציה להציב את נגן הפס הרחב, יוצרים תגי וידאו ותגי wrapper:

<div id="broadband-wrapper">
    <video id="broadband-video"></video>
</div>

יצירת נגן הווידאו

מאתחלים את המחלקה של נגן הווידאו עם משתנים לרכיבי HTML, לנגן dash.js ולקריאות חוזרות ששיטות אחרות של המחלקה יכולות להשתמש בהן.

/**
 * Video player wrapper class to control ad creative playback with dash.js in
 * broadband.
 */
var VideoPlayer = function() {
  this.videoElement = document.querySelector('video');
  this.broadbandWrapper = document.getElementById('broadband-wrapper');
  this.player = dashjs.MediaPlayer().create();
  this.onAdPodEndedCallback = null;

  // Function passed in VideoPlayer.prototype.setEmsgEventHandler.
  this.onCustomEventHandler = null;
  //  Scope (this) passed in VideoPlayer.prototype.setEmsgEventHandler.
  this.customEventHandlerScope = null;

  // Function to remove all of player event listeners.
  this.cleanUpPlayerListener = null;
  debugView.log('Player: Creating dash.js player');
};

הגדרת הפונקציות של פקד ההפעלה

כדי להציג את נגן המודעות ולצרף את נתוני הצפייה בסרטון, צריך ליצור את VideoPlayer.play() השיטה. לאחר מכן, יוצרים את שיטת VideoPlayer.stop() כדי לטפל בניקוי אחרי שמודעות פוד מסתיימות.

/** Starts playback of ad stream. */
VideoPlayer.prototype.play = function() {
  debugView.log('Player: Start playback');
  this.show();
  this.player.attachView(this.videoElement);
};

/** Stops ad stream playback and deconstructs player. */
VideoPlayer.prototype.stop = function() {
  debugView.log('Player: Request to stop player');
  if (this.cleanUpPlayerListener) {
    this.cleanUpPlayerListener();
  }
  this.player.reset();
  this.player.attachView(null);
  this.player.attachSource(null);
  this.player = null;
  this.hide();
};

טעינה מראש של מניפסט של שידור מודעות

כדי לוודא שהמודעות נטענות מספיק זמן במהלך שידור התוכן ולפני תחילת ההפסקה המסחרית, אפשר להשתמש ב-VideoPlayer.preload() וב-VideoPlayer.isPreloaded().

1. טעינה מראש של שידור המודעה

יוצרים את השיטה VideoPlayer.preload() לטעינה מראש של מניפסט של שידור מודעות וליצירת מאגר מודעות לפני הפסקת פרסומות. צריך לעדכן את הגדרות הסטרימינג של הנגן 'cacheInitSegments' ל-true. עדכון ההגדרות מאפשר שמירה במטמון של פלחי ההפעלה, וכך נמנעים עיכובים במעבר למודעות.

/**
 * Starts ad stream prefetching into Media Source Extensions (MSE) buffer.
 * @param {string} url manifest url for ad stream playback.
 */
VideoPlayer.prototype.preload = function(url) {
  if (!this.player) {
    this.player = dashjs.MediaPlayer().create();
  }
  debugView.log('Player: init with ' + url);
  this.player.initialize(/* HTMLVideoElement */ null, url, /* autoplay */ true);

  this.player.updateSettings({
    'debug': {
      'logLevel': dashjs.Debug.LOG_LEVEL_WARNING,
      'dispatchEvent': true,  // flip to false to hide all debug events.
    },
    'streaming': {
      'cacheInitSegments': true,
    }
  });
  this.player.preload();
  this.attachPlayerListener();
  debugView.log('Player: Pre-loading into MSE buffer');
};

2. בדיקת מאגר המודעות שנטענו מראש

יוצרים את השיטה VideoPlayer.isPreloaded() כדי לבדוק אם נטען מראש מספיק מאגר של מודעות בהשוואה לסף מאגר שהוגדר באפליקציה:

// Ads will only play with 10 or more seconds of ad loaded.
var MIN_BUFFER_THRESHOLD = 10;
/**
 * Checks if the ad is preloaded and ready to play.
 * @return {boolean} whether the ad buffer level is sufficient.
 */
VideoPlayer.prototype.isPreloaded = function() {
  var currentBufferLevel = this.player.getDashMetrics()
      .getCurrentBufferLevel('video', true);
  return currentBufferLevel >= MIN_BUFFER_THRESHOLD;
};

צירוף פונקציות listener לנגן

כדי להוסיף מאזינים לאירועים של נגן dash.js, יוצרים את השיטה VideoPlayer.attachPlayerListener(): PLAYBACK_PLAYING,‏ PLAYBACK_ENDED,‏ LOG ו-ERROR. השיטה הזו מטפלת גם באירועים של מזהה הסכימה URI, בנוסף להגדרת פונקציית הניקוי להסרת מאזינים אלה.

var SCHEME_ID_URI = 'https://developer.apple.com/streaming/emsg-id3';
/** Attaches event listener for various dash.js events.*/
VideoPlayer.prototype.attachPlayerListener = function() {
  var playingHandler = function() {
    this.onAdPodPlaying();
  }.bind(this);
  this.player.on(dashjs.MediaPlayer.events['PLAYBACK_PLAYING'], playingHandler);
  var endedHandler = function() {
    this.onAdPodEnded();
  }.bind(this);
  this.player.on(dashjs.MediaPlayer.events['PLAYBACK_ENDED'], endedHandler);
  var logHandler = function(e) {
    this.onLog(e);
  }.bind(this);
  this.player.on(dashjs.MediaPlayer.events['LOG'], logHandler);
  var errorHandler = function(e) {
    this.onAdPodError(e);
  }.bind(this);
  this.player.on(dashjs.MediaPlayer.events['ERROR'], errorHandler);

  var customEventHandler = null;
  if (this.onCustomEventHandler) {
    customEventHandler =
        this.onCustomEventHandler.bind(this.customEventHandlerScope);
    this.player.on(SCHEME_ID_URI, customEventHandler);
  }

  this.cleanUpPlayerListener = function() {
    this.player.off(
        dashjs.MediaPlayer.events['PLAYBACK_PLAYING'], playingHandler);
    this.player.off(dashjs.MediaPlayer.events['PLAYBACK_ENDED'], endedHandler);
    this.player.off(dashjs.MediaPlayer.events['LOG'], logHandler);
    this.player.off(dashjs.MediaPlayer.events['ERROR'], errorHandler);
    if (customEventHandler) {
      this.player.off(SCHEME_ID_URI, customEventHandler);
    }
  };
};

הגדרת קריאות חוזרות (callbacks) לאירועים של נגן

כדי לנהל את ההפעלה של רצף המודעות על סמך אירועים של נגן, צריך ליצור את השיטות VideoPlayer.onAdPodPlaying(), VideoPlayer.onAdPodEnded() ו-VideoPlayer.onAdPodError():

/**
 * Called when ad stream playback buffered and is playing.
 */
VideoPlayer.prototype.onAdPodPlaying = function() {
  debugView.log('Player: Ad Playback started');
};

/**
 * Called when ad stream playback has been completed.
 * Will call the restart of broadcast stream.
 */
VideoPlayer.prototype.onAdPodEnded = function() {
  debugView.log('Player: Ad Playback ended');
  this.stop();
  if (this.onAdPodEndedCallback) {
    this.onAdPodEndedCallback();
  }
};

/**
 * @param {!Event} event The error event to handle.
 */
VideoPlayer.prototype.onAdPodError = function(event) {
  debugView.log('Player: Ad Playback error from dash.js player.');
  this.stop();
  if (this.onAdPodEndedCallback) {
    this.onAdPodEndedCallback();
  }
};

יצירת פונקציית setter לאירוע onAdPodEnded

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

/**
 * Sets a callback function for when an ad pod has ended.
 * @param {!Function} callback Callback function.
 */
VideoPlayer.prototype.setOnAdPodEnded = function(callback) {
  this.onAdPodEndedCallback = callback;
};

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

כדי להגדיר פונקציית קריאה חוזרת שפועלת על סמך אירועי emsg, צריך ליצור את השיטה VideoPlayer.setEmsgEventHandler(). במדריך הזה, צריך לכלול את הפרמטר scope כי מפעילים את setEmsgEventHandler() מחוץ ל-video_player.js.

/**
 * Sets emsg event handler.
 * @param {!Function} customEventHandler Event handler.
 * @param {!Object} scope JS scope in which event handler function is called.
 */
VideoPlayer.prototype.setEmsgEventHandler = function(
    customEventHandler, scope) {
  this.onCustomEventHandler = customEventHandler;
  this.customEventHandlerScope = scope;
};

הצגה והסתרה של נגן הווידאו בהפסקות הפרסום

כדי להציג את נגן הווידאו במהלך הפסקות הפרסום ולהסתיר את הנגן אחרי שהפסקת הפרסום מסתיימת, יוצרים את השיטות VideoPlayer.show() ו-VideoPlayer.hide():

/** Shows the video player. */
VideoPlayer.prototype.show = function() {
  debugView.log('Player: show');
  this.broadbandWrapper.style.display = 'block';
};

/** Hides the video player. */
VideoPlayer.prototype.hide = function() {
  debugView.log('Player: hide');
  this.broadbandWrapper.style.display = 'none';
};

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