/**
* jwplayer.html5 namespace
*
* @author pablo
*/
(function(jwplayer) {
jwplayer.html5 = {};
jwplayer.html5.version = '6.12.0';
// These 'reset' styles must be included before any others
var _css = jwplayer.utils.css;
var JW_CLASS = '.jwplayer ';
var helperString = [JW_CLASS, 'div', 'span', 'a', 'img', 'ul', 'li', 'video'].join(', ' + JW_CLASS);
_css(helperString + ', .jwclick', {
margin: 0,
padding: 0,
border: 0,
color: '#000000',
'font-size': '100%',
font: 'inherit',
'vertical-align': 'baseline',
'background-color': 'transparent',
'text-align': 'left',
'direction': 'ltr',
'line-height': 20,
'-webkit-tap-highlight-color': 'rgba(255, 255, 255, 0)'
});
// Reset box-sizing to default for player and all sub-elements
// Note: If we use pseudo elements we will need to add *:before and *:after
_css(JW_CLASS + ',' + JW_CLASS + '*', { 'box-sizing': 'content-box'});
// Browsers use border-box as a the default box-sizing for many form elements
_css(JW_CLASS + '* button,' + JW_CLASS + '* input,' + JW_CLASS + '* select,' + JW_CLASS + '* textarea',
{ 'box-sizing': 'border-box'});
_css(JW_CLASS + 'ul', {
'list-style': 'none'
});
// These rules allow click and hover events to reach the provider, instead
// of being blocked by the controller element
// ** Note : pointer-events will not work on IE < 11
_css('.jwplayer .jwcontrols', {
'pointer-events': 'none'
});
_css('.jwplayer.jw-user-inactive .jwcontrols', {
'pointer-events': 'all'
});
var acceptClicks = [
'.jwplayer .jwcontrols .jwdockbuttons',
'.jwplayer .jwcontrols .jwcontrolbar',
'.jwplayer .jwcontrols .jwskip',
'.jwplayer .jwcontrols .jwdisplayIcon', // play and replay button
'.jwplayer .jwcontrols .jwpreview', // poster image
'.jwplayer .jwcontrols .jwlogo'
];
_css(acceptClicks.join(', '), {
'pointer-events' : 'all'
});
})(jwplayer);
/**
* HTML5-only utilities for the JW Player.
*
* @author pablo
* @version 6.0
*/
(function(utils) {
var DOCUMENT = document;
/**
* Cleans up a css dimension (e.g. '420px') and returns an integer.
*/
utils.parseDimension = function(dimension) {
if (typeof dimension === 'string') {
if (dimension === '') {
return 0;
} else if (dimension.lastIndexOf('%') > -1) {
return dimension;
}
return parseInt(dimension.replace('px', ''), 10);
}
return dimension;
};
/** Format the elapsed / remaining text. **/
utils.timeFormat = function(sec) {
if (sec > 0) {
var hrs = Math.floor(sec / 3600),
mins = Math.floor((sec - hrs * 3600) / 60),
secs = Math.floor(sec % 60);
return (hrs ? hrs + ':' : '') + (mins < 10 ? '0' : '') + mins + ':' + (secs < 10 ? '0' : '') + secs;
} else {
return '00:00';
}
};
utils.bounds = function(element) {
var bounds = {
left: 0,
right: 0,
width: 0,
height: 0,
top: 0,
bottom: 0
};
if (!element || !DOCUMENT.body.contains(element)) {
return bounds;
}
if (element.getBoundingClientRect) {
var rect = element.getBoundingClientRect(element),
scrollOffsetY = window.pageYOffset,
scrollOffsetX = window.pageXOffset;
if (!rect.width && !rect.height && !rect.left && !rect.top) {
//element is not visible / no layout
return bounds;
}
bounds.left = rect.left + scrollOffsetX;
bounds.right = rect.right + scrollOffsetX;
bounds.top = rect.top + scrollOffsetY;
bounds.bottom = rect.bottom + scrollOffsetY;
bounds.width = rect.right - rect.left;
bounds.height = rect.bottom - rect.top;
} else {
/*jshint -W084 */ // For the while loop assignment
bounds.width = element.offsetWidth | 0;
bounds.height = element.offsetHeight | 0;
do {
bounds.left += element.offsetLeft | 0;
bounds.top += element.offsetTop | 0;
} while (element = element.offsetParent);
bounds.right = bounds.left + bounds.width;
bounds.bottom = bounds.top + bounds.height;
}
return bounds;
};
utils.empty = function(element) {
if (!element) {
return;
}
while (element.childElementCount > 0) {
element.removeChild(element.children[0]);
}
};
})(jwplayer.utils);
(function(utils) {
/*jshint maxparams:6*/
/** Stretching options **/
var _stretching = utils.stretching = {
NONE: 'none',
FILL: 'fill',
UNIFORM: 'uniform',
EXACTFIT: 'exactfit'
};
utils.scale = function(domelement, xscale, yscale, xoffset, yoffset) {
var value = '';
// Set defaults
xscale = xscale || 1;
yscale = yscale || 1;
xoffset = xoffset | 0;
yoffset = yoffset | 0;
if (xscale !== 1 || yscale !== 1) {
value = 'scale(' + xscale + ', ' + yscale + ')';
}
if (xoffset || yoffset) {
if (value) {
value += ' ';
}
value = 'translate(' + xoffset + 'px, ' + yoffset + 'px)';
}
utils.transform(domelement, value);
};
/**
* Stretches domelement based on stretching. parentWidth, parentHeight,
* elementWidth, and elementHeight are required as the elements dimensions
* change as a result of the stretching. Hence, the original dimensions must
* always be supplied.
*
* @param {String}
* stretching
* @param {DOMElement}
* domelement
* @param {Number}
* parentWidth
* @param {Number}
* parentHeight
* @param {Number}
* elementWidth
* @param {Number}
* elementHeight
*/
utils.stretch = function(stretching, domelement, parentWidth, parentHeight, elementWidth, elementHeight) {
if (!domelement) {
return false;
}
if (!parentWidth || !parentHeight || !elementWidth || !elementHeight) {
return false;
}
stretching = stretching || _stretching.UNIFORM;
var xscale = Math.ceil(parentWidth / 2) * 2 / elementWidth,
yscale = Math.ceil(parentHeight / 2) * 2 / elementHeight,
video = (domelement.tagName.toLowerCase() === 'video'),
scale = false,
stretchClass = 'jw' + stretching.toLowerCase();
switch (stretching.toLowerCase()) {
case _stretching.FILL:
if (xscale > yscale) {
yscale = xscale;
} else {
xscale = yscale;
}
scale = true;
break;
case _stretching.NONE:
xscale = yscale = 1;
/* falls through */
case _stretching.EXACTFIT:
scale = true;
break;
case _stretching.UNIFORM:
/* falls through */
default:
if (xscale > yscale) {
if (elementWidth * yscale / parentWidth > 0.95) {
scale = true;
stretchClass = 'jwexactfit';
} else {
elementWidth = elementWidth * yscale;
elementHeight = elementHeight * yscale;
}
} else {
if (elementHeight * xscale / parentHeight > 0.95) {
scale = true;
stretchClass = 'jwexactfit';
} else {
elementWidth = elementWidth * xscale;
elementHeight = elementHeight * xscale;
}
}
if (scale) {
xscale = Math.ceil(parentWidth / 2) * 2 / elementWidth;
yscale = Math.ceil(parentHeight / 2) * 2 / elementHeight;
}
}
if (video) {
var style = {
left: '',
right: '',
width: '',
height: ''
};
if (scale) {
if (parentWidth < elementWidth) {
style.left =
style.right = Math.ceil((parentWidth - elementWidth) / 2);
}
if (parentHeight < elementHeight) {
style.top =
style.bottom = Math.ceil((parentHeight - elementHeight) / 2);
}
style.width = elementWidth;
style.height = elementHeight;
utils.scale(domelement, xscale, yscale, 0, 0);
} else {
scale = false;
utils.transform(domelement);
}
utils.css.style(domelement, style);
} else {
domelement.className = domelement.className.replace(/\s*jw(none|exactfit|uniform|fill)/g, '') +
' ' + stretchClass;
}
return scale;
};
})(jwplayer.utils);
(function(parsers) {
/** Component that loads and parses an DFXP file. **/
parsers.dfxp = function() {
var _seconds = jwplayer.utils.seconds;
this.parse = function(data) {
var _captions = [{
begin: 0,
text: ''
}];
data = data.replace(/^\s+/, '').replace(/\s+$/, '');
var list = data.split('
');
var list2 = data.split('');
var newlist = [];
var i;
for (i = 0; i < list.length; i++) {
if (list[i].indexOf('= 0) {
list[i] = list[i].substr(list[i].indexOf('
= 0) {
list2[i] = list2[i].substr(list2[i].indexOf(' 1) {
return _captions;
} else {
throw {
message: 'Invalid DFXP file:'
};
}
};
/** Parse a single captions entry. **/
function _entry(data) {
var entry = {};
try {
var idx = data.indexOf('begin=\"');
data = data.substr(idx + 7);
idx = data.indexOf('\" end=\"');
entry.begin = _seconds(data.substr(0, idx));
data = data.substr(idx + 7);
idx = data.indexOf('\"');
entry.end = _seconds(data.substr(0, idx));
idx = data.indexOf('\">');
data = data.substr(idx + 2);
entry.text = data;
} catch (error) {}
return entry;
}
};
})(jwplayer.parsers);
(function(parsers) {
/** Component that loads and parses an SRT file. **/
parsers.srt = function() {
/** XMLHTTP Object. **/
var _utils = jwplayer.utils,
_seconds = _utils.seconds;
this.parse = function(data, mergeBeginEnd) {
// Trim whitespace and split the list by returns.
var _captions = mergeBeginEnd ? [] : [{
begin: 0,
text: ''
}];
data = _utils.trim(data);
var list = data.split('\r\n\r\n');
if (list.length === 1) {
list = data.split('\n\n');
}
for (var i = 0; i < list.length; i++) {
if (list[i] === 'WEBVTT') {
continue;
}
// Parse each entry
var entry = _entry(list[i]);
if (entry.text) {
_captions.push(entry);
// Insert empty caption at the end.
if (entry.end && !mergeBeginEnd) {
_captions.push({
begin: entry.end,
text: ''
});
delete entry.end;
}
}
}
if (_captions.length > 1) {
return _captions;
} else {
throw {
message: 'Invalid SRT file'
};
}
};
/** Parse a single captions entry. **/
function _entry(data) {
var entry = {};
var array = data.split('\r\n');
if (array.length === 1) {
array = data.split('\n');
}
try {
// Second line contains the start and end.
var idx = 1;
if (array[0].indexOf(' --> ') > 0) {
idx = 0;
}
var index = array[idx].indexOf(' --> ');
if (index > 0) {
entry.begin = _seconds(array[idx].substr(0, index));
entry.end = _seconds(array[idx].substr(index + 5));
}
// Third line starts the text.
if (array[idx + 1]) {
entry.text = array[idx + 1];
// Arbitrary number of additional lines.
for (var i = idx + 2; i < array.length; i++) {
entry.text += '
' + array[i];
}
}
} catch (error) {}
return entry;
}
};
})(jwplayer.parsers);
(function(jwplayer) {
var noop = jwplayer.utils.noop,
_ = jwplayer._,
events = jwplayer.events,
returnFalse = _.constant(false);
var defaultProvider = {
// This function is required to determine if a provider can work on a given source
supports : returnFalse,
// Basic playback features
play : noop,
load : noop,
stop : noop,
volume : noop,
mute : noop,
seek : noop,
seekDrag : noop, // only for html5 ?
resize : noop,
remove : noop, // removes from page
destroy : noop, // frees memory
setVisibility : noop,
setFullscreen : returnFalse,
getFullscreen : noop,
// If setContainer has been set, this returns the element.
// It's value is used to determine if we should remove the