diff --git a/common/lib/xmodule/xmodule/js/src/video/01_initialize.js b/common/lib/xmodule/xmodule/js/src/video/01_initialize.js
index 63bb442aa3..7f8057c025 100644
--- a/common/lib/xmodule/xmodule/js/src/video/01_initialize.js
+++ b/common/lib/xmodule/xmodule/js/src/video/01_initialize.js
@@ -1,8 +1,9 @@
/**
- * @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.
+ * @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
*
@@ -16,8 +17,17 @@ define(
['video/03_video_player.js'],
function (VideoPlayer) {
- if (typeof(window.gettext) == "undefined") {
- window.gettext = function(s){return s;};
+ // window.console.log() is expected to be available. We do not support
+ // browsers which lack this functionality.
+
+ // The function gettext() is defined by a vendor library. If, however, it
+ // is undefined, it is a simple wrapper. It is used to return a different
+ // version of the string passed (translated string, etc.). In the basic
+ // case, the original string is returned.
+ if (typeof(window.gettext) == 'undefined') {
+ window.gettext = function (s) {
+ return s;
+ };
}
/**
@@ -50,43 +60,54 @@ function (VideoPlayer) {
* methods, modules) of the Video player.
*/
function _makeFunctionsPublic(state) {
- state.setSpeed = _.bind(setSpeed, state);
- state.youtubeId = _.bind(youtubeId, state);
- state.getDuration = _.bind(getDuration, state);
- state.trigger = _.bind(trigger, state);
+ state.setSpeed = _.bind(setSpeed, state);
+ state.youtubeId = _.bind(youtubeId, state);
+ state.getDuration = _.bind(getDuration, state);
+ state.trigger = _.bind(trigger, state);
state.stopBuffering = _.bind(stopBuffering, state);
// Old private functions. Now also public so that can be
// tested by Jasmine.
- state.initialize = _.bind(initialize, state);
- state.parseSpeed = _.bind(parseSpeed, state);
- state.fetchMetadata = _.bind(fetchMetadata, state);
+ state.initialize = _.bind(initialize, state);
+ state.parseSpeed = _.bind(parseSpeed, state);
+ state.fetchMetadata = _.bind(fetchMetadata, state);
state.parseYoutubeStreams = _.bind(parseYoutubeStreams, state);
- state.parseVideoSources = _.bind(parseVideoSources, state);
- state.getVideoMetadata = _.bind(getVideoMetadata, state);
+ state.parseVideoSources = _.bind(parseVideoSources, state);
+ state.getVideoMetadata = _.bind(getVideoMetadata, state);
}
// function _renderElements(state)
//
- // Create any necessary DOM elements, attach them, and set their initial configuration. Also
- // 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.
+ // Create any necessary DOM elements, attach them, and set their
+ // initial configuration. Also 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) {
- // 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.
+ // 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.
//
- // Note that the loading of stand alone HTML5 player API is handled by Require JS. At the time
- // when we reach this code, the stand alone HTML5 player is already loaded, so no further testing
- // in that case is required.
+ // Note that the loading of stand alone HTML5 player API is handled by
+ // Require JS. At the time when we reach this code, the stand alone
+ // HTML5 player is already loaded, so no further testing in that case
+ // is required.
var onPlayerReadyFunc;
if (
- ((state.videoType === 'youtube') && (window.YT) && (window.YT.Player)) ||
+ (
+ (state.videoType === 'youtube') &&
+ (window.YT) &&
+ (window.YT.Player)
+ ) ||
(state.videoType === 'html5')
) {
VideoPlayer(state);
} else {
- onPlayerReadyFunc = (state.videoType === 'youtube') ? 'onYouTubePlayerAPIReady' : 'onHTML5PlayerAPIReady';
+ if (state.videoType === 'youtube') {
+ onPlayerReadyFunc = 'onYouTubePlayerAPIReady';
+ } else {
+ onPlayerReadyFunc = 'onHTML5PlayerAPIReady';
+ }
window[onPlayerReadyFunc] = _.bind(VideoPlayer, window, state);
}
}
@@ -102,7 +123,8 @@ function (VideoPlayer) {
// Option
// this.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.
function _configureCaptions(state) {
if (state.config.show_captions) {
state.hide_captions = ($.cookie('hide_captions') === 'true');
@@ -119,14 +141,19 @@ function (VideoPlayer) {
}
// function _setPlayerMode(state)
- // By default we will be forcing HTML5 player mode. Only in the case when, after initializtion, we will
- // get one available playback rate, we will change to Flash player mode. There is a need to store this
- // setting in cookies because otherwise we will have to change from HTML5 to Flash on every page load
- // in a browser that doesn't fully support HTML5. When we have this setting in cookies, we can select
+ // By default we will be forcing HTML5 player mode. Only in the case
+ // when, after initializtion, we will get one available playback rate,
+ // we will change to Flash player mode. There is a need to store this
+ // setting in cookies because otherwise we will have to change from
+ // HTML5 to Flash on every page load in a browser that doesn't fully
+ // support HTML5. When we have this setting in cookies, we can select
// the proper mode from the start (not having to change mode later on).
function _setPlayerMode(state) {
(function (currentPlayerMode) {
- if ((currentPlayerMode === 'html5') || (currentPlayerMode === 'flash')) {
+ if (
+ (currentPlayerMode === 'html5') ||
+ (currentPlayerMode === 'flash')
+ ) {
state.currentPlayerMode = currentPlayerMode;
} else {
$.cookie('current_player_mode', 'html5', {
@@ -135,20 +162,32 @@ function (VideoPlayer) {
});
state.currentPlayerMode = 'html5';
}
+
+ console.log(
+ '[Video info]: YouTube player mode is "' +
+ state.currentPlayerMode + '".'
+ );
}($.cookie('current_player_mode')));
}
// function _parseYouTubeIDs(state)
// The function parse YouTube stream ID's.
// @return
- // 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.
+ // 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.
function _parseYouTubeIDs(state) {
if (state.parseYoutubeStreams(state.config.youtubeStreams)) {
state.videoType = 'youtube';
return true;
}
+
+ console.log(
+ '[Video info]: Youtube Video IDs are incorrect or absent.'
+ );
+
return false;
}
@@ -184,6 +223,10 @@ function (VideoPlayer) {
state.el.find('.video-player div').addClass('hidden');
state.el.find('.video-player h3').removeClass('hidden');
+ console.log(
+ '[Video info]: Non-youtube video sources aren\'t available.'
+ );
+
return false;
}
@@ -212,8 +255,9 @@ function (VideoPlayer) {
// ***************************************************************
// 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().
+ // 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 initialize(element)
@@ -221,15 +265,21 @@ function (VideoPlayer) {
function initialize(element) {
var _this = this, tempYtTestTimeout;
- // This is used in places where we instead would have to check if an element has a CSS class 'fullscreen'.
+ // This is used in places where we instead would have to check if an
+ // element has a CSS class 'fullscreen'.
this.isFullScreen = false;
// The parent element of the video, and the ID.
this.el = $(element).find('.video');
this.id = this.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
- // modify them. All variable content lives in 'state' object.
+ console.log(
+ '[Video info]: Initializing video with id "' + this.id + '".'
+ );
+
+ // We store all settings passed to us by the server in one place. These
+ // are "read only", so don't modify them. All variable content lives in
+ // 'state' object.
this.config = {
element: element,
@@ -238,7 +288,10 @@ function (VideoPlayer) {
caption_data_dir: this.el.data('caption-data-dir'),
caption_asset_path: this.el.data('caption-asset-path'),
- show_captions: (this.el.data('show-captions').toString().toLowerCase() === 'true'),
+ show_captions: (
+ this.el.data('show-captions')
+ .toString().toLowerCase() === 'true'
+ ),
youtubeStreams: this.el.data('streams'),
sub: this.el.data('sub'),
@@ -262,12 +315,16 @@ function (VideoPlayer) {
this.config.ytTestTimeout = tempYtTestTimeout;
if (!(_parseYouTubeIDs(this))) {
+
// If we do not have YouTube ID's, try parsing HTML5 video sources.
if (!_prepareHTML5Video(this, true)) {
+
// Non-YouTube sources were not found either.
return;
}
+ console.log('[Video info]: Start player in HTML5 mode.');
+
_setConfigurations(this);
_renderElements(this);
} else {
@@ -276,29 +333,52 @@ function (VideoPlayer) {
}
this.youtubeXhr
- .always(function(json, status) {
+ .always(function (json, status) {
var err = $.isPlainObject(json.error) ||
- (status !== 'success' && status !== 'notmodified');
+ (
+ status !== 'success' &&
+ status !== 'notmodified'
+ );
if (err) {
+ console.log(
+ '[Video info]: YouTube returned an error for ' +
+ 'video with id "' + _this.id + '".'
+ );
+
// When the youtube link doesn't work for any reason
// (for example, the great firewall in china) any
// alternate sources should automatically play.
if (!_prepareHTML5Video(_this)) {
+ console.log(
+ '[Video info]: Continue loading ' +
+ 'YouTube video.'
+ );
+
// Non-YouTube sources were not found either.
- _this.el.find('.video-player div').removeClass('hidden');
- _this.el.find('.video-player h3').addClass('hidden');
+ _this.el.find('.video-player div')
+ .removeClass('hidden');
+ _this.el.find('.video-player h3')
+ .addClass('hidden');
// If in reality the timeout was to short, try to
// continue loading the YouTube video anyways.
_this.fetchMetadata();
_this.parseSpeed();
} else {
+ console.log(
+ '[Video info]: Change player mode to HTML5.'
+ );
+
// In-browser HTML5 player does not support quality
// control.
_this.el.find('a.quality_control').hide();
}
} else {
+ console.log(
+ '[Video info]: Start player in YouTube mode.'
+ );
+
_this.fetchMetadata();
_this.parseSpeed();
}
@@ -313,23 +393,28 @@ function (VideoPlayer) {
//
// Take a string in the form:
// "iCawTYPtehk:0.75,KgpclqP-LBA:1.0,9-2670d5nvU:1.5"
- // parse it, and make it available via the 'state' object. If we are not given a string, or
- // it's length is zero, then we return false.
+ // parse it, and make it available via the 'state' object. If we are
+ // not given a string, or it's length is zero, then we return false.
//
// @return
- // 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.
+ // 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.
function parseYoutubeStreams(youtubeStreams) {
var _this;
- if (typeof youtubeStreams === 'undefined' || youtubeStreams.length === 0) {
+ if (
+ typeof youtubeStreams === 'undefined' ||
+ youtubeStreams.length === 0
+ ) {
return false;
}
_this = this;
this.videos = {};
- $.each(youtubeStreams.split(/,/), function(index, video) {
+ $.each(youtubeStreams.split(/,/), function (index, video) {
var speed;
video = video.split(/:/);
@@ -343,8 +428,8 @@ function (VideoPlayer) {
// function parseVideoSources(, mp4Source, webmSource, oggSource)
//
- // Take the HTML5 sources (URLs of videos), and make them available explictly for each type
- // of video format (mp4, webm, ogg).
+ // Take the HTML5 sources (URLs of videos), and make them available
+ // explictly for each type of video format (mp4, webm, ogg).
function parseVideoSources(sources) {
var _this = this,
v = document.createElement('video'),
@@ -376,16 +461,17 @@ function (VideoPlayer) {
// function fetchMetadata()
//
- // When dealing with YouTube videos, we must fetch meta data that has certain key facts
- // not available while the video is loading. For example the length of the video can be
- // determined from the meta data.
+ // When dealing with YouTube videos, we must fetch meta data that has
+ // certain key facts not available while the video is loading. For
+ // example the length of the video can be determined from the meta
+ // data.
function fetchMetadata() {
var _this = this;
this.metadata = {};
$.each(this.videos, function (speed, url) {
- _this.getVideoMetadata(url, function(data) {
+ _this.getVideoMetadata(url, function (data) {
if (data.data) {
_this.metadata[data.data.id] = data.data;
}
@@ -397,7 +483,7 @@ function (VideoPlayer) {
//
// Create a separate array of available speeds.
function parseSpeed() {
- this.speeds = ($.map(this.videos, function(url, speed) {
+ this.speeds = ($.map(this.videos, function (url, speed) {
return speed;
})).sort();
@@ -439,7 +525,7 @@ function (VideoPlayer) {
function stopBuffering() {
var video;
- if (this.videoType === 'html5'){
+ if (this.videoType === 'html5') {
// HTML5 player haven't default way to abort bufferization.
// In this case we simply resetting source and call load().
video = this.videoPlayer.player.video;
@@ -457,9 +543,9 @@ function (VideoPlayer) {
}
/*
- * 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:
+ * 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});
*
@@ -474,10 +560,10 @@ function (VideoPlayer) {
tmpObj = this;
chain = objChain.split('.');
- // At the end of the loop the variable 'tmpObj' will either be the correct
- // object/function to trigger/invoke. If the 'chain' chain of object is
- // incorrect (one of the link is non-existent), then the loop will immediately
- // exit.
+ // At the end of the loop the variable 'tmpObj' will either be the
+ // correct object/function to trigger/invoke. If the 'chain' chain of
+ // object is incorrect (one of the link is non-existent), then the loop
+ // will immediately exit.
while (chain.length) {
i = chain.shift();
diff --git a/common/lib/xmodule/xmodule/js/src/video/03_video_player.js b/common/lib/xmodule/xmodule/js/src/video/03_video_player.js
index 25617283f5..649dd9cf66 100644
--- a/common/lib/xmodule/xmodule/js/src/video/03_video_player.js
+++ b/common/lib/xmodule/xmodule/js/src/video/03_video_player.js
@@ -21,35 +21,46 @@ function (HTML5Video) {
// function _makeFunctionsPublic(state)
//
- // 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.
function _makeFunctionsPublic(state) {
- state.videoPlayer.pause = _.bind(pause, state);
- state.videoPlayer.play = _.bind(play, state);
- state.videoPlayer.update = _.bind(update, state);
- state.videoPlayer.onSpeedChange = _.bind(onSpeedChange, state);
- state.videoPlayer.onCaptionSeek = _.bind(onSeek, state);
- state.videoPlayer.onSlideSeek = _.bind(onSeek, state);
- state.videoPlayer.onEnded = _.bind(onEnded, state);
- state.videoPlayer.onPause = _.bind(onPause, state);
- state.videoPlayer.onPlay = _.bind(onPlay, state);
- state.videoPlayer.onUnstarted = _.bind(onUnstarted, state);
- state.videoPlayer.handlePlaybackQualityChange = _.bind(handlePlaybackQualityChange, state);
- state.videoPlayer.onPlaybackQualityChange = _.bind(onPlaybackQualityChange, state);
- state.videoPlayer.onStateChange = _.bind(onStateChange, state);
- state.videoPlayer.onReady = _.bind(onReady, state);
- state.videoPlayer.updatePlayTime = _.bind(updatePlayTime, state);
- state.videoPlayer.isPlaying = _.bind(isPlaying, state);
- state.videoPlayer.log = _.bind(log, state);
- state.videoPlayer.duration = _.bind(duration, state);
- state.videoPlayer.onVolumeChange = _.bind(onVolumeChange, state);
+ state.videoPlayer.pause = _.bind(pause, state);
+ state.videoPlayer.play = _.bind(play, state);
+ state.videoPlayer.update = _.bind(update, state);
+ state.videoPlayer.onSpeedChange = _.bind(onSpeedChange, state);
+ state.videoPlayer.onCaptionSeek = _.bind(onSeek, state);
+ state.videoPlayer.onSlideSeek = _.bind(onSeek, state);
+ state.videoPlayer.onEnded = _.bind(onEnded, state);
+ state.videoPlayer.onPause = _.bind(onPause, state);
+ state.videoPlayer.onPlay = _.bind(onPlay, state);
+
+ state.videoPlayer.onUnstarted = _.bind(
+ onUnstarted, state
+ );
+
+ state.videoPlayer.handlePlaybackQualityChange = _.bind(
+ handlePlaybackQualityChange, state
+ );
+
+ state.videoPlayer.onPlaybackQualityChange = _.bind(
+ onPlaybackQualityChange, state
+ );
+
+ state.videoPlayer.onStateChange = _.bind(onStateChange, state);
+ state.videoPlayer.onReady = _.bind(onReady, state);
+ state.videoPlayer.updatePlayTime = _.bind(updatePlayTime, state);
+ state.videoPlayer.isPlaying = _.bind(isPlaying, state);
+ state.videoPlayer.log = _.bind(log, state);
+ state.videoPlayer.duration = _.bind(duration, state);
+ state.videoPlayer.onVolumeChange = _.bind(onVolumeChange, state);
}
// function _initialize(state)
//
- // Create any necessary DOM elements, attach them, and set their initial configuration. Also
- // 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.
+ // Create any necessary DOM elements, attach them, and set their
+ // initial configuration. Also 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 _initialize(state) {
var youTubeId;
@@ -92,9 +103,10 @@ function (HTML5Video) {
//
// TODO: Check the status of
// http://code.google.com/p/gdata-issues/issues/detail?id=4654
- // When the YouTube team fixes the API bug, we can remove this temporary
- // bug fix.
- state.browserIsFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
+ // When the YouTube team fixes the API bug, we can remove this
+ // temporary bug fix.
+ state.browserIsFirefox = navigator.userAgent
+ .toLowerCase().indexOf('firefox') > -1;
if (state.videoType === 'html5') {
state.videoPlayer.player = new HTML5Video.Player(state.el, {
@@ -117,7 +129,8 @@ function (HTML5Video) {
events: {
onReady: state.videoPlayer.onReady,
onStateChange: state.videoPlayer.onStateChange,
- onPlaybackQualityChange: state.videoPlayer.onPlaybackQualityChange
+ onPlaybackQualityChange: state.videoPlayer
+ .onPlaybackQualityChange
}
});
}
@@ -125,9 +138,10 @@ function (HTML5Video) {
// function _restartUsingFlash(state)
//
- // When we are about to play a YouTube video in HTML5 mode and discover that we only
- // have one available playback rate, we will switch to Flash mode. In Flash speed
- // switching is done by reloading videos recorded at different frame rates.
+ // When we are about to play a YouTube video in HTML5 mode and discover
+ // that we only have one available playback rate, we will switch to
+ // Flash mode. In Flash speed switching is done by reloading videos
+ // recorded at different frame rates.
function _restartUsingFlash(state) {
// Remove from the page current iFrame with HTML5 video.
state.videoPlayer.player.destroy();
@@ -139,25 +153,29 @@ function (HTML5Video) {
});
state.currentPlayerMode = 'flash';
+ console.log('[Video info]: Changing YouTube player mode to "flash".');
+
// Removed configuration option that requests the HTML5 mode.
delete state.videoPlayer.playerVars.html5;
// Request for the creation of a new Flash player
state.videoPlayer.player = new YT.Player(state.id, {
- 'playerVars': state.videoPlayer.playerVars,
- 'videoId': state.youtubeId(),
- 'events': {
- 'onReady': state.videoPlayer.onReady,
- 'onStateChange': state.videoPlayer.onStateChange,
- 'onPlaybackQualityChange': state.videoPlayer.onPlaybackQualityChange
+ playerVars: state.videoPlayer.playerVars,
+ videoId: state.youtubeId(),
+ events: {
+ onReady: state.videoPlayer.onReady,
+ onStateChange: state.videoPlayer.onStateChange,
+ onPlaybackQualityChange: state.videoPlayer
+ .onPlaybackQualityChange
}
});
}
// ***************************************************************
// 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().
+ // 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 pause() {
@@ -174,9 +192,11 @@ function (HTML5Video) {
// This function gets the video's current play position in time
// (currentTime) and its duration.
- // It is called at a regular interval when the video is playing (see below).
+ // It is called at a regular interval when the video is playing (see
+ // below).
function update() {
- this.videoPlayer.currentTime = this.videoPlayer.player.getCurrentTime();
+ this.videoPlayer.currentTime = this.videoPlayer.player
+ .getCurrentTime();
if (isFinite(this.videoPlayer.currentTime)) {
this.videoPlayer.updatePlayTime(this.videoPlayer.currentTime);
@@ -206,19 +226,27 @@ function (HTML5Video) {
if (
this.currentPlayerMode === 'html5' &&
- !(this.browserIsFirefox && newSpeed === '1.0' && this.videoType === 'youtube')
+ !(
+ this.browserIsFirefox &&
+ newSpeed === '1.0' &&
+ this.videoType === 'youtube'
+ )
) {
this.videoPlayer.player.setPlaybackRate(newSpeed);
} else {
- // We request the reloading of the video in the case when YouTube is in
- // Flash player mode, or when we are in Firefox, and the new speed is 1.0.
- // The second case is necessary to avoid the bug where in Firefox speed
- // switching to 1.0 in HTML5 player mode is handled incorrectly by YouTube
- // API.
+ // We request the reloading of the video in the case when YouTube
+ // is in Flash player mode, or when we are in Firefox, and the new
+ // speed is 1.0. The second case is necessary to avoid the bug
+ // where in Firefox speed switching to 1.0 in HTML5 player mode is
+ // handled incorrectly by YouTube API.
if (this.videoPlayer.isPlaying()) {
- this.videoPlayer.player.loadVideoById(this.youtubeId(), this.videoPlayer.currentTime);
+ this.videoPlayer.player.loadVideoById(
+ this.youtubeId(), this.videoPlayer.currentTime
+ );
} else {
- this.videoPlayer.player.cueVideoById(this.youtubeId(), this.videoPlayer.currentTime);
+ this.videoPlayer.player.cueVideoById(
+ this.youtubeId(), this.videoPlayer.currentTime
+ );
}
this.videoPlayer.updatePlayTime(this.videoPlayer.currentTime);
@@ -243,7 +271,9 @@ function (HTML5Video) {
if (this.videoPlayer.isPlaying()) {
clearInterval(this.videoPlayer.updateInterval);
- this.videoPlayer.updateInterval = setInterval(this.videoPlayer.update, 200);
+ this.videoPlayer.updateInterval = setInterval(
+ this.videoPlayer.update, 200
+ );
} else {
this.videoPlayer.currentTime = params.time;
}
@@ -286,7 +316,9 @@ function (HTML5Video) {
);
if (!this.videoPlayer.updateInterval) {
- this.videoPlayer.updateInterval = setInterval(this.videoPlayer.update, 200);
+ this.videoPlayer.updateInterval = setInterval(
+ this.videoPlayer.update, 200
+ );
}
this.trigger('videoControl.play', null);
@@ -325,19 +357,26 @@ function (HTML5Video) {
// https://bugzilla.mozilla.org/show_bug.cgi?id=840745
// https://developer.mozilla.org/en-US/docs/DOM/HTMLMediaElement
- availablePlaybackRates = _.filter(availablePlaybackRates, function(item){
- var speed = Number(item);
- return speed > 0.25 && speed <= 5;
- });
+ availablePlaybackRates = _.filter(
+ availablePlaybackRates,
+ function (item) {
+ var speed = Number(item);
+ return speed > 0.25 && speed <= 5;
+ }
+ );
- if ((this.currentPlayerMode === 'html5') && (this.videoType === 'youtube')) {
+ if (
+ this.currentPlayerMode === 'html5' &&
+ this.videoType === 'youtube'
+ ) {
if (availablePlaybackRates.length === 1) {
- // This condition is needed in cases when Firefox version is less than 20. In those versions
- // HTML5 playback could only happen at 1 speed (no speed changing). Therefore, in this case,
- // we need to switch back to Flash.
+ // This condition is needed in cases when Firefox version is
+ // less than 20. In those versions HTML5 playback could only
+ // happen at 1 speed (no speed changing). Therefore, in this
+ // case, we need to switch back to Flash.
//
- // This might also happen in other browsers, therefore when we have 1 speed available, we fall
- // back to Flash.
+ // This might also happen in other browsers, therefore when we
+ // have 1 speed available, we fall back to Flash.
_restartUsingFlash(this);
@@ -352,18 +391,26 @@ function (HTML5Video) {
// and their associated subs.
// First clear the dictionary.
- $.each(this.videos, function(index, value) {
+ $.each(this.videos, function (index, value) {
delete _this.videos[index];
});
this.speeds = [];
// Recreate it with the supplied frame rates.
- $.each(availablePlaybackRates, function(index, value) {
- _this.videos[value.toFixed(2).replace(/\.00$/, '.0')] = baseSpeedSubs;
+ $.each(availablePlaybackRates, function (index, value) {
+ var key = value.toFixed(2).replace(/\.00$/, '.0');
- _this.speeds.push(value.toFixed(2).replace(/\.00$/, '.0'));
+ _this.videos[key] = baseSpeedSubs;
+
+ _this.speeds.push(key);
});
- this.trigger('videoSpeedControl.reRender', {'newSpeeds': this.speeds, 'currentSpeed': this.speed});
+ this.trigger(
+ 'videoSpeedControl.reRender',
+ {
+ newSpeeds: this.speeds,
+ currentSpeed: this.speed
+ }
+ );
this.setSpeed($.cookie('video_speed'));
}
@@ -373,7 +420,10 @@ function (HTML5Video) {
this.videoPlayer.player.setPlaybackRate(this.speed);
}
- if (!onTouchBasedDevice() && $('.video:first').data('autoplay') === 'True') {
+ if (
+ !onTouchBasedDevice() &&
+ $('.video:first').data('autoplay') === 'True'
+ ) {
this.videoPlayer.play();
}
}
@@ -400,19 +450,37 @@ function (HTML5Video) {
duration = this.videoPlayer.duration();
- this.trigger('videoProgressSlider.updatePlayTime', {'time': time, 'duration': duration});
- this.trigger('videoControl.updateVcrVidTime', {'time': time, 'duration': duration});
+ this.trigger(
+ 'videoProgressSlider.updatePlayTime',
+ {
+ time: time,
+ duration: duration
+ }
+ );
+
+ this.trigger(
+ 'videoControl.updateVcrVidTime',
+ {
+ time: time,
+ duration: duration
+ }
+ );
+
this.trigger('videoCaption.updatePlayTime', time);
}
function isPlaying() {
- return this.videoPlayer.player.getPlayerState() === this.videoPlayer.PlayerState.PLAYING;
+ var playerState = this.videoPlayer.player.getPlayerState(),
+ PLAYING = this.videoPlayer.PlayerState.PLAYING;
+
+ return playerState === PLAYING;
}
function duration() {
var dur;
dur = this.videoPlayer.player.getDuration();
+
if (!isFinite(dur)) {
dur = this.getDuration();
}
@@ -431,7 +499,7 @@ function (HTML5Video) {
// If extra parameters were passed to the log.
if (data) {
- $.each(data, function(paramName, value) {
+ $.each(data, function (paramName, value) {
logInfo[paramName] = value;
});
}
diff --git a/common/lib/xmodule/xmodule/js/src/video/08_video_speed_control.js b/common/lib/xmodule/xmodule/js/src/video/08_video_speed_control.js
index 6a6587186d..9db56ffc0d 100644
--- a/common/lib/xmodule/xmodule/js/src/video/08_video_speed_control.js
+++ b/common/lib/xmodule/xmodule/js/src/video/08_video_speed_control.js
@@ -19,6 +19,10 @@ function () {
}
if (state.videoType === 'html5' && !(_checkPlaybackRates())) {
+ console.log(
+ '[Video info]: HTML5 mode - playbackRate is not supported.'
+ );
+
_hideSpeedControl(state);
return;
@@ -65,7 +69,7 @@ function () {
state.videoSpeedControl.el
);
- $.each(state.videoSpeedControl.speeds, function(index, speed) {
+ $.each(state.videoSpeedControl.speeds, function (index, speed) {
var link = '' + speed + 'x';
state.videoSpeedControl.videoSpeedsEl
@@ -78,26 +82,27 @@ function () {
}
/**
- * @desc Check if playbackRate supports by browser.
- *
- * @type {function}
- * @access private
- *
- * @param {object} state The object containg the state of the video player.
- * All other modules, their parameters, public variables, etc. are
- * available via this object.
- *
- * @this {object} The global window object.
- *
- * @returns {Boolean}
- * true: Browser support playbackRate functionality.
- * false: Browser doesn't support playbackRate functionality.
- */
+ * @desc Check if playbackRate supports by browser.
+ *
+ * @type {function}
+ * @access private
+ *
+ * @param {object} state The object containg the state of the video player.
+ * All other modules, their parameters, public variables, etc. are
+ * available via this object.
+ *
+ * @this {object} The global window object.
+ *
+ * @returns {Boolean}
+ * true: Browser support playbackRate functionality.
+ * false: Browser doesn't support playbackRate functionality.
+ */
function _checkPlaybackRates() {
var video = document.createElement('video');
- // If browser supports, 1.0 should be returned by playbackRate property.
- // In this case, function return True. Otherwise, False will be returned.
+ // If browser supports, 1.0 should be returned by playbackRate
+ // property. In this case, function return True. Otherwise, False will
+ // be returned.
return Boolean(video.playbackRate);
}
@@ -128,7 +133,7 @@ function () {
.on('click', state.videoSpeedControl.changeVideoSpeed);
if (onTouchBasedDevice()) {
- state.videoSpeedControl.el.on('click', function(event) {
+ state.videoSpeedControl.el.on('click', function (event) {
// So that you can't highlight this control via a drag
// operation, we disable the default browser actions on a
// click event.
@@ -287,7 +292,7 @@ function () {
this.videoSpeedControl.videoSpeedsEl.find('li').removeClass('active');
this.videoSpeedControl.speeds = params.newSpeeds;
- $.each(this.videoSpeedControl.speeds, function(index, speed) {
+ $.each(this.videoSpeedControl.speeds, function (index, speed) {
var link, listItem;
link = '' + speed + 'x';