mirror of https://github.com/yt-dlp/yt-dlp.git
[EmbedSubtitles] Slightly relax duration check
and related cleanup Closes #1385
This commit is contained in:
parent
e04b003e64
commit
5ce1d13eba
|
@ -251,22 +251,23 @@ class FFmpegPostProcessor(PostProcessor):
|
||||||
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 @@ class FFmpegEmbedSubtitlePP(FFmpegPostProcessor):
|
||||||
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 @@ class FFmpegEmbedSubtitlePP(FFmpegPostProcessor):
|
||||||
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 @@ class FFmpegEmbedSubtitlePP(FFmpegPostProcessor):
|
||||||
# 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 @@ class FFmpegEmbedSubtitlePP(FFmpegPostProcessor):
|
||||||
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):
|
||||||
|
|
|
@ -38,7 +38,7 @@ class ModifyChaptersPP(FFmpegPostProcessor):
|
||||||
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 @@ class ModifyChaptersPP(FFmpegPostProcessor):
|
||||||
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):
|
||||||
|
|
Loading…
Reference in New Issue