1
0
mirror of https://github.com/yt-dlp/yt-dlp.git synced 2025-10-03 23:43:21 -04:00

Improved passing of multiple postprocessor-args

* Added `PP+exe:args` syntax
    If `PP+exe:args` is specifically given, only it used.
    Otherwise, `PP:args` and `exe:args` are combined.
    If none of the `PP`, `exe` or `PP+exe` args are given, `default` is used
    `Default` is purposely left undocumented since it exists only for backward compatibility

* Also added proper handling of args in `EmbedThumbnail`

Related: https://github.com/ytdl-org/youtube-dl/pull/27723
This commit is contained in:
pukkandan
2021-01-20 21:37:40 +05:30
parent 5c610515c9
commit 43820c0370
9 changed files with 89 additions and 44 deletions

View File

@@ -2,9 +2,9 @@ from __future__ import unicode_literals
import os
from ..compat import compat_str
from ..utils import (
PostProcessingError,
cli_configuration_args,
encodeFilename,
)
@@ -33,8 +33,12 @@ class PostProcessor(object):
def __init__(self, downloader=None):
self._downloader = downloader
if not hasattr(self, 'PP_NAME'):
self.PP_NAME = self.__class__.__name__[:-2]
self.PP_NAME = self.pp_key()
@classmethod
def pp_key(cls):
name = cls.__name__[:-2]
return compat_str(name[6:]) if name[:6].lower() == 'ffmpeg' else name
def to_screen(self, text, *args, **kwargs):
if self._downloader:
@@ -84,11 +88,40 @@ class PostProcessor(object):
except Exception:
self.report_warning(errnote)
def _configuration_args(self, default=[]):
def _configuration_args(self, default=[], exe=None):
args = self.get_param('postprocessor_args', {})
if isinstance(args, list): # for backward compatibility
args = {'default': args, 'sponskrub': []}
return cli_configuration_args(args, self.PP_NAME.lower(), args.get('default', []))
pp_key = self.pp_key().lower()
if isinstance(args, (list, tuple)): # for backward compatibility
return default if pp_key == 'sponskrub' else args
if args is None:
return default
assert isinstance(args, dict)
exe_args = None
if exe is not None:
assert isinstance(exe, compat_str)
exe = exe.lower()
specific_args = args.get('%s+%s' % (pp_key, exe))
if specific_args is not None:
assert isinstance(specific_args, (list, tuple))
return specific_args
exe_args = args.get(exe)
pp_args = args.get(pp_key) if pp_key != exe else None
if pp_args is None and exe_args is None:
default = args.get('default', default)
assert isinstance(default, (list, tuple))
return default
if pp_args is None:
pp_args = []
elif exe_args is None:
exe_args = []
assert isinstance(pp_args, (list, tuple))
assert isinstance(exe_args, (list, tuple))
return pp_args + exe_args
class AudioConversionError(PostProcessingError):

View File

@@ -24,7 +24,6 @@ class EmbedThumbnailPPError(PostProcessingError):
class EmbedThumbnailPP(FFmpegPostProcessor):
PP_NAME = 'EmbedThumbnail'
def __init__(self, downloader=None, already_have_thumbnail=False):
super(EmbedThumbnailPP, self).__init__(downloader)
@@ -102,6 +101,7 @@ class EmbedThumbnailPP(FFmpegPostProcessor):
encodeFilename(thumbnail_filename, True),
encodeArgument('-o'),
encodeFilename(temp_filename, True)]
cmd += [encodeArgument(o) for o in self._configuration_args(exe='AtomicParsley')]
self.to_screen('Adding thumbnail to "%s"' % filename)
self.write_debug('AtomicParsley command line: %s' % shell_quote(cmd))

View File

@@ -11,12 +11,15 @@ from ..utils import (
class ExecAfterDownloadPP(PostProcessor):
PP_NAME = 'Exec'
def __init__(self, downloader, exec_cmd):
super(ExecAfterDownloadPP, self).__init__(downloader)
self.exec_cmd = exec_cmd
@classmethod
def pp_key(cls):
return 'Exec'
def run(self, information):
cmd = self.exec_cmd
if '{}' not in cmd:

View File

@@ -54,8 +54,6 @@ class FFmpegPostProcessorError(PostProcessingError):
class FFmpegPostProcessor(PostProcessor):
def __init__(self, downloader=None):
if not hasattr(self, 'PP_NAME'):
self.PP_NAME = self.__class__.__name__[6:-2] # Remove ffmpeg from the front
PostProcessor.__init__(self, downloader)
self._determine_executables()
@@ -209,7 +207,7 @@ class FFmpegPostProcessor(PostProcessor):
oldest_mtime = min(
os.stat(encodeFilename(path)).st_mtime for path in input_paths)
opts += self._configuration_args()
opts += self._configuration_args(exe=self.basename)
files_cmd = []
for path in input_paths:

View File

@@ -9,6 +9,7 @@ from ..utils import (
encodeArgument,
encodeFilename,
shell_quote,
str_or_none,
PostProcessingError,
prepend_extension,
)
@@ -16,15 +17,13 @@ from ..utils import (
class SponSkrubPP(PostProcessor):
_temp_ext = 'spons'
_def_args = []
_exe_name = 'sponskrub'
def __init__(self, downloader, path='', args=None, ignoreerror=False, cut=False, force=False):
PostProcessor.__init__(self, downloader)
self.force = force
self.cutout = cut
self.args = ['-chapter'] if not cut else []
self.args += self._configuration_args(self._def_args) if args is None else compat_shlex_split(args)
self.args = str_or_none(args) or '' # For backward compatibility
self.path = self.get_exe(path)
if not ignoreerror and self.path is None:
@@ -64,9 +63,11 @@ class SponSkrubPP(PostProcessor):
if os.path.exists(encodeFilename(temp_filename)):
os.remove(encodeFilename(temp_filename))
cmd = [self.path]
if self.args:
cmd += self.args
cmd = [self.path]
if not self.cutout:
cmd += ['-chapter']
cmd += compat_shlex_split(self.args) # For backward compatibility
cmd += self._configuration_args(exe=self._exe_name)
cmd += ['--', information['id'], filename, temp_filename]
cmd = [encodeArgument(i) for i in cmd]