[EmbedSubtitles] Slightly relax duration check

and related cleanup
Closes #1385
This commit is contained in:
pukkandan 2021-11-27 19:19:02 +05:30
parent e04b003e64
commit 5ce1d13eba
No known key found for this signature in database
GPG key ID: 0F00D95A001F4698
2 changed files with 23 additions and 23 deletions

View file

@ -251,22 +251,23 @@ def get_stream_number(self, path, keys, value):
None) None)
return num, len(streams) return num, len(streams)
def _get_real_video_duration(self, info, fatal=True): def _get_real_video_duration(self, filepath, fatal=True):
try: try:
if '_real_duration' not in info: duration = float_or_none(
info['_real_duration'] = float_or_none( traverse_obj(self.get_metadata_object(filepath), ('format', 'duration')))
traverse_obj(self.get_metadata_object(info['filepath']), ('format', 'duration'))) if not duration:
if not info['_real_duration']:
raise PostProcessingError('ffprobe returned empty duration') raise PostProcessingError('ffprobe returned empty duration')
return duration
except PostProcessingError as e: except PostProcessingError as e:
if fatal: if fatal:
raise PostProcessingError(f'Unable to determine video duration; {e}') raise PostProcessingError(f'Unable to determine video duration: {e.msg}')
return info.setdefault('_real_duration', None)
def _duration_mismatch(self, d1, d2): def _duration_mismatch(self, d1, d2):
if not d1 or not d2: if not d1 or not d2:
return None return None
return abs(d1 - d2) > 1 # The duration is often only known to nearest second. So there can be <1sec disparity natually.
# Further excuse an additional <1sec difference.
return abs(d1 - d2) > 2
def run_ffmpeg_multiple_files(self, input_paths, out_path, opts, **kwargs): def run_ffmpeg_multiple_files(self, input_paths, out_path, opts, **kwargs):
return self.real_run_ffmpeg( return self.real_run_ffmpeg(
@ -575,22 +576,22 @@ def __init__(self, downloader=None, already_have_subtitle=False):
self._already_have_subtitle = already_have_subtitle self._already_have_subtitle = already_have_subtitle
@PostProcessor._restrict_to(images=False) @PostProcessor._restrict_to(images=False)
def run(self, information): def run(self, info):
if information['ext'] not in ('mp4', 'webm', 'mkv'): if info['ext'] not in ('mp4', 'webm', 'mkv'):
self.to_screen('Subtitles can only be embedded in mp4, webm or mkv files') self.to_screen('Subtitles can only be embedded in mp4, webm or mkv files')
return [], information return [], info
subtitles = information.get('requested_subtitles') subtitles = info.get('requested_subtitles')
if not subtitles: if not subtitles:
self.to_screen('There aren\'t any subtitles to embed') self.to_screen('There aren\'t any subtitles to embed')
return [], information return [], info
filename = information['filepath'] filename = info['filepath']
if information.get('duration') and self._duration_mismatch( if info.get('duration') and not info.get('__real_download') and self._duration_mismatch(
self._get_real_video_duration(information, False), information['duration']): self._get_real_video_duration(filename, False), info['duration']):
self.to_screen(f'Skipping {self.pp_key()} since the real and expected durations mismatch') self.to_screen(f'Skipping {self.pp_key()} since the real and expected durations mismatch')
return [], information return [], info
ext = information['ext'] ext = info['ext']
sub_langs, sub_names, sub_filenames = [], [], [] sub_langs, sub_names, sub_filenames = [], [], []
webm_vtt_warn = False webm_vtt_warn = False
mp4_ass_warn = False mp4_ass_warn = False
@ -615,7 +616,7 @@ def run(self, information):
self.report_warning('ASS subtitles cannot be properly embedded in mp4 files; expect issues') self.report_warning('ASS subtitles cannot be properly embedded in mp4 files; expect issues')
if not sub_langs: if not sub_langs:
return [], information return [], info
input_files = [filename] + sub_filenames input_files = [filename] + sub_filenames
@ -628,7 +629,7 @@ def run(self, information):
# https://trac.ffmpeg.org/ticket/6016) # https://trac.ffmpeg.org/ticket/6016)
'-map', '-0:d', '-map', '-0:d',
] ]
if information['ext'] == 'mp4': if info['ext'] == 'mp4':
opts += ['-c:s', 'mov_text'] opts += ['-c:s', 'mov_text']
for i, (lang, name) in enumerate(zip(sub_langs, sub_names)): for i, (lang, name) in enumerate(zip(sub_langs, sub_names)):
opts.extend(['-map', '%d:0' % (i + 1)]) opts.extend(['-map', '%d:0' % (i + 1)])
@ -644,7 +645,7 @@ def run(self, information):
os.replace(temp_filename, filename) os.replace(temp_filename, filename)
files_to_delete = [] if self._already_have_subtitle else sub_filenames files_to_delete = [] if self._already_have_subtitle else sub_filenames
return files_to_delete, information return files_to_delete, info
class FFmpegMetadataPP(FFmpegPostProcessor): class FFmpegMetadataPP(FFmpegPostProcessor):

View file

@ -38,7 +38,7 @@ def run(self, info):
if not chapters and not sponsor_chapters: if not chapters and not sponsor_chapters:
return [], info return [], info
real_duration = self._get_real_video_duration(info) real_duration = self._get_real_video_duration(info['filepath'])
if not chapters: if not chapters:
chapters = [{'start_time': 0, 'end_time': real_duration, 'title': info['title']}] chapters = [{'start_time': 0, 'end_time': real_duration, 'title': info['title']}]
@ -72,7 +72,6 @@ def remove_chapters(file, is_sub):
os.replace(out_file, in_file) os.replace(out_file, in_file)
files_to_remove.append(uncut_file) files_to_remove.append(uncut_file)
info['_real_duration'] = info['chapters'][-1]['end_time']
return files_to_remove, info return files_to_remove, info
def _mark_chapters_to_remove(self, chapters, sponsor_chapters): def _mark_chapters_to_remove(self, chapters, sponsor_chapters):