Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
feee5750
Commit
feee5750
authored
Nov 02, 2017
by
muhammad-ammar
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add video duration to events
EDUCATOR-1409
parent
42396560
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
72 additions
and
22 deletions
+72
-22
common/lib/xmodule/xmodule/js/fixtures/video_hls.html
+1
-1
common/lib/xmodule/xmodule/js/fixtures/video_html5.html
+1
-1
common/lib/xmodule/xmodule/js/spec/video/video_events_plugin_spec.js
+32
-15
common/lib/xmodule/xmodule/js/spec/video/video_player_spec.js
+15
-0
common/lib/xmodule/xmodule/js/src/video/01_initialize.js
+1
-0
common/lib/xmodule/xmodule/js/src/video/03_video_player.js
+3
-0
common/lib/xmodule/xmodule/js/src/video/09_events_plugin.js
+2
-1
common/lib/xmodule/xmodule/video_module/video_module.py
+7
-1
lms/djangoapps/courseware/tests/test_video_mongo.py
+10
-3
No files found.
common/lib/xmodule/xmodule/js/fixtures/video_hls.html
View file @
feee5750
...
...
@@ -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>
...
...
common/lib/xmodule/xmodule/js/fixtures/video_html5.html
View file @
feee5750
...
...
@@ -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>
...
...
common/lib/xmodule/xmodule/js/spec/video/video_events_plugin_spec.js
View file @
feee5750
...
...
@@ -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
();
});
...
...
common/lib/xmodule/xmodule/js/spec/video/video_player_spec.js
View file @
feee5750
...
...
@@ -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
()
{
...
...
common/lib/xmodule/xmodule/js/src/video/01_initialize.js
View file @
feee5750
...
...
@@ -569,6 +569,7 @@ function(VideoPlayer, i18n, moment, _) {
this
.
config
.
speed
||
this
.
config
.
generalSpeed
);
this
.
htmlPlayerLoaded
=
false
;
this
.
duration
=
this
.
metadata
.
duration
;
_setConfigurations
(
this
);
...
...
common/lib/xmodule/xmodule/js/src/video/03_video_player.js
View file @
feee5750
...
...
@@ -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
);
}
...
...
common/lib/xmodule/xmodule/js/src/video/09_events_plugin.js
View file @
feee5750
...
...
@@ -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
);
}
...
...
common/lib/xmodule/xmodule/video_module/video_module.py
View file @
feee5750
...
...
@@ -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
),
...
...
lms/djangoapps/courseware/tests/test_video_mongo.py
View file @
feee5750
...
...
@@ -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
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment