Created
September 12, 2015 22:54
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/***** | |
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