Skip to content

Instantly share code, notes, and snippets.

@jramsahai
Created September 12, 2015 22:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jramsahai/aafa6c0379b5d427896c to your computer and use it in GitHub Desktop.
Save jramsahai/aafa6c0379b5d427896c to your computer and use it in GitHub Desktop.
Based this off the script we use to fire player completion milestones into Google Analytics events. Really easy way to set up the player API to listen for events from all players on a page.
/*****
Purpose:
This code detects all inline embedded Vidyard players on a page and sets up the necessary event
listeners allowing you to execute code on the standard Vidyard player API events such as play,
pause, ready, etc. The script will also calculate when 0, 25, 50, 75 and 99 percent of a chapter
has been viewed and allow you to execute code at these points.
Usage:
This script should be included below the Vidyard API, web analytics tracking code (if applicable) and
all Vidyard embedded players. You can use the following line example to include it:
<script type="text/javascript" src="path/to/this/file/eventlistener.js"></script>
*****/
(function (Vidyard) {
// Stripped down version of: https://github.com/shinout/SortedList
// This part is used to determine how far a view is into a given chapter of a player
var SortedList = function SortedList() {
this._compare = function (a, b) {
if (a[0] < b[0]) {
return -1;
}
if (a[0] > b[0]) {
return 1;
}
if (a[1] < b[1]) {
return -1;
}
if (a[1] > b[1]) {
return 1;
}
return 0;
};
};
SortedList.create = function () {
return new SortedList();
};
SortedList.prototype = new Array();
SortedList.prototype.constructor = Array.prototype.constructor;
SortedList.prototype.insertOne = function (val) {
var pos = this.bsearch(val);
this.splice(pos + 1, 0, val);
return pos + 1;
};
SortedList.prototype.remove = function (pos) {
this.splice(pos, 1);
return this;
};
SortedList.prototype.bsearch = function (val) {
if (!this.length) { return -1; }
var mpos,
mval,
comp,
spos = 0,
epos = this.length;
while (epos - spos > 1) {
mpos = Math.floor((spos + epos) / 2);
mval = this[mpos];
comp = this._compare(val, mval);
if (comp === 0) { return mpos; }
if (comp > 0) {
spos = mpos;
} else { epos = mpos; }
}
return (spos === 0 && this._compare(this[0], val) > 0) ? -1 : spos;
};
function unionIntervals(sortedIntervals) {
var prevInterval = null;
var results = [];
var index;
for (index = 0; index < sortedIntervals.length; ++index) {
if (!prevInterval || prevInterval[1] < sortedIntervals[index][0]) {
if (prevInterval) {
results.push(prevInterval);
}
prevInterval = [sortedIntervals[index][0], sortedIntervals[index][1]];
} else if (sortedIntervals[index][1] > prevInterval[1]) {
prevInterval[1] = sortedIntervals[index][1];
}
}
if (prevInterval) {
results.push(prevInterval);
}
return results;
}
// Set up the player API event listeners for all players found on the page
function setEventListeners(player) {
var THRESHOLDS = [0, 25, 50, 75, 99],
thresholdsCopy = THRESHOLDS.slice(0),
interval = [0, 0],
chapter = 0,
lock = false,
intervalList = SortedList.create();
player.on("timeupdate", function (time) {
var unions,
totalViewed = 0,
checkIntervalPosition,
currTime = Math.floor(time);
if (lock || typeof player.metadata !== 'object' || (currTime <= interval[1])) {
return;
}
interval[1] = time;
checkIntervalPosition = intervalList.insertOne(interval);
unions = unionIntervals(intervalList);
var index;
for (index = 0; index < unions.length; ++index) {
totalViewed += unions[index][1] - unions[index][0];
}
intervalList.remove(checkIntervalPosition);
totalViewed = totalViewed / player.metadata.chapters_attributes[chapter].video_attributes.length_in_seconds * 100;
if (totalViewed >= thresholdsCopy[0]) {
// thresholdsCopy.shift() must be called here in some way to iterate through the percentage milestones.
// In this example, the milestones are output to the console with the player and chapter names
switch(thresholdsCopy.shift()) {
case 0:
console.log("%s in player %s has started",player.metadata.chapters_attributes[chapter].video_attributes.name,player.metadata.name);
// Code to be executed when a chapter starts
break;
case 25:
console.log("%s in player %s at 25%",player.metadata.chapters_attributes[chapter].video_attributes.name,player.metadata.name);
// Code to be executed when a chapter reaches 25%
break;
case 50:
console.log("%s in player %s at 50%",player.metadata.chapters_attributes[chapter].video_attributes.name,player.metadata.name);
// Code to be executed when a chapter reaches 50%
break;
case 75:
console.log("%s in player %s at 75%",player.metadata.chapters_attributes[chapter].video_attributes.name,player.metadata.name);
// Code to be executed when a chapter reaches 75%
break;
case 99:
// Code to be executed when a chapter ends (same as chapterComplete event below)
console.log("%s in player %s has completed",player.metadata.chapters_attributes[chapter].video_attributes.name,player.metadata.name);
break;
default:
break;
}
}
});
player.on("ready", function () {
// Code to execute on player load
});
player.on("play", function () {
// Code to execute on play
});
player.on("pause", function () {
// Code to execute on pause
});
player.on("beforeSeek", function () {
lock = true;
// Add custom code below this line:
});
player.on("seek", function (times) {
lock = false;
interval[1] = times[0];
intervalList.insertOne(interval.slice(0));
interval[0] = times[1];
interval[1] = times[1];
// Add custom code below this line:
});
player.on("chapterComplete", function () {
thresholdsCopy = THRESHOLDS.slice(0);
chapter = player.getCurrentChapter();
interval = [0, 0];
intervalList = SortedList.create();
lock = false;
// Add custom code below this line:
});
player.on("playerComplete", function () {
// Code to execute on player complete
});
player.on("volumeChange", function () {
// Code to execute on volume change
});
}
var videos, isEmpty = true;
try {
videos = new Vidyard.players();
} catch (e) {
throw new Error("The Vidyard API must be loaded before this script can execute");
}
for (var i in videos) {
if (videos.hasOwnProperty(i)) {
setEventListeners(videos[i]);
isEmpty = false;
}
}
if (isEmpty) {
console.warn("No Vidyard Players found. (include this script below player embed codes)");
}
}(Vidyard));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment