mirror of
https://github.com/yt-dlp/yt-dlp.git
synced 2026-03-02 20:29:21 +00:00
[postprocessor] Add plugin support
Adds option `--use-postprocessor` to enable them
This commit is contained in:
@@ -123,7 +123,7 @@ from .extractor import (
|
||||
gen_extractor_classes,
|
||||
get_info_extractor,
|
||||
_LAZY_LOADER,
|
||||
_PLUGIN_CLASSES
|
||||
_PLUGIN_CLASSES as plugin_extractors
|
||||
)
|
||||
from .extractor.openload import PhantomJSwrapper
|
||||
from .downloader import (
|
||||
@@ -142,6 +142,7 @@ from .postprocessor import (
|
||||
FFmpegMergerPP,
|
||||
FFmpegPostProcessor,
|
||||
MoveFilesAfterDownloadPP,
|
||||
_PLUGIN_CLASSES as plugin_postprocessors
|
||||
)
|
||||
from .update import detect_variant
|
||||
from .version import __version__
|
||||
@@ -3201,9 +3202,10 @@ class YoutubeDL(object):
|
||||
self._write_string('[debug] yt-dlp version %s%s\n' % (__version__, '' if source == 'unknown' else f' ({source})'))
|
||||
if _LAZY_LOADER:
|
||||
self._write_string('[debug] Lazy loading extractors enabled\n')
|
||||
if _PLUGIN_CLASSES:
|
||||
self._write_string(
|
||||
'[debug] Plugin Extractors: %s\n' % [ie.ie_key() for ie in _PLUGIN_CLASSES])
|
||||
if plugin_extractors or plugin_postprocessors:
|
||||
self._write_string('[debug] Plugins: %s\n' % [
|
||||
'%s%s' % (klass.__name__, '' if klass.__name__ == name else f' as {name}')
|
||||
for name, klass in itertools.chain(plugin_extractors.items(), plugin_postprocessors.items())])
|
||||
if self.params.get('compat_opts'):
|
||||
self._write_string(
|
||||
'[debug] Compatibility options: %s\n' % ', '.join(self.params.get('compat_opts')))
|
||||
|
||||
@@ -418,7 +418,7 @@ def _real_main(argv=None):
|
||||
opts.sponskrub = False
|
||||
|
||||
# PostProcessors
|
||||
postprocessors = []
|
||||
postprocessors = list(opts.add_postprocessors)
|
||||
if sponsorblock_query:
|
||||
postprocessors.append({
|
||||
'key': 'SponsorBlock',
|
||||
|
||||
@@ -6,7 +6,7 @@ try:
|
||||
from .lazy_extractors import *
|
||||
from .lazy_extractors import _ALL_CLASSES
|
||||
_LAZY_LOADER = True
|
||||
_PLUGIN_CLASSES = []
|
||||
_PLUGIN_CLASSES = {}
|
||||
except ImportError:
|
||||
_LAZY_LOADER = False
|
||||
|
||||
@@ -20,7 +20,7 @@ if not _LAZY_LOADER:
|
||||
_ALL_CLASSES.append(GenericIE)
|
||||
|
||||
_PLUGIN_CLASSES = load_plugins('extractor', 'IE', globals())
|
||||
_ALL_CLASSES = _PLUGIN_CLASSES + _ALL_CLASSES
|
||||
_ALL_CLASSES = list(_PLUGIN_CLASSES.values()) + _ALL_CLASSES
|
||||
|
||||
|
||||
def gen_extractor_classes():
|
||||
|
||||
@@ -17,6 +17,7 @@ from .utils import (
|
||||
get_executable_path,
|
||||
OUTTMPL_TYPES,
|
||||
preferredencoding,
|
||||
remove_end,
|
||||
write_string,
|
||||
)
|
||||
from .cookies import SUPPORTED_BROWSERS
|
||||
@@ -1389,6 +1390,25 @@ def parseOpts(overrideArguments=None):
|
||||
'--no-force-keyframes-at-cuts',
|
||||
action='store_false', dest='force_keyframes_at_cuts',
|
||||
help='Do not force keyframes around the chapters when cutting/splitting (default)')
|
||||
_postprocessor_opts_parser = lambda key, val='': (
|
||||
*(item.split('=', 1) for item in (val.split(';') if val else [])),
|
||||
('key', remove_end(key, 'PP')))
|
||||
postproc.add_option(
|
||||
'--use-postprocessor',
|
||||
metavar='NAME[:ARGS]', dest='add_postprocessors', default=[], type='str',
|
||||
action='callback', callback=_list_from_options_callback,
|
||||
callback_kwargs={
|
||||
'delim': None,
|
||||
'process': lambda val: dict(_postprocessor_opts_parser(*val.split(':', 1)))
|
||||
}, help=(
|
||||
'The (case sensitive) name of plugin postprocessors to be enabled, '
|
||||
'and (optionally) arguments to be passed to it, seperated by a colon ":". '
|
||||
'ARGS are a semicolon ";" delimited list of NAME=VALUE. '
|
||||
'The "when" argument determines when the postprocessor is invoked. '
|
||||
'It can be one of "pre_process" (after extraction), '
|
||||
'"before_dl" (before video download), "post_process" (after video download; default) '
|
||||
'or "after_move" (after moving file to their final locations). '
|
||||
'This option can be used multiple times to add different postprocessors'))
|
||||
|
||||
sponsorblock = optparse.OptionGroup(parser, 'SponsorBlock Options', description=(
|
||||
'Make chapter entries for, or remove various segments (sponsor, introductions, etc.) '
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
from __future__ import unicode_literals
|
||||
# flake8: noqa: F401
|
||||
|
||||
from ..utils import load_plugins
|
||||
|
||||
from .embedthumbnail import EmbedThumbnailPP
|
||||
from .exec import ExecPP, ExecAfterDownloadPP
|
||||
from .ffmpeg import (
|
||||
FFmpegPostProcessor,
|
||||
FFmpegEmbedSubtitlePP,
|
||||
@@ -18,48 +21,23 @@ from .ffmpeg import (
|
||||
FFmpegVideoConvertorPP,
|
||||
FFmpegVideoRemuxerPP,
|
||||
)
|
||||
from .xattrpp import XAttrMetadataPP
|
||||
from .exec import ExecPP, ExecAfterDownloadPP
|
||||
from .metadataparser import (
|
||||
MetadataFromFieldPP,
|
||||
MetadataFromTitlePP,
|
||||
MetadataParserPP,
|
||||
)
|
||||
from .movefilesafterdownload import MoveFilesAfterDownloadPP
|
||||
from .sponsorblock import SponsorBlockPP
|
||||
from .sponskrub import SponSkrubPP
|
||||
from .modify_chapters import ModifyChaptersPP
|
||||
from .movefilesafterdownload import MoveFilesAfterDownloadPP
|
||||
from .sponskrub import SponSkrubPP
|
||||
from .sponsorblock import SponsorBlockPP
|
||||
from .xattrpp import XAttrMetadataPP
|
||||
|
||||
_PLUGIN_CLASSES = load_plugins('postprocessor', 'PP', globals())
|
||||
|
||||
|
||||
def get_postprocessor(key):
|
||||
return globals()[key + 'PP']
|
||||
|
||||
|
||||
__all__ = [
|
||||
'FFmpegPostProcessor',
|
||||
'EmbedThumbnailPP',
|
||||
'ExecPP',
|
||||
'ExecAfterDownloadPP',
|
||||
'FFmpegEmbedSubtitlePP',
|
||||
'FFmpegExtractAudioPP',
|
||||
'FFmpegSplitChaptersPP',
|
||||
'FFmpegFixupDurationPP',
|
||||
'FFmpegFixupM3u8PP',
|
||||
'FFmpegFixupM4aPP',
|
||||
'FFmpegFixupStretchedPP',
|
||||
'FFmpegFixupTimestampPP',
|
||||
'FFmpegMergerPP',
|
||||
'FFmpegMetadataPP',
|
||||
'FFmpegSubtitlesConvertorPP',
|
||||
'FFmpegThumbnailsConvertorPP',
|
||||
'FFmpegVideoConvertorPP',
|
||||
'FFmpegVideoRemuxerPP',
|
||||
'MetadataParserPP',
|
||||
'MetadataFromFieldPP',
|
||||
'MetadataFromTitlePP',
|
||||
'MoveFilesAfterDownloadPP',
|
||||
'SponsorBlockPP',
|
||||
'SponSkrubPP',
|
||||
'ModifyChaptersPP',
|
||||
'XAttrMetadataPP',
|
||||
]
|
||||
__all__ = [name for name in globals().keys() if name.endswith('IE')]
|
||||
__all__.append('FFmpegPostProcessor')
|
||||
|
||||
@@ -6278,7 +6278,7 @@ def get_executable_path():
|
||||
|
||||
def load_plugins(name, suffix, namespace):
|
||||
plugin_info = [None]
|
||||
classes = []
|
||||
classes = {}
|
||||
try:
|
||||
plugin_info = imp.find_module(
|
||||
name, [os.path.join(get_executable_path(), 'ytdlp_plugins')])
|
||||
@@ -6289,8 +6289,7 @@ def load_plugins(name, suffix, namespace):
|
||||
if not name.endswith(suffix):
|
||||
continue
|
||||
klass = getattr(plugins, name)
|
||||
classes.append(klass)
|
||||
namespace[name] = klass
|
||||
classes[name] = namespace[name] = klass
|
||||
except ImportError:
|
||||
pass
|
||||
finally:
|
||||
|
||||
Reference in New Issue
Block a user