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
92cd4627
Commit
92cd4627
authored
Mar 27, 2014
by
polesye
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
BLD-950: Update captions logic on front-end.
parent
52ca4226
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
322 additions
and
52 deletions
+322
-52
cms/djangoapps/contentstore/features/transcripts.py
+3
-1
common/lib/xmodule/xmodule/js/spec/video/async_process_spec.js
+97
-0
common/lib/xmodule/xmodule/js/spec/video/sjson_spec.js
+35
-0
common/lib/xmodule/xmodule/js/spec/video/video_caption_spec.js
+0
-0
common/lib/xmodule/xmodule/js/src/video/00_async_process.js
+59
-0
common/lib/xmodule/xmodule/js/src/video/00_sjson.js
+65
-0
common/lib/xmodule/xmodule/js/src/video/09_video_caption.js
+0
-0
common/lib/xmodule/xmodule/video_module/video_module.py
+2
-0
lms/djangoapps/courseware/features/video.feature
+32
-28
lms/djangoapps/courseware/features/video.py
+29
-23
No files found.
cms/djangoapps/contentstore/features/transcripts.py
View file @
92cd4627
...
...
@@ -201,7 +201,9 @@ def upload_file(_step, file_name):
@step
(
'I see "([^"]*)" text in the captions'
)
def
check_text_in_the_captions
(
_step
,
text
):
assert
world
.
browser
.
is_text_present
(
text
.
strip
(),
5
)
world
.
wait_for
(
lambda
_
:
world
.
css_text
(
'.subtitles'
))
actual_text
=
world
.
css_text
(
'.subtitles'
)
assert
(
text
in
actual_text
)
@step
(
'I see value "([^"]*)" in the field "([^"]*)"$'
)
...
...
common/lib/xmodule/xmodule/js/spec/video/async_process_spec.js
0 → 100644
View file @
92cd4627
(
function
(
require
)
{
require
(
[
'video/00_async_process.js'
],
function
(
AsyncProcess
)
{
var
getArrayNthLength
=
function
(
n
,
multiplier
)
{
var
result
=
[],
mul
=
multiplier
||
1
;
for
(
var
i
=
0
;
i
<
n
;
i
++
)
{
result
[
i
]
=
i
*
mul
;
}
return
result
;
},
items
=
getArrayNthLength
(
1000
);
describe
(
'AsyncProcess'
,
function
()
{
it
(
'Array is processed successfully'
,
function
()
{
var
processedArray
,
expectedArray
=
getArrayNthLength
(
1000
,
2
),
process
=
function
(
item
)
{
return
2
*
item
;
};
runs
(
function
()
{
AsyncProcess
.
array
(
items
,
process
).
done
(
function
(
result
)
{
processedArray
=
result
;
});
});
waitsFor
(
function
()
{
return
processedArray
;
},
'Array processing takes too much time'
,
WAIT_TIMEOUT
);
runs
(
function
()
{
expect
(
processedArray
).
toEqual
(
expectedArray
);
});
});
it
(
'If non-array is passed, error callback is called'
,
function
()
{
var
isError
,
process
=
function
()
{};
runs
(
function
()
{
AsyncProcess
.
array
(
'string'
,
process
).
fail
(
function
()
{
isError
=
true
;
});
});
waitsFor
(
function
()
{
return
isError
;
},
'Error callback wasn
\'
t called'
,
WAIT_TIMEOUT
);
runs
(
function
()
{
expect
(
isError
).
toBeTruthy
();
});
});
it
(
'If an empty array is passed, returns initial array'
,
function
()
{
var
processedArray
,
process
=
function
()
{};
runs
(
function
()
{
AsyncProcess
.
array
([],
process
).
done
(
function
(
result
)
{
processedArray
=
result
;
});
});
waitsFor
(
function
()
{
return
processedArray
;
},
'Array processing takes too much time'
,
WAIT_TIMEOUT
);
runs
(
function
()
{
expect
(
processedArray
).
toEqual
([]);
});
});
it
(
'If no process function passed, returns initial array'
,
function
()
{
var
processedArray
;
runs
(
function
()
{
AsyncProcess
.
array
(
items
).
done
(
function
(
result
)
{
processedArray
=
result
;
});
});
waitsFor
(
function
()
{
return
processedArray
;
},
'Array processing takes too much time'
,
WAIT_TIMEOUT
);
runs
(
function
()
{
expect
(
processedArray
).
toEqual
(
items
);
});
});
});
});
}(
RequireJS
.
require
));
common/lib/xmodule/xmodule/js/spec/video/sjson_spec.js
0 → 100644
View file @
92cd4627
(
function
(
require
)
{
require
(
[
'video/00_sjson.js'
],
function
(
Sjson
)
{
describe
(
'Sjson'
,
function
()
{
var
data
=
jasmine
.
stubbedCaption
,
sjson
;
beforeEach
(
function
()
{
sjson
=
new
Sjson
(
data
);
});
it
(
'returns captions'
,
function
()
{
expect
(
sjson
.
getCaptions
()).
toEqual
(
data
.
text
);
});
it
(
'returns start times'
,
function
()
{
expect
(
sjson
.
getStartTimes
()).
toEqual
(
data
.
start
);
});
it
(
'returns correct length'
,
function
()
{
expect
(
sjson
.
getSize
()).
toEqual
(
data
.
text
.
length
);
});
it
(
'search returns a correct caption index'
,
function
()
{
expect
(
sjson
.
search
(
0
)).
toEqual
(
-
1
);
expect
(
sjson
.
search
(
3120
)).
toEqual
(
1
);
expect
(
sjson
.
search
(
6270
)).
toEqual
(
2
);
expect
(
sjson
.
search
(
8490
)).
toEqual
(
2
);
expect
(
sjson
.
search
(
21620
)).
toEqual
(
4
);
expect
(
sjson
.
search
(
24920
)).
toEqual
(
5
);
});
});
});
}(
RequireJS
.
require
));
common/lib/xmodule/xmodule/js/spec/video/video_caption_spec.js
View file @
92cd4627
This diff is collapsed.
Click to expand it.
common/lib/xmodule/xmodule/js/src/video/00_async_process.js
0 → 100644
View file @
92cd4627
(
function
(
define
)
{
define
(
'video/00_async_process.js'
,
[],
function
()
{
"use strict"
;
/**
* Provides convenient way to process big amount of data without UI blocking.
*
* @param {array} list Array to process.
* @param {function} process Calls this function on each item in the list.
* @return {array} Returns a Promise object to observe when all actions of a
certain type bound to the collection, queued or not, have finished.
*/
var
AsyncProcess
=
{
array
:
function
(
list
,
process
)
{
if
(
!
_
.
isArray
(
list
))
{
return
$
.
Deferred
().
reject
().
promise
();
}
if
(
!
_
.
isFunction
(
process
)
||
!
list
.
length
)
{
return
$
.
Deferred
().
resolve
(
list
).
promise
();
}
var
MAX_DELAY
=
50
,
// maximum amount of time that js code should be allowed to run continuously
dfd
=
$
.
Deferred
(),
result
=
[],
index
=
0
,
len
=
list
.
length
;
var
getCurrentTime
=
function
()
{
return
(
new
Date
()).
getTime
();
};
var
handler
=
function
()
{
var
start
=
getCurrentTime
();
do
{
result
[
index
]
=
process
(
list
[
index
],
index
);
index
++
;
}
while
(
index
<
len
&&
getCurrentTime
()
-
start
<
MAX_DELAY
);
if
(
index
<
len
)
{
setTimeout
(
handler
,
25
);
}
else
{
dfd
.
resolve
(
result
);
}
};
setTimeout
(
handler
,
25
);
return
dfd
.
promise
();
}
};
return
AsyncProcess
;
});
}(
RequireJS
.
define
));
common/lib/xmodule/xmodule/js/src/video/00_sjson.js
0 → 100644
View file @
92cd4627
(
function
(
define
)
{
define
(
'video/00_sjson.js'
,
[],
function
()
{
"use strict"
;
var
Sjson
=
function
(
data
)
{
var
sjson
=
{
start
:
data
.
start
.
concat
(),
text
:
data
.
text
.
concat
()
},
module
=
{};
var
getter
=
function
(
propertyName
)
{
return
function
()
{
return
sjson
[
propertyName
];
};
};
var
getStartTimes
=
getter
(
'start'
);
var
getCaptions
=
getter
(
'text'
);
var
size
=
function
()
{
return
sjson
.
text
.
length
;
};
var
search
=
function
(
time
)
{
var
start
=
getStartTimes
(),
max
=
size
()
-
1
,
min
=
0
,
index
;
if
(
time
<
start
[
min
])
{
return
-
1
;
}
while
(
min
<
max
)
{
index
=
Math
.
ceil
((
max
+
min
)
/
2
);
if
(
time
<
start
[
index
])
{
max
=
index
-
1
;
}
if
(
time
>=
start
[
index
])
{
min
=
index
;
}
}
return
min
;
};
return
{
getCaptions
:
getCaptions
,
getStartTimes
:
getStartTimes
,
getSize
:
size
,
search
:
search
};
};
return
Sjson
;
});
}(
RequireJS
.
define
));
common/lib/xmodule/xmodule/js/src/video/09_video_caption.js
View file @
92cd4627
This diff is collapsed.
Click to expand it.
common/lib/xmodule/xmodule/video_module/video_module.py
View file @
92cd4627
...
...
@@ -72,6 +72,8 @@ class VideoModule(VideoFields, VideoStudentViewHandlers, XModule):
'js'
:
[
resource_string
(
module
,
'js/src/video/00_video_storage.js'
),
resource_string
(
module
,
'js/src/video/00_resizer.js'
),
resource_string
(
module
,
'js/src/video/00_async_process.js'
),
resource_string
(
module
,
'js/src/video/00_sjson.js'
),
resource_string
(
module
,
'js/src/video/01_initialize.js'
),
resource_string
(
module
,
'js/src/video/025_focus_grabber.js'
),
resource_string
(
module
,
'js/src/video/02_html5_video.js'
),
...
...
lms/djangoapps/courseware/features/video.feature
View file @
92cd4627
...
...
@@ -111,18 +111,18 @@ Feature: LMS Video component
# 11
Scenario
:
Language menu works correctly in Video component
Given
I am registered for the course
"test_course"
And
I have a
"chinese_transcripts.srt"
transcript file in assets
And
I have a
"subs_OEoXaMPEzfM.srt.sjson"
transcript file in assets
And it has a video in "Youtube" mode
:
Given
I am registered for the course
"test_course"
And
I have a
"chinese_transcripts.srt"
transcript file in assets
And
I have a
"subs_OEoXaMPEzfM.srt.sjson"
transcript file in assets
And it has a video in "Youtube" mode
:
|
transcripts
|
sub
|
|
{"zh":
"chinese_transcripts.srt"}
|
OEoXaMPEzfM
|
And
I make sure captions are closed
And
I see video menu
"language"
with correct items
And
I select language with code
"zh"
Then
I see
"好 各位同学"
text in the captions
And
I select language with code
"en"
And
I see
"Hi, welcome to Edx."
text in the captions
And
I make sure captions are closed
And
I see video menu
"language"
with correct items
And
I select language with code
"zh"
Then
I see
"好 各位同学"
text in the captions
And
I select language with code
"en"
And
I see
"Hi, welcome to Edx."
text in the captions
# 12
Scenario
:
CC button works correctly w/o english transcript in HTML5 mode of Video component
...
...
@@ -237,29 +237,31 @@ Feature: LMS Video component
# 21
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
And
I have a
"subs_OEoXaMPEzfM.srt.sjson"
transcript file in assets
And it has a video in "Youtube" mode
:
Given
I am registered for the course
"test_course"
And
I have a
"chinese_transcripts.srt"
transcript file in assets
And
I have a
"subs_OEoXaMPEzfM.srt.sjson"
transcript file in assets
And it has a video in "Youtube" mode
:
|
transcripts
|
sub
|
download_track
|
|
{"zh":
"chinese_transcripts.srt"}
|
OEoXaMPEzfM
|
true
|
Then
I can download transcript in
"srt"
format that has text
"Hi, welcome to Edx."
And
I select language with code
"zh"
And
I see
"好 各位同学"
text in the captions
Then
I can download transcript in
"srt"
format that has text
"好 各位同学"
And
I see
"Hi, welcome to Edx."
text in the captions
Then
I can download transcript in
"srt"
format that has text
"Hi, welcome to Edx."
And
I select language with code
"zh"
And
I see
"好 各位同学"
text in the captions
Then
I can download transcript in
"srt"
format that has text
"好 各位同学"
# 22
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
And
I have a
"subs_OEoXaMPEzfM.srt.sjson"
transcript file in assets
And it has a video in "HTML5" mode
:
Given
I am registered for the course
"test_course"
And
I have a
"chinese_transcripts.srt"
transcript file in assets
And
I have a
"subs_OEoXaMPEzfM.srt.sjson"
transcript file in assets
And it has a video in "HTML5" mode
:
|
transcripts
|
sub
|
download_track
|
|
{"zh":
"chinese_transcripts.srt"}
|
OEoXaMPEzfM
|
true
|
Then
I can download transcript in
"srt"
format that has text
"Hi, welcome to Edx."
And
I select language with code
"zh"
And
I see
"好 各位同学"
text in the captions
Then
I can download transcript in
"srt"
format that has text
"好 各位同学"
And
I see
"Hi, welcome to Edx."
text in the captions
Then
I can download transcript in
"srt"
format that has text
"Hi, welcome to Edx."
And
I select language with code
"zh"
And
I see
"好 各位同学"
text in the captions
Then
I can download transcript in
"srt"
format that has text
"好 各位同学"
# 23
Scenario
:
Download button works correctly w/o english transcript in HTML5 mode of Video component
...
...
@@ -298,8 +300,10 @@ Feature: LMS Video component
And
a video
"D"
in
"Youtube_HTML5"
mode in position
"3"
of sequential
And
I open the section with videos
Then
videos have rendered in
"HTML5"
mode
And
I see
"Hi, welcome to Edx."
text in the captions
And
I see
"Equal transcripts"
text in the captions
And I see text in the captions
:
|
text
|
|
Hi,
welcome
to
Edx.
|
|
Equal
transcripts
|
When
I open video
"C"
Then
the video has rendered in
"HTML5"
mode
And
I make sure captions are opened
...
...
lms/djangoapps/courseware/features/video.py
View file @
92cd4627
...
...
@@ -240,25 +240,25 @@ def set_window_dimensions(width, height):
def
duration
():
"""
Total duration of the video, in seconds.
"""
elapsed_time
,
duration
=
video_time
()
return
duration
"""
Total duration of the video, in seconds.
"""
elapsed_time
,
duration
=
video_time
()
return
duration
def
video_time
():
"""
Return a tuple `(elapsed_time, duration)`, each in seconds.
"""
# The full time has the form "0:32 / 3:14"
full_time
=
world
.
css_text
(
'div.vidtime'
)
"""
Return a tuple `(elapsed_time, duration)`, each in seconds.
"""
# The full time has the form "0:32 / 3:14"
full_time
=
world
.
css_text
(
'div.vidtime'
)
# Split the time at the " / ", to get ["0:32", "3:14"]
elapsed_str
,
duration_str
=
full_time
.
split
(
' / '
)
# Split the time at the " / ", to get ["0:32", "3:14"]
elapsed_str
,
duration_str
=
full_time
.
split
(
' / '
)
# Convert each string to seconds
return
(
parse_time_str
(
elapsed_str
),
parse_time_str
(
duration_str
))
# Convert each string to seconds
return
(
parse_time_str
(
elapsed_str
),
parse_time_str
(
duration_str
))
def
parse_time_str
(
time_str
):
...
...
@@ -316,13 +316,13 @@ def visit_video_section(_step):
@step
(
'I select the "([^"]*)" speed$'
)
def
i_select_video_speed
(
_step
,
speed
):
change_video_speed
(
speed
)
change_video_speed
(
speed
)
@step
(
'I select the "([^"]*)" speed on video "([^"]*)"$'
)
def
change_video_speed_on_video
(
_step
,
speed
,
player_id
):
navigate_to_an_item_in_a_sequence
(
world
.
video_sequences
[
player_id
])
change_video_speed
(
speed
)
navigate_to_an_item_in_a_sequence
(
world
.
video_sequences
[
player_id
])
change_video_speed
(
speed
)
@step
(
'I open video "([^"]*)"$'
)
...
...
@@ -419,7 +419,15 @@ def i_see_menu(_step, menu):
@step
(
'I see "([^"]*)" text in the captions$'
)
def
check_text_in_the_captions
(
_step
,
text
):
assert
world
.
browser
.
is_text_present
(
text
.
strip
())
world
.
wait_for
(
lambda
_
:
world
.
css_text
(
'.subtitles'
))
actual_text
=
world
.
css_text
(
'.subtitles'
)
assert
(
text
in
actual_text
)
@step
(
'I see text in the captions:'
)
def
check_captions
(
_step
):
for
index
,
video
in
enumerate
(
_step
.
hashes
):
assert
(
video
.
get
(
'text'
)
in
world
.
css_text
(
'.subtitles'
,
index
=
index
))
@step
(
'I select language with code "([^"]*)"$'
)
...
...
@@ -441,14 +449,14 @@ def select_language(_step, code):
# Make sure that all ajax requests that affects the display of captions are finished.
# For example, request to get new translation etc.
world
.
wait_for_ajax_complete
()
assert
world
.
css_visible
(
'.subtitles'
)
world
.
wait_for_visible
(
'.subtitles'
)
@step
(
'I click video button "([^"]*)"$'
)
def
click_button
(
_step
,
button
):
world
.
css_click
(
VIDEO_BUTTONS
[
button
])
@step
(
'I see video starts playing from "([^"]*)" position$'
)
def
start_playing_video_from_n_seconds
(
_step
,
position
):
world
.
wait_for
(
...
...
@@ -504,9 +512,7 @@ def video_alignment(_step, transcript_visibility):
height
=
abs
(
expected
[
'height'
]
-
real
[
'height'
])
<=
5
# Restore initial window size
set_window_dimensions
(
initial
[
'width'
],
initial
[
'height'
]
)
set_window_dimensions
(
initial
[
'width'
],
initial
[
'height'
])
assert
all
([
width
,
height
])
...
...
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