from .version import __version__
from .downloader.external import list_external_downloaders
-from .postprocessor.ffmpeg import (
+from .postprocessor import (
FFmpegExtractAudioPP,
FFmpegSubtitlesConvertorPP,
FFmpegThumbnailsConvertorPP,
parser.values, option.dest,
current + value if append is True else value + current)
+ def _set_from_options_callback(
+ option, opt_str, value, parser,
+ delim=',', allowed_values=None, process=str.lower, aliases={}):
+ current = getattr(parser.values, option.dest)
+ values = [process(value)] if delim is None else process(value).split(delim)[::-1]
+ while values:
+ actual_val = val = values.pop()
+ if val == 'all':
+ current.update(allowed_values)
+ elif val == '-all':
+ current = set()
+ elif val in aliases:
+ values.extend(aliases[val])
+ else:
+ if val[0] == '-':
+ val = val[1:]
+ current.discard(val)
+ else:
+ current.update([val])
+ if allowed_values is not None and val not in allowed_values:
+ raise optparse.OptionValueError(f'wrong {option.metavar} for {opt_str}: {actual_val}')
+
+ setattr(parser.values, option.dest, current)
+
def _dict_from_options_callback(
option, opt_str, value, parser,
allowed_keys=r'[\w-]+', delimiter=':', default_key=None, process=None, multiple_keys=True):
general.add_option(
'--dump-user-agent',
action='store_true', dest='dump_user_agent', default=False,
- help='Display the current browser identification and exit')
+ help='Display the current user-agent and exit')
general.add_option(
'--list-extractors',
action='store_true', dest='list_extractors', default=False,
'--flat-playlist',
action='store_const', dest='extract_flat', const='in_playlist', default=False,
help='Do not extract the videos of a playlist, only list them')
- general.add_option(
- '--flat-videos',
- action='store_true', dest='extract_flat',
- # help='Do not resolve the video urls')
- # doesn't work
- help=optparse.SUPPRESS_HELP)
general.add_option(
'--no-flat-playlist',
action='store_false', dest='extract_flat',
help='Do not emit color codes in output')
general.add_option(
'--compat-options',
- metavar='OPTS', dest='compat_opts', default=[],
- action='callback', callback=_list_from_options_callback, type='str',
- help=(
- 'Options that can help keep compatibility with youtube-dl and youtube-dlc '
+ metavar='OPTS', dest='compat_opts', default=set(), type='str',
+ action='callback', callback=_set_from_options_callback,
+ callback_kwargs={
+ 'allowed_values': {
+ 'filename', 'format-sort', 'abort-on-error', 'format-spec', 'no-playlist-metafiles',
+ 'multistreams', 'no-live-chat', 'playlist-index', 'list-formats', 'no-direct-merge',
+ 'no-youtube-channel-redirect', 'no-youtube-unavailable-videos', 'no-attach-info-json',
+ 'embed-thumbnail-atomicparsley', 'seperate-video-versions', 'no-clean-infojson', 'no-keep-subs',
+ },
+ 'aliases': {
+ 'youtube-dl': ['-multistreams', 'all'],
+ 'youtube-dlc': ['-no-youtube-channel-redirect', '-no-live-chat', 'all'],
+ }
+ }, help=(
+ 'Options that can help keep compatibility with youtube-dl or youtube-dlc '
'configurations by reverting some of the changes made in yt-dlp. '
'See "Differences in default behavior" for details'))
selection.add_option(
'--match-title',
dest='matchtitle', metavar='REGEX',
- help='Download only matching titles (regex or caseless sub-string)')
+ help=optparse.SUPPRESS_HELP)
selection.add_option(
'--reject-title',
dest='rejecttitle', metavar='REGEX',
- help='Skip download for matching titles (regex or caseless sub-string)')
+ help=optparse.SUPPRESS_HELP)
selection.add_option(
'--max-downloads',
dest='max_downloads', metavar='NUMBER', type=int, default=None,
selection.add_option(
'--min-views',
metavar='COUNT', dest='min_views', default=None, type=int,
- help='Do not download any videos with less than COUNT views')
+ help=optparse.SUPPRESS_HELP)
selection.add_option(
'--max-views',
metavar='COUNT', dest='max_views', default=None, type=int,
- help='Do not download any videos with more than COUNT views')
+ help=optparse.SUPPRESS_HELP)
selection.add_option(
'--match-filter',
metavar='FILTER', dest='match_filter', default=None,
verbosity.add_option(
'-q', '--quiet',
action='store_true', dest='quiet', default=False,
- help='Activate quiet mode')
+ help='Activate quiet mode. If used with --verbose, print the log to stderr')
verbosity.add_option(
'--no-warnings',
dest='no_warnings', action='store_true', default=False,
action='store_true', dest='ignore_no_formats_error', default=False,
help=(
'Ignore "No video formats" error. Usefull for extracting metadata '
- 'even if the video is not actually available for download (experimental)'))
+ 'even if the videos are not actually available for download (experimental)'))
verbosity.add_option(
'--no-ignore-no-formats-error',
action='store_false', dest='ignore_no_formats_error',
action='store_true', dest='skip_download', default=False,
help='Do not download the video but write all related files (Alias: --no-download)')
verbosity.add_option(
- '-O', '--print', metavar='TEMPLATE',
- action='callback', dest='forceprint', type='str', default=[],
- callback=_list_from_options_callback, callback_kwargs={'delim': None},
+ '-O', '--print',
+ metavar='TEMPLATE', action='append', dest='forceprint',
help=(
'Quiet, but print the given fields for each video. Simulate unless --no-simulate is used. '
'Either a field name or same syntax as the output template can be used'))
help=optparse.SUPPRESS_HELP)
postproc.add_option(
'--parse-metadata',
- metavar='FROM:TO', dest='metafromfield', action='append',
+ metavar='FROM:TO', dest='parse_metadata', action='append',
help=(
'Parse additional metadata like title/artist from other fields; '
'see "MODIFYING METADATA" for details'))
+ postproc.add_option(
+ '--replace-in-metadata',
+ dest='parse_metadata', metavar='FIELDS REGEX REPLACE', action='append', nargs=3,
+ help='Replace text in a metadata field using the given regex. This option can be used multiple times')
postproc.add_option(
'--xattrs',
action='store_true', dest='xattrs', default=False,
help='Location of the ffmpeg binary; either the path to the binary or its containing directory')
postproc.add_option(
'--exec', metavar='CMD',
- action='callback', dest='exec_cmd', default=[], type='str',
- callback=_list_from_options_callback, callback_kwargs={'delim': None},
+ action='append', dest='exec_cmd',
help=(
'Execute a command on the file after downloading and post-processing. '
- 'Similar syntax to the output template can be used to pass any field as arguments to the command. '
+ 'Same syntax as the output template can be used to pass any field as arguments to the command. '
'An additional field "filepath" that contains the final path of the downloaded file is also available. '
'If no fields are passed, %(filepath)q is appended to the end of the command. '
'This option can be used multiple times'))
help='Remove any previously defined --exec')
postproc.add_option(
'--exec-before-download', metavar='CMD',
- action='callback', dest='exec_before_dl_cmd', default=[], type='str',
- callback=_list_from_options_callback, callback_kwargs={'delim': None},
+ action='append', dest='exec_before_dl_cmd',
help=(
'Execute a command before the actual download. '
'The syntax is the same as --exec but "filepath" is not available. '