]> jfr.im git - yt-dlp.git/commitdiff
[ffmpeg] Allow passing custom arguments before -i
authorpukkandan <redacted>
Wed, 24 Feb 2021 16:05:18 +0000 (21:35 +0530)
committerpukkandan <redacted>
Wed, 24 Feb 2021 16:06:48 +0000 (21:36 +0530)
:ci skip dl

README.md
youtube_dlc/downloader/external.py
youtube_dlc/options.py
youtube_dlc/postprocessor/common.py
youtube_dlc/postprocessor/ffmpeg.py
youtube_dlc/postprocessor/sponskrub.py
youtube_dlc/utils.py

index cf633974334e68c35c77b25c0bfd3832e92c6885..2141e922de99323d16636bb26361458a7b0a97a4 100644 (file)
--- a/README.md
+++ b/README.md
@@ -611,13 +611,17 @@ ## Post-Processing Options:
                                      SubtitlesConvertor and EmbedThumbnail. The
                                      supported executables are: SponSkrub,
                                      FFmpeg, FFprobe, and AtomicParsley. You can
-                                     use this option multiple times to give
+                                     also specify "PP+EXE:ARGS" to give the
+                                     arguments to the specified executable only
+                                     when being used by the specified
+                                     postprocessor. Additionally, for
+                                     ffmpeg/ffprobe, a number can be appended to
+                                     the exe name seperated by "_i" to pass the
+                                     argument before the specified input file.
+                                     Eg: --ppa "Merger+ffmpeg_i1:-v quiet". You
+                                     can use this option multiple times to give
                                      different arguments to different
-                                     postprocessors. You can also specify
-                                     "PP+EXE:ARGS" to give the arguments to the
-                                     specified executable only when being used
-                                     by the specified postprocessor. You can use
-                                     this option multiple times (Alias: --ppa)
+                                     postprocessors. (Alias: --ppa)
     -k, --keep-video                 Keep the intermediate video file on disk
                                      after post-processing
     --no-keep-video                  Delete the intermediate video file after
index ff82d6779b719b2de1ec94ed913dcf59b281f31d..4bef3bf52462caf592cb4fdf979d5a8c834ca4c7 100644 (file)
@@ -105,9 +105,10 @@ def _bool_option(self, command_option, param, true_value='true', false_value='fa
     def _valueless_option(self, command_option, param, expected_value=True):
         return cli_valueless_option(self.params, command_option, param, expected_value)
 
-    def _configuration_args(self, default=[]):
+    def _configuration_args(self, *args, **kwargs):
         return cli_configuration_args(
-            self.params, 'external_downloader_args', self.get_basename(), default)[0]
+            self.params.get('external_downloader_args'),
+            self.get_basename(), *args, **kwargs)
 
     def _call_downloader(self, tmpfilename, info_dict):
         """ Either overwrite this or implement _make_cmd """
index f2f9dd9dd5fa1f95693a34b828149eac241c67b1..26df62ca509fcf75c5a4ae59404304e478e00609 100644 (file)
@@ -1071,10 +1071,12 @@ def _dict_from_multiple_values_options_callback(
             'SponSkrub, ExtractAudio, VideoRemuxer, VideoConvertor, EmbedSubtitle, Metadata, Merger, '
             'FixupStretched, FixupM4a, FixupM3u8, SubtitlesConvertor and EmbedThumbnail. '
             'The supported executables are: SponSkrub, FFmpeg, FFprobe, and AtomicParsley. '
-            'You can use this option multiple times to give different arguments to different postprocessors. '
             'You can also specify "PP+EXE:ARGS" to give the arguments to the specified executable '
-            'only when being used by the specified postprocessor. '
-            'You can use this option multiple times (Alias: --ppa)'))
+            'only when being used by the specified postprocessor. Additionally, for ffmpeg/ffprobe, '
+            'a number can be appended to the exe name seperated by "_i" to pass the argument '
+            'before the specified input file. Eg: --ppa "Merger+ffmpeg_i1:-v quiet". '
+            'You can use this option multiple times to give different arguments to different '
+            'postprocessors. (Alias: --ppa)'))
     postproc.add_option(
         '-k', '--keep-video',
         action='store_true', dest='keepvideo', default=False,
index b641099e6a3eb07ddfca8b385f4a358acc33058d..f8f4e7693f2175700a63ef9a0e3187b15bcdc869 100644 (file)
@@ -91,11 +91,10 @@ def try_utime(self, path, atime, mtime, errnote='Cannot update utime of file'):
         except Exception:
             self.report_warning(errnote)
 
-    def _configuration_args(self, default=[], exe=None):
-        key = self.pp_key().lower()
-        args, is_compat = cli_configuration_args(
-            self._downloader.params, 'postprocessor_args', key, default, exe)
-        return args if not is_compat or key != 'sponskrub' else default
+    def _configuration_args(self, *args, **kwargs):
+        return cli_configuration_args(
+            self._downloader.params.get('postprocessor_args'),
+            self.pp_key().lower(), *args, **kwargs)
 
 
 class AudioConversionError(PostProcessingError):
index c319cc4290f0ab930788b6a045d06e0e8ccd5b43..b0615ddb28c0b0b2ae29af96b0b19a37f4fe5f5a 100644 (file)
@@ -239,21 +239,20 @@ def run_ffmpeg_multiple_files(self, input_paths, out_path, opts):
         oldest_mtime = min(
             os.stat(encodeFilename(path)).st_mtime for path in input_paths)
 
-        opts += self._configuration_args(exe=self.basename)
-
-        files_cmd = []
-        for path in input_paths:
-            files_cmd.extend([
-                encodeArgument('-i'),
-                encodeFilename(self._ffmpeg_filename_argument(path), True)
-            ])
         cmd = [encodeFilename(self.executable, True), encodeArgument('-y')]
         # avconv does not have repeat option
         if self.basename == 'ffmpeg':
             cmd += [encodeArgument('-loglevel'), encodeArgument('repeat+info')]
-        cmd += (files_cmd
-                + [encodeArgument(o) for o in opts]
-                + [encodeFilename(self._ffmpeg_filename_argument(out_path), True)])
+
+        def make_args(file, pre=[], post=[], *args, **kwargs):
+            args = pre + self._configuration_args(*args, **kwargs) + post
+            return (
+                [encodeArgument(o) for o in args]
+                + [encodeFilename(self._ffmpeg_filename_argument(file), True)])
+
+        for i, path in enumerate(input_paths):
+            cmd += make_args(path, post=['-i'], exe='%s_i%d' % (self.basename, i+1), use_default_arg=False)
+        cmd += make_args(out_path, pre=opts, exe=self.basename)
 
         self.write_debug('ffmpeg command line: %s' % shell_quote(cmd))
         p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
index 8ba4bad212df726905b7ab8cd397144ade4a00a8..2f30acc8e52b43af0204b680a22ab813cb5a614a 100644 (file)
@@ -71,7 +71,7 @@ def run(self, information):
         if not self.cutout:
             cmd += ['-chapter']
         cmd += compat_shlex_split(self.args)  # For backward compatibility
-        cmd += self._configuration_args(exe=self._exe_name)
+        cmd += self._configuration_args(exe=self._exe_name, use_default_arg='no_compat')
         cmd += ['--', information['id'], filename, temp_filename]
         cmd = [encodeArgument(i) for i in cmd]
 
index 99cbb8a28c8b9ec0f786b45fef62ff8b508d0898..c696373e2fcdf4109dc488490bd1050597aa97f1 100644 (file)
@@ -4689,13 +4689,16 @@ def cli_valueless_option(params, command_option, param, expected_value=True):
     return [command_option] if param == expected_value else []
 
 
-def cli_configuration_args(params, arg_name, key, default=[], exe=None):  # returns arg, for_compat
-    argdict = params.get(arg_name, {})
+def cli_configuration_args(argdict, key, default=[], exe=None, use_default_arg=True):
+    # use_default_arg can be True, False, or 'no_compat'
     if isinstance(argdict, (list, tuple)):  # for backward compatibility
-        return argdict, True
+        if use_default_arg == True:
+            return argdict
+        else:
+            argdict = None
 
     if argdict is None:
-        return default, False
+        return default
     assert isinstance(argdict, dict)
 
     key = key.lower()
@@ -4710,12 +4713,12 @@ def cli_configuration_args(params, arg_name, key, default=[], exe=None):  # retu
     if args is None:
         args = argdict.get(key) if key != exe else None
     if args is None and exe_args is None:
-        args = argdict.get('default', default)
+        args = argdict.get('default', default) if use_default_arg else default
 
     args, exe_args = args or [], exe_args or []
     assert isinstance(args, (list, tuple))
     assert isinstance(exe_args, (list, tuple))
-    return args + exe_args, False
+    return args + exe_args
 
 
 class ISO639Utils(object):