mirror of
https://codeberg.org/polarisfm/youtube-dl
synced 2024-11-26 10:24:33 +01:00
Support multiple subs per lang, differentiate by name
Add a new column 'name' to --list-subs output. Output all the subtitles for a given lang with a different 'name' with --write-sub --sub-lang foo. The name will be a component in the output subtitle file names, before the language code, if it is not empty. Also adapt ffmpeg postprocessing funcs accoordingly.
This commit is contained in:
parent
c23c35c9c1
commit
51b70469ed
@ -1673,26 +1673,30 @@ class YoutubeDL(object):
|
|||||||
|
|
||||||
formats_query = self.params.get('subtitlesformat', 'best')
|
formats_query = self.params.get('subtitlesformat', 'best')
|
||||||
formats_preference = formats_query.split('/') if formats_query else []
|
formats_preference = formats_query.split('/') if formats_query else []
|
||||||
subs = {}
|
subs = collections.defaultdict(list)
|
||||||
for lang in requested_langs:
|
for lang in requested_langs:
|
||||||
formats = available_subs.get(lang)
|
formats = available_subs.get(lang)
|
||||||
if formats is None:
|
if formats is None:
|
||||||
self.report_warning('%s subtitles not available for %s' % (lang, video_id))
|
self.report_warning('%s subtitles not available for %s' % (lang, video_id))
|
||||||
continue
|
continue
|
||||||
|
named = collections.defaultdict(list)
|
||||||
|
for f in formats:
|
||||||
|
named[f.get('name', '')].append(f)
|
||||||
|
for name, fmts in named.items():
|
||||||
for ext in formats_preference:
|
for ext in formats_preference:
|
||||||
if ext == 'best':
|
if ext == 'best':
|
||||||
f = formats[-1]
|
f = fmts[-1]
|
||||||
break
|
break
|
||||||
matches = list(filter(lambda f: f['ext'] == ext, formats))
|
matches = [f for f in fmts if f['ext'] == ext]
|
||||||
if matches:
|
if matches:
|
||||||
f = matches[-1]
|
f = matches[-1]
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
f = formats[-1]
|
f = fmts[-1]
|
||||||
self.report_warning(
|
self.report_warning(
|
||||||
'No subtitle format found matching "%s" for language %s, '
|
'No subtitle format found matching "%s" for language %s, '
|
||||||
'using %s' % (formats_query, lang, f['ext']))
|
'using %s' % (formats_query, lang, f['ext']))
|
||||||
subs[lang] = f
|
subs[lang].append(f)
|
||||||
return subs
|
return subs
|
||||||
|
|
||||||
def __forced_printings(self, info_dict, filename, incomplete):
|
def __forced_printings(self, info_dict, filename, incomplete):
|
||||||
@ -1813,11 +1817,13 @@ class YoutubeDL(object):
|
|||||||
# that way it will silently go on when used with unsupporting IE
|
# that way it will silently go on when used with unsupporting IE
|
||||||
subtitles = info_dict['requested_subtitles']
|
subtitles = info_dict['requested_subtitles']
|
||||||
ie = self.get_info_extractor(info_dict['extractor_key'])
|
ie = self.get_info_extractor(info_dict['extractor_key'])
|
||||||
for sub_lang, sub_info in subtitles.items():
|
for sub_lang, sub_info_list in subtitles.items():
|
||||||
|
for sub_info in sub_info_list:
|
||||||
sub_format = sub_info['ext']
|
sub_format = sub_info['ext']
|
||||||
sub_filename = subtitles_filename(filename, sub_lang, sub_format, info_dict.get('ext'))
|
sub_name = sub_info.get('name', '')
|
||||||
|
sub_filename = subtitles_filename(filename, sub_lang, sub_name, sub_format, info_dict.get('ext'))
|
||||||
if self.params.get('nooverwrites', False) and os.path.exists(encodeFilename(sub_filename)):
|
if self.params.get('nooverwrites', False) and os.path.exists(encodeFilename(sub_filename)):
|
||||||
self.to_screen('[info] Video subtitle %s.%s is already present' % (sub_lang, sub_format))
|
self.to_screen('[info] Video subtitle %s is already present' % (sub_filename))
|
||||||
else:
|
else:
|
||||||
self.to_screen('[info] Writing video subtitles to: ' + sub_filename)
|
self.to_screen('[info] Writing video subtitles to: ' + sub_filename)
|
||||||
if sub_info.get('data') is not None:
|
if sub_info.get('data') is not None:
|
||||||
@ -2226,10 +2232,15 @@ class YoutubeDL(object):
|
|||||||
return
|
return
|
||||||
self.to_screen(
|
self.to_screen(
|
||||||
'Available %s for %s:' % (name, video_id))
|
'Available %s for %s:' % (name, video_id))
|
||||||
|
table = []
|
||||||
|
for lang, formats in subtitles.items():
|
||||||
|
named = collections.defaultdict(list)
|
||||||
|
for f in formats:
|
||||||
|
named[f.get('name', '')].append(f['ext'])
|
||||||
|
for name in named.keys():
|
||||||
|
table.append([lang, name, ', '.join(e for e in reversed(named[name]))])
|
||||||
self.to_screen(render_table(
|
self.to_screen(render_table(
|
||||||
['Language', 'formats'],
|
['Language', 'name', 'formats'], table))
|
||||||
[[lang, ', '.join(f['ext'] for f in reversed(formats))]
|
|
||||||
for lang, formats in subtitles.items()]))
|
|
||||||
|
|
||||||
def urlopen(self, req):
|
def urlopen(self, req):
|
||||||
""" Start an HTTP download """
|
""" Start an HTTP download """
|
||||||
|
@ -385,15 +385,17 @@ class FFmpegEmbedSubtitlePP(FFmpegPostProcessor):
|
|||||||
filename = information['filepath']
|
filename = information['filepath']
|
||||||
|
|
||||||
ext = information['ext']
|
ext = information['ext']
|
||||||
sub_langs = []
|
sub_langs = set()
|
||||||
sub_filenames = []
|
sub_filenames = []
|
||||||
webm_vtt_warn = False
|
webm_vtt_warn = False
|
||||||
|
|
||||||
for lang, sub_info in subtitles.items():
|
for lang, sub_info_list in subtitles.items():
|
||||||
|
for sub_info in sub_info_list:
|
||||||
sub_ext = sub_info['ext']
|
sub_ext = sub_info['ext']
|
||||||
if ext != 'webm' or ext == 'webm' and sub_ext == 'vtt':
|
if ext != 'webm' or ext == 'webm' and sub_ext == 'vtt':
|
||||||
sub_langs.append(lang)
|
sub_langs.add(lang)
|
||||||
sub_filenames.append(subtitles_filename(filename, lang, sub_ext, ext))
|
sub_name = sub_info.get('name', '')
|
||||||
|
sub_filenames.append(subtitles_filename(filename, lang, sub_name, sub_ext, ext))
|
||||||
else:
|
else:
|
||||||
if not webm_vtt_warn and ext == 'webm' and sub_ext != 'vtt':
|
if not webm_vtt_warn and ext == 'webm' and sub_ext != 'vtt':
|
||||||
webm_vtt_warn = True
|
webm_vtt_warn = True
|
||||||
@ -611,15 +613,17 @@ class FFmpegSubtitlesConvertorPP(FFmpegPostProcessor):
|
|||||||
return [], info
|
return [], info
|
||||||
self._downloader.to_screen('[ffmpeg] Converting subtitles')
|
self._downloader.to_screen('[ffmpeg] Converting subtitles')
|
||||||
sub_filenames = []
|
sub_filenames = []
|
||||||
for lang, sub in subs.items():
|
for lang, sublist in subs.items():
|
||||||
|
for sub in sublist:
|
||||||
ext = sub['ext']
|
ext = sub['ext']
|
||||||
if ext == new_ext:
|
if ext == new_ext:
|
||||||
self._downloader.to_screen(
|
self._downloader.to_screen(
|
||||||
'[ffmpeg] Subtitle file for %s is already in the requested format' % new_ext)
|
'[ffmpeg] Subtitle file for %s is already in the requested format' % new_ext)
|
||||||
continue
|
continue
|
||||||
old_file = subtitles_filename(filename, lang, ext, info.get('ext'))
|
name = sub.get('name', '')
|
||||||
|
old_file = subtitles_filename(filename, lang, name, ext, info.get('ext'))
|
||||||
sub_filenames.append(old_file)
|
sub_filenames.append(old_file)
|
||||||
new_file = subtitles_filename(filename, lang, new_ext, info.get('ext'))
|
new_file = subtitles_filename(filename, lang, name, new_ext, info.get('ext'))
|
||||||
|
|
||||||
if ext in ('dfxp', 'ttml', 'tt'):
|
if ext in ('dfxp', 'ttml', 'tt'):
|
||||||
self._downloader.report_warning(
|
self._downloader.report_warning(
|
||||||
@ -636,10 +640,13 @@ class FFmpegSubtitlesConvertorPP(FFmpegPostProcessor):
|
|||||||
f.write(srt_data)
|
f.write(srt_data)
|
||||||
old_file = srt_file
|
old_file = srt_file
|
||||||
|
|
||||||
subs[lang] = {
|
slist_new = [s for s in subs[lang] if s.get('name', '') != name]
|
||||||
|
slist_new.append({
|
||||||
|
'name': name,
|
||||||
'ext': 'srt',
|
'ext': 'srt',
|
||||||
'data': srt_data
|
'data': srt_data
|
||||||
}
|
})
|
||||||
|
subs[lang] = slist_new
|
||||||
|
|
||||||
if new_ext == 'srt':
|
if new_ext == 'srt':
|
||||||
continue
|
continue
|
||||||
@ -649,9 +656,12 @@ class FFmpegSubtitlesConvertorPP(FFmpegPostProcessor):
|
|||||||
self.run_ffmpeg(old_file, new_file, ['-f', new_format])
|
self.run_ffmpeg(old_file, new_file, ['-f', new_format])
|
||||||
|
|
||||||
with io.open(new_file, 'rt', encoding='utf-8') as f:
|
with io.open(new_file, 'rt', encoding='utf-8') as f:
|
||||||
subs[lang] = {
|
slist_new = [s for s in subs[lang] if s.get('name', '') != name]
|
||||||
|
slist_new.append({
|
||||||
|
'name': name,
|
||||||
'ext': new_ext,
|
'ext': new_ext,
|
||||||
'data': f.read(),
|
'data': f.read(),
|
||||||
}
|
})
|
||||||
|
subs[lang] = slist_new
|
||||||
|
|
||||||
return sub_filenames, info
|
return sub_filenames, info
|
||||||
|
@ -3002,8 +3002,8 @@ def determine_ext(url, default_ext='unknown_video'):
|
|||||||
return default_ext
|
return default_ext
|
||||||
|
|
||||||
|
|
||||||
def subtitles_filename(filename, sub_lang, sub_format, expected_real_ext=None):
|
def subtitles_filename(filename, sub_lang, sub_name, sub_format, expected_real_ext=None):
|
||||||
return replace_extension(filename, sub_lang + '.' + sub_format, expected_real_ext)
|
return replace_extension(filename, (sub_name + '.' if sub_name else '') + sub_lang + '.' + sub_format, expected_real_ext)
|
||||||
|
|
||||||
|
|
||||||
def date_from_str(date_str):
|
def date_from_str(date_str):
|
||||||
|
Loading…
Reference in New Issue
Block a user