]> jfr.im git - yt-dlp.git/commitdiff
[EmbedSubtitles] Slightly relax duration check
authorpukkandan <redacted>
Sat, 27 Nov 2021 13:49:02 +0000 (19:19 +0530)
committerpukkandan <redacted>
Sat, 27 Nov 2021 13:51:47 +0000 (19:21 +0530)
and related cleanup
Closes #1385

yt_dlp/postprocessor/ffmpeg.py
yt_dlp/postprocessor/modify_chapters.py

index e8b569d72887164242f378cb356611dce2f66254..f712547a83988dc9e633b889f1d7fce1900666fe 100644 (file)
@@ -251,22 +251,23 @@ def get_stream_number(self, path, keys, value):
             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(
@@ -575,22 +576,22 @@ def __init__(self, downloader=None, already_have_subtitle=False):
         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
@@ -615,7 +616,7 @@ def run(self, information):
                 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
 
@@ -628,7 +629,7 @@ def run(self, information):
             # 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)])
@@ -644,7 +645,7 @@ def run(self, information):
         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):
index dca87620037ef44cd1d0d801cd9ad2dd66a801a9..0728bdcf5558a9af4266fcc5561e77fd431adf01 100644 (file)
@@ -38,7 +38,7 @@ def run(self, info):
         if not chapters and not sponsor_chapters:
             return [], info
 
-        real_duration = self._get_real_video_duration(info)
+        real_duration = self._get_real_video_duration(info['filepath'])
         if not chapters:
             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)
             files_to_remove.append(uncut_file)
 
-        info['_real_duration'] = info['chapters'][-1]['end_time']
         return files_to_remove, info
 
     def _mark_chapters_to_remove(self, chapters, sponsor_chapters):