Commit 0e24ff14 by Valera Rozuvan Committed by Vasyl Nakvasiuk

Added fade in/fade out for controls in HTML5 videos.

Making video in the center and not stretched when captions are shown.
Added auto hide/show for captions.
Removed old styling and debug info.
Added missing initalizations for captions auto show/hide.
Fixing bugs. Adding black backgorund to video for when it has not yet loaded. Making sure that the captions are not shown when in YouTube mode.
Added back missing styles for captions when in YouTube mode.
Code review 1 comments
Minor refactoring.
Documenting. Part 1.
parent 9d2eec07
...@@ -10,11 +10,29 @@ div.videoalpha { ...@@ -10,11 +10,29 @@ div.videoalpha {
padding: 12px; padding: 12px;
border-radius: 5px; border-radius: 5px;
div.tc-wrapper {
position: relative;
}
article.video-wrapper { article.video-wrapper {
float: left; float: left;
margin-right: flex-gutter(9); margin-right: flex-gutter(9);
width: flex-grid(6, 9); width: flex-grid(6, 9);
background-color: black;
position: relative;
div.video-player-pre {
height: 50px;
background-color: black;
}
div.video-player-post {
height: 50px;
background-color: black;
}
section.video-player { section.video-player {
height: 0; height: 0;
overflow: hidden; overflow: hidden;
...@@ -31,15 +49,6 @@ div.videoalpha { ...@@ -31,15 +49,6 @@ div.videoalpha {
} }
} }
section.video-roof {
background-color: green;
z-index: 10000;
width: 540px;
height: 100px;
position: absolute;
top: 387px;
}
section.video-controls { section.video-controls {
@include clearfix(); @include clearfix();
background: #333; background: #333;
...@@ -396,7 +405,6 @@ div.videoalpha { ...@@ -396,7 +405,6 @@ div.videoalpha {
a.hide-subtitles { a.hide-subtitles {
background: url('../images/cc.png') center no-repeat; background: url('../images/cc.png') center no-repeat;
color: #797979;
display: block; display: block;
float: left; float: left;
font-weight: 800; font-weight: 800;
...@@ -419,6 +427,10 @@ div.videoalpha { ...@@ -419,6 +427,10 @@ div.videoalpha {
&.off { &.off {
opacity: 0.7; opacity: 0.7;
} }
background-color: #444;
color: #fff;
text-decoration: none;
} }
} }
} }
...@@ -480,11 +492,39 @@ div.videoalpha { ...@@ -480,11 +492,39 @@ div.videoalpha {
article.video-wrapper { article.video-wrapper {
width: flex-grid(9,9); width: flex-grid(9,9);
background-color: inherit;
}
article.video-wrapper section.video-controls.html5 {
bottom: 0px;
left: 0px;
right: 0px;
position: absolute;
}
article.video-wrapper section.video-controls div.secondary-controls a.hide-subtitles {
background-color: inherit;
color: #797979;
text-decoration: inherit;
}
article.video-wrapper div.video-player-pre, article.video-wrapper div.video-player-post {
height: 0px;
} }
ol.subtitles { ol.subtitles {
width: 0; width: 0;
height: 0; height: 0;
}
ol.subtitles.html5 {
background-color: rgba(243, 243, 243, 0.5);
height: 380px;
position: absolute;
right: 0;
width: 275px;
margin-top: 20px;
} }
} }
...@@ -545,7 +585,7 @@ div.videoalpha { ...@@ -545,7 +585,7 @@ div.videoalpha {
background: rgba(#000, .8); background: rgba(#000, .8);
bottom: 0; bottom: 0;
height: 100%; height: 100%;
max-height: 100%; max-height: 460px;
max-width: flex-grid(3); max-width: flex-grid(3);
padding: lh(); padding: lh();
position: fixed; position: fixed;
......
(function (requirejs, require, define) {
// Bind module.
define(
'videoalpha/display/bind.js',
[],
function () {
// bind() function.
return function (fn, me) {
return function () {
return fn.apply(me, arguments);
};
};
});
}(RequireJS.requirejs, RequireJS.require, RequireJS.define));
// var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
/**
* @file HTML5 video player module. Provides methods to control the in-browser HTML5 video player.
*
* The goal was to write this module so that it closely resembles the YouTube API. The main reason
* for this is because initially the edX video player supported only YouTube videos. When HTML5
* support was added, for greater compatibility, and to reduce the amount of code that needed to
* be modified, it was decided to write a similar API as the one provided by YouTube.
*
* @external RequireJS
*
* @module HTML5Video
*/
(function (requirejs, require, define) { (function (requirejs, require, define) {
// HTML5Video module.
define( define(
'videoalpha/display/html5_video.js', 'videoalpha/display/html5_video.js',
[], [],
...@@ -11,7 +23,7 @@ function () { ...@@ -11,7 +23,7 @@ function () {
HTML5Video.Player = (function () { HTML5Video.Player = (function () {
Player.prototype.callStateChangeCallback = function () { Player.prototype.callStateChangeCallback = function () {
if ($.isFunction(this.config.events.onStateChange) === true) { if ($.isFunction(this.config.events.onStateChange)) {
this.config.events.onStateChange({ this.config.events.onStateChange({
'data': this.playerState 'data': this.playerState
}); });
...@@ -62,7 +74,7 @@ function () { ...@@ -62,7 +74,7 @@ function () {
newSpeed = parseFloat(value); newSpeed = parseFloat(value);
if (isFinite(newSpeed) === true) { if (isFinite(newSpeed)) {
this.video.playbackRate = value; this.video.playbackRate = value;
} }
}; };
...@@ -76,10 +88,10 @@ function () { ...@@ -76,10 +88,10 @@ function () {
/* /*
* Constructor function for HTML5 Video player. * Constructor function for HTML5 Video player.
* *
* @el - A DOM element where the HTML5 player will be inserted (as returned by jQuery(selector) function), * @param {String|Object} el A DOM element where the HTML5 player will be inserted (as returned by jQuery(selector) function),
* or a selector string which will be used to select an element. This is a required parameter. * or a selector string which will be used to select an element. This is a required parameter.
* *
* @config - An object whose properties will be used as configuration options for the HTML5 video * @param config - An object whose properties will be used as configuration options for the HTML5 video
* player. This is an optional parameter. In the case if this parameter is missing, or some of the config * player. This is an optional parameter. In the case if this parameter is missing, or some of the config
* object's properties are missing, defaults will be used. The available options (and their defaults) are as * object's properties are missing, defaults will be used. The available options (and their defaults) are as
* follows: * follows:
...@@ -130,14 +142,14 @@ function () { ...@@ -130,14 +142,14 @@ function () {
} }
// A simple test to see that the 'config' is a normal object. // A simple test to see that the 'config' is a normal object.
if ($.isPlainObject(config) === true) { if ($.isPlainObject(config)) {
this.config = config; this.config = config;
} else { } else {
return; return;
} }
// We should have at least one video source. Otherwise there is no point to continue. // We should have at least one video source. Otherwise there is no point to continue.
if (config.hasOwnProperty('videoSources') === false) { if (!config.videoSources) {
return; return;
} }
...@@ -154,9 +166,8 @@ function () { ...@@ -154,9 +166,8 @@ function () {
// Create HTML markup for individual sources of the HTML5 <video> element. // Create HTML markup for individual sources of the HTML5 <video> element.
$.each(sourceStr, function (videoType, videoSource) { $.each(sourceStr, function (videoType, videoSource) {
if ( if (
(_this.config.videoSources.hasOwnProperty(videoType) === true) && (_this.config.videoSources[videoType]) &&
(typeof _this.config.videoSources[videoType] === 'string') && (_this.config.videoSources[videoType].length)
(_this.config.videoSources[videoType].length > 0)
) { ) {
sourceStr[videoType] = sourceStr[videoType] =
'<source ' + '<source ' +
...@@ -174,14 +185,14 @@ function () { ...@@ -174,14 +185,14 @@ function () {
// Determine the starting and ending time for the video. // Determine the starting and ending time for the video.
this.start = 0; this.start = 0;
this.end = null; this.end = null;
if (config.hasOwnProperty('playerVars') === true) { if (config.playerVars) {
this.start = parseFloat(config.playerVars.start); this.start = parseFloat(config.playerVars.start);
if ((isFinite(this.start) !== true) || (this.start < 0)) { if ((!isFinite(this.start)) || (this.start < 0)) {
this.start = 0; this.start = 0;
} }
this.end = parseFloat(config.playerVars.end); this.end = parseFloat(config.playerVars.end);
if ((isFinite(this.end) !== true) || (this.end < this.start)) { if ((!isFinite(this.end)) || (this.end < this.start)) {
this.end = null; this.end = null;
} }
} }
...@@ -242,7 +253,7 @@ function () { ...@@ -242,7 +253,7 @@ function () {
} }
_this.video.currentTime = _this.start; _this.video.currentTime = _this.start;
if ($.isFunction(_this.config.events.onReady) === true) { if ($.isFunction(_this.config.events.onReady)) {
_this.config.events.onReady(null); _this.config.events.onReady(null);
} }
}, false); }, false);
......
...@@ -3,8 +3,8 @@ ...@@ -3,8 +3,8 @@
// VideoCaption module. // VideoCaption module.
define( define(
'videoalpha/display/video_caption.js', 'videoalpha/display/video_caption.js',
['videoalpha/display/bind.js'], [],
function (bind) { function () {
// VideoCaption() function - what this module "exports". // VideoCaption() function - what this module "exports".
return function (state) { return function (state) {
...@@ -24,23 +24,25 @@ function (bind) { ...@@ -24,23 +24,25 @@ function (bind) {
// Functions which will be accessible via 'state' object. When called, these functions will // Functions which will be accessible via 'state' object. When called, these functions will
// get the 'state' object as a context. // get the 'state' object as a context.
function makeFunctionsPublic(state) { function makeFunctionsPublic(state) {
state.videoCaption.resize = bind(resize, state); state.videoCaption.autoShowCaptions = autoShowCaptions.bind(state);
state.videoCaption.toggle = bind(toggle, state); state.videoCaption.autoHideCaptions = autoHideCaptions.bind(state);
state.videoCaption.onMouseEnter = bind(onMouseEnter, state); state.videoCaption.resize = resize.bind(state);
state.videoCaption.onMouseLeave = bind(onMouseLeave, state); state.videoCaption.toggle = toggle.bind(state);
state.videoCaption.onMovement = bind(onMovement, state); state.videoCaption.onMouseEnter = onMouseEnter.bind(state);
state.videoCaption.renderCaption = bind(renderCaption, state); state.videoCaption.onMouseLeave = onMouseLeave.bind(state);
state.videoCaption.captionHeight = bind(captionHeight, state); state.videoCaption.onMovement = onMovement.bind(state);
state.videoCaption.topSpacingHeight = bind(topSpacingHeight, state); state.videoCaption.renderCaption = renderCaption.bind(state);
state.videoCaption.bottomSpacingHeight = bind(bottomSpacingHeight, state); state.videoCaption.captionHeight = captionHeight.bind(state);
state.videoCaption.scrollCaption = bind(scrollCaption, state); state.videoCaption.topSpacingHeight = topSpacingHeight.bind(state);
state.videoCaption.search = bind(search, state); state.videoCaption.bottomSpacingHeight = bottomSpacingHeight.bind(state);
state.videoCaption.play = bind(play, state); state.videoCaption.scrollCaption = scrollCaption.bind(state);
state.videoCaption.pause = bind(pause, state); state.videoCaption.search = search.bind(state);
state.videoCaption.seekPlayer = bind(seekPlayer, state); state.videoCaption.play = play.bind(state);
state.videoCaption.hideCaptions = bind(hideCaptions, state); state.videoCaption.pause = pause.bind(state);
state.videoCaption.calculateOffset = bind(calculateOffset, state); state.videoCaption.seekPlayer = seekPlayer.bind(state);
state.videoCaption.updatePlayTime = bind(updatePlayTime, state); state.videoCaption.hideCaptions = hideCaptions.bind(state);
state.videoCaption.calculateOffset = calculateOffset.bind(state);
state.videoCaption.updatePlayTime = updatePlayTime.bind(state);
} }
// function renderElements(state) // function renderElements(state)
...@@ -64,6 +66,13 @@ function (bind) { ...@@ -64,6 +66,13 @@ function (bind) {
}); });
fetchCaption(state); fetchCaption(state);
if (state.videoType === 'html5') {
state.videoCaption.fadeOutTimeout = 1400;
state.videoCaption.subtitlesEl.addClass('html5');
state.captionHideTimeout = setTimeout(state.videoCaption.autoHideCaptions, state.videoCaption.fadeOutTimeout);
}
} }
// function bindHandlers(state) // function bindHandlers(state)
...@@ -85,6 +94,10 @@ function (bind) { ...@@ -85,6 +94,10 @@ function (bind) {
'DOMMouseScroll', 'DOMMouseScroll',
state.videoCaption.onMovement state.videoCaption.onMovement
); );
if (state.videoType === 'html5') {
state.el.on('mousemove', state.videoCaption.autoShowCaptions)
}
} }
function fetchCaption(state) { function fetchCaption(state) {
...@@ -106,10 +119,6 @@ function (bind) { ...@@ -106,10 +119,6 @@ function (bind) {
} }
function captionURL(state) { function captionURL(state) {
console.log('We are inside captionURL() function.');
console.log('state.config.caption_asset_path = "' + state.config.caption_asset_path + '".');
console.log('state.youtubeId("1.0") = "' + state.youtubeId('1.0') + '".');
return '' + state.config.caption_asset_path + state.youtubeId('1.0') + '.srt.sjson'; return '' + state.config.caption_asset_path + state.youtubeId('1.0') + '.srt.sjson';
} }
...@@ -119,6 +128,51 @@ function (bind) { ...@@ -119,6 +128,51 @@ function (bind) {
// The magic private function that makes them available and sets up their context is makeFunctionsPublic(). // The magic private function that makes them available and sets up their context is makeFunctionsPublic().
// *************************************************************** // ***************************************************************
function autoShowCaptions(event) {
if (!this.captionsShowLock) {
if (!this.captionsHidden) {
return;
}
this.captionsShowLock = true;
if (this.captionState === 'invisible') {
this.videoCaption.subtitlesEl.show();
this.captionState = 'visible';
this.captionHideTimeout = setTimeout(this.videoCaption.autoHideCaptions, this.videoCaption.fadeOutTimeout);
} else if (this.captionState === 'hiding') {
this.videoCaption.subtitlesEl.stop(true, false);
this.videoCaption.subtitlesEl.css('opacity', 1);
this.videoCaption.subtitlesEl.show();
this.captionState = 'visible';
this.captionHideTimeout = setTimeout(this.videoCaption.autoHideCaptions, this.videoCaption.fadeOutTimeout);
} else if (this.captionState === 'visible') {
clearTimeout(this.captionHideTimeout);
this.captionHideTimeout = setTimeout(this.videoCaption.autoHideCaptions, this.videoCaption.fadeOutTimeout);
}
this.captionsShowLock = false;
}
}
function autoHideCaptions() {
var _this;
this.captionHideTimeout = null;
if (!this.captionsHidden) {
return;
}
this.captionState = 'hiding';
_this = this;
this.videoCaption.subtitlesEl.fadeOut(1000, function () {
_this.captionState = 'invisible';
});
}
function resize() { function resize() {
this.videoCaption.subtitlesEl.css({ this.videoCaption.subtitlesEl.css({
'maxHeight': this.videoCaption.captionHeight() 'maxHeight': this.videoCaption.captionHeight()
...@@ -254,7 +308,7 @@ function (bind) { ...@@ -254,7 +308,7 @@ function (bind) {
event.preventDefault(); event.preventDefault();
time = Math.round(Time.convert($(event.target).data('start'), '1.0', this.speed) / 1000); time = Math.round(Time.convert($(event.target).data('start'), '1.0', this.speed) / 1000);
this.trigger(['videoPlayer', 'onSeek'], time, 'method'); this.trigger(['videoPlayer', 'onSeek'], time);
} }
function calculateOffset(element) { function calculateOffset(element) {
...@@ -281,9 +335,11 @@ function (bind) { ...@@ -281,9 +335,11 @@ function (bind) {
function hideCaptions(hide_captions) { function hideCaptions(hide_captions) {
if (hide_captions) { if (hide_captions) {
this.captionsHidden = true;
this.videoCaption.hideSubtitlesEl.attr('title', 'Turn on captions'); this.videoCaption.hideSubtitlesEl.attr('title', 'Turn on captions');
this.el.addClass('closed'); this.el.addClass('closed');
} else { } else {
this.captionsHidden = false;
this.videoCaption.hideSubtitlesEl.attr('title', 'Turn off captions'); this.videoCaption.hideSubtitlesEl.attr('title', 'Turn off captions');
this.el.removeClass('closed'); this.el.removeClass('closed');
this.videoCaption.scrollCaption(); this.videoCaption.scrollCaption();
......
...@@ -3,8 +3,8 @@ ...@@ -3,8 +3,8 @@
// VideoControl module. // VideoControl module.
define( define(
'videoalpha/display/video_control.js', 'videoalpha/display/video_control.js',
['videoalpha/display/bind.js'], [],
function (bind) { function () {
// VideoControl() function - what this module "exports". // VideoControl() function - what this module "exports".
return function (state) { return function (state) {
...@@ -24,14 +24,14 @@ function (bind) { ...@@ -24,14 +24,14 @@ function (bind) {
// Functions which will be accessible via 'state' object. When called, these functions will // Functions which will be accessible via 'state' object. When called, these functions will
// get the 'state' object as a context. // get the 'state' object as a context.
function makeFunctionsPublic(state) { function makeFunctionsPublic(state) {
state.videoControl.showControls = bind(showControls, state); state.videoControl.showControls = showControls.bind(state);
state.videoControl.hideControls = bind(hideControls, state); state.videoControl.hideControls = hideControls.bind(state);
state.videoControl.play = bind(play, state); state.videoControl.play = play.bind(state);
state.videoControl.pause = bind(pause, state); state.videoControl.pause = pause.bind(state);
state.videoControl.togglePlayback = bind(togglePlayback, state); state.videoControl.togglePlayback = togglePlayback.bind(state);
state.videoControl.toggleFullScreen = bind(toggleFullScreen, state); state.videoControl.toggleFullScreen = toggleFullScreen.bind(state);
state.videoControl.exitFullScreen = bind(exitFullScreen, state); state.videoControl.exitFullScreen = exitFullScreen.bind(state);
state.videoControl.updateVcrVidTime = bind(updateVcrVidTime, state); state.videoControl.updateVcrVidTime = updateVcrVidTime.bind(state);
} }
// function renderElements(state) // function renderElements(state)
...@@ -41,7 +41,7 @@ function (bind) { ...@@ -41,7 +41,7 @@ function (bind) {
// way - you don't have to do repeated jQuery element selects. // way - you don't have to do repeated jQuery element selects.
function renderElements(state) { function renderElements(state) {
var el, qTipConfig; var el, qTipConfig;
// REFACTOR move templates and css to one file- to python part
el = $( el = $(
'<div class="slider"></div>' + '<div class="slider"></div>' +
'<div>' + '<div>' +
...@@ -82,8 +82,12 @@ function (bind) { ...@@ -82,8 +82,12 @@ function (bind) {
state.videoControl.play(); state.videoControl.play();
} }
state.controlHideTimeout = setTimeout(state.videoControl.hideControls, 3000); if (state.videoType === 'html5') {
state.el.find('.video-roof').on('mousemove', state.videoControl.showControls); state.videoControl.fadeOutTimeout = 1400;
state.videoControl.el.addClass('html5');
state.controlHideTimeout = setTimeout(state.videoControl.hideControls, state.videoControl.fadeOutTimeout);
}
} }
// function bindHandlers(state) // function bindHandlers(state)
...@@ -93,6 +97,10 @@ function (bind) { ...@@ -93,6 +97,10 @@ function (bind) {
state.videoControl.playPauseEl.on('click', state.videoControl.togglePlayback); state.videoControl.playPauseEl.on('click', state.videoControl.togglePlayback);
state.videoControl.fullScreenEl.on('click', state.videoControl.toggleFullScreen); state.videoControl.fullScreenEl.on('click', state.videoControl.toggleFullScreen);
$(document).on('keyup', state.videoControl.exitFullScreen); $(document).on('keyup', state.videoControl.exitFullScreen);
if (state.videoType === 'html5') {
state.el.on('mousemove', state.videoControl.showControls)
}
} }
// *************************************************************** // ***************************************************************
...@@ -100,61 +108,32 @@ function (bind) { ...@@ -100,61 +108,32 @@ function (bind) {
// These are available via the 'state' object. Their context ('this' keyword) is the 'state' object. // These are available via the 'state' object. Their context ('this' keyword) is the 'state' object.
// The magic private function that makes them available and sets up their context is makeFunctionsPublic(). // The magic private function that makes them available and sets up their context is makeFunctionsPublic().
// *************************************************************** // ***************************************************************
// REFACTOR document
function showControls(event) { function showControls(event) {
var elPosition, elWidth, elHeight; if (!this.controlShowLock) {
if (!this.captionsHidden) {
normalize(event); return;
}
elPosition = this.el.position();
elWidth = this.el.width();
elHeight = this.el.height();
if (
(event.pageX < elPosition.left) ||
(event.pageX > elPosition.left + elWidth) ||
(event.pageY < elPosition.top) ||
(event.pageY > elPosition.top + elHeight)
) {
return;
}
if (this.controlState === 'invisible') {
this.videoControl.el.show();
this.controlState = 'visible';
this.controlHideTimeout = setTimeout(this.videoControl.hideControls, 3000);
}/* else if (this.controlState === 'hiding') {
this.videoControl.el.stop(true, false);
this.videoControl.el.show();
this.controlState = 'visible';
this.controlHideTimeout = setTimeout(this.videoControl.hideControls, 3000);
}*/ else if (this.controlState === 'visible') {
clearTimeout(this.controlHideTimeout);
this.controlHideTimeout = setTimeout(this.videoControl.hideControls, 3000);
}
this.controlShowLock = false;
if (this.videoPlayer && this.videoPlayer.player) {
(function (event, _this) {
var c1;
c1 = 0;
_this.el.find('#' + _this.id).children().each(function (index, value) {
$(value).trigger(event);
c1 += 1;
});
}(event, this));
}
return;
function normalize(event) { this.controlShowLock = true;
if(!event.offsetX) {
event.offsetX = (event.pageX - $(event.target).offset().left); // Refactor: separate UI state in object. No code duplication.
event.offsetY = (event.pageY - $(event.target).offset().top); if (this.controlState === 'invisible') {
this.videoControl.el.show();
this.controlState = 'visible';
this.controlHideTimeout = setTimeout(this.videoControl.hideControls, this.videoControl.fadeOutTimeout);
} else if (this.controlState === 'hiding') {
this.videoControl.el.stop(true, false);
this.videoControl.el.css('opacity', 1);
this.videoControl.el.show();
this.controlState = 'visible';
this.controlHideTimeout = setTimeout(this.videoControl.hideControls, this.videoControl.fadeOutTimeout);
} else if (this.controlState === 'visible') {
clearTimeout(this.controlHideTimeout);
this.controlHideTimeout = setTimeout(this.videoControl.hideControls, this.videoControl.fadeOutTimeout);
} }
return event; this.controlShowLock = false;
} }
} }
...@@ -162,6 +141,11 @@ function (bind) { ...@@ -162,6 +141,11 @@ function (bind) {
var _this; var _this;
this.controlHideTimeout = null; this.controlHideTimeout = null;
if (!this.captionsHidden) {
return;
}
this.controlState = 'hiding'; this.controlState = 'hiding';
_this = this; _this = this;
...@@ -185,16 +169,16 @@ function (bind) { ...@@ -185,16 +169,16 @@ function (bind) {
event.preventDefault(); event.preventDefault();
if (this.videoControl.playPauseState === 'playing') { if (this.videoControl.playPauseState === 'playing') {
this.trigger(['videoPlayer', 'pause'], null, 'method'); this.trigger(['videoPlayer', 'pause'], null);
} else { // if (this.videoControl.playPauseState === 'paused') { } else { // if (this.videoControl.playPauseState === 'paused') {
this.trigger(['videoPlayer', 'play'], null, 'method'); this.trigger(['videoPlayer', 'play'], null);
} }
} }
function toggleFullScreen(event) { function toggleFullScreen(event) {
event.preventDefault(); event.preventDefault();
if (this.videoControl.fullScreenState === true) { if (this.videoControl.fullScreenState) {
this.videoControl.fullScreenState = false; this.videoControl.fullScreenState = false;
this.el.removeClass('fullscreen'); this.el.removeClass('fullscreen');
this.videoControl.fullScreenEl.attr('title', 'Fill browser'); this.videoControl.fullScreenEl.attr('title', 'Fill browser');
...@@ -204,11 +188,11 @@ function (bind) { ...@@ -204,11 +188,11 @@ function (bind) {
this.videoControl.fullScreenEl.attr('title', 'Exit fill browser'); this.videoControl.fullScreenEl.attr('title', 'Exit fill browser');
} }
this.trigger(['videoCaption', 'resize'], null, 'method'); this.trigger(['videoCaption', 'resize'], null);
} }
function exitFullScreen(event) { function exitFullScreen(event) {
if ((this.el.hasClass('fullscreen') === true) && (event.keyCode === 27)) { if ((this.el.hasClass('fullscreen')) && (event.keyCode === 27)) {
this.videoControl.toggleFullScreen(event); this.videoControl.toggleFullScreen(event);
} }
} }
......
...@@ -3,11 +3,8 @@ ...@@ -3,11 +3,8 @@
// VideoPlayer module. // VideoPlayer module.
define( define(
'videoalpha/display/video_player.js', 'videoalpha/display/video_player.js',
[ ['videoalpha/display/html5_video.js'],
'videoalpha/display/html5_video.js', function (HTML5Video) {
'videoalpha/display/bind.js'
],
function (HTML5Video, bind) {
// VideoPlayer() function - what this module "exports". // VideoPlayer() function - what this module "exports".
return function (state) { return function (state) {
...@@ -27,24 +24,24 @@ function (HTML5Video, bind) { ...@@ -27,24 +24,24 @@ function (HTML5Video, bind) {
// Functions which will be accessible via 'state' object. When called, these functions will // Functions which will be accessible via 'state' object. When called, these functions will
// get the 'state' object as a context. // get the 'state' object as a context.
function makeFunctionsPublic(state) { function makeFunctionsPublic(state) {
state.videoPlayer.pause = bind(pause, state); state.videoPlayer.pause = pause.bind(state);
state.videoPlayer.play = bind(play, state); state.videoPlayer.play = play.bind(state);
state.videoPlayer.update = bind(update, state); state.videoPlayer.update = update.bind(state);
state.videoPlayer.onSpeedChange = bind(onSpeedChange, state); state.videoPlayer.onSpeedChange = onSpeedChange.bind(state);
state.videoPlayer.onSeek = bind(onSeek, state); state.videoPlayer.onSeek = onSeek.bind(state);
state.videoPlayer.onEnded = bind(onEnded, state); state.videoPlayer.onEnded = onEnded.bind(state);
state.videoPlayer.onPause = bind(onPause, state); state.videoPlayer.onPause = onPause.bind(state);
state.videoPlayer.onPlay = bind(onPlay, state); state.videoPlayer.onPlay = onPlay.bind(state);
state.videoPlayer.onUnstarted = bind(onUnstarted, state); state.videoPlayer.onUnstarted = onUnstarted.bind(state);
state.videoPlayer.handlePlaybackQualityChange = bind(handlePlaybackQualityChange, state); state.videoPlayer.handlePlaybackQualityChange = handlePlaybackQualityChange.bind(state);
state.videoPlayer.onPlaybackQualityChange = bind(onPlaybackQualityChange, state); state.videoPlayer.onPlaybackQualityChange = onPlaybackQualityChange.bind(state);
state.videoPlayer.onStateChange = bind(onStateChange, state); state.videoPlayer.onStateChange = onStateChange.bind(state);
state.videoPlayer.onReady = bind(onReady, state); state.videoPlayer.onReady = onReady.bind(state);
state.videoPlayer.updatePlayTime = bind(updatePlayTime, state); state.videoPlayer.updatePlayTime = updatePlayTime.bind(state);
state.videoPlayer.isPlaying = bind(isPlaying, state); state.videoPlayer.isPlaying = isPlaying.bind(state);
state.videoPlayer.log = bind(log, state); state.videoPlayer.log = log.bind(state);
state.videoPlayer.duration = bind(duration, state); state.videoPlayer.duration = duration.bind(state);
state.videoPlayer.onVolumeChange = bind(onVolumeChange, state); state.videoPlayer.onVolumeChange = onVolumeChange.bind(state);
} }
// function renderElements(state) // function renderElements(state)
...@@ -171,7 +168,7 @@ function (HTML5Video, bind) { ...@@ -171,7 +168,7 @@ function (HTML5Video, bind) {
function update() { function update() {
this.videoPlayer.currentTime = this.videoPlayer.player.getCurrentTime(); this.videoPlayer.currentTime = this.videoPlayer.player.getCurrentTime();
if (isFinite(this.videoPlayer.currentTime) === true) { if (isFinite(this.videoPlayer.currentTime)) {
this.videoPlayer.updatePlayTime(this.videoPlayer.currentTime); this.videoPlayer.updatePlayTime(this.videoPlayer.currentTime);
} }
} }
...@@ -214,7 +211,7 @@ function (HTML5Video, bind) { ...@@ -214,7 +211,7 @@ function (HTML5Video, bind) {
} }
function onEnded() { function onEnded() {
this.trigger(['videoControl','pause'], null, 'method'); this.trigger(['videoControl','pause'], null);
} }
function onPause() { function onPause() {
...@@ -223,7 +220,7 @@ function (HTML5Video, bind) { ...@@ -223,7 +220,7 @@ function (HTML5Video, bind) {
clearInterval(this.videoPlayer.updateInterval); clearInterval(this.videoPlayer.updateInterval);
delete this.videoPlayer.updateInterval; delete this.videoPlayer.updateInterval;
this.trigger(['videoControl','pause'], null, 'method'); this.trigger(['videoControl','pause'], null);
} }
function onPlay() { function onPlay() {
...@@ -233,7 +230,7 @@ function (HTML5Video, bind) { ...@@ -233,7 +230,7 @@ function (HTML5Video, bind) {
this.videoPlayer.updateInterval = setInterval(this.videoPlayer.update, 200); this.videoPlayer.updateInterval = setInterval(this.videoPlayer.update, 200);
} }
this.trigger(['videoControl','play'], null, 'method'); this.trigger(['videoControl','play'], null);
} }
function onUnstarted() { } function onUnstarted() { }
...@@ -247,7 +244,7 @@ function (HTML5Video, bind) { ...@@ -247,7 +244,7 @@ function (HTML5Video, bind) {
quality = this.videoPlayer.player.getPlaybackQuality(); quality = this.videoPlayer.player.getPlaybackQuality();
this.trigger(['videoQualityControl', 'onQualityChange'], quality, 'method'); this.trigger(['videoQualityControl', 'onQualityChange'], quality);
} }
function onReady() { function onReady() {
...@@ -274,7 +271,7 @@ function (HTML5Video, bind) { ...@@ -274,7 +271,7 @@ function (HTML5Video, bind) {
_this.speeds.push(value.toFixed(2).replace(/\.00$/, '.0')); _this.speeds.push(value.toFixed(2).replace(/\.00$/, '.0'));
}); });
this.trigger(['videoSpeedControl', 'reRender'], {'newSpeeds': this.speeds, 'currentSpeed': this.speed}, 'method'); this.trigger(['videoSpeedControl', 'reRender'], {'newSpeeds': this.speeds, 'currentSpeed': this.speed});
this.setSpeed($.cookie('video_speed')); this.setSpeed($.cookie('video_speed'));
} }
...@@ -311,9 +308,9 @@ function (HTML5Video, bind) { ...@@ -311,9 +308,9 @@ function (HTML5Video, bind) {
duration = this.videoPlayer.duration(); duration = this.videoPlayer.duration();
this.trigger(['videoProgressSlider', 'updatePlayTime'], {'time': time, 'duration': duration}, 'method'); this.trigger(['videoProgressSlider', 'updatePlayTime'], {'time': time, 'duration': duration});
this.trigger(['videoControl', 'updateVcrVidTime'], {'time': time, 'duration': duration}, 'method'); this.trigger(['videoControl', 'updateVcrVidTime'], {'time': time, 'duration': duration});
this.trigger(['videoCaption', 'updatePlayTime'], time, 'method'); this.trigger(['videoCaption', 'updatePlayTime'], time);
} }
function isPlaying() { function isPlaying() {
...@@ -324,7 +321,7 @@ function (HTML5Video, bind) { ...@@ -324,7 +321,7 @@ function (HTML5Video, bind) {
var duration; var duration;
duration = this.videoPlayer.player.getDuration(); duration = this.videoPlayer.player.getDuration();
if (isFinite(duration) === false) { if (!isFinite(duration)) {
duration = this.getDuration(); duration = this.getDuration();
} }
......
...@@ -10,8 +10,8 @@ mind, or whether to act, and in acting, to live." ...@@ -10,8 +10,8 @@ mind, or whether to act, and in acting, to live."
// VideoProgressSlider module. // VideoProgressSlider module.
define( define(
'videoalpha/display/video_progress_slider.js', 'videoalpha/display/video_progress_slider.js',
['videoalpha/display/bind.js'], [],
function (bind) { function () {
// VideoProgressSlider() function - what this module "exports". // VideoProgressSlider() function - what this module "exports".
return function (state) { return function (state) {
...@@ -31,11 +31,11 @@ function (bind) { ...@@ -31,11 +31,11 @@ function (bind) {
// Functions which will be accessible via 'state' object. When called, these functions will // Functions which will be accessible via 'state' object. When called, these functions will
// get the 'state' object as a context. // get the 'state' object as a context.
function makeFunctionsPublic(state) { function makeFunctionsPublic(state) {
state.videoProgressSlider.onSlide = bind(onSlide, state); state.videoProgressSlider.onSlide = onSlide.bind(state);
state.videoProgressSlider.onChange = bind(onChange, state); state.videoProgressSlider.onChange = onChange.bind(state);
state.videoProgressSlider.onStop = bind(onStop, state); state.videoProgressSlider.onStop = onStop.bind(state);
state.videoProgressSlider.updateTooltip = bind(updateTooltip, state); state.videoProgressSlider.updateTooltip = updateTooltip.bind(state);
state.videoProgressSlider.updatePlayTime = bind(updatePlayTime, state); state.videoProgressSlider.updatePlayTime = updatePlayTime.bind(state);
} }
// function renderElements(state) // function renderElements(state)
...@@ -98,7 +98,7 @@ function (bind) { ...@@ -98,7 +98,7 @@ function (bind) {
this.videoProgressSlider.frozen = true; this.videoProgressSlider.frozen = true;
this.videoProgressSlider.updateTooltip(ui.value); this.videoProgressSlider.updateTooltip(ui.value);
this.trigger(['videoPlayer', 'onSeek'], ui.value, 'method'); this.trigger(['videoPlayer', 'onSeek'], ui.value);
} }
function onChange(event, ui) { function onChange(event, ui) {
...@@ -112,7 +112,7 @@ function (bind) { ...@@ -112,7 +112,7 @@ function (bind) {
this.videoProgressSlider.frozen = true; this.videoProgressSlider.frozen = true;
this.trigger(['videoPlayer', 'onSeek'], ui.value, 'method'); this.trigger(['videoPlayer', 'onSeek'], ui.value);
setTimeout(function() { setTimeout(function() {
_this.videoProgressSlider.frozen = false; _this.videoProgressSlider.frozen = false;
......
...@@ -3,8 +3,8 @@ ...@@ -3,8 +3,8 @@
// VideoQualityControl module. // VideoQualityControl module.
define( define(
'videoalpha/display/video_quality_control.js', 'videoalpha/display/video_quality_control.js',
['videoalpha/display/bind.js'], [],
function (bind) { function () {
// VideoQualityControl() function - what this module "exports". // VideoQualityControl() function - what this module "exports".
return function (state) { return function (state) {
...@@ -29,8 +29,8 @@ function (bind) { ...@@ -29,8 +29,8 @@ function (bind) {
// Functions which will be accessible via 'state' object. When called, these functions will // Functions which will be accessible via 'state' object. When called, these functions will
// get the 'state' object as a context. // get the 'state' object as a context.
function makeFunctionsPublic(state) { function makeFunctionsPublic(state) {
state.videoQualityControl.onQualityChange = bind(onQualityChange, state); state.videoQualityControl.onQualityChange = onQualityChange.bind(state);
state.videoQualityControl.toggleQuality = bind(toggleQuality, state); state.videoQualityControl.toggleQuality = toggleQuality.bind(state);
} }
// function renderElements(state) // function renderElements(state)
...@@ -92,7 +92,7 @@ function (bind) { ...@@ -92,7 +92,7 @@ function (bind) {
newQuality = 'hd720'; newQuality = 'hd720';
} }
this.trigger(['videoPlayer', 'handlePlaybackQualityChange'], newQuality, 'method'); this.trigger(['videoPlayer', 'handlePlaybackQualityChange'], newQuality);
} }
}); });
......
...@@ -3,8 +3,8 @@ ...@@ -3,8 +3,8 @@
// VideoSpeedControl module. // VideoSpeedControl module.
define( define(
'videoalpha/display/video_speed_control.js', 'videoalpha/display/video_speed_control.js',
['videoalpha/display/bind.js'], [],
function (bind) { function () {
// VideoSpeedControl() function - what this module "exports". // VideoSpeedControl() function - what this module "exports".
return function (state) { return function (state) {
...@@ -24,9 +24,9 @@ function (bind) { ...@@ -24,9 +24,9 @@ function (bind) {
// Functions which will be accessible via 'state' object. When called, these functions will // Functions which will be accessible via 'state' object. When called, these functions will
// get the 'state' object as a context. // get the 'state' object as a context.
function makeFunctionsPublic(state) { function makeFunctionsPublic(state) {
state.videoSpeedControl.changeVideoSpeed = bind(changeVideoSpeed, state); state.videoSpeedControl.changeVideoSpeed = changeVideoSpeed.bind(state);
state.videoSpeedControl.setSpeed = bind(setSpeed, state); state.videoSpeedControl.setSpeed = setSpeed.bind(state);
state.videoSpeedControl.reRender = bind(reRender, state); state.videoSpeedControl.reRender = reRender.bind(state);
} }
// function renderElements(state) // function renderElements(state)
...@@ -113,7 +113,7 @@ function (bind) { ...@@ -113,7 +113,7 @@ function (bind) {
parseFloat(this.videoSpeedControl.currentSpeed).toFixed(2).replace(/\.00$/, '.0') parseFloat(this.videoSpeedControl.currentSpeed).toFixed(2).replace(/\.00$/, '.0')
); );
this.trigger(['videoPlayer', 'onSpeedChange'], this.videoSpeedControl.currentSpeed, 'method'); this.trigger(['videoPlayer', 'onSpeedChange'], this.videoSpeedControl.currentSpeed);
} }
} }
......
...@@ -3,8 +3,8 @@ ...@@ -3,8 +3,8 @@
// VideoVolumeControl module. // VideoVolumeControl module.
define( define(
'videoalpha/display/video_volume_control.js', 'videoalpha/display/video_volume_control.js',
['videoalpha/display/bind.js'], [],
function (bind) { function () {
// VideoVolumeControl() function - what this module "exports". // VideoVolumeControl() function - what this module "exports".
return function (state) { return function (state) {
...@@ -24,8 +24,8 @@ function (bind) { ...@@ -24,8 +24,8 @@ function (bind) {
// Functions which will be accessible via 'state' object. When called, these functions will // Functions which will be accessible via 'state' object. When called, these functions will
// get the 'state' object as a context. // get the 'state' object as a context.
function makeFunctionsPublic(state) { function makeFunctionsPublic(state) {
state.videoVolumeControl.onChange = bind(onChange, state); state.videoVolumeControl.onChange = onChange.bind(state);
state.videoVolumeControl.toggleMute = bind(toggleMute, state); state.videoVolumeControl.toggleMute = toggleMute.bind(state);
} }
// function renderElements(state) // function renderElements(state)
...@@ -54,7 +54,7 @@ function (bind) { ...@@ -54,7 +54,7 @@ function (bind) {
state.videoVolumeControl.currentVolume = parseInt($.cookie('video_player_volume_level'), 10); state.videoVolumeControl.currentVolume = parseInt($.cookie('video_player_volume_level'), 10);
state.videoVolumeControl.previousVolume = 100; state.videoVolumeControl.previousVolume = 100;
if ( if (
(isFinite(state.videoVolumeControl.currentVolume) === false) || (!isFinite(state.videoVolumeControl.currentVolume)) ||
(state.videoVolumeControl.currentVolume < 0) || (state.videoVolumeControl.currentVolume < 0) ||
(state.videoVolumeControl.currentVolume > 100) (state.videoVolumeControl.currentVolume > 100)
) { ) {
...@@ -104,7 +104,7 @@ function (bind) { ...@@ -104,7 +104,7 @@ function (bind) {
'path': '/' 'path': '/'
}); });
this.trigger(['videoPlayer', 'onVolumeChange'], ui.value, 'method'); this.trigger(['videoPlayer', 'onVolumeChange'], ui.value);
} }
function toggleMute(event) { function toggleMute(event) {
......
...@@ -69,7 +69,6 @@ class VideoAlphaModule(VideoAlphaFields, XModule): ...@@ -69,7 +69,6 @@ class VideoAlphaModule(VideoAlphaFields, XModule):
js = { js = {
'js': [ 'js': [
resource_string(__name__, 'js/src/videoalpha/display/bind.js'),
resource_string(__name__, 'js/src/videoalpha/display/initialize.js'), resource_string(__name__, 'js/src/videoalpha/display/initialize.js'),
resource_string(__name__, 'js/src/videoalpha/display/html5_video.js'), resource_string(__name__, 'js/src/videoalpha/display/html5_video.js'),
resource_string(__name__, 'js/src/videoalpha/display/video_player.js'), resource_string(__name__, 'js/src/videoalpha/display/video_player.js'),
......
...@@ -29,10 +29,11 @@ ...@@ -29,10 +29,11 @@
> >
<div class="tc-wrapper"> <div class="tc-wrapper">
<article class="video-wrapper"> <article class="video-wrapper">
<div class="video-player-pre"></div>
<section class="video-player"> <section class="video-player">
<div id="${id}"></div> <div id="${id}"></div>
</section> </section>
<section class="video-roof"></section> <div class="video-player-post"></div>
<section class="video-controls"></section> <section class="video-controls"></section>
</article> </article>
</div> </div>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment