Merge pull request #5974 from edx/mobile/MA-135-122
MA-135, MA-122 Support CDN, alternative sources with VAL-enabled-videos
This commit is contained in:
@@ -176,18 +176,6 @@ class VideoModule(VideoFields, VideoTranscriptsMixin, VideoStudentViewHandlers,
|
||||
transcript_download_format = self.transcript_download_format if not (self.download_track and self.track) else None
|
||||
sources = filter(None, self.html5_sources)
|
||||
|
||||
# If the user comes from China use China CDN for html5 videos.
|
||||
# 'CN' is China ISO 3166-1 country code.
|
||||
# Video caching is disabled for Studio. User_location is always None in Studio.
|
||||
# CountryMiddleware disabled for Studio.
|
||||
cdn_url = getattr(settings, 'VIDEO_CDN_URL', {}).get(self.system.user_location)
|
||||
|
||||
if getattr(self, 'video_speed_optimizations', True) and cdn_url:
|
||||
for index, source_url in enumerate(sources):
|
||||
new_url = get_video_from_cdn(cdn_url, source_url)
|
||||
if new_url:
|
||||
sources[index] = new_url
|
||||
|
||||
download_video_link = None
|
||||
youtube_streams = ""
|
||||
|
||||
@@ -202,8 +190,12 @@ class VideoModule(VideoFields, VideoTranscriptsMixin, VideoStudentViewHandlers,
|
||||
# VAL will always give us the keys for the profiles we asked for, but
|
||||
# if it doesn't have an encoded video entry for that Video + Profile, the
|
||||
# value will map to `None`
|
||||
if val_video_urls["desktop_mp4"] and self.download_video:
|
||||
download_video_link = val_video_urls["desktop_mp4"]
|
||||
if val_video_urls["desktop_mp4"]:
|
||||
if self.download_video:
|
||||
download_video_link = val_video_urls["desktop_mp4"]
|
||||
# add the desktop_mp4 profile to the list of alternative sources
|
||||
if val_video_urls["desktop_mp4"] not in sources:
|
||||
sources.append(val_video_urls["desktop_mp4"])
|
||||
if val_video_urls["youtube"]:
|
||||
youtube_streams = "1.00:{}".format(val_video_urls["youtube"])
|
||||
except edxval_api.ValInternalError:
|
||||
@@ -212,6 +204,18 @@ class VideoModule(VideoFields, VideoTranscriptsMixin, VideoStudentViewHandlers,
|
||||
# exception and fallback to whatever we find in the VideoDescriptor.
|
||||
log.warning("Could not retrieve information from VAL for edx Video ID: %s.", self.edx_video_id)
|
||||
|
||||
# If the user comes from China use China CDN for html5 videos.
|
||||
# 'CN' is China ISO 3166-1 country code.
|
||||
# Video caching is disabled for Studio. User_location is always None in Studio.
|
||||
# CountryMiddleware disabled for Studio.
|
||||
cdn_url = getattr(settings, 'VIDEO_CDN_URL', {}).get(self.system.user_location)
|
||||
|
||||
if getattr(self, 'video_speed_optimizations', True) and cdn_url:
|
||||
for index, source_url in enumerate(sources):
|
||||
new_url = get_video_from_cdn(cdn_url, source_url)
|
||||
if new_url:
|
||||
sources[index] = new_url
|
||||
|
||||
# If there was no edx_video_id, or if there was no download specified
|
||||
# for it, we fall back on whatever we find in the VideoDescriptor
|
||||
if not download_video_link and self.download_video:
|
||||
|
||||
@@ -372,7 +372,7 @@ class TestGetHtmlMethod(BaseTestXmodule):
|
||||
self.item_descriptor.xmodule_runtime.render_template('video.html', expected_context)
|
||||
)
|
||||
|
||||
def test_get_html_with_non_existant_edx_video_id(self):
|
||||
def test_get_html_with_non_existent_edx_video_id(self):
|
||||
"""
|
||||
Tests the VideoModule get_html where a edx_video_id is given but a video is not found
|
||||
"""
|
||||
@@ -452,7 +452,8 @@ class TestGetHtmlMethod(BaseTestXmodule):
|
||||
'edx_video_id': "mock item",
|
||||
'result': {
|
||||
'download_video_link': None,
|
||||
'sources': json.dumps([u'example.mp4', u'example.webm']),
|
||||
# make sure the desktop_mp4 url is included as part of the alternative sources.
|
||||
'sources': json.dumps([u'example.mp4', u'example.webm', u'http://www.meowmix.com']),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -527,7 +528,7 @@ class TestGetHtmlMethod(BaseTestXmodule):
|
||||
edx_video_id="thundercats",
|
||||
encoded_videos=[
|
||||
dict(
|
||||
url="http://fake-video.edx.org/thundercats.mp4",
|
||||
url=u"http://fake-video.edx.org/thundercats.mp4",
|
||||
file_size=9000,
|
||||
bitrate=42,
|
||||
profile="desktop_mp4",
|
||||
@@ -558,7 +559,8 @@ class TestGetHtmlMethod(BaseTestXmodule):
|
||||
'edx_video_id': "thundercats",
|
||||
'result': {
|
||||
'download_video_link': u'http://fake-video.edx.org/thundercats.mp4',
|
||||
'sources': json.dumps([u'example.mp4', u'example.webm']),
|
||||
# make sure the desktop_mp4 url is included as part of the alternative sources.
|
||||
'sources': json.dumps([u'example.mp4', u'example.webm', u"http://fake-video.edx.org/thundercats.mp4"]),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -635,30 +637,35 @@ class TestGetHtmlMethod(BaseTestXmodule):
|
||||
display_name="A Name"
|
||||
sub="a_sub_file.srt.sjson" source="{source}"
|
||||
download_video="{download_video}"
|
||||
edx_video_id="{edx_video_id}"
|
||||
start_time="01:00:03" end_time="01:00:10"
|
||||
>
|
||||
{sources}
|
||||
</video>
|
||||
"""
|
||||
cases = [
|
||||
#
|
||||
{
|
||||
'download_video': 'true',
|
||||
'source': 'example_source.mp4',
|
||||
'sources': """
|
||||
<source src="http://example.com/example.mp4"/>
|
||||
<source src="http://example.com/example.webm"/>
|
||||
""",
|
||||
'result': {
|
||||
'download_video_link': u'example_source.mp4',
|
||||
'sources': json.dumps(
|
||||
[
|
||||
u'http://cdn_example.com/example.mp4',
|
||||
u'http://cdn_example.com/example.webm'
|
||||
]
|
||||
),
|
||||
},
|
||||
|
||||
case_data = {
|
||||
'download_video': 'true',
|
||||
'source': 'example_source.mp4',
|
||||
'sources': """
|
||||
<source src="http://example.com/example.mp4"/>
|
||||
<source src="http://example.com/example.webm"/>
|
||||
""",
|
||||
'result': {
|
||||
'download_video_link': u'example_source.mp4',
|
||||
'sources': json.dumps(
|
||||
[
|
||||
u'http://cdn_example.com/example.mp4',
|
||||
u'http://cdn_example.com/example.webm'
|
||||
]
|
||||
),
|
||||
},
|
||||
}
|
||||
|
||||
# test with and without edx_video_id specified.
|
||||
cases = [
|
||||
dict(case_data, edx_video_id=""),
|
||||
dict(case_data, edx_video_id="vid-v1:12345"),
|
||||
]
|
||||
|
||||
initial_context = {
|
||||
@@ -691,106 +698,8 @@ class TestGetHtmlMethod(BaseTestXmodule):
|
||||
DATA = SOURCE_XML.format(
|
||||
download_video=data['download_video'],
|
||||
source=data['source'],
|
||||
sources=data['sources']
|
||||
)
|
||||
self.initialize_module(data=DATA)
|
||||
self.item_descriptor.xmodule_runtime.user_location = 'CN'
|
||||
|
||||
context = self.item_descriptor.render('student_view').content
|
||||
|
||||
expected_context = dict(initial_context)
|
||||
expected_context.update({
|
||||
'transcript_translation_url': self.item_descriptor.xmodule_runtime.handler_url(
|
||||
self.item_descriptor, 'transcript', 'translation'
|
||||
).rstrip('/?'),
|
||||
'transcript_available_translations_url': self.item_descriptor.xmodule_runtime.handler_url(
|
||||
self.item_descriptor, 'transcript', 'available_translations'
|
||||
).rstrip('/?'),
|
||||
'ajax_url': self.item_descriptor.xmodule_runtime.ajax_url + '/save_user_state',
|
||||
'id': self.item_descriptor.location.html_id(),
|
||||
})
|
||||
expected_context.update(data['result'])
|
||||
|
||||
self.assertEqual(
|
||||
context,
|
||||
self.item_descriptor.xmodule_runtime.render_template('video.html', expected_context)
|
||||
)
|
||||
|
||||
@patch('xmodule.video_module.video_module.get_video_from_cdn')
|
||||
def test_get_html_cdn_source(self, mocked_get_video):
|
||||
"""
|
||||
Test if sources got from CDN.
|
||||
"""
|
||||
def side_effect(*args, **kwargs):
|
||||
cdn = {
|
||||
'http://example.com/example.mp4': 'http://cdn_example.com/example.mp4',
|
||||
'http://example.com/example.webm': 'http://cdn_example.com/example.webm',
|
||||
}
|
||||
return cdn.get(args[1])
|
||||
|
||||
mocked_get_video.side_effect = side_effect
|
||||
|
||||
SOURCE_XML = """
|
||||
<video show_captions="true"
|
||||
display_name="A Name"
|
||||
sub="a_sub_file.srt.sjson" source="{source}"
|
||||
download_video="{download_video}"
|
||||
start_time="01:00:03" end_time="01:00:10"
|
||||
>
|
||||
{sources}
|
||||
</video>
|
||||
"""
|
||||
cases = [
|
||||
{
|
||||
'download_video': 'true',
|
||||
'source': 'example_source.mp4',
|
||||
'sources': """
|
||||
<source src="http://example.com/example.mp4"/>
|
||||
<source src="http://example.com/example.webm"/>
|
||||
""",
|
||||
'result': {
|
||||
'download_video_link': u'example_source.mp4',
|
||||
'sources': json.dumps(
|
||||
[
|
||||
u'http://cdn_example.com/example.mp4',
|
||||
u'http://cdn_example.com/example.webm'
|
||||
]
|
||||
),
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
initial_context = {
|
||||
'data_dir': getattr(self, 'data_dir', None),
|
||||
'show_captions': 'true',
|
||||
'handout': None,
|
||||
'display_name': u'A Name',
|
||||
'download_video_link': None,
|
||||
'end': 3610.0,
|
||||
'id': None,
|
||||
'sources': '[]',
|
||||
'speed': 'null',
|
||||
'general_speed': 1.0,
|
||||
'start': 3603.0,
|
||||
'saved_video_position': 0.0,
|
||||
'sub': u'a_sub_file.srt.sjson',
|
||||
'track': None,
|
||||
'youtube_streams': '1.00:OEoXaMPEzfM',
|
||||
'autoplay': settings.FEATURES.get('AUTOPLAY_VIDEOS', True),
|
||||
'yt_test_timeout': 1500,
|
||||
'yt_api_url': 'www.youtube.com/iframe_api',
|
||||
'yt_test_url': 'gdata.youtube.com/feeds/api/videos/',
|
||||
'transcript_download_format': 'srt',
|
||||
'transcript_download_formats_list': [{'display_name': 'SubRip (.srt) file', 'value': 'srt'}, {'display_name': 'Text (.txt) file', 'value': 'txt'}],
|
||||
'transcript_language': u'en',
|
||||
'transcript_languages': '{"en": "English"}',
|
||||
}
|
||||
|
||||
for data in cases:
|
||||
DATA = SOURCE_XML.format(
|
||||
download_video=data['download_video'],
|
||||
source=data['source'],
|
||||
sources=data['sources']
|
||||
sources=data['sources'],
|
||||
edx_video_id=data['edx_video_id'],
|
||||
)
|
||||
self.initialize_module(data=DATA)
|
||||
self.item_descriptor.xmodule_runtime.user_location = 'CN'
|
||||
|
||||
Reference in New Issue
Block a user