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 09d95e789182e75cdff310d75f726cdd834cc1f8..cf37e68e79a18f6c9420e1b9297e55c5b6bc97a4 100644 --- a/common/lib/xmodule/xmodule/js/src/video/01_initialize.js +++ b/common/lib/xmodule/xmodule/js/src/video/01_initialize.js @@ -73,7 +73,10 @@ function (VideoPlayer, VideoStorage) { setSpeed: setSpeed, trigger: trigger, youtubeId: youtubeId - }; + }, + + _youtubeApiDeferred = null, + _oldOnYouTubeIframeAPIReady; Initialize.prototype = methodsDict; @@ -112,7 +115,7 @@ function (VideoPlayer, VideoStorage) { // 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 video, onYTApiReady; + var video, onYTApiReady, setupOnYouTubeIframeAPIReady; if (state.videoType === 'youtube') { state.youtubeApiAvailable = false; @@ -129,13 +132,65 @@ function (VideoPlayer, VideoStorage) { }; if (window.YT) { - window.YT.ready(onYTApiReady); - } else { - window.onYouTubeIframeAPIReady = function () { + // If we have a Deferred object responsible for calling OnYouTubeIframeAPIReady + // callbacks, make sure that they have all been called by trying to resolve the + // Deferred object. Upon resolving, all the OnYouTubeIframeAPIReady will be + // called. If the object has been already resolved, the callbacks will not + // be called a second time. + if (_youtubeApiDeferred) { + _youtubeApiDeferred.resolve(); + } + + window.YT.ready(function () { onYTApiReady(); + }); + } else { + // There is only one global variable window.onYouTubeIframeAPIReady which + // is supposed to be a function that will be called by the YouTube API + // when it finished initializing. This function will update this global function + // so that it resolves our Deferred object, which will call all of the + // OnYouTubeIframeAPIReady callbacks. + // + // If this global function is already defined, we store it first, and make + // sure that it gets executed when our Deferred object is resolved. + setupOnYouTubeIframeAPIReady = function () { + _oldOnYouTubeIframeAPIReady = window.onYouTubeIframeAPIReady || undefined; + + window.onYouTubeIframeAPIReady = function () { + window.onYouTubeIframeAPIReady.resolve(); + }; + + window.onYouTubeIframeAPIReady.resolve = _youtubeApiDeferred.resolve; + window.onYouTubeIframeAPIReady.done = _youtubeApiDeferred.done; + + if (_oldOnYouTubeIframeAPIReady) { + window.onYouTubeIframeAPIReady.done(_oldOnYouTubeIframeAPIReady); + } }; - _loadYoutubeApi(state); + // If a Deferred object hasn't been created yet, create one now. It will + // be responsible for calling OnYouTubeIframeAPIReady callbacks once the + // YouTube API loads. After creating the Deferred object, load the YouTube + // API. + if (!_youtubeApiDeferred) { + _youtubeApiDeferred = $.Deferred(); + setupOnYouTubeIframeAPIReady(); + _loadYoutubeApi(state); + } else if (!window.onYouTubeIframeAPIReady || !window.onYouTubeIframeAPIReady.done) { + // The Deferred object could have been already defined in a previous + // initialization of the video module. However, since then the global variable + // window.onYouTubeIframeAPIReady could have been overwritten. If so, + // we should set it up again. + setupOnYouTubeIframeAPIReady(); + } + + // Attach a callback to our Deferred object to be called once the + // YouTube API loads. + window.onYouTubeIframeAPIReady.done(function () { + window.YT.ready(function () { + onYTApiReady(); + }); + }); } } else { video = VideoPlayer(state); diff --git a/lms/djangoapps/courseware/features/video.feature b/lms/djangoapps/courseware/features/video.feature index b4fe67269924c1d4ab140e9cba879c96bd657a87..56d33eed72f83fe27d4d5a308fa216dd3da96430 100644 --- a/lms/djangoapps/courseware/features/video.feature +++ b/lms/djangoapps/courseware/features/video.feature @@ -26,37 +26,59 @@ Feature: LMS Video component Given the course has a Video component in "HTML5" mode Then when I view the video it does not have autoplay enabled - # 4 + # 3 # Youtube testing Scenario: Video component is fully rendered in the LMS in Youtube mode with HTML5 sources Given youtube server is up and response time is 0.4 seconds And the course has a Video component in "Youtube_HTML5" mode When the video has rendered in "Youtube" mode - # 5 + # 4 Scenario: Video component is not rendered in the LMS in Youtube mode with HTML5 sources Given youtube server is up and response time is 2 seconds And the course has a Video component in "Youtube_HTML5" mode When the video has rendered in "HTML5" mode - # 6 + # 5 Scenario: Video component is rendered in the LMS in Youtube mode without HTML5 sources Given youtube server is up and response time is 2 seconds And the course has a Video component in "Youtube" mode When the video has rendered in "Youtube" mode - # 7 + # 6 Scenario: Video component is rendered in the LMS in Youtube mode with HTML5 sources that doesn't supported by browser Given youtube server is up and response time is 2 seconds And the course has a Video component in "Youtube_HTML5_Unsupported_Video" mode When the video has rendered in "Youtube" mode - # 8 + # 7 Scenario: Video component is rendered in the LMS in HTML5 mode with HTML5 sources that doesn't supported by browser Given the course has a Video component in "HTML5_Unsupported_Video" mode Then error message is shown And error message has correct text + # 8 + Scenario: Multiple videos in sequentials all load and work, switching between sequentials + Given I am registered for the course "test_course" + And it has a video "A" in "Youtube" mode in position "1" of sequential + And a video "B" in "HTML5" mode in position "1" of sequential + And a video "C" in "Youtube" mode in position "1" of sequential + And a video "D" in "Youtube" mode in position "1" of sequential + And a video "E" in "Youtube" mode in position "2" of sequential + And a video "F" in "Youtube" mode in position "2" of sequential + And a video "G" in "Youtube" mode in position "2" of sequential + And I open the section with videos + Then video "A" should start playing at speed "1.0" + And I select the "2.0" speed on video "B" + And I select the "2.0" speed on video "C" + And I select the "2.0" speed on video "D" + When I open video "E" + Then video "E" should start playing at speed "2.0" + And I select the "1.0" speed on video "F" + And I select the "1.0" speed on video "G" + When I open video "A" + Then video "A" should start playing at speed "2.0" + # 9 Scenario: Video component stores speed correctly when each video is in separate sequence Given I am registered for the course "test_course" @@ -94,7 +116,7 @@ Feature: LMS Video component And I select language with code "en" And I see "Hi, welcome to Edx." text in the captions - # 11 + # 10 Scenario: CC button works correctly w/o english transcript in HTML5 mode of Video component Given I am registered for the course "test_course" And I have a "chinese_transcripts.srt" transcript file in assets @@ -104,7 +126,7 @@ Feature: LMS Video component And I make sure captions are opened Then I see "好 å„ä½åŒå¦" text in the captions - # 12 + # 11 Scenario: CC button works correctly only w/ english transcript in HTML5 mode of Video component Given I am registered for the course "test_course" And I have a "subs_OEoXaMPEzfM.srt.sjson" transcript file in assets @@ -114,7 +136,7 @@ Feature: LMS Video component And I make sure captions are opened Then I see "Hi, welcome to Edx." text in the captions - # 13 + # 12 Scenario: CC button works correctly w/o english transcript in Youtube mode of Video component Given I am registered for the course "test_course" And I have a "chinese_transcripts.srt" transcript file in assets @@ -124,7 +146,7 @@ Feature: LMS Video component And I make sure captions are opened Then I see "好 å„ä½åŒå¦" text in the captions - # 14 + # 13 Scenario: CC button works correctly if transcripts and sub fields are empty, but transcript file exists in assets (Youtube mode of Video component) Given I am registered for the course "test_course" And I have a "subs_OEoXaMPEzfM.srt.sjson" transcript file in assets @@ -132,12 +154,12 @@ Feature: LMS Video component And I make sure captions are opened Then I see "Hi, welcome to Edx." text in the captions - # 15 + # 14 Scenario: CC button is hidden if no translations Given the course has a Video component in "Youtube" mode Then button "CC" is hidden - # 16 + # 15 Scenario: Video is aligned correctly if transcript is visible in fullscreen mode Given I am registered for the course "test_course" And I have a "subs_OEoXaMPEzfM.srt.sjson" transcript file in assets @@ -148,13 +170,13 @@ Feature: LMS Video component And I click video button "fullscreen" Then I see video aligned correctly with enabled transcript - # 17 + # 16 Scenario: Video is aligned correctly if transcript is hidden in fullscreen mode Given the course has a Video component in "Youtube" mode And I click video button "fullscreen" Then I see video aligned correctly without enabled transcript - # 18 + # 17 Scenario: Video is aligned correctly on transcript toggle in fullscreen mode Given I am registered for the course "test_course" And I have a "subs_OEoXaMPEzfM.srt.sjson" transcript file in assets @@ -167,7 +189,7 @@ Feature: LMS Video component And I click video button "CC" Then I see video aligned correctly without enabled transcript - # 19 + # 18 Scenario: Download Transcript button works correctly in Video component Given I am registered for the course "test_course" And I have a "subs_OEoXaMPEzfM.srt.sjson" transcript file in assets @@ -205,7 +227,7 @@ Feature: LMS Video component # Then I see "Hi, welcome to Edx." text in the captions # And I see duration "1:00" - # 21 + # 20 Scenario: Download button works correctly for non-english transcript in Youtube mode of Video component Given I am registered for the course "test_course" And I have a "chinese_transcripts.srt" transcript file in assets @@ -218,7 +240,7 @@ Feature: LMS Video component And I see "好 å„ä½åŒå¦" text in the captions Then I can download transcript in "srt" format that has text "好 å„ä½åŒå¦" - # 22 + # 21 Scenario: Download button works correctly for non-english transcript in HTML5 mode of Video component Given I am registered for the course "test_course" And I have a "chinese_transcripts.srt" transcript file in assets @@ -231,7 +253,7 @@ Feature: LMS Video component And I see "好 å„ä½åŒå¦" text in the captions Then I can download transcript in "srt" format that has text "好 å„ä½åŒå¦" - # 23 + # 22 Scenario: Download button works correctly w/o english transcript in HTML5 mode of Video component Given I am registered for the course "test_course" And I have a "chinese_transcripts.srt" transcript file in assets @@ -241,7 +263,7 @@ Feature: LMS Video component And I see "好 å„ä½åŒå¦" text in the captions Then I can download transcript in "srt" format that has text "好 å„ä½åŒå¦" - # 24 + # 23 Scenario: Download button works correctly w/o english transcript in Youtube mode of Video component Given I am registered for the course "test_course" And I have a "chinese_transcripts.srt" transcript file in assets @@ -251,7 +273,7 @@ Feature: LMS Video component And I see "好 å„ä½åŒå¦" text in the captions Then I can download transcript in "srt" format that has text "好 å„ä½åŒå¦" - # 25 + # 24 Scenario: Verify that each video in each sub-section includes a transcript for non-Youtube countries. Given youtube server is up and response time is 2 seconds And I am registered for the course "test_course"