(function ($) {
// Set default variable values.
AblePlayer.prototype.setDefaults = function () {
// this.playing will change to true after 'playing' event is triggered
this.playing = false;
this.getUserAgent();
this.setIconColor();
this.setButtonImages();
};
AblePlayer.prototype.getRootPath = function() {
// returns Able Player root path (assumes ableplayer.js is in /build, one directory removed from root)
var scripts, i, scriptSrc, scriptFile, fullPath, ablePath, parentFolderIndex, rootPath;
scripts= document.getElementsByTagName('script');
for (i=0; i < scripts.length; i++) {
scriptSrc = scripts[i].src;
scriptFile = scriptSrc.substr(scriptSrc.lastIndexOf('/'));
if (scriptFile.indexOf('ableplayer') !== -1) {
// this is the ableplayerscript
fullPath = scriptSrc.split('?')[0]; // remove any ? params
break;
}
}
ablePath= fullPath.split('/').slice(0, -1).join('/'); // remove last filename part of path
parentFolderIndex = ablePath.lastIndexOf('/');
rootPath = ablePath.substring(0, parentFolderIndex) + '/';
return rootPath;
}
AblePlayer.prototype.setIconColor = function() {
// determine the best color choice (white or black) for icons,
// given the background-color of their container elements
// Source for relative luminance formula:
// https://en.wikipedia.org/wiki/Relative_luminance
// We need to know the color *before* creating the element
// so the element doesn't exist yet when this function is called
// therefore, need to create a temporary element then remove it after color is determined
// Temp element must be added to the DOM or WebKit can't retrieve its CSS properties
var $elements, i, $el, bgColor, rgb, red, green, blue, luminance, iconColor;
$elements = ['controller', 'toolbar'];
for (i=0; i<$elements.length; i++) {
if ($elements[i] == 'controller') {
$el = $('
', {
'class': 'able-window-toolbar'
}).hide();
}
$('body').append($el);
bgColor = $el.css('background-color');
// bgColor is a string in the form 'rgb(R, G, B)', perhaps with a 4th item for alpha;
// split the 3 or 4 channels into an array
rgb = bgColor.replace(/[^\d,]/g, '').split(',');
red = rgb[0];
green = rgb[1];
blue = rgb[2];
luminance = (0.2126 * red) + (0.7152 * green) + (0.0722 * blue);
// range is 1 - 255; therefore 125 is the tipping point
if (luminance < 125) { // background is dark
iconColor = 'white';
}
else { // background is light
iconColor = 'black';
}
if ($elements[i] === 'controller') {
this.iconColor = iconColor;
}
else if ($elements[i] === 'toolbar') {
this.toolbarIconColor = iconColor;
}
$el.remove();
}
};
AblePlayer.prototype.setButtonImages = function() {
// NOTE: volume button images are now set dynamically within volume.js
this.imgPath = this.rootPath + 'button-icons/' + this.iconColor + '/';
this.playButtonImg = this.imgPath + 'play.png';
this.pauseButtonImg = this.imgPath + 'pause.png';
this.restartButtonImg = this.imgPath + 'restart.png';
this.rewindButtonImg = this.imgPath + 'rewind.png';
this.forwardButtonImg = this.imgPath + 'forward.png';
this.previousButtonImg = this.imgPath + 'previous.png';
this.nextButtonImg = this.imgPath + 'next.png';
if (this.speedIcons === 'arrows') {
this.fasterButtonImg = this.imgPath + 'slower.png';
this.slowerButtonImg = this.imgPath + 'faster.png';
}
else if (this.speedIcons === 'animals') {
this.fasterButtonImg = this.imgPath + 'rabbit.png';
this.slowerButtonImg = this.imgPath + 'turtle.png';
}
this.captionsButtonImg = this.imgPath + 'captions.png';
this.chaptersButtonImg = this.imgPath + 'chapters.png';
this.signButtonImg = this.imgPath + 'sign.png';
this.transcriptButtonImg = this.imgPath + 'transcript.png';
this.descriptionsButtonImg = this.imgPath + 'descriptions.png';
this.fullscreenExpandButtonImg = this.imgPath + 'fullscreen-expand.png';
this.fullscreenCollapseButtonImg = this.imgPath + 'fullscreen-collapse.png';
this.prefsButtonImg = this.imgPath + 'preferences.png';
this.helpButtonImg = this.imgPath + 'help.png';
};
// Initialize player based on data on page.
// This sets some variables, but does not modify anything. Safe to call multiple times.
// Can call again after updating this.media so long as new media element has the same ID.
AblePlayer.prototype.reinitialize = function () {
var deferred, promise, thisObj, errorMsg, srcFile;
deferred = new $.Deferred();
promise = deferred.promise();
thisObj = this;
// if F12 Developer Tools aren't open in IE (through 9, no longer a problen in IE10)
// console.log causes an error - can't use debug without a console to log messages to
if (! window.console) {
this.debug = false;
}
this.startedPlaying = false;
// TODO: Move this setting to cookie.
this.autoScrollTranscript = true;
//this.autoScrollTranscript = this.getCookie(autoScrollTranscript); // (doesn't work)
// Bootstrap from this.media possibly being an ID or other selector.
this.$media = $(this.media).first();
this.media = this.$media[0];
// Set media type to 'audio' or 'video'; this determines some of the behavior of player creation.
if (this.$media.is('audio')) {
this.mediaType = 'audio';
}
else if (this.$media.is('video')) {
this.mediaType = 'video';
}
else {
this.mediaType = this.$media.get(0).tagName;
errorMsg = 'Media player initialized with ' + this.mediaType + '#' + this.mediaId + '. ';
errorMsg += 'Expecting an HTML5 audio or video element.';
this.provideFallback(errorMsg);
deferred.fail();
return promise;
}
this.$sources = this.$media.find('source');
this.player = this.getPlayer();
if (!this.player) {
// an error was generated in getPlayer()
this.provideFallback(this.error);
}
this.setIconType();
this.setDimensions();
deferred.resolve();
return promise;
};
AblePlayer.prototype.setDimensions = function() {
// if