aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md9
-rw-r--r--yt_dlp/downloader/external.py20
-rw-r--r--yt_dlp/options.py3
-rw-r--r--yt_dlp/postprocessor/common.py17
-rw-r--r--yt_dlp/utils.py12
5 files changed, 34 insertions, 27 deletions
diff --git a/README.md b/README.md
index 20be11468..248b7e688 100644
--- a/README.md
+++ b/README.md
@@ -439,9 +439,12 @@ Then simply run `make`. You can also run `make yt-dlp` instead to compile only t
(Alias: --external-downloader)
--downloader-args NAME:ARGS Give these arguments to the external
downloader. Specify the downloader name and
- the arguments separated by a colon ":". You
- can use this option multiple times to give
- different arguments to different downloaders
+ the arguments separated by a colon ":". For
+ ffmpeg, arguments can be passed to
+ different positions using the same syntax
+ as --postprocessor-args. You can use this
+ option multiple times to give different
+ arguments to different downloaders
(Alias: --external-downloader-args)
## Filesystem Options:
diff --git a/yt_dlp/downloader/external.py b/yt_dlp/downloader/external.py
index f91e10599..be5bd6dd8 100644
--- a/yt_dlp/downloader/external.py
+++ b/yt_dlp/downloader/external.py
@@ -22,7 +22,7 @@ from ..utils import (
cli_option,
cli_valueless_option,
cli_bool_option,
- cli_configuration_args,
+ _configuration_args,
encodeFilename,
encodeArgument,
handle_youtubedl_headers,
@@ -111,11 +111,10 @@ class ExternalFD(FileDownloader):
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, *args, **kwargs):
- return cli_configuration_args(
- self.params.get('external_downloader_args'),
- [self.get_basename(), 'default'],
- *args, **kwargs)
+ def _configuration_args(self, keys=None, *args, **kwargs):
+ return _configuration_args(
+ self.get_basename(), self.params.get('external_downloader_args'), self.get_basename(),
+ keys, *args, **kwargs)
def _call_downloader(self, tmpfilename, info_dict):
""" Either overwrite this or implement _make_cmd """
@@ -459,10 +458,10 @@ class FFmpegFD(ExternalFD):
elif isinstance(conn, compat_str):
args += ['-rtmp_conn', conn]
- for url in urls:
- args += ['-i', url]
+ for i, url in enumerate(urls):
+ args += self._configuration_args((f'_i{i + 1}', '_i')) + ['-i', url]
- args += self._configuration_args() + ['-c', 'copy']
+ args += ['-c', 'copy']
if info_dict.get('requested_formats'):
for (i, fmt) in enumerate(info_dict['requested_formats']):
if fmt.get('acodec') != 'none':
@@ -491,9 +490,10 @@ class FFmpegFD(ExternalFD):
else:
args += ['-f', EXT_TO_OUT_FORMATS.get(ext, ext)]
+ args += self._configuration_args((f'_o1', '_o', ''))
+
args = [encodeArgument(opt) for opt in args]
args.append(encodeFilename(ffpp._ffmpeg_filename_argument(tmpfilename), True))
-
self._debug_cmd(args)
proc = subprocess.Popen(args, stdin=subprocess.PIPE, env=env)
diff --git a/yt_dlp/options.py b/yt_dlp/options.py
index 56ab001be..6bad37d19 100644
--- a/yt_dlp/options.py
+++ b/yt_dlp/options.py
@@ -742,12 +742,13 @@ def parseOpts(overrideArguments=None):
metavar='NAME:ARGS', dest='external_downloader_args', default={}, type='str',
action='callback', callback=_dict_from_options_callback,
callback_kwargs={
- 'allowed_keys': '|'.join(list_external_downloaders()),
+ 'allowed_keys': r'ffmpeg_[io]\d*|%s' % '|'.join(list_external_downloaders()),
'default_key': 'default',
'process': compat_shlex_split
}, help=(
'Give these arguments to the external downloader. '
'Specify the downloader name and the arguments separated by a colon ":". '
+ 'For ffmpeg, arguments can be passed to different positions using the same syntax as --postprocessor-args. '
'You can use this option multiple times to give different arguments to different downloaders '
'(Alias: --external-downloader-args)'))
diff --git a/yt_dlp/postprocessor/common.py b/yt_dlp/postprocessor/common.py
index e8577c9ee..aa4715b06 100644
--- a/yt_dlp/postprocessor/common.py
+++ b/yt_dlp/postprocessor/common.py
@@ -5,7 +5,7 @@ import os
from ..compat import compat_str
from ..utils import (
- cli_configuration_args,
+ _configuration_args,
encodeFilename,
PostProcessingError,
)
@@ -110,18 +110,9 @@ class PostProcessor(object):
except Exception:
self.report_warning(errnote)
- def _configuration_args(self, exe, keys=None, default=[], use_compat=True):
- pp_key = self.pp_key().lower()
- exe = exe.lower()
- root_key = exe if pp_key == exe else '%s+%s' % (pp_key, exe)
- keys = ['%s%s' % (root_key, k) for k in (keys or [''])]
- if root_key in keys:
- keys += [root_key] + ([] if pp_key == exe else [(self.pp_key(), exe)]) + ['default']
- else:
- use_compat = False
- return cli_configuration_args(
- self.get_param('postprocessor_args'),
- keys, default, use_compat)
+ def _configuration_args(self, exe, *args, **kwargs):
+ return _configuration_args(
+ self.pp_key(), self.get_param('postprocessor_args'), exe, *args, **kwargs)
class AudioConversionError(PostProcessingError):
diff --git a/yt_dlp/utils.py b/yt_dlp/utils.py
index 61878b8d7..04c280ba3 100644
--- a/yt_dlp/utils.py
+++ b/yt_dlp/utils.py
@@ -4987,6 +4987,18 @@ def cli_configuration_args(argdict, keys, default=[], use_compat=True):
return [arg for args in arg_list for arg in args]
return default
+def _configuration_args(main_key, argdict, exe, keys=None, default=[], use_compat=True):
+ main_key, exe = main_key.lower(), exe.lower()
+ root_key = exe if main_key == exe else f'{main_key}+{exe}'
+ keys = [f'{root_key}{k}' for k in (keys or [''])]
+ if root_key in keys:
+ if main_key != exe:
+ keys.append((main_key, exe))
+ keys.append('default')
+ else:
+ use_compat = False
+ return cli_configuration_args(argdict, keys, default, use_compat)
+
class ISO639Utils(object):
# See http://www.loc.gov/standards/iso639-2/ISO-639-2_utf-8.txt