Commit 9d2eec07 by Valera Rozuvan Committed by Vasyl Nakvasiuk

Refactoring of events system.

Minor fix.
Minor fix. Now state of captions is properly set from cookies.
Fix for hiding-showing subs based on cookie when subs are not found.
Partial feature - hide show controls on mouse.
Removed debugging messages. Changed trigger() method - now it has a better interface.
Better function rewrite. Now .trigger() is more readable and understandable.
In between.
parent 74ad637e
......@@ -2,7 +2,7 @@
margin-bottom: 30px;
}
div.video {
div.videoalpha {
@include clearfix();
background: #f3f3f3;
display: block;
......@@ -31,6 +31,15 @@ div.video {
}
}
section.video-roof {
background-color: green;
z-index: 10000;
width: 540px;
height: 100px;
position: absolute;
top: 387px;
}
section.video-controls {
@include clearfix();
background: #333;
......
......@@ -27,6 +27,7 @@ function (bind, VideoPlayer) {
state.setSpeed = bind(setSpeed, state);
state.youtubeId = bind(youtubeId, state);
state.getDuration = bind(getDuration, state);
state.trigger = bind(trigger, state);
}
// function renderElements(state)
......@@ -36,7 +37,7 @@ function (bind, VideoPlayer) {
// way - you don't have to do repeated jQuery element selects.
function renderElements(state, element) {
// The parent element of the video, and the ID.
state.el = $(element).find('.video');
state.el = $(element).find('.videoalpha');
state.id = state.el.attr('id').replace(/video_/, '');
// We store all settings passed to us by the server in one place. These are "read only", so don't
......@@ -113,8 +114,8 @@ function (bind, VideoPlayer) {
state.hide_captions = true;
$.cookie('hide_captions', state.hide_captions, {
expires: 3650,
path: '/'
'expires': 3650,
'path': '/'
});
state.el.addClass('closed');
......@@ -128,8 +129,8 @@ function (bind, VideoPlayer) {
(function (currentPlayerMode) {
if ((currentPlayerMode !== 'html5') && (currentPlayerMode !== 'flash')) {
$.cookie('current_player_mode', 'html5', {
expires: 3650,
path: '/'
'expires': 3650,
'path': '/'
});
state.currentPlayerMode = 'html5';
} else {
......@@ -137,39 +138,9 @@ function (bind, VideoPlayer) {
}
}($.cookie('current_player_mode')));
// Will be used by various components to register callbacks that can be then called by video core,
// or other components.
state.callbacks = {
'videoPlayer': {
'onPlay': [],
'onPause': [],
'onEnded': [],
'onPlaybackQualityChange': [],
'updatePlayTime': [],
'onSpeedSetChange': []
},
'videoControl': {
'togglePlaybackPlay': [],
'togglePlaybackPause': [],
'toggleFullScreen': []
},
'videoQualityControl': {
'toggleQuality': []
},
'videoProgressSlider': {
'onSlide': [],
'onStop': []
},
'videoVolumeControl': {
'onChange': []
},
'videoSpeedControl': {
'changeVideoSpeed': []
},
'videoCaption': {
'seekPlayer': []
}
};
// Possible value are: 'visible', 'hiding', and 'invisible'.
state.controlState = 'visible';
state.controlHideTimeout = null;
// 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.
......@@ -291,8 +262,8 @@ function (bind, VideoPlayer) {
if (updateCookie !== false) {
$.cookie('video_speed', this.speed, {
expires: 3650,
path: '/'
'expires': 3650,
'path': '/'
});
}
}
......@@ -305,7 +276,20 @@ function (bind, VideoPlayer) {
return this.metadata[this.youtubeId()].duration;
}
/*
/* he function .trigger() expects the parameter @callType one of
*
* 'event'
* 'method'
*
* Based on this parameter, this function can be used in two ways.
*
*
*
* First use: A safe way to trigger jQuery events.
* -----------------------------------------------
*
* @callType === 'event'
*
* Because jQuery events can be triggered on some jQuery object, we must make sure that
* we don't trigger an event on an undefined object. For this we will have an in-between
* method that will check for the existance of an object before triggering an event on it.
......@@ -321,34 +305,60 @@ function (bind, VideoPlayer) {
*
* object, and, if found to be present, will trigger the specified event on this object.
*
* @eventName - the name of the event to trigger on the specified object.
* @eventName is a string the name of the event to trigger on the specified object.
*
* @extraParameters is an object or an array that should be passed to the triggered method.
*
*
* Second use: A safe way to call methods.
* ---------------------------------------
*
* @callType === 'method'
*
* Parameter @eventName is NOT necessary.
*
* The trigger() function will assume that the @objChain is a complete chain with a method
* (function) at the end. It will call this function. So for example, when trigger() is
* called like so:
*
* state.trigger(['videoPlayer', 'pause'], {'param1': 10}, 'method');
*
* Then trigger() will execute:
*
* state.videoPlayer.pause({'param1': 10});
*/
function trigger(objChain, eventName, extraParameters) {
var tmpObj;
function trigger(objChain, extraParameters, callType, eventName) {
var i, tmpObj;
// Remember that 'this' is the 'state' object.
tmpObj = this;
getFinalObj(0);
// At the end of the loop the variable 'tmpObj' will either be the correct
// 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
// exit.
while (objChain.length > 0) {
i = objChain.shift();
if (tmpObj === null) {
return false;
if (tmpObj.hasOwnProperty(i) === true) {
tmpObj = tmpObj[i];
} else {
// An incorrect object chain was specified.
return false;
}
}
tmpObj.trigger(eventName, extraParameters);
// Based on the type, either trigger, or invoke.
if (callType === 'event') {
tmpObj.trigger(eventName, extraParameters);
} else if (callType === 'method') {
tmpObj(extraParameters);
} else {
return false;
}
return true;
function getFinalObj(i) {
if (objChain.length !== i) {
if (tmpObj.hasOwnProperty(objChain[i]) === true) {
tmpObj = tmpObj[objChain[i]];
getFinalObj(i + 1);
} else {
tmpObj = null;
}
}
}
}
});
......
......@@ -13,7 +13,6 @@ function (bind) {
makeFunctionsPublic(state);
renderElements(state);
bindHandlers(state);
registerCallbacks(state);
};
// ***************************************************************
......@@ -88,15 +87,9 @@ function (bind) {
);
}
// function registerCallbacks(state)
//
// Register function callbacks to be called by other modules.
function registerCallbacks(state) {
state.callbacks.videoPlayer.updatePlayTime.push(state.videoCaption.updatePlayTime);
state.callbacks.videoControl.toggleFullScreen.push(state.videoCaption.resize);
}
function fetchCaption(state) {
state.videoCaption.hideCaptions(state.hide_captions);
$.getWithPrefix(captionURL(state), function(captions) {
state.videoCaption.captions = captions.text;
state.videoCaption.start = captions.start;
......@@ -113,6 +106,10 @@ function (bind) {
}
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';
}
......@@ -257,10 +254,7 @@ function (bind) {
event.preventDefault();
time = Math.round(Time.convert($(event.target).data('start'), '1.0', this.speed) / 1000);
$.each(this.callbacks.videoCaption.seekPlayer, function (index, value) {
// Each value is a registered callback (JavaScript function object).
value(time);
});
this.trigger(['videoPlayer', 'onSeek'], time, 'method');
}
function calculateOffset(element) {
......
......@@ -13,7 +13,6 @@ function (bind) {
makeFunctionsPublic(state);
renderElements(state);
bindHandlers(state);
registerCallbacks(state);
};
// ***************************************************************
......@@ -25,6 +24,8 @@ function (bind) {
// Functions which will be accessible via 'state' object. When called, these functions will
// get the 'state' object as a context.
function makeFunctionsPublic(state) {
state.videoControl.showControls = bind(showControls, state);
state.videoControl.hideControls = bind(hideControls, state);
state.videoControl.play = bind(play, state);
state.videoControl.pause = bind(pause, state);
state.videoControl.togglePlayback = bind(togglePlayback, state);
......@@ -80,6 +81,9 @@ function (bind) {
} else {
state.videoControl.play();
}
state.controlHideTimeout = setTimeout(state.videoControl.hideControls, 3000);
state.el.find('.video-roof').on('mousemove', state.videoControl.showControls);
}
// function bindHandlers(state)
......@@ -91,22 +95,82 @@ function (bind) {
$(document).on('keyup', state.videoControl.exitFullScreen);
}
// function registerCallbacks(state)
//
// Register function callbacks to be called by other modules.
function registerCallbacks(state) {
state.callbacks.videoPlayer.onPlay.push(state.videoControl.play);
state.callbacks.videoPlayer.onPause.push(state.videoControl.pause);
state.callbacks.videoPlayer.onEnded.push(state.videoControl.pause);
state.callbacks.videoPlayer.updatePlayTime.push(state. videoControl.updateVcrVidTime);
}
// ***************************************************************
// Public functions start here.
// 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().
// ***************************************************************
function showControls(event) {
var elPosition, elWidth, elHeight;
normalize(event);
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) {
if(!event.offsetX) {
event.offsetX = (event.pageX - $(event.target).offset().left);
event.offsetY = (event.pageY - $(event.target).offset().top);
}
return event;
}
}
function hideControls() {
var _this;
this.controlHideTimeout = null;
this.controlState = 'hiding';
_this = this;
this.videoControl.el.fadeOut(1000, function () {
_this.controlState = 'invisible';
});
}
function play() {
this.videoControl.playPauseEl.removeClass('play').addClass('pause').attr('title', 'Pause');
this.videoControl.playPauseState = 'playing';
......@@ -121,15 +185,9 @@ function (bind) {
event.preventDefault();
if (this.videoControl.playPauseState === 'playing') {
$.each(this.callbacks.videoControl.togglePlaybackPause, function (index, value) {
// Each value is a registered callback (JavaScript function object).
value();
});
this.trigger(['videoPlayer', 'pause'], null, 'method');
} else { // if (this.videoControl.playPauseState === 'paused') {
$.each(this.callbacks.videoControl.togglePlaybackPlay, function (index, value) {
// Each value is a registered callback (JavaScript function object).
value();
});
this.trigger(['videoPlayer', 'play'], null, 'method');
}
}
......@@ -146,11 +204,7 @@ function (bind) {
this.videoControl.fullScreenEl.attr('title', 'Exit fill browser');
}
$.each(this.callbacks.videoControl.toggleFullScreen, function (index, value) {
// Each value is a registered callback (JavaScript function object).
value();
});
this.trigger(['videoCaption', 'resize'], null, 'method');
}
function exitFullScreen(event) {
......@@ -159,12 +213,8 @@ function (bind) {
}
}
function updateVcrVidTime(time, duration) {
var progress;
progress = Time.format(time) + ' / ' + Time.format(duration);
this.videoControl.vidTimeEl.html(progress);
function updateVcrVidTime(params) {
this.videoControl.vidTimeEl.html(Time.format(params.time) + ' / ' + Time.format(params.duration));
}
});
......
......@@ -16,7 +16,6 @@ function (HTML5Video, bind) {
makeFunctionsPublic(state);
renderElements(state);
bindHandlers();
registerCallbacks(state);
};
// ***************************************************************
......@@ -120,24 +119,6 @@ function (HTML5Video, bind) {
}
// function registerCallbacks(state)
//
// Register function callbacks to be called by other modules.
function registerCallbacks(state) {
state.callbacks.videoControl.togglePlaybackPlay.push(state.videoPlayer.play);
state.callbacks.videoControl.togglePlaybackPause.push(state.videoPlayer.pause);
state.callbacks.videoQualityControl.toggleQuality.push(state.videoPlayer.handlePlaybackQualityChange);
state.callbacks.videoProgressSlider.onSlide.push(state.videoPlayer.onSeek);
state.callbacks.videoProgressSlider.onStop.push(state.videoPlayer.onSeek);
state.callbacks.videoVolumeControl.onChange.push(state.videoPlayer.onVolumeChange);
state.callbacks.videoSpeedControl.changeVideoSpeed.push(state.videoPlayer.onSpeedChange);
state.callbacks.videoCaption.seekPlayer.push(state.videoPlayer.onSeek);
}
// function reinitAsFlash(state)
//
// When we are about to play a YouTube video in HTML5 mode and discover that we only
......@@ -149,8 +130,8 @@ function (HTML5Video, bind) {
// Remember for future page loads that we should use Flash mode.
$.cookie('current_player_mode', 'flash', {
expires: 3650,
path: '/'
'expires': 3650,
'path': '/'
});
state.currentPlayerMode = 'flash';
......@@ -214,8 +195,7 @@ function (HTML5Video, bind) {
} else {
this.videoPlayer.player.cueVideoById(this.youtubeId(), this.videoPlayer.currentTime);
}
}
if (this.currentPlayerMode === 'flash') {
this.videoPlayer.updatePlayTime(this.videoPlayer.currentTime);
}
}
......@@ -234,10 +214,7 @@ function (HTML5Video, bind) {
}
function onEnded() {
$.each(this.callbacks.videoPlayer.onEnded, function (index, value) {
// Each value is a registered callback (JavaScript function object).
value();
});
this.trigger(['videoControl','pause'], null, 'method');
}
function onPause() {
......@@ -246,10 +223,7 @@ function (HTML5Video, bind) {
clearInterval(this.videoPlayer.updateInterval);
delete this.videoPlayer.updateInterval;
$.each(this.callbacks.videoPlayer.onPause, function (index, value) {
// Each value is a registered callback (JavaScript function object).
value();
});
this.trigger(['videoControl','pause'], null, 'method');
}
function onPlay() {
......@@ -259,10 +233,7 @@ function (HTML5Video, bind) {
this.videoPlayer.updateInterval = setInterval(this.videoPlayer.update, 200);
}
$.each(this.callbacks.videoPlayer.onPlay, function (index, value) {
// Each value is a registered callback (JavaScript function object).
value();
});
this.trigger(['videoControl','play'], null, 'method');
}
function onUnstarted() { }
......@@ -276,10 +247,7 @@ function (HTML5Video, bind) {
quality = this.videoPlayer.player.getPlaybackQuality();
$.each(this.callbacks.videoPlayer.onPlaybackQualityChange, function (index, value) {
// Each value is a registered callback (JavaScript function object).
value(quality);
});
this.trigger(['videoQualityControl', 'onQualityChange'], quality, 'method');
}
function onReady() {
......@@ -306,10 +274,7 @@ function (HTML5Video, bind) {
_this.speeds.push(value.toFixed(2).replace(/\.00$/, '.0'));
});
$.each(this.callbacks.videoPlayer.onSpeedSetChange, function (index, value) {
// Each value is a registered callback (JavaScript function object).
value(_this.speeds, _this.speed);
});
this.trigger(['videoSpeedControl', 'reRender'], {'newSpeeds': this.speeds, 'currentSpeed': this.speed}, 'method');
this.setSpeed($.cookie('video_speed'));
}
......@@ -346,10 +311,9 @@ function (HTML5Video, bind) {
duration = this.videoPlayer.duration();
$.each(this.callbacks.videoPlayer.updatePlayTime, function (index, value) {
// Each value is a registered callback (JavaScript function object).
value(time, duration);
});
this.trigger(['videoProgressSlider', 'updatePlayTime'], {'time': time, 'duration': duration}, 'method');
this.trigger(['videoControl', 'updateVcrVidTime'], {'time': time, 'duration': duration}, 'method');
this.trigger(['videoCaption', 'updatePlayTime'], time, 'method');
}
function isPlaying() {
......
......@@ -20,7 +20,6 @@ function (bind) {
makeFunctionsPublic(state);
renderElements(state);
bindHandlers(state);
registerCallbacks(state);
};
// ***************************************************************
......@@ -60,19 +59,12 @@ function (bind) {
}
// function registerCallbacks(state)
//
// Register function callbacks to be called by other modules.
function registerCallbacks(state) {
state.callbacks.videoPlayer.updatePlayTime.push(state.videoProgressSlider.updatePlayTime);
}
function buildSlider(state) {
state.videoProgressSlider.slider = state.videoProgressSlider.el.slider({
'range': 'min',
'range': 'min',
'change': state.videoProgressSlider.onChange,
'slide': state.videoProgressSlider.onSlide,
'stop': state.videoProgressSlider.onStop
'slide': state.videoProgressSlider.onSlide,
'stop': state.videoProgressSlider.onStop
});
}
......@@ -106,10 +98,7 @@ function (bind) {
this.videoProgressSlider.frozen = true;
this.videoProgressSlider.updateTooltip(ui.value);
$.each(this.callbacks.videoProgressSlider.onSlide, function (index, value) {
// Each value is a registered callback (JavaScript function object).
value(ui.value);
});
this.trigger(['videoPlayer', 'onSeek'], ui.value, 'method');
}
function onChange(event, ui) {
......@@ -123,10 +112,7 @@ function (bind) {
this.videoProgressSlider.frozen = true;
$.each(this.callbacks.videoProgressSlider.onStop, function (index, value) {
// Each value is a registered callback (JavaScript function object).
value(ui.value);
});
this.trigger(['videoPlayer', 'onSeek'], ui.value, 'method');
setTimeout(function() {
_this.videoProgressSlider.frozen = false;
......@@ -137,10 +123,10 @@ function (bind) {
this.videoProgressSlider.handle.qtip('option', 'content.text', '' + Time.format(value));
}
function updatePlayTime(currentTime, duration) {
function updatePlayTime(params) {
if ((this.videoProgressSlider.slider) && (!this.videoProgressSlider.frozen)) {
this.videoProgressSlider.slider.slider('option', 'max', duration);
this.videoProgressSlider.slider.slider('value', currentTime);
this.videoProgressSlider.slider.slider('option', 'max', params.duration);
this.videoProgressSlider.slider.slider('value', params.time);
}
}
......
......@@ -18,7 +18,6 @@ function (bind) {
makeFunctionsPublic(state);
renderElements(state);
bindHandlers(state);
registerCallbacks(state);
};
// ***************************************************************
......@@ -64,13 +63,6 @@ function (bind) {
state.videoQualityControl.el.on('click', state.videoQualityControl.toggleQuality);
}
// function registerCallbacks(state)
//
// Register function callbacks to be called by other modules.
function registerCallbacks(state) {
state.callbacks.videoPlayer.onPlaybackQualityChange.push(state.videoQualityControl.onQualityChange);
}
// ***************************************************************
// Public functions start here.
// These are available via the 'state' object. Their context ('this' keyword) is the 'state' object.
......@@ -100,10 +92,7 @@ function (bind) {
newQuality = 'hd720';
}
$.each(this.callbacks.videoQualityControl.toggleQuality, function (index, value) {
// Each value is a registered callback (JavaScript function object).
value(newQuality);
});
this.trigger(['videoPlayer', 'handlePlaybackQualityChange'], newQuality, 'method');
}
});
......
......@@ -13,7 +13,6 @@ function (bind) {
makeFunctionsPublic(state);
renderElements(state);
bindHandlers(state);
registerCallbacks(state);
};
// ***************************************************************
......@@ -92,13 +91,6 @@ function (bind) {
}
}
// function registerCallbacks(state)
//
// Register function callbacks to be called by other modules.
function registerCallbacks(state) {
state.callbacks.videoPlayer.onSpeedSetChange.push(state.videoSpeedControl.reRender);
}
// ***************************************************************
// Public functions start here.
// These are available via the 'state' object. Their context ('this' keyword) is the 'state' object.
......@@ -112,8 +104,6 @@ function (bind) {
}
function changeVideoSpeed(event) {
var _this;
event.preventDefault();
if (!$(event.target).parent().hasClass('active')) {
......@@ -123,21 +113,16 @@ function (bind) {
parseFloat(this.videoSpeedControl.currentSpeed).toFixed(2).replace(/\.00$/, '.0')
);
_this = this;
$.each(this.callbacks.videoSpeedControl.changeVideoSpeed, function (index, value) {
// Each value is a registered callback (JavaScript function object).
value(_this.videoSpeedControl.currentSpeed);
});
this.trigger(['videoPlayer', 'onSpeedChange'], this.videoSpeedControl.currentSpeed, 'method');
}
}
function reRender(newSpeeds, currentSpeed) {
function reRender(params /*newSpeeds, currentSpeed*/) {
var _this;
this.videoSpeedControl.videoSpeedsEl.empty();
this.videoSpeedControl.videoSpeedsEl.find('li').removeClass('active');
this.videoSpeedControl.speeds = newSpeeds;
this.videoSpeedControl.speeds = params.newSpeeds;
_this = this;
$.each(this.videoSpeedControl.speeds, function(index, speed) {
......@@ -149,7 +134,7 @@ function (bind) {
listItem = $('<li>').attr('data-speed', speed).html(link);
if (speed === currentSpeed) {
if (speed === params.currentSpeed) {
listItem.addClass('active');
}
......
......@@ -13,7 +13,6 @@ function (bind) {
makeFunctionsPublic(state);
renderElements(state);
bindHandlers(state);
registerCallbacks(state);
};
// ***************************************************************
......@@ -35,8 +34,6 @@ function (bind) {
// 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.
function renderElements(state) {
state.videoVolumeControl.currentVolume = 100;
state.videoVolumeControl.el = $(
'<div class="volume">' +
'<a href="#"></a>' +
......@@ -51,15 +48,30 @@ function (bind) {
state.videoControl.secondaryControlsEl.prepend(state.videoVolumeControl.el);
// Figure out what the current volume is. Set it up so that muting/unmuting works correctly.
// If no information about volume level could be retrieved, then we will use the default
// 100 level (full volume).
state.videoVolumeControl.currentVolume = parseInt($.cookie('video_player_volume_level'), 10);
state.videoVolumeControl.previousVolume = 100;
if (
(isFinite(state.videoVolumeControl.currentVolume) === false) ||
(state.videoVolumeControl.currentVolume < 0) ||
(state.videoVolumeControl.currentVolume > 100)
) {
state.videoVolumeControl.currentVolume = 100;
}
state.videoVolumeControl.slider = state.videoVolumeControl.volumeSliderEl.slider({
'orientation': 'vertical',
'range': 'min',
'min': 0,
'max': 100,
'value': 100,
'value': state.videoVolumeControl.currentVolume,
'change': state.videoVolumeControl.onChange,
'slide': state.videoVolumeControl.onChange
});
state.videoVolumeControl.el.toggleClass('muted', state.videoVolumeControl.currentVolume === 0);
}
// function bindHandlers(state)
......@@ -77,13 +89,6 @@ function (bind) {
});
}
// function registerCallbacks(state)
//
// Register function callbacks to be called by other modules.
function registerCallbacks(state) {
}
// ***************************************************************
// Public functions start here.
// These are available via the 'state' object. Their context ('this' keyword) is the 'state' object.
......@@ -94,10 +99,12 @@ function (bind) {
this.videoVolumeControl.currentVolume = ui.value;
this.videoVolumeControl.el.toggleClass('muted', this.videoVolumeControl.currentVolume === 0);
$.each(this.callbacks.videoVolumeControl.onChange, function (index, value) {
// Each value is a registered callback (JavaScript function object).
value(ui.value);
$.cookie('video_player_volume_level', ui.value, {
'expires': 3650,
'path': '/'
});
this.trigger(['videoPlayer', 'onVolumeChange'], ui.value, 'method');
}
function toggleMute(event) {
......
......@@ -96,7 +96,7 @@ class VideoAlphaModule(VideoAlphaFields, XModule):
self.autoplay = xmltree.get('autoplay') or ''
if self.autoplay.lower() not in ['true', 'false']:
self.autoplay = ''
self.autoplay = 'true'
self.position = 0
self.show_captions = xmltree.get('show_captions', 'true')
......
......@@ -6,14 +6,14 @@
<div
id="video_${id}"
class="video"
class="videoalpha"
% if not settings.MITX_FEATURES['STUB_VIDEO_FOR_TESTING']:
data-streams="${youtube_streams}"
% endif
${'data-sub="{}"'.format(sub) if sub else ''}
${'data-autoplay="{}"'.format(sub) if sub else ''}
${'data-autoplay="{}"'.format(autoplay) if autoplay else ''}
% if not settings.MITX_FEATURES['STUB_VIDEO_FOR_TESTING']:
${'data-mp4-source="{}"'.format(sources.get('mp4')) if sources.get('mp4') else ''}
${'data-webm-source="{}"'.format(sources.get('webm')) if sources.get('webm') else ''}
......@@ -32,6 +32,7 @@
<section class="video-player">
<div id="${id}"></div>
</section>
<section class="video-roof"></section>
<section class="video-controls"></section>
</article>
</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