Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Video editor supports transcripts [FC-0076] #36058

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions xmodule/tests/test_video.py
Original file line number Diff line number Diff line change
Expand Up @@ -741,6 +741,48 @@ def test_export_to_xml(self, mock_val_api):
course_id=self.block.scope_ids.usage_id.context_key,
)

def test_export_to_xml_without_video_id(self):
"""
Test that we write the correct XML without video_id on export.
"""
self.block.youtube_id_0_75 = 'izygArpw-Qo'
self.block.youtube_id_1_0 = 'p2Q6BrNhdh8'
self.block.youtube_id_1_25 = '1EeWXzPdhSA'
self.block.youtube_id_1_5 = 'rABDYkeK0x8'
self.block.show_captions = False
self.block.start_time = datetime.timedelta(seconds=1.0)
self.block.end_time = datetime.timedelta(seconds=60)
self.block.track = 'http://www.example.com/track'
self.block.handout = 'http://www.example.com/handout'
self.block.download_track = True
self.block.html5_sources = ['http://www.example.com/source.mp4', 'http://www.example.com/source1.ogg']
self.block.download_video = True
self.block.transcripts = {'ua': 'ukrainian_translation.srt', 'ge': 'german_translation.srt'}

xml = self.block.definition_to_xml(self.file_system)
parser = etree.XMLParser(remove_blank_text=True)
xml_string = '''\
<video
url_name="SampleProblem"
start_time="0:00:01"
show_captions="false"
end_time="0:01:00"
download_video="true"
download_track="true"
youtube="0.75:izygArpw-Qo,1.00:p2Q6BrNhdh8,1.25:1EeWXzPdhSA,1.50:rABDYkeK0x8"
transcripts='{"ge": "german_translation.srt", "ua": "ukrainian_translation.srt"}'
>
<source src="http://www.example.com/source.mp4"/>
<source src="http://www.example.com/source1.ogg"/>
<track src="http://www.example.com/track"/>
<handout src="http://www.example.com/handout"/>
<transcript language="ge" src="german_translation.srt" />
<transcript language="ua" src="ukrainian_translation.srt" />
</video>
'''
expected = etree.XML(xml_string, parser=parser)
self.assertXmlEqual(expected, xml)

@patch('xmodule.video_block.video_block.edxval_api')
def test_export_to_xml_val_error(self, mock_val_api):
# Export should succeed without VAL data if video does not exist
Expand Down
22 changes: 22 additions & 0 deletions xmodule/video_block/transcripts_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,8 @@ def manage_video_subtitles_save(item, user, old_metadata=None, generate_translat
)
except TranscriptException:
pass
except AttributeError:
pass
if reraised_message:
item.save_with_metadata(user)
raise TranscriptException(reraised_message)
Expand Down Expand Up @@ -1019,6 +1021,26 @@ def get_transcript_from_contentstore(video, language, output_format, transcripts
except (KeyError, NotFoundError):
continue

if transcript_content is None and language == 'en':
# `get_transcript_for_video`` can get the transcript using just the filename,
# but in the above loop the filename from 'en' is overwritten.
#
# If it doesn't yet have the transcription and the language is 'en',
# check again but this time using the original filename.
#
# The use case for which this has been implemented is when copying a video from
# a library and pasting it into a course.
# The asset is copied, but we only have the filename to obtain the content.
try:
input_format, base_name, transcript_content = get_transcript_for_video(
video.location,
subs_id=None,
file_name=other_languages['en'],
language=language
)
except (KeyError, NotFoundError):
pass

if transcript_content is None:
raise NotFoundError('No transcript for `{lang}` language'.format(
lang=language
Expand Down
10 changes: 7 additions & 3 deletions xmodule/video_block/video_block.py
Original file line number Diff line number Diff line change
Expand Up @@ -855,11 +855,15 @@ def definition_to_xml(self, resource_fs): # lint-amnesty, pylint: disable=too-m
if new_transcripts.get('en'):
xml.set('sub', '')

# Update `transcripts` attribute in the xml
xml.set('transcripts', json.dumps(transcripts, sort_keys=True))

except edxval_api.ValVideoNotFoundError:
pass
else:
if transcripts.get('en'):
xml.set('sub', '')

if transcripts:
# Update `transcripts` attribute in the xml
xml.set('transcripts', json.dumps(transcripts, sort_keys=True))

# Sorting transcripts for easy testing of resulting xml
for transcript_language in sorted(transcripts.keys()):
Expand Down
Loading