2013-01-10 13:06:12 -08:00
|
|
|
/**
|
|
|
|
* @fileoverview Controls classes for Video.js buttons, sliders, etc.
|
|
|
|
*/
|
|
|
|
|
2013-01-12 22:23:22 -08:00
|
|
|
goog.provide('vjs.Control');
|
|
|
|
goog.provide('vjs.Menu');
|
|
|
|
goog.provide('vjs.MenuItem');
|
|
|
|
|
|
|
|
goog.require('vjs.Player');
|
|
|
|
|
2012-12-30 21:45:50 -08:00
|
|
|
/**
|
|
|
|
* Base class for all control elements
|
2013-01-04 16:58:23 -08:00
|
|
|
* @param {vjs.Player|Object} player
|
2012-12-30 21:45:50 -08:00
|
|
|
* @param {Object=} options
|
|
|
|
* @constructor
|
|
|
|
*/
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.Control = function(player, options){
|
2012-12-30 21:45:50 -08:00
|
|
|
goog.base(this, player, options);
|
|
|
|
};
|
2013-01-04 16:58:23 -08:00
|
|
|
goog.inherits(vjs.Control, vjs.Component);
|
2012-12-30 21:45:50 -08:00
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.Control.prototype.buildCSSClass = function(){
|
2013-01-10 13:06:12 -08:00
|
|
|
return 'vjs-control ' + goog.base(this, 'buildCSSClass');
|
2012-12-30 21:45:50 -08:00
|
|
|
};
|
2011-11-29 11:40:05 -08:00
|
|
|
|
2012-03-16 12:29:38 -07:00
|
|
|
/* Control Bar
|
|
|
|
================================================================================ */
|
2012-12-30 21:45:50 -08:00
|
|
|
/**
|
|
|
|
* Container of main controls
|
2013-01-04 16:58:23 -08:00
|
|
|
* @param {vjs.Player|Object} player
|
2012-12-30 21:45:50 -08:00
|
|
|
* @param {Object=} options
|
|
|
|
* @constructor
|
|
|
|
*/
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.ControlBar = function(player, options){
|
2012-12-30 21:45:50 -08:00
|
|
|
goog.base(this, player, options);
|
|
|
|
|
2013-01-10 13:06:12 -08:00
|
|
|
player.one('play', vjs.bind(this, function(){
|
2012-12-30 21:45:50 -08:00
|
|
|
this.fadeIn();
|
2013-01-10 13:06:12 -08:00
|
|
|
this.player.on('mouseover', vjs.bind(this, this.fadeIn));
|
|
|
|
this.player.on('mouseout', vjs.bind(this, this.fadeOut));
|
2012-12-30 21:45:50 -08:00
|
|
|
}));
|
|
|
|
};
|
2013-01-04 16:58:23 -08:00
|
|
|
goog.inherits(vjs.ControlBar, vjs.Component);
|
2012-12-30 21:45:50 -08:00
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.ControlBar.prototype.options = {
|
2013-01-10 13:06:12 -08:00
|
|
|
loadEvent: 'play',
|
2012-12-30 21:45:50 -08:00
|
|
|
children: {
|
2013-01-10 13:06:12 -08:00
|
|
|
'playToggle': {},
|
|
|
|
'fullscreenToggle': {},
|
|
|
|
'currentTimeDisplay': {},
|
|
|
|
'timeDivider': {},
|
|
|
|
'durationDisplay': {},
|
|
|
|
'remainingTimeDisplay': {},
|
|
|
|
'progressControl': {},
|
|
|
|
'volumeControl': {},
|
|
|
|
'muteToggle': {}
|
2012-12-30 21:45:50 -08:00
|
|
|
}
|
|
|
|
};
|
2012-03-16 12:29:38 -07:00
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.ControlBar.prototype.createEl = function(){
|
2013-01-10 13:06:12 -08:00
|
|
|
return vjs.createEl('div', {
|
|
|
|
className: 'vjs-control-bar'
|
2012-12-30 21:45:50 -08:00
|
|
|
});
|
|
|
|
};
|
2012-03-16 12:29:38 -07:00
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.ControlBar.prototype.fadeIn = function(){
|
2012-12-30 21:45:50 -08:00
|
|
|
goog.base(this, 'fadeIn');
|
2013-01-10 13:06:12 -08:00
|
|
|
this.player.trigger('controlsvisible');
|
2012-12-30 21:45:50 -08:00
|
|
|
};
|
2012-03-16 12:29:38 -07:00
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.ControlBar.prototype.fadeOut = function(){
|
2012-12-30 21:45:50 -08:00
|
|
|
goog.base(this, 'fadeOut');
|
2013-01-10 13:06:12 -08:00
|
|
|
this.player.trigger('controlshidden');
|
2012-12-30 21:45:50 -08:00
|
|
|
};
|
2012-03-16 12:29:38 -07:00
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.ControlBar.prototype.lockShowing = function(){
|
2013-01-10 13:06:12 -08:00
|
|
|
this.el_.style.opacity = '1';
|
2012-12-30 21:45:50 -08:00
|
|
|
};
|
2012-03-16 12:29:38 -07:00
|
|
|
|
2011-11-29 11:40:05 -08:00
|
|
|
/* Button - Base class for all buttons
|
|
|
|
================================================================================ */
|
2012-12-30 21:45:50 -08:00
|
|
|
/**
|
|
|
|
* Base class for all buttons
|
2013-01-04 16:58:23 -08:00
|
|
|
* @param {vjs.Player|Object} player
|
2012-12-30 21:45:50 -08:00
|
|
|
* @param {Object=} options
|
|
|
|
* @constructor
|
|
|
|
*/
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.Button = function(player, options){
|
2012-12-30 21:45:50 -08:00
|
|
|
goog.base(this, player, options);
|
|
|
|
|
2013-01-10 13:06:12 -08:00
|
|
|
this.on('click', this.onClick);
|
|
|
|
this.on('focus', this.onFocus);
|
|
|
|
this.on('blur', this.onBlur);
|
2012-12-30 21:45:50 -08:00
|
|
|
};
|
2013-01-04 16:58:23 -08:00
|
|
|
goog.inherits(vjs.Button, vjs.Control);
|
2012-12-30 21:45:50 -08:00
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.Button.prototype.createEl = function(type, attrs){
|
2012-12-30 21:45:50 -08:00
|
|
|
// Add standard Aria and Tabindex info
|
2013-01-04 16:58:23 -08:00
|
|
|
attrs = vjs.merge({
|
2012-12-30 21:45:50 -08:00
|
|
|
className: this.buildCSSClass(),
|
2013-01-10 13:06:12 -08:00
|
|
|
innerHTML: '<div><span class="vjs-control-text">' + (this.buttonText || 'Need Text') + '</span></div>',
|
|
|
|
role: 'button',
|
2012-12-30 21:45:50 -08:00
|
|
|
tabIndex: 0
|
|
|
|
}, attrs);
|
|
|
|
|
|
|
|
return goog.base(this, 'createEl', type, attrs);
|
|
|
|
};
|
2011-11-29 11:40:05 -08:00
|
|
|
|
|
|
|
// Click - Override with specific functionality for button
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.Button.prototype.onClick = function(){};
|
2011-11-29 11:40:05 -08:00
|
|
|
|
|
|
|
// Focus - Add keyboard functionality to element
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.Button.prototype.onFocus = function(){
|
2013-01-10 13:06:12 -08:00
|
|
|
vjs.on(document, 'keyup', vjs.bind(this, this.onKeyPress));
|
2012-12-30 21:45:50 -08:00
|
|
|
};
|
2011-11-29 11:40:05 -08:00
|
|
|
|
|
|
|
// KeyPress (document level) - Trigger click when keys are pressed
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.Button.prototype.onKeyPress = function(event){
|
2012-12-30 21:45:50 -08:00
|
|
|
// Check for space bar (32) or enter (13) keys
|
|
|
|
if (event.which == 32 || event.which == 13) {
|
|
|
|
event.preventDefault();
|
|
|
|
this.onClick();
|
2011-11-29 11:40:05 -08:00
|
|
|
}
|
2012-12-30 21:45:50 -08:00
|
|
|
};
|
2011-11-29 11:40:05 -08:00
|
|
|
|
2012-12-30 21:45:50 -08:00
|
|
|
// Blur - Remove keyboard triggers
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.Button.prototype.onBlur = function(){
|
2013-01-10 13:06:12 -08:00
|
|
|
vjs.off(document, 'keyup', vjs.bind(this, this.onKeyPress));
|
|
|
|
};
|
2011-11-29 11:40:05 -08:00
|
|
|
|
|
|
|
/* Play Button
|
|
|
|
================================================================================ */
|
2012-12-30 21:45:50 -08:00
|
|
|
/**
|
|
|
|
* Basic play button
|
2013-01-04 16:58:23 -08:00
|
|
|
* @param {vjs.Player|Object} player
|
2012-12-30 21:45:50 -08:00
|
|
|
* @param {Object=} options
|
|
|
|
* @constructor
|
|
|
|
*/
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.PlayButton = function(player, options){
|
2012-12-30 21:45:50 -08:00
|
|
|
goog.base(this, player, options);
|
|
|
|
};
|
2013-01-04 16:58:23 -08:00
|
|
|
goog.inherits(vjs.PlayButton, vjs.Button);
|
2012-12-30 21:45:50 -08:00
|
|
|
|
2013-01-10 13:06:12 -08:00
|
|
|
vjs.PlayButton.prototype.buttonText = 'Play';
|
2012-12-30 21:45:50 -08:00
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.PlayButton.prototype.buildCSSClass = function(){
|
2013-01-10 13:06:12 -08:00
|
|
|
return 'vjs-play-button ' + goog.base(this, 'buildCSSClass');
|
2012-12-30 21:45:50 -08:00
|
|
|
};
|
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.PlayButton.prototype.onClick = function(){
|
2012-12-30 21:45:50 -08:00
|
|
|
this.player.play();
|
2013-01-10 13:06:12 -08:00
|
|
|
};
|
2011-11-29 11:40:05 -08:00
|
|
|
|
|
|
|
/* Pause Button
|
|
|
|
================================================================================ */
|
2012-12-30 21:45:50 -08:00
|
|
|
/**
|
|
|
|
* Basic pause button
|
2013-01-04 16:58:23 -08:00
|
|
|
* @param {vjs.Player|Object} player
|
2012-12-30 21:45:50 -08:00
|
|
|
* @param {Object=} options
|
|
|
|
* @constructor
|
|
|
|
*/
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.PauseButton = function(player, options){
|
2012-12-30 21:45:50 -08:00
|
|
|
goog.base(this, player, options);
|
|
|
|
};
|
2013-01-04 16:58:23 -08:00
|
|
|
goog.inherits(vjs.PauseButton, vjs.Button);
|
2012-12-30 21:45:50 -08:00
|
|
|
|
2013-01-10 13:06:12 -08:00
|
|
|
vjs.PauseButton.prototype.buttonText = 'Play';
|
2012-12-30 21:45:50 -08:00
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.PauseButton.prototype.buildCSSClass = function(){
|
2013-01-10 13:06:12 -08:00
|
|
|
return 'vjs-pause-button ' + goog.base(this, 'buildCSSClass');
|
2012-12-30 21:45:50 -08:00
|
|
|
};
|
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.PauseButton.prototype.onClick = function(){
|
2012-12-30 21:45:50 -08:00
|
|
|
this.player.pause();
|
|
|
|
};
|
2011-11-29 11:40:05 -08:00
|
|
|
|
|
|
|
/* Play Toggle - Play or Pause Media
|
|
|
|
================================================================================ */
|
2012-12-30 21:45:50 -08:00
|
|
|
/**
|
|
|
|
* Button to toggle between play and pause
|
2013-01-04 16:58:23 -08:00
|
|
|
* @param {vjs.Player|Object} player
|
2012-12-30 21:45:50 -08:00
|
|
|
* @param {Object=} options
|
|
|
|
* @constructor
|
|
|
|
*/
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.PlayToggle = function(player, options){
|
2012-12-30 21:45:50 -08:00
|
|
|
goog.base(this, player, options);
|
|
|
|
|
2013-01-10 13:06:12 -08:00
|
|
|
player.on('play', vjs.bind(this, this.onPlay));
|
|
|
|
player.on('pause', vjs.bind(this, this.onPause));
|
2012-12-30 21:45:50 -08:00
|
|
|
};
|
2013-01-04 16:58:23 -08:00
|
|
|
goog.inherits(vjs.PlayToggle, vjs.Button);
|
2012-12-30 21:45:50 -08:00
|
|
|
|
2013-01-10 13:06:12 -08:00
|
|
|
vjs.PlayToggle.prototype.buttonText = 'Play';
|
2012-12-30 21:45:50 -08:00
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.PlayToggle.prototype.buildCSSClass = function(){
|
2013-01-10 13:06:12 -08:00
|
|
|
return 'vjs-play-control ' + goog.base(this, 'buildCSSClass');
|
2012-12-30 21:45:50 -08:00
|
|
|
};
|
2011-11-29 11:40:05 -08:00
|
|
|
|
|
|
|
// OnClick - Toggle between play and pause
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.PlayToggle.prototype.onClick = function(){
|
2012-12-30 21:45:50 -08:00
|
|
|
if (this.player.paused()) {
|
|
|
|
this.player.play();
|
|
|
|
} else {
|
|
|
|
this.player.pause();
|
|
|
|
}
|
|
|
|
};
|
2011-11-29 11:40:05 -08:00
|
|
|
|
|
|
|
// OnPlay - Add the vjs-playing class to the element so it can change appearance
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.PlayToggle.prototype.onPlay = function(){
|
2013-01-10 13:06:12 -08:00
|
|
|
vjs.removeClass(this.el_, 'vjs-paused');
|
|
|
|
vjs.addClass(this.el_, 'vjs-playing');
|
2012-12-30 21:45:50 -08:00
|
|
|
};
|
2011-11-29 11:40:05 -08:00
|
|
|
|
|
|
|
// OnPause - Add the vjs-paused class to the element so it can change appearance
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.PlayToggle.prototype.onPause = function(){
|
2013-01-10 13:06:12 -08:00
|
|
|
vjs.removeClass(this.el_, 'vjs-playing');
|
|
|
|
vjs.addClass(this.el_, 'vjs-paused');
|
|
|
|
};
|
2011-11-29 11:40:05 -08:00
|
|
|
|
|
|
|
|
|
|
|
/* Fullscreen Toggle Behaviors
|
|
|
|
================================================================================ */
|
2012-12-30 21:45:50 -08:00
|
|
|
/**
|
|
|
|
* Toggle fullscreen video
|
2013-01-04 16:58:23 -08:00
|
|
|
* @param {vjs.Player|Object} player
|
2012-12-30 21:45:50 -08:00
|
|
|
* @param {Object=} options
|
|
|
|
* @constructor
|
|
|
|
*/
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.FullscreenToggle = function(player, options){
|
2012-12-30 21:45:50 -08:00
|
|
|
goog.base(this, player, options);
|
|
|
|
};
|
2013-01-04 16:58:23 -08:00
|
|
|
goog.inherits(vjs.FullscreenToggle, vjs.Button);
|
2012-12-30 21:45:50 -08:00
|
|
|
|
2013-01-10 13:06:12 -08:00
|
|
|
vjs.FullscreenToggle.prototype.buttonText = 'Fullscreen';
|
2012-12-30 21:45:50 -08:00
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.FullscreenToggle.prototype.buildCSSClass = function(){
|
2013-01-10 13:06:12 -08:00
|
|
|
return 'vjs-fullscreen-control ' + goog.base(this, 'buildCSSClass');
|
2012-12-30 21:45:50 -08:00
|
|
|
};
|
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.FullscreenToggle.prototype.onClick = function(){
|
2012-12-30 21:45:50 -08:00
|
|
|
if (!this.player.isFullScreen) {
|
|
|
|
this.player.requestFullScreen();
|
|
|
|
} else {
|
|
|
|
this.player.cancelFullScreen();
|
2011-11-29 11:40:05 -08:00
|
|
|
}
|
2012-12-30 21:45:50 -08:00
|
|
|
};
|
2011-11-29 11:40:05 -08:00
|
|
|
|
|
|
|
|
|
|
|
/* Big Play Button
|
|
|
|
================================================================================ */
|
2012-12-30 21:45:50 -08:00
|
|
|
/**
|
|
|
|
* Initial play button. Shows before the video has played.
|
2013-01-04 16:58:23 -08:00
|
|
|
* @param {vjs.Player|Object} player
|
2012-12-30 21:45:50 -08:00
|
|
|
* @param {Object=} options
|
|
|
|
* @constructor
|
|
|
|
*/
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.BigPlayButton = function(player, options){
|
2012-12-30 21:45:50 -08:00
|
|
|
goog.base(this, player, options);
|
|
|
|
|
2013-01-10 13:06:12 -08:00
|
|
|
player.on('play', vjs.bind(this, this.hide));
|
|
|
|
player.on('ended', vjs.bind(this, this.show));
|
2012-12-30 21:45:50 -08:00
|
|
|
};
|
2013-01-04 16:58:23 -08:00
|
|
|
goog.inherits(vjs.BigPlayButton, vjs.Button);
|
2012-12-30 21:45:50 -08:00
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.BigPlayButton.prototype.createEl = function(){
|
2013-01-10 13:06:12 -08:00
|
|
|
return goog.base(this, 'createEl', 'div', {
|
|
|
|
className: 'vjs-big-play-button',
|
|
|
|
innerHTML: '<span></span>'
|
2012-12-30 21:45:50 -08:00
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.BigPlayButton.prototype.onClick = function(){
|
2012-12-30 21:45:50 -08:00
|
|
|
// Go back to the beginning if big play button is showing at the end.
|
|
|
|
// Have to check for current time otherwise it might throw a 'not ready' error.
|
|
|
|
if(this.player.currentTime()) {
|
|
|
|
this.player.currentTime(0);
|
2011-11-29 11:40:05 -08:00
|
|
|
}
|
2012-12-30 21:45:50 -08:00
|
|
|
this.player.play();
|
|
|
|
};
|
2011-11-29 11:40:05 -08:00
|
|
|
|
2011-12-21 17:59:36 -08:00
|
|
|
/* Loading Spinner
|
|
|
|
================================================================================ */
|
2012-12-30 21:45:50 -08:00
|
|
|
/**
|
|
|
|
* Loading spinner for waiting events
|
2013-01-04 16:58:23 -08:00
|
|
|
* @param {vjs.Player|Object} player
|
2012-12-30 21:45:50 -08:00
|
|
|
* @param {Object=} options
|
|
|
|
* @constructor
|
|
|
|
*/
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.LoadingSpinner = function(player, options){
|
2012-12-30 21:45:50 -08:00
|
|
|
goog.base(this, player, options);
|
|
|
|
|
2013-01-10 13:06:12 -08:00
|
|
|
player.on('canplay', vjs.bind(this, this.hide));
|
|
|
|
player.on('canplaythrough', vjs.bind(this, this.hide));
|
|
|
|
player.on('playing', vjs.bind(this, this.hide));
|
|
|
|
player.on('seeked', vjs.bind(this, this.hide));
|
2012-12-30 21:45:50 -08:00
|
|
|
|
2013-01-10 13:06:12 -08:00
|
|
|
player.on('seeking', vjs.bind(this, this.show));
|
2012-12-30 21:45:50 -08:00
|
|
|
|
|
|
|
// in some browsers seeking does not trigger the 'playing' event,
|
|
|
|
// so we also need to trap 'seeked' if we are going to set a
|
|
|
|
// 'seeking' event
|
2013-01-10 13:06:12 -08:00
|
|
|
player.on('seeked', vjs.bind(this, this.hide));
|
2012-12-30 21:45:50 -08:00
|
|
|
|
2013-01-10 13:06:12 -08:00
|
|
|
player.on('error', vjs.bind(this, this.show));
|
2012-12-30 21:45:50 -08:00
|
|
|
|
|
|
|
// Not showing spinner on stalled any more. Browsers may stall and then not trigger any events that would remove the spinner.
|
|
|
|
// Checked in Chrome 16 and Safari 5.1.2. http://help.videojs.com/discussions/problems/883-why-is-the-download-progress-showing
|
2013-01-10 13:06:12 -08:00
|
|
|
// player.on('stalled', vjs.bind(this, this.show));
|
2012-12-30 21:45:50 -08:00
|
|
|
|
2013-01-10 13:06:12 -08:00
|
|
|
player.on('waiting', vjs.bind(this, this.show));
|
2012-12-30 21:45:50 -08:00
|
|
|
};
|
2013-01-04 16:58:23 -08:00
|
|
|
goog.inherits(vjs.LoadingSpinner, vjs.Component);
|
2012-12-30 21:45:50 -08:00
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.LoadingSpinner.prototype.createEl = function(){
|
2012-12-30 21:45:50 -08:00
|
|
|
var classNameSpinner, innerHtmlSpinner;
|
|
|
|
|
2013-01-10 13:06:12 -08:00
|
|
|
if ( typeof this.player.el().style.WebkitBorderRadius == 'string'
|
|
|
|
|| typeof this.player.el().style.MozBorderRadius == 'string'
|
|
|
|
|| typeof this.player.el().style.KhtmlBorderRadius == 'string'
|
|
|
|
|| typeof this.player.el().style.borderRadius == 'string')
|
2012-12-30 21:45:50 -08:00
|
|
|
{
|
2013-01-10 13:06:12 -08:00
|
|
|
classNameSpinner = 'vjs-loading-spinner';
|
|
|
|
innerHtmlSpinner = '<div class="ball1"></div><div class="ball2"></div><div class="ball3"></div><div class="ball4"></div><div class="ball5"></div><div class="ball6"></div><div class="ball7"></div><div class="ball8"></div>';
|
2012-12-30 21:45:50 -08:00
|
|
|
} else {
|
2013-01-10 13:06:12 -08:00
|
|
|
classNameSpinner = 'vjs-loading-spinner-fallback';
|
|
|
|
innerHtmlSpinner = '';
|
2012-12-30 21:45:50 -08:00
|
|
|
}
|
2011-12-21 17:59:36 -08:00
|
|
|
|
2013-01-10 13:06:12 -08:00
|
|
|
return goog.base(this, 'createEl', 'div', {
|
2012-12-30 21:45:50 -08:00
|
|
|
className: classNameSpinner,
|
|
|
|
innerHTML: innerHtmlSpinner
|
|
|
|
});
|
|
|
|
};
|
2011-12-21 17:59:36 -08:00
|
|
|
|
2011-11-29 11:40:05 -08:00
|
|
|
/* Time
|
|
|
|
================================================================================ */
|
|
|
|
|
2012-12-30 21:45:50 -08:00
|
|
|
/**
|
|
|
|
* Displays the current time
|
2013-01-04 16:58:23 -08:00
|
|
|
* @param {vjs.Player|Object} player
|
2012-12-30 21:45:50 -08:00
|
|
|
* @param {Object=} options
|
|
|
|
* @constructor
|
|
|
|
*/
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.CurrentTimeDisplay = function(player, options){
|
2012-12-30 21:45:50 -08:00
|
|
|
goog.base(this, player, options);
|
|
|
|
|
2013-01-10 13:06:12 -08:00
|
|
|
player.on('timeupdate', vjs.bind(this, this.updateContent));
|
2012-12-30 21:45:50 -08:00
|
|
|
};
|
2013-01-04 16:58:23 -08:00
|
|
|
goog.inherits(vjs.CurrentTimeDisplay, vjs.Component);
|
2012-12-30 21:45:50 -08:00
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.CurrentTimeDisplay.prototype.createEl = function(){
|
2013-01-10 13:06:12 -08:00
|
|
|
var el = goog.base(this, 'createEl', 'div', {
|
|
|
|
className: 'vjs-current-time vjs-time-controls vjs-control'
|
2012-12-30 21:45:50 -08:00
|
|
|
});
|
|
|
|
|
2013-01-10 13:06:12 -08:00
|
|
|
this.content = vjs.createEl('div', {
|
|
|
|
className: 'vjs-current-time-display',
|
2012-12-30 21:45:50 -08:00
|
|
|
innerHTML: '0:00'
|
|
|
|
});
|
|
|
|
|
2013-01-10 13:06:12 -08:00
|
|
|
el.appendChild(vjs.createEl('div').appendChild(this.content));
|
2012-12-30 21:45:50 -08:00
|
|
|
return el;
|
|
|
|
};
|
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.CurrentTimeDisplay.prototype.updateContent = function(){
|
2012-12-30 21:45:50 -08:00
|
|
|
// Allows for smooth scrubbing, when player can't keep up.
|
|
|
|
var time = (this.player.scrubbing) ? this.player.getCache().currentTime : this.player.currentTime();
|
2013-01-04 16:58:23 -08:00
|
|
|
this.content.innerHTML = vjs.formatTime(time, this.player.duration());
|
2012-12-30 21:45:50 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Displays the duration
|
2013-01-04 16:58:23 -08:00
|
|
|
* @param {vjs.Player|Object} player
|
2012-12-30 21:45:50 -08:00
|
|
|
* @param {Object=} options
|
|
|
|
* @constructor
|
|
|
|
*/
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.DurationDisplay = function(player, options){
|
2012-12-30 21:45:50 -08:00
|
|
|
goog.base(this, player, options);
|
|
|
|
|
2013-01-10 13:06:12 -08:00
|
|
|
player.on('timeupdate', vjs.bind(this, this.updateContent));
|
2012-12-30 21:45:50 -08:00
|
|
|
};
|
2013-01-04 16:58:23 -08:00
|
|
|
goog.inherits(vjs.DurationDisplay, vjs.Component);
|
2012-12-30 21:45:50 -08:00
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.DurationDisplay.prototype.createEl = function(){
|
2013-01-10 13:06:12 -08:00
|
|
|
var el = goog.base(this, 'createEl', 'div', {
|
|
|
|
className: 'vjs-duration vjs-time-controls vjs-control'
|
2012-12-30 21:45:50 -08:00
|
|
|
});
|
|
|
|
|
2013-01-10 13:06:12 -08:00
|
|
|
this.content = vjs.createEl('div', {
|
|
|
|
className: 'vjs-duration-display',
|
2012-12-30 21:45:50 -08:00
|
|
|
innerHTML: '0:00'
|
|
|
|
});
|
|
|
|
|
2013-01-10 13:06:12 -08:00
|
|
|
el.appendChild(vjs.createEl('div').appendChild(this.content));
|
2012-12-30 21:45:50 -08:00
|
|
|
return el;
|
|
|
|
};
|
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.DurationDisplay.prototype.updateContent = function(){
|
|
|
|
if (this.player.duration()) { this.content.innerHTML = vjs.formatTime(this.player.duration()); }
|
2012-12-30 21:45:50 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Time Separator (Not used in main skin, but still available, and could be used as a 'spare element')
|
2013-01-04 16:58:23 -08:00
|
|
|
* @param {vjs.Player|Object} player
|
2012-12-30 21:45:50 -08:00
|
|
|
* @param {Object=} options
|
|
|
|
* @constructor
|
|
|
|
*/
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.TimeDivider = function(player, options){
|
2012-12-30 21:45:50 -08:00
|
|
|
goog.base(this, player, options);
|
|
|
|
};
|
2013-01-04 16:58:23 -08:00
|
|
|
goog.inherits(vjs.TimeDivider, vjs.Component);
|
2012-12-30 21:45:50 -08:00
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.TimeDivider.prototype.createEl = function(){
|
2013-01-10 13:06:12 -08:00
|
|
|
return goog.base(this, 'createEl', 'div', {
|
|
|
|
className: 'vjs-time-divider',
|
2012-12-30 21:45:50 -08:00
|
|
|
innerHTML: '<div><span>/</span></div>'
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Displays the time left in the video
|
2013-01-04 16:58:23 -08:00
|
|
|
* @param {vjs.Player|Object} player
|
2012-12-30 21:45:50 -08:00
|
|
|
* @param {Object=} options
|
|
|
|
* @constructor
|
|
|
|
*/
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.RemainingTimeDisplay = function(player, options){
|
2012-12-30 21:45:50 -08:00
|
|
|
goog.base(this, player, options);
|
|
|
|
|
2013-01-10 13:06:12 -08:00
|
|
|
player.on('timeupdate', vjs.bind(this, this.updateContent));
|
2012-12-30 21:45:50 -08:00
|
|
|
};
|
2013-01-04 16:58:23 -08:00
|
|
|
goog.inherits(vjs.RemainingTimeDisplay, vjs.Component);
|
2012-12-30 21:45:50 -08:00
|
|
|
|
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.RemainingTimeDisplay.prototype.createEl = function(){
|
2013-01-10 13:06:12 -08:00
|
|
|
var el = goog.base(this, 'createEl', 'div', {
|
|
|
|
className: 'vjs-remaining-time vjs-time-controls vjs-control'
|
2012-12-30 21:45:50 -08:00
|
|
|
});
|
|
|
|
|
2013-01-10 13:06:12 -08:00
|
|
|
this.content = vjs.createEl('div', {
|
|
|
|
className: 'vjs-remaining-time-display',
|
2012-12-30 21:45:50 -08:00
|
|
|
innerHTML: '-0:00'
|
|
|
|
});
|
|
|
|
|
2013-01-10 13:06:12 -08:00
|
|
|
el.appendChild(vjs.createEl('div').appendChild(this.content));
|
2012-12-30 21:45:50 -08:00
|
|
|
return el;
|
|
|
|
};
|
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.RemainingTimeDisplay.prototype.updateContent = function(){
|
2013-01-10 13:06:12 -08:00
|
|
|
if (this.player.duration()) { this.content.innerHTML = '-'+vjs.formatTime(this.player.remainingTime()); }
|
2012-12-30 21:45:50 -08:00
|
|
|
|
|
|
|
// Allows for smooth scrubbing, when player can't keep up.
|
|
|
|
// var time = (this.player.scrubbing) ? this.player.getCache().currentTime : this.player.currentTime();
|
2013-01-04 16:58:23 -08:00
|
|
|
// this.content.innerHTML = vjs.formatTime(time, this.player.duration());
|
2012-12-30 21:45:50 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
/* Slider
|
|
|
|
================================================================================ */
|
|
|
|
/**
|
|
|
|
* Parent for seek bar and volume slider
|
2013-01-04 16:58:23 -08:00
|
|
|
* @param {vjs.Player|Object} player
|
2012-12-30 21:45:50 -08:00
|
|
|
* @param {Object=} options
|
|
|
|
* @constructor
|
|
|
|
*/
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.Slider = function(player, options){
|
2012-12-30 21:45:50 -08:00
|
|
|
goog.base(this, player, options);
|
2011-11-29 11:40:05 -08:00
|
|
|
|
2012-12-30 21:45:50 -08:00
|
|
|
// Set property names to bar and handle to match with the child Slider class is looking for
|
2013-01-10 13:06:12 -08:00
|
|
|
this.bar = this.getChild(this.options['barName']);
|
|
|
|
this.handle = this.getChild(this.options['handleName']);
|
2011-11-29 11:40:05 -08:00
|
|
|
|
2012-12-30 21:45:50 -08:00
|
|
|
// console.log('asdf', this.bar, this.childNameIndex_, this.options)
|
2011-11-29 11:40:05 -08:00
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
player.on(this.playerEvent, vjs.bind(this, this.update));
|
2011-11-29 11:40:05 -08:00
|
|
|
|
2013-01-10 13:06:12 -08:00
|
|
|
this.on('mousedown', this.onMouseDown);
|
|
|
|
this.on('focus', this.onFocus);
|
|
|
|
this.on('blur', this.onBlur);
|
2011-11-29 11:40:05 -08:00
|
|
|
|
2013-01-10 13:06:12 -08:00
|
|
|
this.player.on('controlsvisible', vjs.bind(this, this.update));
|
2011-11-29 11:40:05 -08:00
|
|
|
|
2012-12-30 21:45:50 -08:00
|
|
|
// This is actually to fix the volume handle position. http://twitter.com/#!/gerritvanaaken/status/159046254519787520
|
2013-01-10 13:06:12 -08:00
|
|
|
// this.player.one('timeupdate', vjs.bind(this, this.update));
|
2011-11-29 11:40:05 -08:00
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
player.ready(vjs.bind(this, this.update));
|
2012-12-30 21:45:50 -08:00
|
|
|
};
|
2013-01-04 16:58:23 -08:00
|
|
|
goog.inherits(vjs.Slider, vjs.Component);
|
2011-11-29 11:40:05 -08:00
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.Slider.prototype.createEl = function(type, attrs) {
|
|
|
|
attrs = vjs.merge({
|
2013-01-10 13:06:12 -08:00
|
|
|
role: 'slider',
|
|
|
|
'aria-valuenow': 0,
|
|
|
|
'aria-valuemin': 0,
|
|
|
|
'aria-valuemax': 100,
|
2012-12-30 21:45:50 -08:00
|
|
|
tabIndex: 0
|
|
|
|
}, attrs);
|
2011-11-29 11:40:05 -08:00
|
|
|
|
2012-12-30 21:45:50 -08:00
|
|
|
return goog.base(this, 'createEl', type, attrs);
|
|
|
|
};
|
2011-11-29 11:40:05 -08:00
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.Slider.prototype.onMouseDown = function(event){
|
2012-12-30 21:45:50 -08:00
|
|
|
event.preventDefault();
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.blockTextSelection();
|
2011-11-29 11:40:05 -08:00
|
|
|
|
2013-01-10 13:06:12 -08:00
|
|
|
vjs.on(document, 'mousemove', vjs.bind(this, this.onMouseMove));
|
|
|
|
vjs.on(document, 'mouseup', vjs.bind(this, this.onMouseUp));
|
2011-11-29 11:40:05 -08:00
|
|
|
|
2012-12-30 21:45:50 -08:00
|
|
|
this.onMouseMove(event);
|
|
|
|
};
|
2011-11-29 11:40:05 -08:00
|
|
|
|
2013-01-10 13:06:12 -08:00
|
|
|
vjs.Slider.prototype.onMouseUp = function() {
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.unblockTextSelection();
|
2013-01-10 13:06:12 -08:00
|
|
|
vjs.off(document, 'mousemove', this.onMouseMove, false);
|
|
|
|
vjs.off(document, 'mouseup', this.onMouseUp, false);
|
2011-11-29 11:40:05 -08:00
|
|
|
|
2012-12-30 21:45:50 -08:00
|
|
|
this.update();
|
|
|
|
};
|
2011-11-29 11:40:05 -08:00
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.Slider.prototype.update = function(){
|
2012-12-30 21:45:50 -08:00
|
|
|
// If scrubbing, we could use a cached value to make the handle keep up with the user's mouse.
|
|
|
|
// On HTML5 browsers scrubbing is really smooth, but some flash players are slow, so we might want to utilize this later.
|
|
|
|
// var progress = (this.player.scrubbing) ? this.player.getCache().currentTime / this.player.duration() : this.player.currentTime() / this.player.duration();
|
2011-11-29 11:40:05 -08:00
|
|
|
|
2012-12-30 21:45:50 -08:00
|
|
|
var barProgress,
|
2013-01-10 13:06:12 -08:00
|
|
|
progress = this.getPercent(),
|
2012-12-30 21:45:50 -08:00
|
|
|
handle = this.handle,
|
|
|
|
bar = this.bar;
|
2011-11-29 11:40:05 -08:00
|
|
|
|
2012-12-30 21:45:50 -08:00
|
|
|
// Protect against no duration and other division issues
|
|
|
|
if (isNaN(progress)) { progress = 0; }
|
2011-11-29 11:40:05 -08:00
|
|
|
|
2012-12-30 21:45:50 -08:00
|
|
|
barProgress = progress;
|
2011-11-29 11:40:05 -08:00
|
|
|
|
2012-12-30 21:45:50 -08:00
|
|
|
// If there is a handle, we need to account for the handle in our calculation for progress bar
|
|
|
|
// so that it doesn't fall short of or extend past the handle.
|
|
|
|
if (handle) {
|
2011-11-29 11:40:05 -08:00
|
|
|
|
2012-12-30 21:45:50 -08:00
|
|
|
var box = this.el_,
|
|
|
|
boxWidth = box.offsetWidth,
|
2011-11-29 11:40:05 -08:00
|
|
|
|
2013-01-10 13:06:12 -08:00
|
|
|
handleWidth = handle.el().offsetWidth,
|
2011-11-29 11:40:05 -08:00
|
|
|
|
2012-12-30 21:45:50 -08:00
|
|
|
// The width of the handle in percent of the containing box
|
|
|
|
// In IE, widths may not be ready yet causing NaN
|
|
|
|
handlePercent = (handleWidth) ? handleWidth / boxWidth : 0,
|
2011-11-29 11:40:05 -08:00
|
|
|
|
2012-12-30 21:45:50 -08:00
|
|
|
// Get the adjusted size of the box, considering that the handle's center never touches the left or right side.
|
|
|
|
// There is a margin of half the handle's width on both sides.
|
2013-01-10 13:06:12 -08:00
|
|
|
boxAdjustedPercent = 1 - handlePercent,
|
2011-11-29 11:40:05 -08:00
|
|
|
|
2012-12-30 21:45:50 -08:00
|
|
|
// Adjust the progress that we'll use to set widths to the new adjusted box width
|
2013-01-10 13:06:12 -08:00
|
|
|
adjustedProgress = progress * boxAdjustedPercent;
|
2011-11-29 11:40:05 -08:00
|
|
|
|
2013-01-10 13:06:12 -08:00
|
|
|
// The bar does reach the left side, so we need to account for this in the bar's width
|
|
|
|
barProgress = adjustedProgress + (handlePercent / 2);
|
2011-11-29 11:40:05 -08:00
|
|
|
|
2012-12-30 21:45:50 -08:00
|
|
|
// Move the handle from the left based on the adjected progress
|
2013-01-10 13:06:12 -08:00
|
|
|
handle.el().style.left = vjs.round(adjustedProgress * 100, 2) + '%';
|
2012-12-30 21:45:50 -08:00
|
|
|
}
|
2011-12-05 11:28:18 -08:00
|
|
|
|
2012-12-30 21:45:50 -08:00
|
|
|
// Set the new bar width
|
2013-01-10 13:06:12 -08:00
|
|
|
bar.el().style.width = vjs.round(barProgress * 100, 2) + '%';
|
2012-12-30 21:45:50 -08:00
|
|
|
};
|
2011-12-05 11:28:18 -08:00
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.Slider.prototype.calculateDistance = function(event){
|
2012-12-30 21:45:50 -08:00
|
|
|
var box = this.el_,
|
2013-01-04 16:58:23 -08:00
|
|
|
boxX = vjs.findPosX(box),
|
2012-12-30 21:45:50 -08:00
|
|
|
boxW = box.offsetWidth,
|
|
|
|
handle = this.handle;
|
2011-12-05 11:28:18 -08:00
|
|
|
|
2012-12-30 21:45:50 -08:00
|
|
|
if (handle) {
|
2013-01-10 13:06:12 -08:00
|
|
|
var handleW = handle.el().offsetWidth;
|
2012-01-28 16:27:03 -08:00
|
|
|
|
2012-12-30 21:45:50 -08:00
|
|
|
// Adjusted X and Width, so handle doesn't go outside the bar
|
|
|
|
boxX = boxX + (handleW / 2);
|
|
|
|
boxW = boxW - handleW;
|
|
|
|
}
|
2011-12-05 11:28:18 -08:00
|
|
|
|
2012-12-30 21:45:50 -08:00
|
|
|
// Percent that the click is through the adjusted area
|
|
|
|
return Math.max(0, Math.min(1, (event.pageX - boxX) / boxW));
|
|
|
|
};
|
2011-12-05 11:28:18 -08:00
|
|
|
|
2013-01-10 13:06:12 -08:00
|
|
|
vjs.Slider.prototype.onFocus = function(){
|
|
|
|
vjs.on(document, 'keyup', vjs.bind(this, this.onKeyPress));
|
2012-12-30 21:45:50 -08:00
|
|
|
};
|
2011-12-05 11:28:18 -08:00
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.Slider.prototype.onKeyPress = function(event){
|
2012-12-30 21:45:50 -08:00
|
|
|
if (event.which == 37) { // Left Arrow
|
|
|
|
event.preventDefault();
|
|
|
|
this.stepBack();
|
|
|
|
} else if (event.which == 39) { // Right Arrow
|
2011-12-05 11:28:18 -08:00
|
|
|
event.preventDefault();
|
2012-12-30 21:45:50 -08:00
|
|
|
this.stepForward();
|
|
|
|
}
|
|
|
|
};
|
2011-12-05 11:28:18 -08:00
|
|
|
|
2013-01-10 13:06:12 -08:00
|
|
|
vjs.Slider.prototype.onBlur = function(){
|
|
|
|
vjs.off(document, 'keyup', vjs.bind(this, this.onKeyPress));
|
2012-12-30 21:45:50 -08:00
|
|
|
};
|
2011-12-05 11:28:18 -08:00
|
|
|
|
|
|
|
|
2012-12-30 21:45:50 -08:00
|
|
|
/* Progress
|
|
|
|
================================================================================ */
|
2011-12-21 17:59:36 -08:00
|
|
|
|
2012-12-30 21:45:50 -08:00
|
|
|
/**
|
|
|
|
* Seek, Load Progress, and Play Progress
|
2013-01-04 16:58:23 -08:00
|
|
|
* @param {vjs.Player|Object} player
|
2012-12-30 21:45:50 -08:00
|
|
|
* @param {Object=} options
|
|
|
|
* @constructor
|
|
|
|
*/
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.ProgressControl = function(player, options){
|
2012-12-30 21:45:50 -08:00
|
|
|
goog.base(this, player, options);
|
|
|
|
};
|
2013-01-04 16:58:23 -08:00
|
|
|
goog.inherits(vjs.ProgressControl, vjs.Component);
|
2012-12-30 21:45:50 -08:00
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.ProgressControl.prototype.options = {
|
2012-12-30 21:45:50 -08:00
|
|
|
children: {
|
2013-01-10 13:06:12 -08:00
|
|
|
'seekBar': {}
|
2012-12-30 21:45:50 -08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.ProgressControl.prototype.createEl = function(){
|
2013-01-10 13:06:12 -08:00
|
|
|
return goog.base(this, 'createEl', 'div', {
|
|
|
|
className: 'vjs-progress-control vjs-control'
|
2012-12-30 21:45:50 -08:00
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Seek Bar and holder for the progress bars
|
2013-01-04 16:58:23 -08:00
|
|
|
* @param {vjs.Player|Object} player
|
2012-12-30 21:45:50 -08:00
|
|
|
* @param {Object=} options
|
|
|
|
* @constructor
|
|
|
|
*/
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.SeekBar = function(player, options){
|
2012-12-30 21:45:50 -08:00
|
|
|
goog.base(this, player, options);
|
|
|
|
};
|
2013-01-04 16:58:23 -08:00
|
|
|
goog.inherits(vjs.SeekBar, vjs.Slider);
|
2012-12-30 21:45:50 -08:00
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.SeekBar.prototype.options = {
|
2012-12-30 21:45:50 -08:00
|
|
|
children: {
|
2013-01-10 13:06:12 -08:00
|
|
|
'loadProgressBar': {},
|
|
|
|
'playProgressBar': {},
|
|
|
|
'seekHandle': {}
|
2011-12-05 11:28:18 -08:00
|
|
|
},
|
2013-01-10 13:06:12 -08:00
|
|
|
'barName': 'playProgressBar',
|
|
|
|
'handleName': 'seekHandle'
|
2012-12-30 21:45:50 -08:00
|
|
|
};
|
2011-12-05 11:28:18 -08:00
|
|
|
|
2013-01-10 13:06:12 -08:00
|
|
|
vjs.SeekBar.prototype.playerEvent = 'timeupdate';
|
2011-12-05 11:28:18 -08:00
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.SeekBar.prototype.createEl = function(){
|
2013-01-10 13:06:12 -08:00
|
|
|
return goog.base(this, 'createEl', 'div', {
|
|
|
|
className: 'vjs-progress-holder'
|
2012-12-30 21:45:50 -08:00
|
|
|
});
|
|
|
|
};
|
2012-01-09 16:28:26 -08:00
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.SeekBar.prototype.getPercent = function(){
|
2012-12-30 21:45:50 -08:00
|
|
|
return this.player.currentTime() / this.player.duration();
|
|
|
|
};
|
2012-01-27 15:04:25 -08:00
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.SeekBar.prototype.onMouseDown = function(event){
|
2012-12-30 21:45:50 -08:00
|
|
|
goog.base(this, 'onMouseDown', event);
|
2011-12-05 11:28:18 -08:00
|
|
|
|
2012-12-30 21:45:50 -08:00
|
|
|
this.player.scrubbing = true;
|
2012-01-27 15:04:25 -08:00
|
|
|
|
2012-12-30 21:45:50 -08:00
|
|
|
this.videoWasPlaying = !this.player.paused();
|
|
|
|
this.player.pause();
|
|
|
|
};
|
2011-12-05 11:28:18 -08:00
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.SeekBar.prototype.onMouseMove = function(event){
|
2012-12-30 21:45:50 -08:00
|
|
|
var newTime = this.calculateDistance(event) * this.player.duration();
|
2011-12-05 11:28:18 -08:00
|
|
|
|
2012-12-30 21:45:50 -08:00
|
|
|
// Don't let video end while scrubbing.
|
|
|
|
if (newTime == this.player.duration()) { newTime = newTime - 0.1; }
|
2011-12-05 11:28:18 -08:00
|
|
|
|
2012-12-30 21:45:50 -08:00
|
|
|
// Set new time (tell player to seek to new time)
|
|
|
|
this.player.currentTime(newTime);
|
|
|
|
};
|
2011-12-05 11:28:18 -08:00
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.SeekBar.prototype.onMouseUp = function(event){
|
2012-12-30 21:45:50 -08:00
|
|
|
goog.base(this, 'onMouseUp', event);
|
2011-12-05 11:28:18 -08:00
|
|
|
|
2012-12-30 21:45:50 -08:00
|
|
|
this.player.scrubbing = false;
|
|
|
|
if (this.videoWasPlaying) {
|
|
|
|
this.player.play();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.SeekBar.prototype.stepForward = function(){
|
2012-12-30 21:45:50 -08:00
|
|
|
this.player.currentTime(this.player.currentTime() + 1);
|
|
|
|
};
|
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.SeekBar.prototype.stepBack = function(){
|
2012-12-30 21:45:50 -08:00
|
|
|
this.player.currentTime(this.player.currentTime() - 1);
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Shows load progres
|
2013-01-04 16:58:23 -08:00
|
|
|
* @param {vjs.Player|Object} player
|
2012-12-30 21:45:50 -08:00
|
|
|
* @param {Object=} options
|
|
|
|
* @constructor
|
|
|
|
*/
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.LoadProgressBar = function(player, options){
|
2012-12-30 21:45:50 -08:00
|
|
|
goog.base(this, player, options);
|
2013-01-10 13:06:12 -08:00
|
|
|
player.on('progress', vjs.bind(this, this.update));
|
2012-12-30 21:45:50 -08:00
|
|
|
};
|
2013-01-04 16:58:23 -08:00
|
|
|
goog.inherits(vjs.LoadProgressBar, vjs.Component);
|
2012-12-30 21:45:50 -08:00
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.LoadProgressBar.prototype.createEl = function(){
|
2013-01-10 13:06:12 -08:00
|
|
|
return goog.base(this, 'createEl', 'div', {
|
|
|
|
className: 'vjs-load-progress',
|
2012-12-30 21:45:50 -08:00
|
|
|
innerHTML: '<span class="vjs-control-text">Loaded: 0%</span>'
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.LoadProgressBar.prototype.update = function(){
|
2013-01-10 13:06:12 -08:00
|
|
|
if (this.el_.style) { this.el_.style.width = vjs.round(this.player.bufferedPercent() * 100, 2) + '%'; }
|
2012-12-30 21:45:50 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Shows play progress
|
2013-01-04 16:58:23 -08:00
|
|
|
* @param {vjs.Player|Object} player
|
2012-12-30 21:45:50 -08:00
|
|
|
* @param {Object=} options
|
|
|
|
* @constructor
|
|
|
|
*/
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.PlayProgressBar = function(player, options){
|
2012-12-30 21:45:50 -08:00
|
|
|
goog.base(this, player, options);
|
|
|
|
};
|
2013-01-04 16:58:23 -08:00
|
|
|
goog.inherits(vjs.PlayProgressBar, vjs.Component);
|
2012-12-30 21:45:50 -08:00
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.PlayProgressBar.prototype.createEl = function(){
|
2013-01-10 13:06:12 -08:00
|
|
|
return goog.base(this, 'createEl', 'div', {
|
|
|
|
className: 'vjs-play-progress',
|
2012-12-30 21:45:50 -08:00
|
|
|
innerHTML: '<span class="vjs-control-text">Progress: 0%</span>'
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* SeekBar Behavior includes play progress bar, and seek handle
|
|
|
|
* Needed so it can determine seek position based on handle position/size
|
2013-01-04 16:58:23 -08:00
|
|
|
* @param {vjs.Player|Object} player
|
2012-12-30 21:45:50 -08:00
|
|
|
* @param {Object=} options
|
|
|
|
* @constructor
|
|
|
|
*/
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.SeekHandle = function(player, options){
|
2012-12-30 21:45:50 -08:00
|
|
|
goog.base(this, player, options);
|
|
|
|
};
|
2013-01-04 16:58:23 -08:00
|
|
|
goog.inherits(vjs.SeekHandle, vjs.Component);
|
2012-12-30 21:45:50 -08:00
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.SeekHandle.prototype.createEl = function(){
|
2013-01-10 13:06:12 -08:00
|
|
|
return goog.base(this, 'createEl', 'div', {
|
|
|
|
className: 'vjs-seek-handle',
|
2012-12-30 21:45:50 -08:00
|
|
|
innerHTML: '<span class="vjs-control-text">00:00</span>'
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Control the volume
|
2013-01-04 16:58:23 -08:00
|
|
|
* @param {vjs.Player|Object} player
|
2012-12-30 21:45:50 -08:00
|
|
|
* @param {Object=} options
|
|
|
|
* @constructor
|
|
|
|
*/
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.VolumeControl = function(player, options){
|
2012-12-30 21:45:50 -08:00
|
|
|
goog.base(this, player, options);
|
|
|
|
};
|
2013-01-04 16:58:23 -08:00
|
|
|
goog.inherits(vjs.VolumeControl, vjs.Component);
|
2012-12-30 21:45:50 -08:00
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.VolumeControl.prototype.options = {
|
2012-12-30 21:45:50 -08:00
|
|
|
children: {
|
2013-01-10 13:06:12 -08:00
|
|
|
'volumeBar': {}
|
2012-12-30 21:45:50 -08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.VolumeControl.prototype.createEl = function(){
|
2013-01-10 13:06:12 -08:00
|
|
|
return goog.base(this, 'createEl', 'div', {
|
|
|
|
className: 'vjs-volume-control vjs-control'
|
2012-12-30 21:45:50 -08:00
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Contains volume level
|
2013-01-04 16:58:23 -08:00
|
|
|
* @param {vjs.Player|Object} player
|
2012-12-30 21:45:50 -08:00
|
|
|
* @param {Object=} options
|
|
|
|
* @constructor
|
|
|
|
*/
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.VolumeBar = function(player, options){
|
2012-12-30 21:45:50 -08:00
|
|
|
goog.base(this, player, options);
|
|
|
|
};
|
2013-01-04 16:58:23 -08:00
|
|
|
goog.inherits(vjs.VolumeBar, vjs.Slider);
|
2012-12-30 21:45:50 -08:00
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.VolumeBar.prototype.options = {
|
2012-12-30 21:45:50 -08:00
|
|
|
children: {
|
2013-01-10 13:06:12 -08:00
|
|
|
'volumeLevel': {},
|
|
|
|
'volumeHandle': {}
|
2011-12-05 11:28:18 -08:00
|
|
|
},
|
2013-01-10 13:06:12 -08:00
|
|
|
'barName': 'volumeLevel',
|
|
|
|
'handleName': 'volumeHandle'
|
2012-12-30 21:45:50 -08:00
|
|
|
};
|
2011-12-05 11:28:18 -08:00
|
|
|
|
2013-01-10 13:06:12 -08:00
|
|
|
vjs.VolumeBar.prototype.playerEvent = 'volumechange';
|
2011-12-05 11:28:18 -08:00
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.VolumeBar.prototype.createEl = function(){
|
2013-01-10 13:06:12 -08:00
|
|
|
return goog.base(this, 'createEl', 'div', {
|
|
|
|
className: 'vjs-volume-bar'
|
2012-12-30 21:45:50 -08:00
|
|
|
});
|
|
|
|
};
|
2011-12-05 11:28:18 -08:00
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.VolumeBar.prototype.onMouseMove = function(event) {
|
2012-12-30 21:45:50 -08:00
|
|
|
this.player.volume(this.calculateDistance(event));
|
|
|
|
};
|
2011-12-05 11:28:18 -08:00
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.VolumeBar.prototype.getPercent = function(){
|
2012-12-30 21:45:50 -08:00
|
|
|
return this.player.volume();
|
|
|
|
};
|
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.VolumeBar.prototype.stepForward = function(){
|
2012-12-30 21:45:50 -08:00
|
|
|
this.player.volume(this.player.volume() + 0.1);
|
|
|
|
};
|
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.VolumeBar.prototype.stepBack = function(){
|
2012-12-30 21:45:50 -08:00
|
|
|
this.player.volume(this.player.volume() - 0.1);
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Shows volume level
|
2013-01-04 16:58:23 -08:00
|
|
|
* @param {vjs.Player|Object} player
|
2012-12-30 21:45:50 -08:00
|
|
|
* @param {Object=} options
|
|
|
|
* @constructor
|
|
|
|
*/
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.VolumeLevel = function(player, options){
|
2012-12-30 21:45:50 -08:00
|
|
|
goog.base(this, player, options);
|
|
|
|
};
|
2013-01-04 16:58:23 -08:00
|
|
|
goog.inherits(vjs.VolumeLevel, vjs.Component);
|
2012-12-30 21:45:50 -08:00
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.VolumeLevel.prototype.createEl = function(){
|
2013-01-10 13:06:12 -08:00
|
|
|
return goog.base(this, 'createEl', 'div', {
|
|
|
|
className: 'vjs-volume-level',
|
2012-12-30 21:45:50 -08:00
|
|
|
innerHTML: '<span class="vjs-control-text"></span>'
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Change volume level
|
2013-01-04 16:58:23 -08:00
|
|
|
* @param {vjs.Player|Object} player
|
2012-12-30 21:45:50 -08:00
|
|
|
* @param {Object=} options
|
|
|
|
* @constructor
|
|
|
|
*/
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.VolumeHandle = function(player, options){
|
2012-12-30 21:45:50 -08:00
|
|
|
goog.base(this, player, options);
|
|
|
|
};
|
2013-01-04 16:58:23 -08:00
|
|
|
goog.inherits(vjs.VolumeHandle, vjs.Component);
|
2012-12-30 21:45:50 -08:00
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.VolumeHandle.prototype.createEl = function(){
|
2013-01-10 13:06:12 -08:00
|
|
|
return goog.base(this, 'createEl', 'div', {
|
|
|
|
className: 'vjs-volume-handle',
|
2012-12-30 21:45:50 -08:00
|
|
|
innerHTML: '<span class="vjs-control-text"></span>'
|
|
|
|
// tabindex: 0,
|
2013-01-10 13:06:12 -08:00
|
|
|
// role: 'slider', 'aria-valuenow': 0, 'aria-valuemin': 0, 'aria-valuemax': 100
|
2012-12-30 21:45:50 -08:00
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Mute the audio
|
2013-01-04 16:58:23 -08:00
|
|
|
* @param {vjs.Player|Object} player
|
2012-12-30 21:45:50 -08:00
|
|
|
* @param {Object=} options
|
|
|
|
* @constructor
|
|
|
|
*/
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.MuteToggle = function(player, options){
|
2012-12-30 21:45:50 -08:00
|
|
|
goog.base(this, player, options);
|
|
|
|
|
2013-01-10 13:06:12 -08:00
|
|
|
player.on('volumechange', vjs.bind(this, this.update));
|
2012-12-30 21:45:50 -08:00
|
|
|
};
|
2013-01-04 16:58:23 -08:00
|
|
|
goog.inherits(vjs.MuteToggle, vjs.Button);
|
2012-12-30 21:45:50 -08:00
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.MuteToggle.prototype.createEl = function(){
|
2013-01-10 13:06:12 -08:00
|
|
|
return goog.base(this, 'createEl', 'div', {
|
|
|
|
className: 'vjs-mute-control vjs-control',
|
2012-12-30 21:45:50 -08:00
|
|
|
innerHTML: '<div><span class="vjs-control-text">Mute</span></div>'
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2013-01-10 13:06:12 -08:00
|
|
|
vjs.MuteToggle.prototype.onClick = function(){
|
2012-12-30 21:45:50 -08:00
|
|
|
this.player.muted( this.player.muted() ? false : true );
|
|
|
|
};
|
|
|
|
|
2013-01-10 13:06:12 -08:00
|
|
|
vjs.MuteToggle.prototype.update = function(){
|
2012-12-30 21:45:50 -08:00
|
|
|
var vol = this.player.volume(),
|
|
|
|
level = 3;
|
|
|
|
|
2013-01-10 13:06:12 -08:00
|
|
|
if (vol === 0 || this.player.muted()) {
|
2012-12-30 21:45:50 -08:00
|
|
|
level = 0;
|
|
|
|
} else if (vol < 0.33) {
|
|
|
|
level = 1;
|
|
|
|
} else if (vol < 0.67) {
|
|
|
|
level = 2;
|
2011-12-05 11:28:18 -08:00
|
|
|
}
|
|
|
|
|
2012-12-30 21:45:50 -08:00
|
|
|
/* TODO improve muted icon classes */
|
|
|
|
for (var i = 0; i < 4; i++) {
|
2013-01-10 13:06:12 -08:00
|
|
|
vjs.removeClass(this.el_, 'vjs-vol-'+i);
|
|
|
|
}
|
|
|
|
vjs.addClass(this.el_, 'vjs-vol-'+level);
|
|
|
|
};
|
2011-12-05 11:28:18 -08:00
|
|
|
|
2012-12-30 21:45:50 -08:00
|
|
|
/* Poster Image
|
2011-11-29 11:40:05 -08:00
|
|
|
================================================================================ */
|
2012-12-30 21:45:50 -08:00
|
|
|
/**
|
|
|
|
* Poster image. Shows before the video plays.
|
2013-01-04 16:58:23 -08:00
|
|
|
* @param {vjs.Player|Object} player
|
2012-12-30 21:45:50 -08:00
|
|
|
* @param {Object=} options
|
|
|
|
* @constructor
|
|
|
|
*/
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.PosterImage = function(player, options){
|
2012-12-30 21:45:50 -08:00
|
|
|
goog.base(this, player, options);
|
|
|
|
|
|
|
|
if (!this.player.options.poster) {
|
|
|
|
this.hide();
|
|
|
|
}
|
2011-11-29 11:40:05 -08:00
|
|
|
|
2013-01-10 13:06:12 -08:00
|
|
|
player.on('play', vjs.bind(this, this.hide));
|
2012-12-30 21:45:50 -08:00
|
|
|
};
|
2013-01-04 16:58:23 -08:00
|
|
|
goog.inherits(vjs.PosterImage, vjs.Button);
|
2011-11-29 11:40:05 -08:00
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.PosterImage.prototype.createEl = function(){
|
2013-01-10 13:06:12 -08:00
|
|
|
var el = vjs.createEl('img', {
|
|
|
|
className: 'vjs-poster',
|
2012-01-27 15:04:25 -08:00
|
|
|
|
2012-12-30 21:45:50 -08:00
|
|
|
// Don't want poster to be tabbable.
|
|
|
|
tabIndex: -1
|
|
|
|
});
|
|
|
|
|
|
|
|
// src throws errors if no poster was defined.
|
|
|
|
if (this.player.options.poster) {
|
|
|
|
el.src = this.player.options.poster;
|
2011-11-29 11:40:05 -08:00
|
|
|
}
|
2012-12-30 21:45:50 -08:00
|
|
|
return el;
|
|
|
|
};
|
2011-11-29 11:40:05 -08:00
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.PosterImage.prototype.onClick = function(){
|
2012-12-30 21:45:50 -08:00
|
|
|
this.player.play();
|
2013-01-10 13:06:12 -08:00
|
|
|
};
|
2011-11-29 11:40:05 -08:00
|
|
|
|
2012-12-30 21:45:50 -08:00
|
|
|
/* Menu
|
|
|
|
================================================================================ */
|
|
|
|
/**
|
|
|
|
* The base for text track and settings menu buttons.
|
2013-01-04 16:58:23 -08:00
|
|
|
* @param {vjs.Player|Object} player
|
2012-12-30 21:45:50 -08:00
|
|
|
* @param {Object=} options
|
|
|
|
* @constructor
|
|
|
|
*/
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.Menu = function(player, options){
|
2012-12-30 21:45:50 -08:00
|
|
|
goog.base(this, player, options);
|
|
|
|
};
|
2013-01-04 16:58:23 -08:00
|
|
|
goog.inherits(vjs.Menu, vjs.Component);
|
2012-12-30 21:45:50 -08:00
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.Menu.prototype.addItem = function(component){
|
|
|
|
this.addChild(component);
|
2013-01-10 13:06:12 -08:00
|
|
|
component.on('click', vjs.bind(this, function(){
|
2012-12-30 21:45:50 -08:00
|
|
|
this.unlockShowing();
|
|
|
|
}));
|
|
|
|
};
|
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.Menu.prototype.createEl = function(){
|
2013-01-10 13:06:12 -08:00
|
|
|
return goog.base(this, 'createEl', 'ul', {
|
|
|
|
className: 'vjs-menu'
|
2012-12-30 21:45:50 -08:00
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Menu item
|
2013-01-04 16:58:23 -08:00
|
|
|
* @param {vjs.Player|Object} player
|
2012-12-30 21:45:50 -08:00
|
|
|
* @param {Object=} options
|
|
|
|
* @constructor
|
|
|
|
*/
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.MenuItem = function(player, options){
|
2012-12-30 21:45:50 -08:00
|
|
|
goog.base(this, player, options);
|
|
|
|
|
|
|
|
if (options.selected) {
|
2013-01-10 13:06:12 -08:00
|
|
|
this.addClass('vjs-selected');
|
2012-12-30 21:45:50 -08:00
|
|
|
}
|
|
|
|
};
|
2013-01-04 16:58:23 -08:00
|
|
|
goog.inherits(vjs.MenuItem, vjs.Button);
|
2012-12-30 21:45:50 -08:00
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.MenuItem.prototype.createEl = function(type, attrs){
|
2013-01-10 13:06:12 -08:00
|
|
|
return goog.base(this, 'createEl', 'li', vjs.merge({
|
|
|
|
className: 'vjs-menu-item',
|
2012-12-30 21:45:50 -08:00
|
|
|
innerHTML: this.options.label
|
|
|
|
}, attrs));
|
|
|
|
};
|
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.MenuItem.prototype.onClick = function(){
|
2012-12-30 21:45:50 -08:00
|
|
|
this.selected(true);
|
|
|
|
};
|
|
|
|
|
2013-01-04 16:58:23 -08:00
|
|
|
vjs.MenuItem.prototype.selected = function(selected){
|
2012-12-30 21:45:50 -08:00
|
|
|
if (selected) {
|
2013-01-10 13:06:12 -08:00
|
|
|
this.addClass('vjs-selected');
|
2012-12-30 21:45:50 -08:00
|
|
|
} else {
|
2013-01-10 13:06:12 -08:00
|
|
|
this.removeClass('vjs-selected');
|
2012-12-30 21:45:50 -08:00
|
|
|
}
|
|
|
|
};
|