None)
return num, len(streams)
- def _get_real_video_duration(self, info, fatal=True):
+ def _get_real_video_duration(self, filepath, fatal=True):
try:
- if '_real_duration' not in info:
- info['_real_duration'] = float_or_none(
- traverse_obj(self.get_metadata_object(info['filepath']), ('format', 'duration')))
- if not info['_real_duration']:
+ duration = float_or_none(
+ traverse_obj(self.get_metadata_object(filepath), ('format', 'duration')))
+ if not duration:
raise PostProcessingError('ffprobe returned empty duration')
+ return duration
except PostProcessingError as e:
if fatal:
- raise PostProcessingError(f'Unable to determine video duration; {e}')
- return info.setdefault('_real_duration', None)
+ raise PostProcessingError(f'Unable to determine video duration: {e.msg}')
def _duration_mismatch(self, d1, d2):
if not d1 or not d2:
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):
return self.real_run_ffmpeg(
self._already_have_subtitle = already_have_subtitle
@PostProcessor._restrict_to(images=False)
- def run(self, information):
- if information['ext'] not in ('mp4', 'webm', 'mkv'):
+ def run(self, info):
+ if info['ext'] not in ('mp4', 'webm', 'mkv'):
self.to_screen('Subtitles can only be embedded in mp4, webm or mkv files')
- return [], information
- subtitles = information.get('requested_subtitles')
+ return [], info
+ subtitles = info.get('requested_subtitles')
if not subtitles:
self.to_screen('There aren\'t any subtitles to embed')
- return [], information
+ return [], info
- filename = information['filepath']
- if information.get('duration') and self._duration_mismatch(
- self._get_real_video_duration(information, False), information['duration']):
+ filename = info['filepath']
+ if info.get('duration') and not info.get('__real_download') and self._duration_mismatch(
+ self._get_real_video_duration(filename, False), info['duration']):
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 = [], [], []
webm_vtt_warn = False
mp4_ass_warn = False
self.report_warning('ASS subtitles cannot be properly embedded in mp4 files; expect issues')
if not sub_langs:
- return [], information
+ return [], info
input_files = [filename] + sub_filenames
# https://trac.ffmpeg.org/ticket/6016)
'-map', '-0:d',
]
- if information['ext'] == 'mp4':
+ if info['ext'] == 'mp4':
opts += ['-c:s', 'mov_text']
for i, (lang, name) in enumerate(zip(sub_langs, sub_names)):
opts.extend(['-map', '%d:0' % (i + 1)])
os.replace(temp_filename, filename)
files_to_delete = [] if self._already_have_subtitle else sub_filenames
- return files_to_delete, information
+ return files_to_delete, info
class FFmpegMetadataPP(FFmpegPostProcessor):