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);
......
/**
* @file Initialize module works with the JSON config, and sets up various settings, parameters,
* variables. After all setup actions are performed, it invokes the video player to play the
* specified video. This module must be invoked first. It provides several functions which do not
* fit in with other modules.
*
* @external VideoPlayer
*
* @module Initialize
*/
(function (requirejs, require, define) { (function (requirejs, require, define) {
// Initialize module.
define( define(
'videoalpha/display/initialize.js', 'videoalpha/display/initialize.js',
[ ['videoalpha/display/video_player.js'],
'videoalpha/display/bind.js', function (VideoPlayer) {
'videoalpha/display/video_player.js'
],
function (bind, VideoPlayer) {
// Initialize() function - what this module "exports". /**
* @function
*
* Initialize module exports this function.
*
* @param {Object} state A place for all properties, and methods of Video Alpha.
* @param {DOM element} element Container of the entire Video Alpha DOM element.
*/
return function (state, element) { return function (state, element) {
checkForNativeFunctions();
makeFunctionsPublic(state); makeFunctionsPublic(state);
renderElements(state, element); renderElements(state, element);
}; };
...@@ -19,15 +34,19 @@ function (bind, VideoPlayer) { ...@@ -19,15 +34,19 @@ function (bind, VideoPlayer) {
// Private functions start here. // Private functions start here.
// *************************************************************** // ***************************************************************
// function makeFunctionsPublic(state) /**
// * @function makeFunctionsPublic
// Functions which will be accessible via 'state' object. When called, these functions will *
// get the 'state' object as a context. * Functions which will be accessible via 'state' object. When called, these functions will get the 'state'
* object as a context.
*
* @param {Object} state A place for all properties, and methods of Video Alpha.
*/
function makeFunctionsPublic(state) { function makeFunctionsPublic(state) {
state.setSpeed = bind(setSpeed, state); state.setSpeed = setSpeed.bind(state);
state.youtubeId = bind(youtubeId, state); state.youtubeId = youtubeId.bind(state);
state.getDuration = bind(getDuration, state); state.getDuration = getDuration.bind(state);
state.trigger = bind(trigger, state); state.trigger = trigger.bind(state);
} }
// function renderElements(state) // function renderElements(state)
...@@ -36,6 +55,8 @@ function (bind, VideoPlayer) { ...@@ -36,6 +55,8 @@ function (bind, VideoPlayer) {
// make the created DOM elements available via the 'state' object. Much easier to work this // make the created DOM elements available via the 'state' object. Much easier to work this
// 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, element) { function renderElements(state, element) {
var onPlayerReadyFunc;
// The parent element of the video, and the ID. // The parent element of the video, and the ID.
state.el = $(element).find('.videoalpha'); state.el = $(element).find('.videoalpha');
state.id = state.el.attr('id').replace(/video_/, ''); state.id = state.el.attr('id').replace(/video_/, '');
...@@ -50,8 +71,7 @@ function (bind, VideoPlayer) { ...@@ -50,8 +71,7 @@ function (bind, VideoPlayer) {
'caption_data_dir': state.el.data('caption-data-dir'), 'caption_data_dir': state.el.data('caption-data-dir'),
'caption_asset_path': state.el.data('caption-asset-path'), 'caption_asset_path': state.el.data('caption-asset-path'),
'show_captions': (state.el.data('show-captions').toString() === 'true'), 'show_captions': (state.el.data('show-captions').toString().toLowerCase === 'true'),
'youtubeStreams': state.el.data('streams'), 'youtubeStreams': state.el.data('streams'),
'sub': state.el.data('sub'), 'sub': state.el.data('sub'),
...@@ -61,7 +81,7 @@ function (bind, VideoPlayer) { ...@@ -61,7 +81,7 @@ function (bind, VideoPlayer) {
}; };
// Try to parse YouTube stream ID's. If // Try to parse YouTube stream ID's. If
if (parseYoutubeStreams(state, state.config.youtubeStreams) === true) { if (parseYoutubeStreams(state, state.config.youtubeStreams)) {
state.videoType = 'youtube'; state.videoType = 'youtube';
fetchMetadata(state); fetchMetadata(state);
...@@ -74,12 +94,14 @@ function (bind, VideoPlayer) { ...@@ -74,12 +94,14 @@ function (bind, VideoPlayer) {
parseVideoSources( parseVideoSources(
state, state,
state.config.mp4Source, {
state.config.webmSource, 'mp4': state.config.mp4Source,
state.config.oggSource 'webm': state.config.webmSource,
'ogg': state.config.oggSource
}
); );
if ((typeof state.config.sub !== 'string') || (state.config.sub.length === 0)) { if (!state.config.sub.length) {
state.config.sub = ''; state.config.sub = '';
state.config.show_captions = false; state.config.show_captions = false;
} }
...@@ -108,7 +130,7 @@ function (bind, VideoPlayer) { ...@@ -108,7 +130,7 @@ function (bind, VideoPlayer) {
// state.hide_captions = true | false // state.hide_captions = true | false
// //
// represents the user's choice of having the subtitles shown or hidden. This choice is stored in cookies. // represents the user's choice of having the subtitles shown or hidden. This choice is stored in cookies.
if (state.config.show_captions === true) { if (state.config.show_captions) {
state.hide_captions = ($.cookie('hide_captions') === 'true'); state.hide_captions = ($.cookie('hide_captions') === 'true');
} else { } else {
state.hide_captions = true; state.hide_captions = true;
...@@ -141,6 +163,8 @@ function (bind, VideoPlayer) { ...@@ -141,6 +163,8 @@ function (bind, VideoPlayer) {
// Possible value are: 'visible', 'hiding', and 'invisible'. // Possible value are: 'visible', 'hiding', and 'invisible'.
state.controlState = 'visible'; state.controlState = 'visible';
state.controlHideTimeout = null; state.controlHideTimeout = null;
state.captionState = 'visible';
state.captionHideTimeout = null;
// Launch embedding of actual video content, or set it up so that it will be done as soon as the // Launch embedding of actual video content, or set it up so that it will be done as soon as the
// appropriate video player (YouTube or stand alone HTML5) is loaded, and can handle embedding. // appropriate video player (YouTube or stand alone HTML5) is loaded, and can handle embedding.
...@@ -152,17 +176,10 @@ function (bind, VideoPlayer) { ...@@ -152,17 +176,10 @@ function (bind, VideoPlayer) {
((state.videoType === 'youtube') && (window.YT) && (window.YT.Player)) || ((state.videoType === 'youtube') && (window.YT) && (window.YT.Player)) ||
(state.videoType === 'html5') (state.videoType === 'html5')
) { ) {
embed(state); VideoPlayer(state);
} else { } else {
if (state.videoType === 'youtube') { onPlayerReadyFunc = (state.videoType === 'youtube') ? 'onYouTubePlayerAPIReady' : 'onHTML5PlayerAPIReady';
window.onYouTubePlayerAPIReady = function() { window[onPlayerReadyFunc] = VideoPlayer.bind(window, state);
embed(state);
};
} else { // if (state.videoType === 'html5') {
window.onHTML5PlayerAPIReady = function() {
embed(state);
};
}
} }
} }
...@@ -176,8 +193,10 @@ function (bind, VideoPlayer) { ...@@ -176,8 +193,10 @@ function (bind, VideoPlayer) {
// @return // @return
// false: We don't have YouTube video IDs to work with; most likely we have HTML5 video sources. // false: We don't have YouTube video IDs to work with; most likely we have HTML5 video sources.
// true: Parsing of YouTube video IDs went OK, and we can proceed onwards to play YouTube videos. // true: Parsing of YouTube video IDs went OK, and we can proceed onwards to play YouTube videos.
function parseYoutubeStreams(state, youtubeStreams) { function parseYoutubeStreams(state, youtubeStreams) {
if ((typeof youtubeStreams !== 'string') || (youtubeStreams.length === 0)) { if (!youtubeStreams.length) {
return false; return false;
} }
...@@ -199,18 +218,14 @@ function (bind, VideoPlayer) { ...@@ -199,18 +218,14 @@ function (bind, VideoPlayer) {
// //
// Take the HTML5 sources (URLs of videos), and make them available explictly for each type // Take the HTML5 sources (URLs of videos), and make them available explictly for each type
// of video format (mp4, webm, ogg). // of video format (mp4, webm, ogg).
function parseVideoSources(state, mp4Source, webmSource, oggSource) { function parseVideoSources(state, sources) {
state.html5Sources = { 'mp4': null, 'webm': null, 'ogg': null }; state.html5Sources = { 'mp4': null, 'webm': null, 'ogg': null };
if ((typeof mp4Source === 'string') && (mp4Source.length > 0)) { $.each(sources, function (name, source) {
state.html5Sources.mp4 = mp4Source; if (source.length) {
} state.html5Sources[name] = source;
if ((typeof webmSource === 'string') && (webmSource.length > 0)) { }
state.html5Sources.webm = webmSource; });
}
if ((typeof oggSource === 'string') && (oggSource.length > 0)) {
state.html5Sources.ogg = oggSource;
}
} }
// function fetchMetadata(state) // function fetchMetadata(state)
...@@ -239,12 +254,38 @@ function (bind, VideoPlayer) { ...@@ -239,12 +254,38 @@ function (bind, VideoPlayer) {
state.setSpeed($.cookie('video_speed')); state.setSpeed($.cookie('video_speed'));
} }
// function embed(state) function checkForNativeFunctions() {
// // The bind function is a recent addition to ECMA-262, 5th edition; as such it may not be present in all
// This function is called when the current type of video player API becomes available. // browsers. You can partially work around this by inserting the following code at the beginning of your
// It instantiates the core video module. // scripts, allowing use of much of the functionality of bind() in implementations that do not natively support
function embed(state) { // it.
VideoPlayer(state); //
// https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/bind
if (!Function.prototype.bind) {
Function.prototype.bind = function (oThis) {
var aArgs, fToBind, fNOP, fBound;
if (typeof this !== 'function') {
// closest thing possible to the ECMAScript 5 internal IsCallable function
throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
}
aArgs = Array.prototype.slice.call(arguments, 1);
fToBind = this;
fNOP = function () {};
fBound = function () {
return fToBind.apply(
this instanceof fNOP && oThis ? this : oThis,
aArgs.concat(Array.prototype.slice.call(arguments))
);
};
fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();
return fBound;
};
}
} }
// *************************************************************** // ***************************************************************
...@@ -260,7 +301,7 @@ function (bind, VideoPlayer) { ...@@ -260,7 +301,7 @@ function (bind, VideoPlayer) {
this.speed = '1.0'; this.speed = '1.0';
} }
if (updateCookie !== false) { if (updateCookie) {
$.cookie('video_speed', this.speed, { $.cookie('video_speed', this.speed, {
'expires': 3650, 'expires': 3650,
'path': '/' 'path': '/'
...@@ -281,7 +322,8 @@ function (bind, VideoPlayer) { ...@@ -281,7 +322,8 @@ function (bind, VideoPlayer) {
* 'event' * 'event'
* 'method' * 'method'
* *
* Based on this parameter, this function can be used in two ways. * The default value (if @callType and @eventName are not specified) is 'method'. Based on this parameter, this
* function can be used in two ways.
* *
* *
* *
...@@ -337,10 +379,10 @@ function (bind, VideoPlayer) { ...@@ -337,10 +379,10 @@ function (bind, VideoPlayer) {
// object/function to trigger/invoke. If the 'objChain' chain of object is // object/function to trigger/invoke. If the 'objChain' chain of object is
// incorrect (one of the link is non-existent), then the loop will immediately // incorrect (one of the link is non-existent), then the loop will immediately
// exit. // exit.
while (objChain.length > 0) { while (objChain.length) {
i = objChain.shift(); i = objChain.shift();
if (tmpObj.hasOwnProperty(i) === true) { if (tmpObj.hasOwnProperty(i)) {
tmpObj = tmpObj[i]; tmpObj = tmpObj[i];
} else { } else {
// An incorrect object chain was specified. // An incorrect object chain was specified.
...@@ -349,6 +391,10 @@ function (bind, VideoPlayer) { ...@@ -349,6 +391,10 @@ function (bind, VideoPlayer) {
} }
} }
if ((typeof callType === 'undefined') && (typeof eventName === 'undefined')) {
callType = 'method';
}
// Based on the type, either trigger, or invoke. // Based on the type, either trigger, or invoke.
if (callType === 'event') { if (callType === 'event') {
tmpObj.trigger(eventName, extraParameters); tmpObj.trigger(eventName, extraParameters);
......
...@@ -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