Commit feee5750 by muhammad-ammar

add video duration to events

EDUCATOR-1409
parent 42396560
......@@ -4,7 +4,7 @@
<div
id="video_id"
class="video closed"
data-metadata='{"autohideHtml5": "true", "autoplay": "false", "captionDataDir": "", "endTime": "", "generalSpeed": "1.0", "saveStateUrl": "/save_user_state", "savedVideoPosition": "0", "showCaptions": "true", "sources": ["/base/fixtures/hls/hls.m3u8", "/base/fixtures/test.mp4","/base/fixtures/test.webm"], "speed": "1.5", "startTime": "", "streams": "", "sub": "Z5KLxerq05Y", "transcriptAvailableTranslationsUrl": "/transcript/available_translations", "transcriptLanguage": "en", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "transcriptTranslationUrl": "/transcript/translation/__lang__", "ytApiUrl": "/base/fixtures/youtube_iframe_api.js", "ytImageUrl": "", "ytTestTimeout": "1500", "ytMetadataUrl": "www.googleapis.com/youtube/v3/videos/", "source": "", "poster": "/media/video-images/poster.png"}'
data-metadata='{"duration": 111, "autohideHtml5": "true", "autoplay": "false", "captionDataDir": "", "endTime": "", "generalSpeed": "1.0", "saveStateUrl": "/save_user_state", "savedVideoPosition": "0", "showCaptions": "true", "sources": ["/base/fixtures/hls/hls.m3u8", "/base/fixtures/test.mp4","/base/fixtures/test.webm"], "speed": "1.5", "startTime": "", "streams": "", "sub": "Z5KLxerq05Y", "transcriptAvailableTranslationsUrl": "/transcript/available_translations", "transcriptLanguage": "en", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "transcriptTranslationUrl": "/transcript/translation/__lang__", "ytApiUrl": "/base/fixtures/youtube_iframe_api.js", "ytImageUrl": "", "ytTestTimeout": "1500", "ytMetadataUrl": "www.googleapis.com/youtube/v3/videos/", "source": "", "poster": "/media/video-images/poster.png"}'
>
<div class="focus_grabber first"></div>
......
......@@ -4,7 +4,7 @@
<div
id="video_id"
class="video closed"
data-metadata='{"autohideHtml5": "true", "autoplay": "false", "captionDataDir": "", "endTime": "", "generalSpeed": "1.0", "saveStateUrl": "/save_user_state", "savedVideoPosition": "0", "showCaptions": "true", "sources": ["/base/fixtures/test.mp4","/base/fixtures/test.webm","/base/fixtures/test.ogv"], "speed": "1.5", "startTime": "", "streams": "", "sub": "Z5KLxerq05Y", "transcriptAvailableTranslationsUrl": "/transcript/available_translations", "transcriptLanguage": "en", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "transcriptTranslationUrl": "/transcript/translation/__lang__", "ytApiUrl": "/base/fixtures/youtube_iframe_api.js", "ytImageUrl": "", "ytTestTimeout": "1500", "ytMetadataUrl": "www.googleapis.com/youtube/v3/videos/", "source": "", "html5_sources": ["http://youtu.be/3_yD_cEKoCk.mp4"], "poster": "/media/video-images/poster.png"}'
data-metadata='{"duration": 111, "autohideHtml5": "true", "autoplay": "false", "captionDataDir": "", "endTime": "", "generalSpeed": "1.0", "saveStateUrl": "/save_user_state", "savedVideoPosition": "0", "showCaptions": "true", "sources": ["/base/fixtures/test.mp4","/base/fixtures/test.webm","/base/fixtures/test.ogv"], "speed": "1.5", "startTime": "", "streams": "", "sub": "Z5KLxerq05Y", "transcriptAvailableTranslationsUrl": "/transcript/available_translations", "transcriptLanguage": "en", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "transcriptTranslationUrl": "/transcript/translation/__lang__", "ytApiUrl": "/base/fixtures/youtube_iframe_api.js", "ytImageUrl": "", "ytTestTimeout": "1500", "ytMetadataUrl": "www.googleapis.com/youtube/v3/videos/", "source": "", "html5_sources": ["http://youtu.be/3_yD_cEKoCk.mp4"], "poster": "/media/video-images/poster.png"}'
>
<div class="focus_grabber first"></div>
......
......@@ -23,7 +23,8 @@
state.el.trigger('ready');
expect(Logger.log).toHaveBeenCalledWith('load_video', {
id: 'id',
code: this.code
code: this.code,
duration: this.duration
});
});
......@@ -33,7 +34,8 @@
expect(Logger.log).toHaveBeenCalledWith('play_video', {
id: 'id',
code: this.code,
currentTime: 10
currentTime: 10,
duration: this.duration
});
expect(state.videoEventsPlugin.emitPlayVideoEvent).toBeFalsy();
});
......@@ -49,7 +51,8 @@
expect(Logger.log).toHaveBeenCalledWith('pause_video', {
id: 'id',
code: this.code,
currentTime: 10
currentTime: 10,
duration: this.duration
});
expect(state.videoEventsPlugin.emitPlayVideoEvent).toBeTruthy();
});
......@@ -61,7 +64,8 @@
code: this.code,
current_time: 10,
old_speed: '1.0',
new_speed: '2.0'
new_speed: '2.0',
duration: this.duration
});
});
......@@ -72,7 +76,8 @@
code: this.code,
old_time: 0,
new_time: 1,
type: 'any'
type: 'any',
duration: this.duration
});
expect(state.videoEventsPlugin.emitPlayVideoEvent).toBeTruthy();
});
......@@ -88,7 +93,8 @@
expect(Logger.log).toHaveBeenCalledWith('stop_video', {
id: 'id',
code: this.code,
currentTime: 10
currentTime: 10,
duration: this.duration
});
expect(state.videoEventsPlugin.emitPlayVideoEvent).toBeTruthy();
......@@ -97,7 +103,8 @@
expect(Logger.log).toHaveBeenCalledWith('stop_video', {
id: 'id',
code: this.code,
currentTime: 10
currentTime: 10,
duration: this.duration
});
expect(state.videoEventsPlugin.emitPlayVideoEvent).toBeTruthy();
});
......@@ -107,7 +114,8 @@
expect(Logger.log).toHaveBeenCalledWith('skip_video', {
id: 'id',
code: this.code,
currentTime: 10
currentTime: 10,
duration: this.duration
});
});
......@@ -116,7 +124,8 @@
expect(Logger.log).toHaveBeenCalledWith('do_not_show_again_video', {
id: 'id',
code: this.code,
currentTime: 10
currentTime: 10,
duration: this.duration
});
});
......@@ -124,7 +133,8 @@
state.el.trigger('language_menu:show');
expect(Logger.log).toHaveBeenCalledWith('edx.video.language_menu.shown', {
id: 'id',
code: this.code
code: this.code,
duration: this.duration
});
});
......@@ -133,7 +143,8 @@
expect(Logger.log).toHaveBeenCalledWith('edx.video.language_menu.hidden', {
id: 'id',
code: this.code,
language: 'en'
language: 'en',
duration: this.duration
});
});
......@@ -142,7 +153,8 @@
expect(Logger.log).toHaveBeenCalledWith('show_transcript', {
id: 'id',
code: this.code,
current_time: 10
current_time: 10,
duration: this.duration
});
});
......@@ -151,7 +163,8 @@
expect(Logger.log).toHaveBeenCalledWith('hide_transcript', {
id: 'id',
code: this.code,
current_time: 10
current_time: 10,
duration: this.duration
});
});
......@@ -160,7 +173,8 @@
expect(Logger.log).toHaveBeenCalledWith('edx.video.closed_captions.shown', {
id: 'id',
code: this.code,
current_time: 10
current_time: 10,
duration: this.duration
});
});
......@@ -169,7 +183,8 @@
expect(Logger.log).toHaveBeenCalledWith('edx.video.closed_captions.hidden', {
id: 'id',
code: this.code,
current_time: 10
current_time: 10,
duration: this.duration
});
});
......@@ -208,6 +223,7 @@
describe('html5 encoding only', function() {
beforeEach(function(done) {
this.code = 'html5';
this.duration = 111;
state = jasmine.initializePlayer('video_html5.html');
done();
});
......@@ -217,6 +233,7 @@
describe('hls encoding', function() {
beforeEach(function(done) {
this.code = 'hls';
this.duration = 111;
state = jasmine.initializeHLSPlayer();
done();
});
......
......@@ -1011,6 +1011,21 @@ function(VideoPlayer, HLS) {
});
});
describe('Video duration', function() {
beforeEach(function() {
state = jasmine.initializePlayer();
spyOn(state.videoPlayer, 'duration').and.returnValue(61);
});
it('overrides the duration if not set', function(done) {
jasmine.waitUntil(function() {
return state.duration !== undefined;
}).then(function() {
expect(state.duration).toEqual(61);
}).always(done);
});
});
describe('Overlay Play Button', function() {
var playButtonOverlaySelector = '.video-wrapper .btn-play.fa.fa-youtube-play.fa-2x';
beforeEach(function() {
......
......@@ -569,6 +569,7 @@ function(VideoPlayer, i18n, moment, _) {
this.config.speed || this.config.generalSpeed
);
this.htmlPlayerLoaded = false;
this.duration = this.metadata.duration;
_setConfigurations(this);
......
......@@ -653,6 +653,9 @@ function(HTML5Video, HTML5HLSVideo, Resizer, HLS, _) {
var duration = this.videoPlayer.duration(),
time = this.videoPlayer.figureOutStartingTime(duration);
// this.duration will be set initially only if duration is coming from edx-val
this.duration = this.duration || duration;
if (time > 0 && this.videoPlayer.goToStartTime) {
this.videoPlayer.seekTo(time);
}
......
......@@ -143,7 +143,8 @@
var logInfo = _.extend({
id: this.state.id,
// eslint-disable-next-line no-nested-ternary
code: this.state.isYoutubeType() ? this.state.youtubeId() : this.state.canPlayHLS ? 'hls' : 'html5'
code: this.state.isYoutubeType() ? this.state.youtubeId() : this.state.canPlayHLS ? 'hls' : 'html5',
duration: this.state.duration
}, data, this.options.data);
Logger.log(eventName, logInfo);
}
......
......@@ -211,6 +211,7 @@ class VideoModule(VideoFields, VideoTranscriptsMixin, VideoStudentViewHandlers,
download_video_link = None
branding_info = None
youtube_streams = ""
video_duration = None
# Determine if there is an alternative source for this video
# based on user locale. This exists to support cases where
......@@ -253,7 +254,11 @@ class VideoModule(VideoFields, VideoTranscriptsMixin, VideoStudentViewHandlers,
if val_video_urls["youtube"]:
youtube_streams = "1.00:{}".format(val_video_urls["youtube"])
except edxval_api.ValInternalError:
# get video duration
video_data = edxval_api.get_video_info(self.edx_video_id.strip())
video_duration = video_data.get('duration')
except (edxval_api.ValInternalError, edxval_api.ValVideoNotFoundError):
# VAL raises this exception if it can't find data for the edx video ID. This can happen if the
# course data is ported to a machine that does not have the VAL data. So for now, pass on this
# exception and fallback to whatever we find in the VideoDescriptor.
......@@ -326,6 +331,7 @@ class VideoModule(VideoFields, VideoTranscriptsMixin, VideoStudentViewHandlers,
'sub': self.sub,
'sources': sources,
'poster': poster,
'duration': video_duration,
# This won't work when we move to data that
# isn't on the filesystem
'captionDataDir': getattr(self, 'data_dir', None),
......
......@@ -69,6 +69,7 @@ class TestVideoYouTube(TestVideo):
'streams': '0.75:jNCf2gIqpeE,1.00:ZwkTiUPN0mg,1.25:rsq9auxASqI,1.50:kMyNdzVHHgg',
'sub': 'a_sub_file.srt.sjson',
'sources': sources,
'duration': None,
'poster': None,
'captionDataDir': None,
'showCaptions': 'true',
......@@ -149,6 +150,7 @@ class TestVideoNonYouTube(TestVideo):
'streams': '1.00:3_yD_cEKoCk',
'sub': 'a_sub_file.srt.sjson',
'sources': sources,
'duration': None,
'poster': None,
'captionDataDir': None,
'showCaptions': 'true',
......@@ -206,6 +208,7 @@ class TestGetHtmlMethod(BaseTestXmodule):
'streams': '1.00:3_yD_cEKoCk',
'sub': 'a_sub_file.srt.sjson',
'sources': '[]',
'duration': 111.0,
'poster': None,
'captionDataDir': None,
'showCaptions': 'true',
......@@ -306,6 +309,7 @@ class TestGetHtmlMethod(BaseTestXmodule):
for data in cases:
metadata = self.default_metadata_dict
metadata['sources'] = sources
metadata['duration'] = None
DATA = SOURCE_XML.format(
download_track=data['download_track'],
track=data['track'],
......@@ -424,6 +428,7 @@ class TestGetHtmlMethod(BaseTestXmodule):
],
'poster': 'null',
}
initial_context['metadata']['duration'] = None
for data in cases:
DATA = SOURCE_XML.format(
......@@ -674,7 +679,7 @@ class TestGetHtmlMethod(BaseTestXmodule):
result = create_video(
dict(
client_video_id='A Client Video id',
duration=111,
duration=111.0,
edx_video_id=edx_video_id,
status='test',
encoded_videos=encoded_videos,
......@@ -835,6 +840,7 @@ class TestGetHtmlMethod(BaseTestXmodule):
],
'poster': 'null',
}
initial_context['metadata']['duration'] = None
for data in cases:
DATA = SOURCE_XML.format(
......@@ -1542,7 +1548,7 @@ class VideoDescriptorTest(TestCase, VideoDescriptorTestBase):
create_video({
'edx_video_id': self.descriptor.edx_video_id,
'client_video_id': 'test_client_video_id',
'duration': 111,
'duration': 111.0,
'status': 'dummy',
'encoded_videos': [{
'profile': 'mobile',
......@@ -1643,7 +1649,7 @@ class VideoDescriptorTest(TestCase, VideoDescriptorTestBase):
self.assertEqual(video.edx_video_id, 'test_edx_video_id')
video_data = get_video_info(video.edx_video_id)
self.assertEqual(video_data['client_video_id'], 'test_client_video_id')
self.assertEqual(video_data['duration'], 111)
self.assertEqual(video_data['duration'], 111.0)
self.assertEqual(video_data['status'], 'imported')
self.assertEqual(video_data['courses'], [{id_generator.target_course_id: None}])
self.assertEqual(video_data['encoded_videos'][0]['profile'], 'mobile')
......@@ -1788,6 +1794,7 @@ class TestVideoWithBumper(TestVideo):
'sub': 'a_sub_file.srt.sjson',
'sources': sources,
'poster': None,
'duration': None,
'captionDataDir': None,
'showCaptions': 'true',
'generalSpeed': 1.0,
......
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