]> jfr.im git - yt-dlp.git/blame - yt_dlp/options.py
[docs] Consistent use of `e.g.` (#4643)
[yt-dlp.git] / yt_dlp / options.py
CommitLineData
9e491463 1import collections
2import contextlib
34a741a8 3import optparse
f8271158 4import os.path
3aa9a735 5import re
f9934b96 6import shlex
ac668111 7import shutil
9e491463 8import string
34a741a8
PH
9import sys
10
ac668111 11from .compat import compat_expanduser
f59f5ef8 12from .cookies import SUPPORTED_BROWSERS, SUPPORTED_KEYRINGS
81a23040 13from .downloader.external import list_external_downloaders
ad3dc496 14from .postprocessor import (
81a23040 15 FFmpegExtractAudioPP,
4f04be6a 16 FFmpegMergerPP,
81a23040 17 FFmpegSubtitlesConvertorPP,
18 FFmpegThumbnailsConvertorPP,
19 FFmpegVideoRemuxerPP,
7a340e0d 20 SponsorBlockPP,
81a23040 21)
7a340e0d 22from .postprocessor.modify_chapters import DEFAULT_SPONSORBLOCK_CHAPTER_TITLE
70b23409 23from .update import detect_variant, is_non_updateable
f8271158 24from .utils import (
25 OUTTMPL_TYPES,
26 POSTPROCESS_WHEN,
27 Config,
28 expand_path,
70b23409 29 format_field,
f8271158 30 get_executable_path,
19a03940 31 join_nonempty,
f8271158 32 remove_end,
33 write_string,
34)
35from .version import __version__
81a23040 36
34a741a8 37
06e57990 38def parseOpts(overrideArguments=None, ignore_config_files='if_override'):
9e491463 39 root = Config(create_parser())
06e57990 40 if ignore_config_files == 'if_override':
41 ignore_config_files = overrideArguments is not None
34a741a8 42
e2e43aea 43 def _readUserConf(package_name, default=[]):
44 # .config
ac668111 45 xdg_config_home = os.getenv('XDG_CONFIG_HOME') or compat_expanduser('~/.config')
e2e43aea 46 userConfFile = os.path.join(xdg_config_home, package_name, 'config')
47 if not os.path.isfile(userConfFile):
48 userConfFile = os.path.join(xdg_config_home, '%s.conf' % package_name)
06e57990 49 userConf = Config.read_file(userConfFile, default=None)
e2e43aea 50 if userConf is not None:
0202b52a 51 return userConf, userConfFile
34a741a8 52
e2e43aea 53 # appdata
ac668111 54 appdata_dir = os.getenv('appdata')
e2e43aea 55 if appdata_dir:
56 userConfFile = os.path.join(appdata_dir, package_name, 'config')
06e57990 57 userConf = Config.read_file(userConfFile, default=None)
e2e43aea 58 if userConf is None:
0202b52a 59 userConfFile += '.txt'
06e57990 60 userConf = Config.read_file(userConfFile, default=None)
e2e43aea 61 if userConf is not None:
0202b52a 62 return userConf, userConfFile
34a741a8 63
e2e43aea 64 # home
65 userConfFile = os.path.join(compat_expanduser('~'), '%s.conf' % package_name)
06e57990 66 userConf = Config.read_file(userConfFile, default=None)
34a741a8 67 if userConf is None:
0202b52a 68 userConfFile += '.txt'
06e57990 69 userConf = Config.read_file(userConfFile, default=None)
e2e43aea 70 if userConf is not None:
0202b52a 71 return userConf, userConfFile
34a741a8 72
0202b52a 73 return default, None
34a741a8 74
06e57990 75 def add_config(label, path, user=False):
76 """ Adds config and returns whether to continue """
9e491463 77 if root.parse_known_args()[0].ignoreconfig:
06e57990 78 return False
79 # Multiple package names can be given here
62b58c09 80 # E.g. ('yt-dlp', 'youtube-dlc', 'youtube-dl') will look for
06e57990 81 # the configuration file of any of these three packages
82 for package in ('yt-dlp',):
83 if user:
84 args, current_path = _readUserConf(package, default=None)
85 else:
86 current_path = os.path.join(path, '%s.conf' % package)
87 args = Config.read_file(current_path, default=None)
88 if args is not None:
89 root.append_config(args, current_path, label=label)
90 return True
91 return True
92
93 def load_configs():
94 yield not ignore_config_files
95 yield add_config('Portable', get_executable_path())
9e491463 96 yield add_config('Home', expand_path(root.parse_known_args()[0].paths.get('home', '')).strip())
06e57990 97 yield add_config('User', None, user=True)
98 yield add_config('System', '/etc')
99
9e491463 100 opts = optparse.Values({'verbose': True, 'print_help': False})
101 try:
44a6fcff 102 try:
103 if overrideArguments:
104 root.append_config(overrideArguments, label='Override')
105 else:
106 root.append_config(sys.argv[1:], label='Command-line')
107 loaded_all_configs = all(load_configs())
108 except ValueError as err:
109 raise root.parser.error(err)
9e491463 110
44a6fcff 111 if loaded_all_configs:
9e491463 112 # If ignoreconfig is found inside the system configuration file,
113 # the user configuration is removed
114 if root.parse_known_args()[0].ignoreconfig:
115 user_conf = next((i for i, conf in enumerate(root.configs) if conf.label == 'User'), None)
116 if user_conf is not None:
117 root.configs.pop(user_conf)
06e57990 118
284a60c5 119 try:
120 root.configs[0].load_configs() # Resolve any aliases using --config-location
121 except ValueError as err:
122 raise root.parser.error(err)
123
9e491463 124 opts, args = root.parse_args()
125 except optparse.OptParseError:
126 with contextlib.suppress(optparse.OptParseError):
127 opts, _ = root.parse_known_args(strict=False)
128 raise
129 except (SystemExit, KeyboardInterrupt):
130 opts.verbose = False
131 raise
132 finally:
133 verbose = opts.verbose and f'\n{root}'.replace('\n| ', '\n[debug] ')[1:]
134 if verbose:
135 write_string(f'{verbose}\n')
136 if opts.print_help:
137 if verbose:
138 write_string('\n')
139 root.parser.print_help()
140 if opts.print_help:
141 sys.exit()
142 return root.parser, opts, args
06e57990 143
144
19a03940 145class _YoutubeDLHelpFormatter(optparse.IndentedHelpFormatter):
146 def __init__(self):
147 # No need to wrap help messages if we're on a wide console
ac668111 148 max_width = shutil.get_terminal_size().columns or 80
2dd5a2e3 149 # The % is chosen to get a pretty output in README.md
150 super().__init__(width=max_width, max_help_position=int(0.45 * max_width))
19a03940 151
152 @staticmethod
153 def format_option_strings(option):
154 """ ('-o', '--option') -> -o, --format METAVAR """
155 opts = join_nonempty(
156 option._short_opts and option._short_opts[0],
157 option._long_opts and option._long_opts[0],
158 delim=', ')
159 if option.takes_value():
160 opts += f' {option.metavar}'
161 return opts
162
163
db2e129c 164class _YoutubeDLOptionParser(optparse.OptionParser):
165 # optparse is deprecated since python 3.2. So assume a stable interface even for private methods
9e491463 166 ALIAS_TRIGGER_LIMIT = 100
db2e129c 167
19a03940 168 def __init__(self):
169 super().__init__(
9e491463 170 prog='yt-dlp' if detect_variant() == 'source' else None,
19a03940 171 version=__version__,
172 usage='%prog [OPTIONS] URL [URL...]',
173 epilog='See full documentation at https://github.com/yt-dlp/yt-dlp#readme',
174 formatter=_YoutubeDLHelpFormatter(),
175 conflict_handler='resolve',
176 )
177
9e491463 178 _UNKNOWN_OPTION = (optparse.BadOptionError, optparse.AmbiguousOptionError)
179 _BAD_OPTION = optparse.OptionValueError
180
181 def parse_known_args(self, args=None, values=None, strict=True):
182 """Same as parse_args, but ignore unknown switches. Similar to argparse.parse_known_args"""
183 self.rargs, self.largs = self._get_args(args), []
184 self.values = values or self.get_default_values()
185 while self.rargs:
c800598c 186 arg = self.rargs[0]
9e491463 187 try:
c800598c 188 if arg == '--':
189 del self.rargs[0]
190 break
191 elif arg.startswith('--'):
192 self._process_long_opt(self.rargs, self.values)
193 elif arg.startswith('-') and arg != '-':
194 self._process_short_opts(self.rargs, self.values)
195 elif self.allow_interspersed_args:
196 self.largs.append(self.rargs.pop(0))
197 else:
198 break
9e491463 199 except optparse.OptParseError as err:
200 if isinstance(err, self._UNKNOWN_OPTION):
201 self.largs.append(err.opt_str)
202 elif strict:
203 if isinstance(err, self._BAD_OPTION):
204 self.error(str(err))
205 raise
206 return self.check_values(self.values, self.largs)
207
208 def error(self, msg):
44a6fcff 209 msg = f'{self.get_prog_name()}: error: {str(msg).strip()}\n'
9e491463 210 raise optparse.OptParseError(f'{self.get_usage()}\n{msg}' if self.usage else msg)
211
19a03940 212 def _get_args(self, args):
213 return sys.argv[1:] if args is None else list(args)
214
db2e129c 215 def _match_long_opt(self, opt):
962ffcf8 216 """Improve ambiguous argument resolution by comparing option objects instead of argument strings"""
db2e129c 217 try:
218 return super()._match_long_opt(opt)
219 except optparse.AmbiguousOptionError as e:
86e5f3ed 220 if len({self._long_opt[p] for p in e.possibilities}) == 1:
db2e129c 221 return e.possibilities[0]
222 raise
223
224
06e57990 225def create_parser():
d21bba78 226 def _list_from_options_callback(option, opt_str, value, parser, append=True, delim=',', process=str.strip):
e632bce2 227 # append can be True, False or -1 (prepend)
9e907ebd 228 current = list(getattr(parser.values, option.dest)) if append else []
1f8471e2 229 value = list(filter(None, [process(value)] if delim is None else map(process, value.split(delim))))
d818eb74 230 setattr(
231 parser.values, option.dest,
e632bce2 232 current + value if append is True else value + current)
34a741a8 233
31654882 234 def _set_from_options_callback(
d21bba78 235 option, opt_str, value, parser, delim=',', allowed_values=None, aliases={},
236 process=lambda x: x.lower().strip()):
9e907ebd 237 current = set(getattr(parser.values, option.dest))
d21bba78 238 values = [process(value)] if delim is None else list(map(process, value.split(delim)[::-1]))
31654882 239 while values:
240 actual_val = val = values.pop()
a44ca5a4 241 if not val:
242 raise optparse.OptionValueError(f'Invalid {option.metavar} for {opt_str}: {value}')
31654882 243 if val == 'all':
244 current.update(allowed_values)
245 elif val == '-all':
246 current = set()
247 elif val in aliases:
248 values.extend(aliases[val])
249 else:
250 if val[0] == '-':
251 val = val[1:]
252 current.discard(val)
253 else:
254 current.update([val])
255 if allowed_values is not None and val not in allowed_values:
256 raise optparse.OptionValueError(f'wrong {option.metavar} for {opt_str}: {actual_val}')
257
258 setattr(parser.values, option.dest, current)
259
e632bce2 260 def _dict_from_options_callback(
d818eb74 261 option, opt_str, value, parser,
44bcb8d1 262 allowed_keys=r'[\w-]+', delimiter=':', default_key=None, process=None, multiple_keys=True,
ca30f449 263 process_key=str.lower, append=False):
45016689 264
ca30f449 265 out_dict = dict(getattr(parser.values, option.dest))
bb66c247 266 multiple_args = not isinstance(value, str)
d818eb74 267 if multiple_keys:
86e5f3ed 268 allowed_keys = fr'({allowed_keys})(,({allowed_keys}))*'
bb66c247 269 mobj = re.match(
86e5f3ed 270 fr'(?i)(?P<keys>{allowed_keys}){delimiter}(?P<val>.*)$',
bb66c247 271 value[0] if multiple_args else value)
45016689 272 if mobj is not None:
44bcb8d1 273 keys, val = mobj.group('keys').split(','), mobj.group('val')
bb66c247 274 if multiple_args:
275 val = [val, *value[1:]]
45016689 276 elif default_key is not None:
d818eb74 277 keys, val = [default_key], value
45016689 278 else:
279 raise optparse.OptionValueError(
86e5f3ed 280 f'wrong {opt_str} formatting; it should be {option.metavar}, not "{value}"')
4bb6b02f 281 try:
44bcb8d1 282 keys = map(process_key, keys) if process_key else keys
4bb6b02f 283 val = process(val) if process else val
284 except Exception as err:
44bcb8d1 285 raise optparse.OptionValueError(f'wrong {opt_str} formatting; {err}')
d818eb74 286 for key in keys:
ca30f449 287 out_dict[key] = out_dict.get(key, []) + [val] if append else val
288 setattr(parser.values, option.dest, out_dict)
45016689 289
19a03940 290 parser = _YoutubeDLOptionParser()
9e491463 291 alias_group = optparse.OptionGroup(parser, 'Aliases')
292 Formatter = string.Formatter()
293
294 def _create_alias(option, opt_str, value, parser):
295 aliases, opts = value
296 try:
297 nargs = len({i if f == '' else f
298 for i, (_, f, _, _) in enumerate(Formatter.parse(opts)) if f is not None})
299 opts.format(*map(str, range(nargs))) # validate
300 except Exception as err:
301 raise optparse.OptionValueError(f'wrong {opt_str} OPTIONS formatting; {err}')
302 if alias_group not in parser.option_groups:
303 parser.add_option_group(alias_group)
304
305 aliases = (x if x.startswith('-') else f'--{x}' for x in map(str.strip, aliases.split(',')))
306 try:
307 alias_group.add_option(
308 *aliases, help=opts, nargs=nargs, type='str' if nargs else None,
309 dest='_triggered_aliases', default=collections.defaultdict(int),
310 metavar=' '.join(f'ARG{i}' for i in range(nargs)), action='callback',
311 callback=_alias_callback, callback_kwargs={'opts': opts, 'nargs': nargs})
312 except Exception as err:
313 raise optparse.OptionValueError(f'wrong {opt_str} formatting; {err}')
314
315 def _alias_callback(option, opt_str, value, parser, opts, nargs):
316 counter = getattr(parser.values, option.dest)
317 counter[opt_str] += 1
318 if counter[opt_str] > parser.ALIAS_TRIGGER_LIMIT:
319 raise optparse.OptionValueError(f'Alias {opt_str} exceeded invocation limit')
320 if nargs == 1:
321 value = [value]
322 assert (nargs == 0 and value is None) or len(value) == nargs
323 parser.rargs[:0] = shlex.split(
324 opts if value is None else opts.format(*map(shlex.quote, value)))
34a741a8 325
8450c15c
PH
326 general = optparse.OptionGroup(parser, 'General Options')
327 general.add_option(
9e491463 328 '-h', '--help', dest='print_help', action='store_true',
17941321 329 help='Print this help text and exit')
8450c15c 330 general.add_option(
b76f0e58 331 '--version',
8450c15c 332 action='version',
17941321 333 help='Print program version and exit')
8450c15c
PH
334 general.add_option(
335 '-U', '--update',
336 action='store_true', dest='update_self',
70b23409 337 help=format_field(
338 is_non_updateable(), None, 'Check if updates are available. %s',
339 default='Update this program to the latest version'))
d32f30ac 340 general.add_option(
341 '--no-update',
342 action='store_false', dest='update_self',
70b23409 343 help='Do not check for updates (default)')
8450c15c 344 general.add_option(
b1940459 345 '-i', '--ignore-errors',
346 action='store_true', dest='ignoreerrors',
0930b11f 347 help='Ignore download and postprocessing errors. The download will be considered successful even if the postprocessing fails')
b1940459 348 general.add_option(
349 '--no-abort-on-error',
350 action='store_const', dest='ignoreerrors', const='only_download',
351 help='Continue with next video on download errors; e.g. to skip unavailable videos in a playlist (default)')
8450c15c 352 general.add_option(
6623ac34 353 '--abort-on-error', '--no-ignore-errors',
8450c15c 354 action='store_false', dest='ignoreerrors',
8a51f564 355 help='Abort downloading of further videos if an error occurs (Alias: --no-ignore-errors)')
8450c15c
PH
356 general.add_option(
357 '--dump-user-agent',
358 action='store_true', dest='dump_user_agent', default=False,
34488702 359 help='Display the current user-agent and exit')
34a741a8 360 general.add_option(
8450c15c
PH
361 '--list-extractors',
362 action='store_true', dest='list_extractors', default=False,
b7b04c78 363 help='List all supported extractors and exit')
8450c15c
PH
364 general.add_option(
365 '--extractor-descriptions',
366 action='store_true', dest='list_extractor_descriptions', default=False,
b7b04c78 367 help='Output descriptions of all supported extractors and exit')
d22dec74
S
368 general.add_option(
369 '--force-generic-extractor',
370 action='store_true', dest='force_generic_extractor', default=False,
371 help='Force extraction to use the generic extractor')
34a741a8
PH
372 general.add_option(
373 '--default-search',
374 dest='default_search', metavar='PREFIX',
2dd5a2e3 375 help=(
376 'Use this prefix for unqualified URLs. '
62b58c09 377 'E.g. "gvsearch2:python" downloads two videos from google videos for the search term "python". '
2dd5a2e3 378 'Use the value "auto" to let yt-dlp guess ("auto_warning" to emit a warning when guessing). '
379 '"error" just throws an error. The default value "fixup_error" repairs broken URLs, '
380 'but emits an error if this is not possible instead of searching'))
34a741a8 381 general.add_option(
6623ac34 382 '--ignore-config', '--no-config',
7303f84a 383 action='store_true', dest='ignoreconfig',
6623ac34 384 help=(
9e907ebd 385 'Don\'t load any more configuration files except those given by --config-locations. '
ed8d87f9 386 'For backward compatibility, if this option is found inside the system configuration file, the user configuration is not loaded. '
fc5fa964 387 '(Alias: --no-config)'))
e66dca5e 388 general.add_option(
06e57990 389 '--no-config-locations',
390 action='store_const', dest='config_locations', const=[],
391 help=(
392 'Do not load any custom configuration files (default). When given inside a '
393 'configuration file, ignore all previous --config-locations defined in the current file'))
394 general.add_option(
395 '--config-locations',
396 dest='config_locations', metavar='PATH', action='append',
397 help=(
6b9e832d 398 'Location of the main configuration file; either the path to the config or its containing directory '
399 '("-" for stdin). Can be used multiple times and inside other configuration files'))
057a5206
PH
400 general.add_option(
401 '--flat-playlist',
6623ac34 402 action='store_const', dest='extract_flat', const='in_playlist', default=False,
8a51f564 403 help='Do not extract the videos of a playlist, only list them')
6623ac34 404 general.add_option(
405 '--no-flat-playlist',
406 action='store_false', dest='extract_flat',
407 help='Extract the videos of a playlist')
adbc4ec4
THD
408 general.add_option(
409 '--live-from-start',
410 action='store_true', dest='live_from_start',
9e907ebd 411 help='Download livestreams from the start. Currently only supported for YouTube (Experimental)')
adbc4ec4
THD
412 general.add_option(
413 '--no-live-from-start',
414 action='store_false', dest='live_from_start',
415 help='Download livestreams from the current time (default)')
f2ebc5c7 416 general.add_option(
417 '--wait-for-video',
418 dest='wait_for_video', metavar='MIN[-MAX]', default=None,
419 help=(
420 'Wait for scheduled streams to become available. '
421 'Pass the minimum number of seconds (or range) to wait between retries'))
422 general.add_option(
423 '--no-wait-for-video',
424 dest='wait_for_video', action='store_const', const=None,
425 help='Do not wait for scheduled streams (default)')
d77ab8e2
S
426 general.add_option(
427 '--mark-watched',
428 action='store_true', dest='mark_watched', default=False,
e248be33 429 help='Mark videos watched (even with --simulate)')
90f794c6
S
430 general.add_option(
431 '--no-mark-watched',
597c1866 432 action='store_false', dest='mark_watched',
433 help='Do not mark videos watched (default)')
7e5db8c9 434 general.add_option(
f2df4071 435 '--no-colors', '--no-colours',
597c1866 436 action='store_true', dest='no_color', default=False,
f2df4071 437 help='Do not emit color codes in output (Alias: --no-colours)')
53ed7066 438 general.add_option(
439 '--compat-options',
31654882 440 metavar='OPTS', dest='compat_opts', default=set(), type='str',
441 action='callback', callback=_set_from_options_callback,
442 callback_kwargs={
443 'allowed_values': {
5c3895ff 444 'filename', 'filename-sanitization', 'format-sort', 'abort-on-error', 'format-spec', 'no-playlist-metafiles',
31654882 445 'multistreams', 'no-live-chat', 'playlist-index', 'list-formats', 'no-direct-merge',
f279aaee 446 'no-youtube-channel-redirect', 'no-youtube-unavailable-videos', 'no-attach-info-json', 'embed-metadata',
d5820461 447 'embed-thumbnail-atomicparsley', 'seperate-video-versions', 'no-clean-infojson', 'no-keep-subs', 'no-certifi',
d21bba78 448 }, 'aliases': {
31654882 449 'youtube-dl': ['-multistreams', 'all'],
450 'youtube-dlc': ['-no-youtube-channel-redirect', '-no-live-chat', 'all'],
451 }
452 }, help=(
453 'Options that can help keep compatibility with youtube-dl or youtube-dlc '
53ed7066 454 'configurations by reverting some of the changes made in yt-dlp. '
455 'See "Differences in default behavior" for details'))
9e491463 456 general.add_option(
457 '--alias', metavar='ALIASES OPTIONS', dest='_', type='str', nargs=2,
458 action='callback', callback=_create_alias,
459 help=(
460 'Create aliases for an option string. Unless an alias starts with a dash "-", it is prefixed with "--". '
461 'Arguments are parsed according to the Python string formatting mini-language. '
62b58c09 462 'E.g. --alias get-audio,-X "-S=aext:{0},abr -x --audio-format {0}" creates options '
9e491463 463 '"--get-audio" and "-X" that takes an argument (ARG0) and expands to '
464 '"-S=aext:ARG0,abr -x --audio-format ARG0". All defined aliases are listed in the --help output. '
962ffcf8 465 'Alias options can trigger more aliases; so be careful to avoid defining recursive options. '
9e491463 466 f'As a safety measure, each alias may be triggered a maximum of {_YoutubeDLOptionParser.ALIAS_TRIGGER_LIMIT} times. '
467 'This option can be used multiple times'))
34a741a8 468
be4a824d
PH
469 network = optparse.OptionGroup(parser, 'Network Options')
470 network.add_option(
471 '--proxy', dest='proxy',
472 default=None, metavar='URL',
6623ac34 473 help=(
62b58c09
L
474 'Use the specified HTTP/HTTPS/SOCKS proxy. To enable SOCKS proxy, specify a proper scheme, '
475 'e.g. socks5://user:pass@127.0.0.1:1080/. Pass in an empty string (--proxy "") for direct connection'))
be4a824d
PH
476 network.add_option(
477 '--socket-timeout',
478 dest='socket_timeout', type=float, default=None, metavar='SECONDS',
479 help='Time to wait before giving up, in seconds')
480 network.add_option(
481 '--source-address',
482 metavar='IP', dest='source_address', default=None,
24ee6b97 483 help='Client-side IP address to bind to',
be4a824d 484 )
500b8b41
PH
485 network.add_option(
486 '-4', '--force-ipv4',
487 action='store_const', const='0.0.0.0', dest='source_address',
24ee6b97 488 help='Make all connections via IPv4',
500b8b41
PH
489 )
490 network.add_option(
491 '-6', '--force-ipv6',
492 action='store_const', const='::', dest='source_address',
24ee6b97 493 help='Make all connections via IPv6',
500b8b41 494 )
0aa10994 495
b31fdeed 496 geo = optparse.OptionGroup(parser, 'Geo-restriction')
0aa10994 497 geo.add_option(
38cce791
YCH
498 '--geo-verification-proxy',
499 dest='geo_verification_proxy', default=None, metavar='URL',
6623ac34 500 help=(
501 'Use this proxy to verify the IP address for some geo-restricted sites. '
8a51f564 502 'The default proxy specified by --proxy (or none, if the option is not present) is used for the actual downloading'))
0aa10994 503 geo.add_option(
91410c9b
PH
504 '--cn-verification-proxy',
505 dest='cn_verification_proxy', default=None, metavar='URL',
0aa10994
S
506 help=optparse.SUPPRESS_HELP)
507 geo.add_option(
508 '--geo-bypass',
509 action='store_true', dest='geo_bypass', default=True,
455a15e2 510 help='Bypass geographic restriction via faking X-Forwarded-For HTTP header (default)')
0aa10994
S
511 geo.add_option(
512 '--no-geo-bypass',
455a15e2 513 action='store_false', dest='geo_bypass',
504f20dd 514 help='Do not bypass geographic restriction via faking X-Forwarded-For HTTP header')
0aa10994
S
515 geo.add_option(
516 '--geo-bypass-country', metavar='CODE',
517 dest='geo_bypass_country', default=None,
504f20dd 518 help='Force bypass geographic restriction with explicitly provided two-letter ISO 3166-2 country code')
5f95927a
S
519 geo.add_option(
520 '--geo-bypass-ip-block', metavar='IP_BLOCK',
521 dest='geo_bypass_ip_block', default=None,
504f20dd 522 help='Force bypass geographic restriction with explicitly provided IP block in CIDR notation')
be4a824d 523
8450c15c 524 selection = optparse.OptionGroup(parser, 'Video Selection')
34a741a8
PH
525 selection.add_option(
526 '--playlist-start',
527 dest='playliststart', metavar='NUMBER', default=1, type=int,
7e88d7d7 528 help=optparse.SUPPRESS_HELP)
34a741a8
PH
529 selection.add_option(
530 '--playlist-end',
531 dest='playlistend', metavar='NUMBER', default=None, type=int,
7e88d7d7 532 help=optparse.SUPPRESS_HELP)
c14e88f0 533 selection.add_option(
7e88d7d7 534 '-I', '--playlist-items',
c14e88f0 535 dest='playlist_items', metavar='ITEM_SPEC', default=None,
7e88d7d7 536 help=(
962ffcf8 537 'Comma separated playlist_index of the videos to download. '
7e88d7d7 538 'You can specify a range using "[START]:[STOP][:STEP]". For backward compatibility, START-STOP is also supported. '
539 'Use negative indices to count from the right and negative STEP to download in reverse order. '
62b58c09 540 'E.g. "-I 1:3,7,-5::2" used on a playlist of size 15 will download the videos at index 1,2,3,7,11,13,15'))
34a741a8 541 selection.add_option(
8450c15c
PH
542 '--match-title',
543 dest='matchtitle', metavar='REGEX',
8f18aca8 544 help=optparse.SUPPRESS_HELP)
8450c15c
PH
545 selection.add_option(
546 '--reject-title',
547 dest='rejecttitle', metavar='REGEX',
8f18aca8 548 help=optparse.SUPPRESS_HELP)
8450c15c
PH
549 selection.add_option(
550 '--min-filesize',
551 metavar='SIZE', dest='min_filesize', default=None,
62b58c09 552 help='Do not download any videos smaller than SIZE, e.g. 50k or 44.6M')
8450c15c
PH
553 selection.add_option(
554 '--max-filesize',
555 metavar='SIZE', dest='max_filesize', default=None,
62b58c09 556 help='Do not download any videos larger than SIZE, e.g. 50k or 44.6M')
8450c15c
PH
557 selection.add_option(
558 '--date',
559 metavar='DATE', dest='date', default=None,
c76eb41b 560 help=(
3d38b2d6 561 'Download only videos uploaded on this date. The date can be "YYYYMMDD" or in the format '
62b58c09 562 '[now|today|yesterday][-N[day|week|month|year]]. E.g. --date today-2weeks'))
8450c15c
PH
563 selection.add_option(
564 '--datebefore',
565 metavar='DATE', dest='datebefore', default=None,
c76eb41b 566 help=(
567 'Download only videos uploaded on or before this date. '
568 'The date formats accepted is the same as --date'))
34a741a8 569 selection.add_option(
8450c15c
PH
570 '--dateafter',
571 metavar='DATE', dest='dateafter', default=None,
c76eb41b 572 help=(
573 'Download only videos uploaded on or after this date. '
574 'The date formats accepted is the same as --date'))
34a741a8 575 selection.add_option(
8450c15c
PH
576 '--min-views',
577 metavar='COUNT', dest='min_views', default=None, type=int,
8f18aca8 578 help=optparse.SUPPRESS_HELP)
34a741a8 579 selection.add_option(
8450c15c
PH
580 '--max-views',
581 metavar='COUNT', dest='max_views', default=None, type=int,
8f18aca8 582 help=optparse.SUPPRESS_HELP)
347de493 583 selection.add_option(
b1a7cd05 584 '--match-filters',
585 metavar='FILTER', dest='match_filter', action='append',
347de493 586 help=(
2dd5a2e3 587 'Generic video filter. Any "OUTPUT TEMPLATE" field can be compared with a '
d4ada357 588 'number or a string using the operators defined in "Filtering Formats". '
b1a7cd05 589 'You can also simply specify a field to match if the field is present, '
590 'use "!field" to check if the field is not present, and "&" to check multiple conditions. '
591 'Use a "\\" to escape "&" or quotes if needed. If used multiple times, '
62b58c09 592 'the filter matches if atleast one of the conditions are met. E.g. --match-filter '
b1a7cd05 593 '!is_live --match-filter "like_count>?100 & description~=\'(?i)\\bcats \\& dogs\\b\'" '
594 'matches only videos that are not live OR those that have a like count more than 100 '
595 '(or the like field is not available) and also has a description '
2dd5a2e3 596 'that contains the phrase "cats & dogs" (caseless). '
492272fe 597 'Use "--match-filter -" to interactively ask whether to download each video'))
6623ac34 598 selection.add_option(
599 '--no-match-filter',
600 metavar='FILTER', dest='match_filter', action='store_const', const=None,
601 help='Do not use generic video filter (default)')
34a741a8 602 selection.add_option(
8450c15c
PH
603 '--no-playlist',
604 action='store_true', dest='noplaylist', default=False,
8a51f564 605 help='Download only the video, if the URL refers to a video and a playlist')
df4bd0d5
PH
606 selection.add_option(
607 '--yes-playlist',
f0884c8b 608 action='store_false', dest='noplaylist',
8a51f564 609 help='Download the playlist, if the URL refers to a video and a playlist')
8450c15c
PH
610 selection.add_option(
611 '--age-limit',
612 metavar='YEARS', dest='age_limit', default=None, type=int,
17941321 613 help='Download only videos suitable for the given age')
8450c15c
PH
614 selection.add_option(
615 '--download-archive', metavar='FILE',
616 dest='download_archive',
8a51f564 617 help='Download only videos not listed in the archive file. Record the IDs of all downloaded videos in it')
f304da8a 618 selection.add_option(
619 '--no-download-archive',
620 dest='download_archive', action="store_const", const=None,
621 help='Do not use archive file (default)')
622 selection.add_option(
623 '--max-downloads',
624 dest='max_downloads', metavar='NUMBER', type=int, default=None,
625 help='Abort after downloading NUMBER files')
ea6e0c2b 626 selection.add_option(
627 '--break-on-existing',
628 action='store_true', dest='break_on_existing', default=False,
8a51f564 629 help='Stop the download process when encountering a file that is in the archive')
8b0d7497 630 selection.add_option(
631 '--break-on-reject',
632 action='store_true', dest='break_on_reject', default=False,
8a51f564 633 help='Stop the download process when encountering a file that has been filtered out')
b222c271 634 selection.add_option(
635 '--break-per-input',
636 action='store_true', dest='break_per_url', default=False,
490110c5 637 help='Make --break-on-existing, --break-on-reject and --max-downloads act only on the current input URL')
b222c271 638 selection.add_option(
639 '--no-break-per-input',
640 action='store_false', dest='break_per_url',
490110c5 641 help='--break-on-existing and similar options terminates the entire download queue')
26e2805c 642 selection.add_option(
643 '--skip-playlist-after-errors', metavar='N',
644 dest='skip_playlist_after_errors', default=None, type=int,
645 help='Number of allowed failures until the rest of the playlist is skipped')
8450c15c
PH
646 selection.add_option(
647 '--include-ads',
648 dest='include_ads', action='store_true',
d9aa2332 649 help=optparse.SUPPRESS_HELP)
6623ac34 650 selection.add_option(
651 '--no-include-ads',
652 dest='include_ads', action='store_false',
d9aa2332 653 help=optparse.SUPPRESS_HELP)
34a741a8 654
8450c15c
PH
655 authentication = optparse.OptionGroup(parser, 'Authentication Options')
656 authentication.add_option(
657 '-u', '--username',
658 dest='username', metavar='USERNAME',
17941321 659 help='Login with this account ID')
8450c15c
PH
660 authentication.add_option(
661 '-p', '--password',
662 dest='password', metavar='PASSWORD',
7a5c1cfe 663 help='Account password. If this option is left out, yt-dlp will ask interactively')
8450c15c
PH
664 authentication.add_option(
665 '-2', '--twofactor',
666 dest='twofactor', metavar='TWOFACTOR',
3540fe26 667 help='Two-factor authentication code')
8450c15c
PH
668 authentication.add_option(
669 '-n', '--netrc',
670 action='store_true', dest='usenetrc', default=False,
17941321 671 help='Use .netrc authentication data')
0001fcb5 672 authentication.add_option(
673 '--netrc-location',
674 dest='netrc_location', metavar='PATH',
675 help='Location of .netrc authentication data; either the path or its containing directory. Defaults to ~/.netrc')
8450c15c
PH
676 authentication.add_option(
677 '--video-password',
678 dest='videopassword', metavar='PASSWORD',
29f7c58a 679 help='Video password (vimeo, youku)')
b31fdeed 680 authentication.add_option(
797c636b
RA
681 '--ap-mso',
682 dest='ap_mso', metavar='MSO',
537f7533 683 help='Adobe Pass multiple-system operator (TV provider) identifier, use --ap-list-mso for a list of available MSOs')
b31fdeed 684 authentication.add_option(
1b6712ab 685 '--ap-username',
797c636b 686 dest='ap_username', metavar='USERNAME',
537f7533 687 help='Multiple-system operator account login')
b31fdeed 688 authentication.add_option(
1b6712ab 689 '--ap-password',
797c636b 690 dest='ap_password', metavar='PASSWORD',
7a5c1cfe 691 help='Multiple-system operator account password. If this option is left out, yt-dlp will ask interactively')
b31fdeed 692 authentication.add_option(
87148bb7
RA
693 '--ap-list-mso',
694 action='store_true', dest='ap_list_mso', default=False,
537f7533 695 help='List all supported multiple-system operators')
bb58c9ed 696 authentication.add_option(
697 '--client-certificate',
698 dest='client_certificate', metavar='CERTFILE',
699 help='Path to client certificate file in PEM format. May include the private key')
700 authentication.add_option(
701 '--client-certificate-key',
702 dest='client_certificate_key', metavar='KEYFILE',
703 help='Path to private key file for client certificate')
704 authentication.add_option(
705 '--client-certificate-password',
706 dest='client_certificate_password', metavar='PASSWORD',
707 help='Password for client certificate private key, if encrypted. '
2dd5a2e3 708 'If not provided, and the key is encrypted, yt-dlp will ask interactively')
8450c15c
PH
709
710 video_format = optparse.OptionGroup(parser, 'Video Format Options')
711 video_format.add_option(
712 '-f', '--format',
713 action='store', dest='format', metavar='FORMAT', default=None,
eb8a4433 714 help='Video format code, see "FORMAT SELECTION" for more details')
715 video_format.add_option(
c76eb41b 716 '-S', '--format-sort', metavar='SORTORDER',
e632bce2 717 dest='format_sort', default=[], type='str', action='callback',
718 callback=_list_from_options_callback, callback_kwargs={'append': -1},
eb8a4433 719 help='Sort the formats by the fields given, see "Sorting Formats" for more details')
720 video_format.add_option(
721 '--format-sort-force', '--S-force',
722 action='store_true', dest='format_sort_force', metavar='FORMAT', default=False,
723 help=(
724 'Force user specified sort order to have precedence over all fields, '
2dd5a2e3 725 'see "Sorting Formats" for more details (Alias: --S-force)'))
eb8a4433 726 video_format.add_option(
727 '--no-format-sort-force',
728 action='store_false', dest='format_sort_force', metavar='FORMAT', default=False,
2dd5a2e3 729 help='Some fields have precedence over the user specified sort order (default)')
909d24dd 730 video_format.add_option(
731 '--video-multistreams',
53ed7066 732 action='store_true', dest='allow_multiple_video_streams', default=None,
91ebc640 733 help='Allow multiple video streams to be merged into a single file')
909d24dd 734 video_format.add_option(
735 '--no-video-multistreams',
736 action='store_false', dest='allow_multiple_video_streams',
91ebc640 737 help='Only one video stream is downloaded for each output file (default)')
909d24dd 738 video_format.add_option(
739 '--audio-multistreams',
53ed7066 740 action='store_true', dest='allow_multiple_audio_streams', default=None,
91ebc640 741 help='Allow multiple audio streams to be merged into a single file')
909d24dd 742 video_format.add_option(
743 '--no-audio-multistreams',
744 action='store_false', dest='allow_multiple_audio_streams',
91ebc640 745 help='Only one audio stream is downloaded for each output file (default)')
8450c15c
PH
746 video_format.add_option(
747 '--all-formats',
748 action='store_const', dest='format', const='all',
d9aa2332 749 help=optparse.SUPPRESS_HELP)
8450c15c
PH
750 video_format.add_option(
751 '--prefer-free-formats',
752 action='store_true', dest='prefer_free_formats', default=False,
da9be05e 753 help=(
754 'Prefer video formats with free containers over non-free ones of same quality. '
755 'Use with "-S ext" to strictly prefer free containers irrespective of quality'))
756 video_format.add_option(
757 '--no-prefer-free-formats',
1c36c1f3 758 action='store_false', dest='prefer_free_formats', default=False,
da9be05e 759 help="Don't give any special preference to free containers (default)")
e8e73840 760 video_format.add_option(
761 '--check-formats',
9f1a1c36 762 action='store_const', const='selected', dest='check_formats', default=None,
ebc7d3ff 763 help='Make sure formats are selected only from those that are actually downloadable')
9f1a1c36 764 video_format.add_option(
765 '--check-all-formats',
766 action='store_true', dest='check_formats',
767 help='Check all formats for whether they are actually downloadable')
0ba692ac 768 video_format.add_option(
769 '--no-check-formats',
770 action='store_false', dest='check_formats',
9f1a1c36 771 help='Do not check that the formats are actually downloadable')
8450c15c
PH
772 video_format.add_option(
773 '-F', '--list-formats',
774 action='store_true', dest='listformats',
b7b04c78 775 help='List available formats of each video. Simulate unless --no-simulate is used')
76d321f6 776 video_format.add_option(
777 '--list-formats-as-table',
91ebc640 778 action='store_true', dest='listformats_table', default=True,
53ed7066 779 help=optparse.SUPPRESS_HELP)
76d321f6 780 video_format.add_option(
6623ac34 781 '--list-formats-old', '--no-list-formats-as-table',
76d321f6 782 action='store_false', dest='listformats_table',
53ed7066 783 help=optparse.SUPPRESS_HELP)
d120e901 784 video_format.add_option(
bd1a281e
PH
785 '--merge-output-format',
786 action='store', dest='merge_output_format', metavar='FORMAT', default=None,
d120e901 787 help=(
62b58c09 788 'Containers that may be used when merging formats, separated by "/", e.g. "mp4/mkv". '
fc61aff4 789 'Ignored if no merge is required. '
4f04be6a 790 f'(currently supported: {", ".join(sorted(FFmpegMergerPP.SUPPORTED_EXTS))})'))
63ad4d43 791 video_format.add_option(
792 '--allow-unplayable-formats',
793 action='store_true', dest='allow_unplayable_formats', default=False,
88acdbc2 794 help=optparse.SUPPRESS_HELP)
63ad4d43 795 video_format.add_option(
796 '--no-allow-unplayable-formats',
797 action='store_false', dest='allow_unplayable_formats',
88acdbc2 798 help=optparse.SUPPRESS_HELP)
8450c15c
PH
799
800 subtitles = optparse.OptionGroup(parser, 'Subtitle Options')
801 subtitles.add_option(
6623ac34 802 '--write-subs', '--write-srt',
8450c15c 803 action='store_true', dest='writesubtitles', default=False,
17941321 804 help='Write subtitle file')
8450c15c 805 subtitles.add_option(
6623ac34 806 '--no-write-subs', '--no-write-srt',
807 action='store_false', dest='writesubtitles',
808 help='Do not write subtitle file (default)')
809 subtitles.add_option(
810 '--write-auto-subs', '--write-automatic-subs',
8450c15c 811 action='store_true', dest='writeautomaticsub', default=False,
e167860c 812 help='Write automatically generated subtitle file (Alias: --write-automatic-subs)')
6623ac34 813 subtitles.add_option(
814 '--no-write-auto-subs', '--no-write-automatic-subs',
815 action='store_false', dest='writeautomaticsub', default=False,
e167860c 816 help='Do not write auto-generated subtitles (default) (Alias: --no-write-automatic-subs)')
8450c15c
PH
817 subtitles.add_option(
818 '--all-subs',
819 action='store_true', dest='allsubtitles', default=False,
c32b0aab 820 help=optparse.SUPPRESS_HELP)
8450c15c
PH
821 subtitles.add_option(
822 '--list-subs',
823 action='store_true', dest='listsubtitles', default=False,
b7b04c78 824 help='List available subtitles of each video. Simulate unless --no-simulate is used')
8450c15c
PH
825 subtitles.add_option(
826 '--sub-format',
a504ced0 827 action='store', dest='subtitlesformat', metavar='FORMAT', default='best',
62b58c09 828 help='Subtitle format; accepts formats preference, e.g. "srt" or "ass/srt/best"')
8450c15c 829 subtitles.add_option(
e167860c 830 '--sub-langs', '--srt-langs',
8450c15c 831 action='callback', dest='subtitleslangs', metavar='LANGS', type='str',
e632bce2 832 default=[], callback=_list_from_options_callback,
c32b0aab 833 help=(
62b58c09
L
834 'Languages of the subtitles to download (can be regex) or "all" separated by commas, e.g. --sub-langs "en.*,ja". '
835 'You can prefix the language code with a "-" to exclude it from the requested languages, e.g. --sub-langs all,-live_chat. '
c32b0aab 836 'Use --list-subs for a list of available language tags'))
8450c15c
PH
837
838 downloader = optparse.OptionGroup(parser, 'Download Options')
4cf1e5d2 839 downloader.add_option(
840 '-N', '--concurrent-fragments',
841 dest='concurrent_fragment_downloads', metavar='N', default=1, type=int,
b69fd25c 842 help='Number of fragments of a dash/hlsnative video that should be downloaded concurrently (default is %default)')
8450c15c 843 downloader.add_option(
8ec2b2c4
S
844 '-r', '--limit-rate', '--rate-limit',
845 dest='ratelimit', metavar='RATE',
62b58c09 846 help='Maximum download rate in bytes per second, e.g. 50K or 4.2M')
51d9739f 847 downloader.add_option(
848 '--throttled-rate',
849 dest='throttledratelimit', metavar='RATE',
62b58c09 850 help='Minimum download rate in bytes per second below which throttling is assumed and the video data is re-extracted, e.g. 100K')
8450c15c
PH
851 downloader.add_option(
852 '-R', '--retries',
853 dest='retries', metavar='RETRIES', default=10,
8a51f564 854 help='Number of retries (default is %default), or "infinite"')
205a0654
EH
855 downloader.add_option(
856 '--file-access-retries',
45806d44 857 dest='file_access_retries', metavar='RETRIES', default=3,
205a0654 858 help='Number of times to retry on file access error (default is %default), or "infinite"')
52bb437e
S
859 downloader.add_option(
860 '--fragment-retries',
861 dest='fragment_retries', metavar='RETRIES', default=10,
12ee65ea 862 help='Number of retries for a fragment (default is %default), or "infinite" (DASH, hlsnative and ISM)')
23326151 863 downloader.add_option(
864 '--retry-sleep',
865 dest='retry_sleep', metavar='[TYPE:]EXPR', default={}, type='str',
866 action='callback', callback=_dict_from_options_callback,
867 callback_kwargs={
be5c1ae8 868 'allowed_keys': 'http|fragment|file_access|extractor',
23326151 869 'default_key': 'http',
870 }, help=(
be5c1ae8 871 'Time to sleep between retries in seconds (optionally) prefixed by the type of retry '
872 '(http (default), fragment, file_access, extractor) to apply the sleep to. '
2dd5a2e3 873 'EXPR can be a number, linear=START[:END[:STEP=1]] or exp=START[:END[:BASE=2]]. '
62b58c09
L
874 'This option can be used multiple times to set the sleep for the different retry types, '
875 'e.g. --retry-sleep linear=1::2 --retry-sleep fragment:exp=1:20'))
9603b660 876 downloader.add_option(
c76eb41b 877 '--skip-unavailable-fragments', '--no-abort-on-unavailable-fragment',
9603b660 878 action='store_true', dest='skip_unavailable_fragments', default=True,
2dd5a2e3 879 help='Skip unavailable fragments for DASH, hlsnative and ISM downloads (default) (Alias: --no-abort-on-unavailable-fragment)')
732fb3f8 880 downloader.add_option(
6623ac34 881 '--abort-on-unavailable-fragment', '--no-skip-unavailable-fragments',
9603b660 882 action='store_false', dest='skip_unavailable_fragments',
2dd5a2e3 883 help='Abort download if a fragment is unavailable (Alias: --no-skip-unavailable-fragments)')
0eee52f3
S
884 downloader.add_option(
885 '--keep-fragments',
886 action='store_true', dest='keep_fragments', default=False,
6623ac34 887 help='Keep downloaded fragments on disk after downloading is finished')
888 downloader.add_option(
889 '--no-keep-fragments',
890 action='store_false', dest='keep_fragments',
891 help='Delete downloaded fragments after downloading is finished (default)')
8450c15c
PH
892 downloader.add_option(
893 '--buffer-size',
894 dest='buffersize', metavar='SIZE', default='1024',
62b58c09 895 help='Size of download buffer, e.g. 1024 or 16K (default is %default)')
6623ac34 896 downloader.add_option(
897 '--resize-buffer',
898 action='store_false', dest='noresizebuffer',
899 help='The buffer size is automatically resized from an initial value of --buffer-size (default)')
8450c15c
PH
900 downloader.add_option(
901 '--no-resize-buffer',
902 action='store_true', dest='noresizebuffer', default=False,
6623ac34 903 help='Do not automatically adjust the buffer size')
ba515388
S
904 downloader.add_option(
905 '--http-chunk-size',
906 dest='http_chunk_size', metavar='SIZE', default=None,
6623ac34 907 help=(
62b58c09 908 'Size of a chunk for chunk-based HTTP downloading, e.g. 10485760 or 10M (default is disabled). '
6623ac34 909 'May be useful for bypassing bandwidth throttling imposed by a webserver (experimental)'))
8450c15c
PH
910 downloader.add_option(
911 '--test',
912 action='store_true', dest='test', default=False,
913 help=optparse.SUPPRESS_HELP)
ff815fe6
MS
914 downloader.add_option(
915 '--playlist-reverse',
7e9a6125 916 action='store_true', dest='playlist_reverse',
7e88d7d7 917 help=optparse.SUPPRESS_HELP)
6623ac34 918 downloader.add_option(
919 '--no-playlist-reverse',
c76eb41b 920 action='store_false', dest='playlist_reverse',
7e88d7d7 921 help=optparse.SUPPRESS_HELP)
75822ca7
TC
922 downloader.add_option(
923 '--playlist-random',
7e9a6125 924 action='store_true', dest='playlist_random',
75822ca7 925 help='Download playlist videos in random order')
7e9a6125 926 downloader.add_option(
927 '--lazy-playlist',
928 action='store_true', dest='lazy_playlist',
929 help='Process entries in the playlist as they are received. This disables n_entries, --playlist-random and --playlist-reverse')
930 downloader.add_option(
931 '--no-lazy-playlist',
932 action='store_false', dest='lazy_playlist',
933 help='Process videos in the playlist only after the entire playlist is parsed (default)')
881e6a1f
PH
934 downloader.add_option(
935 '--xattr-set-filesize',
936 dest='xattr_set_filesize', action='store_true',
504f20dd 937 help='Set file xattribute ytdl.filesize with expected file size')
85729c51
PH
938 downloader.add_option(
939 '--hls-prefer-native',
bf09af3a 940 dest='hls_prefer_native', action='store_true', default=None,
52a8a1e1 941 help=optparse.SUPPRESS_HELP)
bf09af3a
S
942 downloader.add_option(
943 '--hls-prefer-ffmpeg',
944 dest='hls_prefer_native', action='store_false', default=None,
52a8a1e1 945 help=optparse.SUPPRESS_HELP)
7d106a65
JMF
946 downloader.add_option(
947 '--hls-use-mpegts',
9bd20204 948 dest='hls_use_mpegts', action='store_true', default=None,
6623ac34 949 help=(
9bd20204 950 'Use the mpegts container for HLS videos; '
951 'allowing some players to play the video while downloading, '
952 'and reducing the chance of file corruption if download is interrupted. '
953 'This is enabled by default for live streams'))
954 downloader.add_option(
955 '--no-hls-use-mpegts',
956 dest='hls_use_mpegts', action='store_false',
957 help=(
958 'Do not use the mpegts container for HLS videos. '
959 'This is default when not downloading live streams'))
5ec1b6b7 960 downloader.add_option(
961 '--download-sections',
962 metavar='REGEX', dest='download_ranges', action='append',
963 help=(
964 'Download only chapters whose title matches the given regular expression. '
965 'Time ranges prefixed by a "*" can also be used in place of chapters to download the specified range. '
62b58c09
L
966 'Needs ffmpeg. This option can be used multiple times to download multiple sections, '
967 'e.g. --download-sections "*10:15-15:00" --download-sections "intro"'))
222516d9 968 downloader.add_option(
52a8a1e1 969 '--downloader', '--external-downloader',
970 dest='external_downloader', metavar='[PROTO:]NAME', default={}, type='str',
e632bce2 971 action='callback', callback=_dict_from_options_callback,
52a8a1e1 972 callback_kwargs={
973 'allowed_keys': 'http|ftp|m3u8|dash|rtsp|rtmp|mms',
cc0ec3e1 974 'default_key': 'default',
dbf5416a 975 'process': str.strip
976 }, help=(
52a8a1e1 977 'Name or path of the external downloader to use (optionally) prefixed by '
978 'the protocols (http, ftp, m3u8, dash, rstp, rtmp, mms) to use it for. '
8dc59305 979 f'Currently supports native, {", ".join(sorted(list_external_downloaders()))}. '
52a8a1e1 980 'You can use this option multiple times to set different downloaders for different protocols. '
62b58c09 981 'E.g. --downloader aria2c --downloader "dash,m3u8:native" will use '
52a8a1e1 982 'aria2c for http/ftp downloads, and the native downloader for dash/m3u8 downloads '
0a41f331 983 '(Alias: --external-downloader)'))
c75f0b36 984 downloader.add_option(
46ee996e 985 '--downloader-args', '--external-downloader-args',
986 metavar='NAME:ARGS', dest='external_downloader_args', default={}, type='str',
e632bce2 987 action='callback', callback=_dict_from_options_callback,
b8f6bbe6 988 callback_kwargs={
9e907ebd 989 'allowed_keys': r'ffmpeg_[io]\d*|%s' % '|'.join(map(re.escape, list_external_downloaders())),
cc0ec3e1 990 'default_key': 'default',
f9934b96 991 'process': shlex.split
dbf5416a 992 }, help=(
46ee996e 993 'Give these arguments to the external downloader. '
994 'Specify the downloader name and the arguments separated by a colon ":". '
330690a2 995 'For ffmpeg, arguments can be passed to different positions using the same syntax as --postprocessor-args. '
5d3a0e79 996 'You can use this option multiple times to give different arguments to different downloaders '
997 '(Alias: --external-downloader-args)'))
8450c15c
PH
998
999 workarounds = optparse.OptionGroup(parser, 'Workarounds')
34a741a8 1000 workarounds.add_option(
8450c15c
PH
1001 '--encoding',
1002 dest='encoding', metavar='ENCODING',
34a741a8 1003 help='Force the specified encoding (experimental)')
f81c62a6 1004 workarounds.add_option(
1005 '--legacy-server-connect',
1006 action='store_true', dest='legacy_server_connect', default=False,
1007 help='Explicitly allow HTTPS connection to servers that do not support RFC 5746 secure renegotiation')
34a741a8 1008 workarounds.add_option(
e6f21b3d 1009 '--no-check-certificates',
8450c15c 1010 action='store_true', dest='no_check_certificate', default=False,
17941321 1011 help='Suppress HTTPS certificate validation')
34a741a8 1012 workarounds.add_option(
6623ac34 1013 '--prefer-insecure', '--prefer-unsecure',
1014 action='store_true', dest='prefer_insecure',
e167860c 1015 help='Use an unencrypted connection to retrieve information about the video (Currently supported only for YouTube)')
34a741a8 1016 workarounds.add_option(
8450c15c
PH
1017 '--user-agent',
1018 metavar='UA', dest='user_agent',
8b7539d2 1019 help=optparse.SUPPRESS_HELP)
34a741a8 1020 workarounds.add_option(
8450c15c
PH
1021 '--referer',
1022 metavar='URL', dest='referer', default=None,
8b7539d2 1023 help=optparse.SUPPRESS_HELP)
34a741a8 1024 workarounds.add_option(
8450c15c 1025 '--add-header',
45016689 1026 metavar='FIELD:VALUE', dest='headers', default={}, type='str',
e632bce2 1027 action='callback', callback=_dict_from_options_callback,
8b7539d2 1028 callback_kwargs={'multiple_keys': False},
45016689 1029 help='Specify a custom HTTP header and its value, separated by a colon ":". You can use this option multiple times',
34a741a8
PH
1030 )
1031 workarounds.add_option(
8450c15c
PH
1032 '--bidi-workaround',
1033 dest='bidi_workaround', action='store_true',
1034 help='Work around terminals that lack bidirectional text support. Requires bidiv or fribidi executable in PATH')
1cf376f5 1035 workarounds.add_option(
1036 '--sleep-requests', metavar='SECONDS',
1037 dest='sleep_interval_requests', type=float,
1038 help='Number of seconds to sleep between requests during data extraction')
5f0d813d 1039 workarounds.add_option(
065bc354 1040 '--sleep-interval', '--min-sleep-interval', metavar='SECONDS',
649f7966 1041 dest='sleep_interval', type=float,
7aa589a5 1042 help=(
e167860c 1043 'Number of seconds to sleep before each download. '
1044 'This is the minimum time to sleep when used along with --max-sleep-interval '
1045 '(Alias: --min-sleep-interval)'))
065bc354 1046 workarounds.add_option(
1047 '--max-sleep-interval', metavar='SECONDS',
1048 dest='max_sleep_interval', type=float,
e167860c 1049 help='Maximum number of seconds to sleep. Can only be used along with --min-sleep-interval')
0c9df79e 1050 workarounds.add_option(
c76eb41b 1051 '--sleep-subtitles', metavar='SECONDS',
31108ce9 1052 dest='sleep_interval_subtitles', default=0, type=int,
1cf376f5 1053 help='Number of seconds to sleep before each subtitle download')
34a741a8 1054
0744a815 1055 verbosity = optparse.OptionGroup(parser, 'Verbosity and Simulation Options')
8450c15c
PH
1056 verbosity.add_option(
1057 '-q', '--quiet',
1058 action='store_true', dest='quiet', default=False,
34488702 1059 help='Activate quiet mode. If used with --verbose, print the log to stderr')
34a741a8
PH
1060 verbosity.add_option(
1061 '--no-warnings',
1062 dest='no_warnings', action='store_true', default=False,
1063 help='Ignore warnings')
8450c15c
PH
1064 verbosity.add_option(
1065 '-s', '--simulate',
b7b04c78 1066 action='store_true', dest='simulate', default=None,
17941321 1067 help='Do not download the video and do not write anything to disk')
b7b04c78 1068 verbosity.add_option(
1069 '--no-simulate',
1070 action='store_false', dest='simulate',
1071 help='Download the video even if printing/listing options are used')
b7da73eb 1072 verbosity.add_option(
1073 '--ignore-no-formats-error',
1074 action='store_true', dest='ignore_no_formats_error', default=False,
1075 help=(
0930b11f 1076 'Ignore "No video formats" error. Useful for extracting metadata '
34488702 1077 'even if the videos are not actually available for download (experimental)'))
b7da73eb 1078 verbosity.add_option(
1079 '--no-ignore-no-formats-error',
1080 action='store_false', dest='ignore_no_formats_error',
1081 help='Throw error when no downloadable video formats are found (default)')
8450c15c 1082 verbosity.add_option(
6623ac34 1083 '--skip-download', '--no-download',
8450c15c 1084 action='store_true', dest='skip_download', default=False,
e167860c 1085 help='Do not download the video but write all related files (Alias: --no-download)')
53c18592 1086 verbosity.add_option(
ad3dc496 1087 '-O', '--print',
ca30f449 1088 metavar='[WHEN:]TEMPLATE', dest='forceprint', default={}, type='str',
1089 action='callback', callback=_dict_from_options_callback,
1090 callback_kwargs={
ed5835b4 1091 'allowed_keys': 'video|' + '|'.join(map(re.escape, POSTPROCESS_WHEN)),
ca30f449 1092 'default_key': 'video',
1093 'multiple_keys': False,
1094 'append': True,
1095 }, help=(
ed5835b4 1096 'Field name or output template to print to screen, optionally prefixed with when to print it, separated by a ":". '
1097 'Supported values of "WHEN" are the same as that of --use-postprocessor, and "video" (default). '
62f6f1cb 1098 'Implies --quiet. Implies --simulate unless --no-simulate or later stages of WHEN are used. '
1099 'This option can be used multiple times'))
bb66c247 1100 verbosity.add_option(
1101 '--print-to-file',
1102 metavar='[WHEN:]TEMPLATE FILE', dest='print_to_file', default={}, type='str', nargs=2,
1103 action='callback', callback=_dict_from_options_callback,
1104 callback_kwargs={
1105 'allowed_keys': 'video|' + '|'.join(map(re.escape, POSTPROCESS_WHEN)),
1106 'default_key': 'video',
1107 'multiple_keys': False,
1108 'append': True,
1109 }, help=(
1110 'Append given template to the file. The values of WHEN and TEMPLATE are same as that of --print. '
1111 'FILE uses the same syntax as the output template. This option can be used multiple times'))
8450c15c
PH
1112 verbosity.add_option(
1113 '-g', '--get-url',
1114 action='store_true', dest='geturl', default=False,
53c18592 1115 help=optparse.SUPPRESS_HELP)
8450c15c
PH
1116 verbosity.add_option(
1117 '-e', '--get-title',
1118 action='store_true', dest='gettitle', default=False,
53c18592 1119 help=optparse.SUPPRESS_HELP)
8450c15c
PH
1120 verbosity.add_option(
1121 '--get-id',
1122 action='store_true', dest='getid', default=False,
53c18592 1123 help=optparse.SUPPRESS_HELP)
8450c15c
PH
1124 verbosity.add_option(
1125 '--get-thumbnail',
1126 action='store_true', dest='getthumbnail', default=False,
53c18592 1127 help=optparse.SUPPRESS_HELP)
8450c15c
PH
1128 verbosity.add_option(
1129 '--get-description',
1130 action='store_true', dest='getdescription', default=False,
53c18592 1131 help=optparse.SUPPRESS_HELP)
8450c15c
PH
1132 verbosity.add_option(
1133 '--get-duration',
1134 action='store_true', dest='getduration', default=False,
53c18592 1135 help=optparse.SUPPRESS_HELP)
8450c15c
PH
1136 verbosity.add_option(
1137 '--get-filename',
1138 action='store_true', dest='getfilename', default=False,
53c18592 1139 help=optparse.SUPPRESS_HELP)
8450c15c
PH
1140 verbosity.add_option(
1141 '--get-format',
1142 action='store_true', dest='getformat', default=False,
53c18592 1143 help=optparse.SUPPRESS_HELP)
8450c15c
PH
1144 verbosity.add_option(
1145 '-j', '--dump-json',
1146 action='store_true', dest='dumpjson', default=False,
b7b04c78 1147 help='Quiet, but print JSON information for each video. Simulate unless --no-simulate is used. See "OUTPUT TEMPLATE" for a description of available keys')
63e0be34
PH
1148 verbosity.add_option(
1149 '-J', '--dump-single-json',
1150 action='store_true', dest='dump_single_json', default=False,
6623ac34 1151 help=(
b7b04c78 1152 'Quiet, but print JSON information for each url or infojson passed. Simulate unless --no-simulate is used. '
1153 'If the URL refers to a playlist, the whole playlist information is dumped in a single line'))
c0bdf32a
PH
1154 verbosity.add_option(
1155 '--print-json',
1156 action='store_true', dest='print_json', default=False,
b7b04c78 1157 help=optparse.SUPPRESS_HELP)
2d30509f 1158 verbosity.add_option(
c76eb41b 1159 '--force-write-archive', '--force-write-download-archive', '--force-download-archive',
2d30509f 1160 action='store_true', dest='force_write_download_archive', default=False,
1161 help=(
e58c22a0 1162 'Force download archive entries to be written as far as no errors occur, '
1163 'even if -s or another simulation option is used (Alias: --force-download-archive)'))
8450c15c
PH
1164 verbosity.add_option(
1165 '--newline',
1166 action='store_true', dest='progress_with_newline', default=False,
17941321 1167 help='Output progress bar as new lines')
8450c15c
PH
1168 verbosity.add_option(
1169 '--no-progress',
819e0531 1170 action='store_true', dest='noprogress', default=None,
17941321 1171 help='Do not print progress bar')
819e0531 1172 verbosity.add_option(
1173 '--progress',
1174 action='store_false', dest='noprogress',
1175 help='Show progress bar, even if in quiet mode')
8450c15c
PH
1176 verbosity.add_option(
1177 '--console-title',
1178 action='store_true', dest='consoletitle', default=False,
17941321 1179 help='Display progress in console titlebar')
819e0531 1180 verbosity.add_option(
1181 '--progress-template',
1182 metavar='[TYPES:]TEMPLATE', dest='progress_template', default={}, type='str',
1183 action='callback', callback=_dict_from_options_callback,
1184 callback_kwargs={
1185 'allowed_keys': '(download|postprocess)(-title)?',
1186 'default_key': 'download'
1187 }, help=(
1188 'Template for progress outputs, optionally prefixed with one of "download:" (default), '
1189 '"download-title:" (the console title), "postprocess:", or "postprocess-title:". '
1190 'The video\'s fields are accessible under the "info" key and '
62b58c09 1191 'the progress attributes are accessible under "progress" key. E.g. '
819e0531 1192 # TODO: Document the fields inside "progress"
1193 '--console-title --progress-template "download-title:%(info.id)s-%(progress.eta)s"'))
8450c15c
PH
1194 verbosity.add_option(
1195 '-v', '--verbose',
1196 action='store_true', dest='verbose', default=False,
17941321 1197 help='Print various debugging information')
8450c15c 1198 verbosity.add_option(
8bba753c 1199 '--dump-pages', '--dump-intermediate-pages',
8450c15c 1200 action='store_true', dest='dump_intermediate_pages', default=False,
79979c68 1201 help='Print downloaded pages encoded using base64 to debug problems (very verbose)')
8450c15c
PH
1202 verbosity.add_option(
1203 '--write-pages',
1204 action='store_true', dest='write_pages', default=False,
1205 help='Write downloaded intermediary pages to files in the current directory to debug problems')
f95b9dee 1206 verbosity.add_option(
1207 '--load-pages',
1208 action='store_true', dest='load_pages', default=False,
1209 help=optparse.SUPPRESS_HELP)
8450c15c
PH
1210 verbosity.add_option(
1211 '--youtube-print-sig-code',
1212 action='store_true', dest='youtube_print_sig_code', default=False,
1213 help=optparse.SUPPRESS_HELP)
1214 verbosity.add_option(
2f543a21 1215 '--print-traffic', '--dump-headers',
8450c15c
PH
1216 dest='debug_printtraffic', action='store_true', default=False,
1217 help='Display sent and read HTTP traffic')
58b1f00d
PH
1218 verbosity.add_option(
1219 '-C', '--call-home',
1220 dest='call_home', action='store_true', default=False,
19a03940 1221 # help='Contact the yt-dlp server for debugging')
8d801631 1222 help=optparse.SUPPRESS_HELP)
8bfa7545
PH
1223 verbosity.add_option(
1224 '--no-call-home',
6623ac34 1225 dest='call_home', action='store_false',
7a5c1cfe 1226 # help='Do not contact the yt-dlp server for debugging (default)')
8d801631 1227 help=optparse.SUPPRESS_HELP)
8450c15c
PH
1228
1229 filesystem = optparse.OptionGroup(parser, 'Filesystem Options')
1230 filesystem.add_option(
1231 '-a', '--batch-file',
1232 dest='batchfile', metavar='FILE',
940a67a3 1233 help=(
1234 'File containing URLs to download ("-" for stdin), one URL per line. '
1235 'Lines starting with "#", ";" or "]" are considered as comments and ignored'))
1e520b55
Z
1236 filesystem.add_option(
1237 '--no-batch-file',
1238 dest='batchfile', action='store_const', const=None,
1239 help='Do not read URLs from batch file (default)')
19b824f6 1240 filesystem.add_option(
1241 '--id', default=False,
1242 action='store_true', dest='useid', help=optparse.SUPPRESS_HELP)
0202b52a 1243 filesystem.add_option(
1244 '-P', '--paths',
d74a58a1 1245 metavar='[TYPES:]PATH', dest='paths', default={}, type='str',
e632bce2 1246 action='callback', callback=_dict_from_options_callback,
d74a58a1 1247 callback_kwargs={
9e907ebd 1248 'allowed_keys': 'home|temp|%s' % '|'.join(map(re.escape, OUTTMPL_TYPES.keys())),
d74a58a1 1249 'default_key': 'home'
1250 }, help=(
0202b52a 1251 'The paths where the files should be downloaded. '
de6000d9 1252 'Specify the type of file and the path separated by a colon ":". '
6a34813a 1253 'All the same TYPES as --output are supported. '
d74a58a1 1254 'Additionally, you can also provide "home" (default) and "temp" paths. '
0202b52a 1255 'All intermediary files are first downloaded to the temp path and '
1256 'then the final files are moved over to the home path after download is finished. '
de6000d9 1257 'This option is ignored if --output is an absolute path'))
8450c15c
PH
1258 filesystem.add_option(
1259 '-o', '--output',
d818eb74 1260 metavar='[TYPES:]TEMPLATE', dest='outtmpl', default={}, type='str',
e632bce2 1261 action='callback', callback=_dict_from_options_callback,
de6000d9 1262 callback_kwargs={
9e907ebd 1263 'allowed_keys': '|'.join(map(re.escape, OUTTMPL_TYPES.keys())),
cc0ec3e1 1264 'default_key': 'default'
dbf5416a 1265 }, help='Output filename template; see "OUTPUT TEMPLATE" for details')
a820dc72
RA
1266 filesystem.add_option(
1267 '--output-na-placeholder',
0bc0a322 1268 dest='outtmpl_na_placeholder', metavar='TEXT', default='NA',
2dd5a2e3 1269 help=('Placeholder for unavailable fields in "OUTPUT TEMPLATE" (default: "%default")'))
8450c15c
PH
1270 filesystem.add_option(
1271 '--autonumber-size',
be5df5ee
S
1272 dest='autonumber_size', metavar='NUMBER', type=int,
1273 help=optparse.SUPPRESS_HELP)
acbb2374
CP
1274 filesystem.add_option(
1275 '--autonumber-start',
1a241a2d 1276 dest='autonumber_start', metavar='NUMBER', default=1, type=int,
a439a3a4 1277 help=optparse.SUPPRESS_HELP)
8450c15c
PH
1278 filesystem.add_option(
1279 '--restrict-filenames',
1280 action='store_true', dest='restrictfilenames', default=False,
1281 help='Restrict filenames to only ASCII characters, and avoid "&" and spaces in filenames')
6623ac34 1282 filesystem.add_option(
1283 '--no-restrict-filenames',
c2934512 1284 action='store_false', dest='restrictfilenames',
6623ac34 1285 help='Allow Unicode characters, "&" and spaces in filenames (default)')
c2934512 1286 filesystem.add_option(
1287 '--windows-filenames',
1288 action='store_true', dest='windowsfilenames', default=False,
0930b11f 1289 help='Force filenames to be Windows-compatible')
c2934512 1290 filesystem.add_option(
1291 '--no-windows-filenames',
1292 action='store_false', dest='windowsfilenames',
0930b11f 1293 help='Make filenames Windows-compatible only if using Windows (default)')
c2934512 1294 filesystem.add_option(
1295 '--trim-filenames', '--trim-file-names', metavar='LENGTH',
1296 dest='trim_file_name', default=0, type=int,
1297 help='Limit the filename length (excluding extension) to the specified number of characters')
8450c15c
PH
1298 filesystem.add_option(
1299 '-w', '--no-overwrites',
0c3d0f51 1300 action='store_false', dest='overwrites', default=None,
1301 help='Do not overwrite any files')
1302 filesystem.add_option(
1303 '--force-overwrites', '--yes-overwrites',
1304 action='store_true', dest='overwrites',
1305 help='Overwrite all video and metadata files. This option includes --no-continue')
1306 filesystem.add_option(
1307 '--no-force-overwrites',
1308 action='store_const', dest='overwrites', const=None,
1309 help='Do not overwrite the video, but overwrite related files (default)')
8450c15c
PH
1310 filesystem.add_option(
1311 '-c', '--continue',
1312 action='store_true', dest='continue_dl', default=True,
c25228e5 1313 help='Resume partially downloaded files/fragments (default)')
8450c15c
PH
1314 filesystem.add_option(
1315 '--no-continue',
1316 action='store_false', dest='continue_dl',
c25228e5 1317 help=(
1318 'Do not resume partially downloaded fragments. '
e58c22a0 1319 'If the file is not fragmented, restart download of the entire file'))
6623ac34 1320 filesystem.add_option(
1321 '--part',
1322 action='store_false', dest='nopart', default=False,
1323 help='Use .part files instead of writing directly into output file (default)')
8450c15c
PH
1324 filesystem.add_option(
1325 '--no-part',
6623ac34 1326 action='store_true', dest='nopart',
17941321 1327 help='Do not use .part files - write directly into output file')
6623ac34 1328 filesystem.add_option(
1329 '--mtime',
1330 action='store_true', dest='updatetime', default=True,
1331 help='Use the Last-modified header to set the file modification time (default)')
8450c15c
PH
1332 filesystem.add_option(
1333 '--no-mtime',
6623ac34 1334 action='store_false', dest='updatetime',
17941321 1335 help='Do not use the Last-modified header to set the file modification time')
8450c15c
PH
1336 filesystem.add_option(
1337 '--write-description',
1338 action='store_true', dest='writedescription', default=False,
17941321 1339 help='Write video description to a .description file')
6623ac34 1340 filesystem.add_option(
1341 '--no-write-description',
1342 action='store_false', dest='writedescription',
1343 help='Do not write video description (default)')
8450c15c
PH
1344 filesystem.add_option(
1345 '--write-info-json',
d1b5f70b 1346 action='store_true', dest='writeinfojson', default=None,
c25228e5 1347 help='Write video metadata to a .info.json file (this may contain personal information)')
6623ac34 1348 filesystem.add_option(
1349 '--no-write-info-json',
1350 action='store_false', dest='writeinfojson',
1351 help='Do not write video metadata (default)')
8450c15c
PH
1352 filesystem.add_option(
1353 '--write-annotations',
1354 action='store_true', dest='writeannotations', default=False,
0bb1bc1b 1355 help=optparse.SUPPRESS_HELP)
6623ac34 1356 filesystem.add_option(
1357 '--no-write-annotations',
1358 action='store_false', dest='writeannotations',
0bb1bc1b 1359 help=optparse.SUPPRESS_HELP)
cac96421 1360 filesystem.add_option(
1361 '--write-playlist-metafiles',
53ed7066 1362 action='store_true', dest='allow_playlist_files', default=None,
cac96421 1363 help=(
1364 'Write playlist metadata in addition to the video metadata '
1365 'when using --write-info-json, --write-description etc. (default)'))
1366 filesystem.add_option(
1367 '--no-write-playlist-metafiles',
1368 action='store_false', dest='allow_playlist_files',
e167860c 1369 help='Do not write playlist metadata when using --write-info-json, --write-description etc.')
75d43ca0 1370 filesystem.add_option(
3856407a 1371 '--clean-info-json', '--clean-infojson',
e4f02757 1372 action='store_true', dest='clean_infojson', default=None,
75d43ca0 1373 help=(
1374 'Remove some private fields such as filenames from the infojson. '
1375 'Note that it could still contain some personal information (default)'))
1376 filesystem.add_option(
3856407a 1377 '--no-clean-info-json', '--no-clean-infojson',
75d43ca0 1378 action='store_false', dest='clean_infojson',
1379 help='Write all fields to the infojson')
06167fbb 1380 filesystem.add_option(
2305e2e5 1381 '--write-comments', '--get-comments',
06167fbb 1382 action='store_true', dest='getcomments', default=False,
277d6ff5 1383 help=(
2305e2e5 1384 'Retrieve video comments to be placed in the infojson. '
1385 'The comments are fetched even without this option if the extraction is known to be quick (Alias: --get-comments)'))
1386 filesystem.add_option(
1387 '--no-write-comments', '--no-get-comments',
dd594deb 1388 action='store_false', dest='getcomments',
2305e2e5 1389 help='Do not retrieve video comments unless the extraction is known to be quick (Alias: --no-get-comments)')
8450c15c 1390 filesystem.add_option(
244fe977 1391 '--load-info-json', '--load-info',
8450c15c 1392 dest='load_info_filename', metavar='FILE',
1a48181a 1393 help='JSON file containing the video information (created with the "--write-info-json" option)')
8450c15c
PH
1394 filesystem.add_option(
1395 '--cookies',
1396 dest='cookiefile', metavar='FILE',
f304da8a 1397 help='Netscape formatted file to read cookies from and dump cookie jar in')
6623ac34 1398 filesystem.add_option(
1399 '--no-cookies',
1400 action='store_const', const=None, dest='cookiefile', metavar='FILE',
982ee69a
MB
1401 help='Do not read/dump cookies from/to file (default)')
1402 filesystem.add_option(
1403 '--cookies-from-browser',
f59f5ef8 1404 dest='cookiesfrombrowser', metavar='BROWSER[+KEYRING][:PROFILE]',
982ee69a 1405 help=(
f59f5ef8
MB
1406 'The name of the browser and (optionally) the name/path of '
1407 'the profile to load cookies from, separated by a ":". '
1408 f'Currently supported browsers are: {", ".join(sorted(SUPPORTED_BROWSERS))}. '
1409 'By default, the most recently accessed profile is used. '
1410 'The keyring used for decrypting Chromium cookies on Linux can be '
1411 '(optionally) specified after the browser name separated by a "+". '
1412 f'Currently supported keyrings are: {", ".join(map(str.lower, sorted(SUPPORTED_KEYRINGS)))}'))
982ee69a
MB
1413 filesystem.add_option(
1414 '--no-cookies-from-browser',
1415 action='store_const', const=None, dest='cookiesfrombrowser',
1416 help='Do not load cookies from browser (default)')
34a741a8
PH
1417 filesystem.add_option(
1418 '--cache-dir', dest='cachedir', default=None, metavar='DIR',
9ee4f0bb 1419 help='Location in the filesystem where youtube-dl can store some downloaded information (such as client ids and signatures) permanently. By default $XDG_CACHE_HOME/yt-dlp or ~/.cache/yt-dlp')
34a741a8 1420 filesystem.add_option(
6623ac34 1421 '--no-cache-dir', action='store_false', dest='cachedir',
34a741a8
PH
1422 help='Disable filesystem caching')
1423 filesystem.add_option(
8450c15c
PH
1424 '--rm-cache-dir',
1425 action='store_true', dest='rm_cachedir',
34a741a8
PH
1426 help='Delete all filesystem cache files')
1427
b31fdeed 1428 thumbnail = optparse.OptionGroup(parser, 'Thumbnail Options')
cfb56d1a
PH
1429 thumbnail.add_option(
1430 '--write-thumbnail',
acc0d6a4 1431 action='callback', dest='writethumbnail', default=False,
1432 # Should override --no-write-thumbnail, but not --write-all-thumbnail
1433 callback=lambda option, _, __, parser: setattr(
1434 parser.values, option.dest, getattr(parser.values, option.dest) or True),
17941321 1435 help='Write thumbnail image to disk')
6623ac34 1436 thumbnail.add_option(
1437 '--no-write-thumbnail',
1438 action='store_false', dest='writethumbnail',
1439 help='Do not write thumbnail image to disk (default)')
ec82d85a
PH
1440 thumbnail.add_option(
1441 '--write-all-thumbnails',
acc0d6a4 1442 action='store_const', dest='writethumbnail', const='all',
17941321 1443 help='Write all thumbnail image formats to disk')
cfb56d1a
PH
1444 thumbnail.add_option(
1445 '--list-thumbnails',
1446 action='store_true', dest='list_thumbnails', default=False,
b7b04c78 1447 help='List available thumbnails of each video. Simulate unless --no-simulate is used')
cfb56d1a 1448
732044af 1449 link = optparse.OptionGroup(parser, 'Internet Shortcut Options')
1450 link.add_option(
1451 '--write-link',
1452 action='store_true', dest='writelink', default=False,
8a51f564 1453 help='Write an internet shortcut file, depending on the current platform (.url, .webloc or .desktop). The URL may be cached by the OS')
732044af 1454 link.add_option(
1455 '--write-url-link',
1456 action='store_true', dest='writeurllink', default=False,
8a51f564 1457 help='Write a .url Windows internet shortcut. The OS caches the URL based on the file path')
732044af 1458 link.add_option(
1459 '--write-webloc-link',
1460 action='store_true', dest='writewebloclink', default=False,
8a51f564 1461 help='Write a .webloc macOS internet shortcut')
732044af 1462 link.add_option(
1463 '--write-desktop-link',
1464 action='store_true', dest='writedesktoplink', default=False,
8a51f564 1465 help='Write a .desktop Linux internet shortcut')
732044af 1466
1467 postproc = optparse.OptionGroup(parser, 'Post-Processing Options')
8450c15c
PH
1468 postproc.add_option(
1469 '-x', '--extract-audio',
1470 action='store_true', dest='extractaudio', default=False,
e4172ac9 1471 help='Convert video files to audio-only files (requires ffmpeg and ffprobe)')
8450c15c
PH
1472 postproc.add_option(
1473 '--audio-format', metavar='FORMAT', dest='audioformat', default='best',
81a23040 1474 help=(
35faefee 1475 'Format to convert the audio to when -x is used. '
8dc59305 1476 f'(currently supported: best (default), {", ".join(sorted(FFmpegExtractAudioPP.SUPPORTED_EXTS))}). '
e0ab9854 1477 'You can specify multiple rules using similar syntax as --remux-video'))
8450c15c
PH
1478 postproc.add_option(
1479 '--audio-quality', metavar='QUALITY',
1480 dest='audioquality', default='5',
35faefee 1481 help=(
1482 'Specify ffmpeg audio quality to use when converting the audio with -x. '
1483 'Insert a value between 0 (best) and 10 (worst) for VBR or a specific bitrate like 128K (default %default)'))
efe87a10
FS
1484 postproc.add_option(
1485 '--remux-video',
1486 metavar='FORMAT', dest='remuxvideo', default=None,
6623ac34 1487 help=(
35faefee 1488 'Remux the video into another container if necessary '
1489 f'(currently supported: {", ".join(FFmpegVideoRemuxerPP.SUPPORTED_EXTS)}). '
1490 'If target container does not support the video/audio codec, remuxing will fail. You can specify multiple rules; '
62b58c09 1491 'e.g. "aac>m4a/mov>mp4/mkv" will remux aac to m4a, mov to mp4 and anything else to mkv'))
8450c15c
PH
1492 postproc.add_option(
1493 '--recode-video',
1494 metavar='FORMAT', dest='recodevideo', default=None,
2dd5a2e3 1495 help='Re-encode the video into another format if necessary. The syntax and supported formats are the same as --remux-video')
d84f1d14 1496 postproc.add_option(
45016689 1497 '--postprocessor-args', '--ppa',
1498 metavar='NAME:ARGS', dest='postprocessor_args', default={}, type='str',
e632bce2 1499 action='callback', callback=_dict_from_options_callback,
d818eb74 1500 callback_kwargs={
9e907ebd 1501 'allowed_keys': r'\w+(?:\+\w+)?',
1502 'default_key': 'default-compat',
f9934b96 1503 'process': shlex.split,
cc0ec3e1 1504 'multiple_keys': False
dbf5416a 1505 }, help=(
1b77b347 1506 'Give these arguments to the postprocessors. '
43820c03 1507 'Specify the postprocessor/executable name and the arguments separated by a colon ":" '
8fa43c73 1508 'to give the argument to the specified postprocessor/executable. Supported PP are: '
7a340e0d
NA
1509 'Merger, ModifyChapters, SplitChapters, ExtractAudio, VideoRemuxer, VideoConvertor, '
1510 'Metadata, EmbedSubtitle, EmbedThumbnail, SubtitlesConvertor, ThumbnailsConvertor, '
1511 'FixupStretched, FixupM4a, FixupM3u8, FixupTimestamp and FixupDuration. '
1512 'The supported executables are: AtomicParsley, FFmpeg and FFprobe. '
43820c03 1513 'You can also specify "PP+EXE:ARGS" to give the arguments to the specified executable '
5b1ecbb3 1514 'only when being used by the specified postprocessor. Additionally, for ffmpeg/ffprobe, '
597c1866 1515 '"_i"/"_o" can be appended to the prefix optionally followed by a number to pass the argument '
62b58c09 1516 'before the specified input/output file, e.g. --ppa "Merger+ffmpeg_i1:-v quiet". '
5b1ecbb3 1517 'You can use this option multiple times to give different arguments to different '
1518 'postprocessors. (Alias: --ppa)'))
8450c15c
PH
1519 postproc.add_option(
1520 '-k', '--keep-video',
1521 action='store_true', dest='keepvideo', default=False,
6623ac34 1522 help='Keep the intermediate video file on disk after post-processing')
1523 postproc.add_option(
1524 '--no-keep-video',
1525 action='store_false', dest='keepvideo',
1526 help='Delete the intermediate video file after post-processing (default)')
1527 postproc.add_option(
1528 '--post-overwrites',
1529 action='store_false', dest='nopostoverwrites',
1530 help='Overwrite post-processed files (default)')
8450c15c
PH
1531 postproc.add_option(
1532 '--no-post-overwrites',
1533 action='store_true', dest='nopostoverwrites', default=False,
6623ac34 1534 help='Do not overwrite post-processed files')
8450c15c
PH
1535 postproc.add_option(
1536 '--embed-subs',
1537 action='store_true', dest='embedsubtitles', default=False,
40025ee2 1538 help='Embed subtitles in the video (only for mp4, webm and mkv videos)')
6623ac34 1539 postproc.add_option(
1540 '--no-embed-subs',
1541 action='store_false', dest='embedsubtitles',
1542 help='Do not embed subtitles (default)')
8450c15c
PH
1543 postproc.add_option(
1544 '--embed-thumbnail',
1545 action='store_true', dest='embedthumbnail', default=False,
6aecd871 1546 help='Embed thumbnail in the video as cover art')
6623ac34 1547 postproc.add_option(
1548 '--no-embed-thumbnail',
1549 action='store_false', dest='embedthumbnail',
1550 help='Do not embed thumbnail (default)')
8450c15c 1551 postproc.add_option(
7e067091 1552 '--embed-metadata', '--add-metadata',
8450c15c 1553 action='store_true', dest='addmetadata', default=False,
dac5df5a 1554 help=(
1555 'Embed metadata to the video file. Also embeds chapters/infojson if present '
1556 'unless --no-embed-chapters/--no-embed-info-json are used (Alias: --add-metadata)'))
6623ac34 1557 postproc.add_option(
7e067091 1558 '--no-embed-metadata', '--no-add-metadata',
6623ac34 1559 action='store_false', dest='addmetadata',
7a340e0d
NA
1560 help='Do not add metadata to file (default) (Alias: --no-add-metadata)')
1561 postproc.add_option(
1562 '--embed-chapters', '--add-chapters',
1563 action='store_true', dest='addchapters', default=None,
1564 help='Add chapter markers to the video file (Alias: --add-chapters)')
1565 postproc.add_option(
1566 '--no-embed-chapters', '--no-add-chapters',
1567 action='store_false', dest='addchapters',
1568 help='Do not add chapter markers (default) (Alias: --no-add-chapters)')
dac5df5a 1569 postproc.add_option(
1570 '--embed-info-json',
1571 action='store_true', dest='embed_infojson', default=None,
1572 help='Embed the infojson as an attachment to mkv/mka video files')
1573 postproc.add_option(
1574 '--no-embed-info-json',
1575 action='store_false', dest='embed_infojson',
1576 help='Do not embed the infojson as an attachment to the video file')
e7db87f7 1577 postproc.add_option(
1578 '--metadata-from-title',
1579 metavar='FORMAT', dest='metafromtitle',
5bfa4862 1580 help=optparse.SUPPRESS_HELP)
1581 postproc.add_option(
1582 '--parse-metadata',
e9f4ccd1 1583 metavar='FROM:TO', dest='parse_metadata', action='append',
6623ac34 1584 help=(
73cd218f 1585 'Parse additional metadata like title/artist from other fields; '
1586 'see "MODIFYING METADATA" for details'))
e9f4ccd1 1587 postproc.add_option(
1588 '--replace-in-metadata',
1589 dest='parse_metadata', metavar='FIELDS REGEX REPLACE', action='append', nargs=3,
1590 help='Replace text in a metadata field using the given regex. This option can be used multiple times')
8450c15c 1591 postproc.add_option(
6f7563be 1592 '--xattrs', '--xattr',
8450c15c 1593 action='store_true', dest='xattrs', default=False,
17941321 1594 help='Write metadata to the video file\'s xattrs (using dublin core and xdg standards)')
3b603dbd 1595 postproc.add_option(
1596 '--concat-playlist',
1597 metavar='POLICY', dest='concat_playlist', default='multi_video',
1598 choices=('never', 'always', 'multi_video'),
1599 help=(
fc5fa964 1600 'Concatenate videos in a playlist. One of "never", "always", or '
1601 '"multi_video" (default; only when the videos form a single show). '
3b603dbd 1602 'All the video files must have same codecs and number of streams to be concatable. '
1603 'The "pl_video:" prefix can be used with "--paths" and "--output" to '
a44ca5a4 1604 'set the output filename for the concatenated files. See "OUTPUT TEMPLATE" for details'))
6271f1ca
PH
1605 postproc.add_option(
1606 '--fixup',
99594a11 1607 metavar='POLICY', dest='fixup', default=None,
f89b3e2d 1608 choices=('never', 'ignore', 'warn', 'detect_or_warn', 'force'),
6623ac34 1609 help=(
1610 'Automatically correct known faults of the file. '
1611 'One of never (do nothing), warn (only emit a warning), '
f89b3e2d 1612 'detect_or_warn (the default; fix file if we can, warn otherwise), '
f304da8a 1613 'force (try fixing even if file already exists)'))
8450c15c 1614 postproc.add_option(
6623ac34 1615 '--prefer-avconv', '--no-prefer-ffmpeg',
8450c15c 1616 action='store_false', dest='prefer_ffmpeg',
e4172ac9 1617 help=optparse.SUPPRESS_HELP)
8450c15c 1618 postproc.add_option(
6623ac34 1619 '--prefer-ffmpeg', '--no-prefer-avconv',
e4172ac9 1620 action='store_true', dest='prefer_ffmpeg', default=True,
1621 help=optparse.SUPPRESS_HELP)
73fac4e9
PH
1622 postproc.add_option(
1623 '--ffmpeg-location', '--avconv-location', metavar='PATH',
1624 dest='ffmpeg_location',
e4172ac9 1625 help='Location of the ffmpeg binary; either the path to the binary or its containing directory')
34a741a8 1626 postproc.add_option(
1e43a6f7 1627 '--exec',
1628 metavar='[WHEN:]CMD', dest='exec_cmd', default={}, type='str',
1629 action='callback', callback=_dict_from_options_callback,
1630 callback_kwargs={
1631 'allowed_keys': '|'.join(map(re.escape, POSTPROCESS_WHEN)),
1632 'default_key': 'after_move',
1633 'multiple_keys': False,
1634 'append': True,
1635 }, help=(
1636 'Execute a command, optionally prefixed with when to execute it (after_move if unspecified), separated by a ":". '
1637 'Supported values of "WHEN" are the same as that of --use-postprocessor. '
34488702 1638 'Same syntax as the output template can be used to pass any field as arguments to the command. '
1e43a6f7 1639 'After download, an additional field "filepath" that contains the final path of the downloaded file '
1640 'is also available, and if no fields are passed, %(filepath)q is appended to the end of the command. '
c681cb5d 1641 'This option can be used multiple times'))
1642 postproc.add_option(
1643 '--no-exec',
1e43a6f7 1644 action='store_const', dest='exec_cmd', const={},
c681cb5d 1645 help='Remove any previously defined --exec')
1646 postproc.add_option(
1647 '--exec-before-download', metavar='CMD',
ad3dc496 1648 action='append', dest='exec_before_dl_cmd',
1e43a6f7 1649 help=optparse.SUPPRESS_HELP)
5520aa2d 1650 postproc.add_option(
c681cb5d 1651 '--no-exec-before-download',
a44ca5a4 1652 action='store_const', dest='exec_before_dl_cmd', const=None,
1e43a6f7 1653 help=optparse.SUPPRESS_HELP)
e9fade72 1654 postproc.add_option(
e167860c 1655 '--convert-subs', '--convert-sub', '--convert-subtitles',
e9fade72 1656 metavar='FORMAT', dest='convertsubtitles', default=None,
81a23040 1657 help=(
1658 'Convert the subtitles to another format (currently supported: %s) '
8dc59305 1659 '(Alias: --convert-subtitles)' % ', '.join(sorted(FFmpegSubtitlesConvertorPP.SUPPORTED_EXTS))))
8fa43c73 1660 postproc.add_option(
1661 '--convert-thumbnails',
1662 metavar='FORMAT', dest='convertthumbnails', default=None,
81a23040 1663 help=(
1664 'Convert the thumbnails to another format '
8dc59305 1665 f'(currently supported: {", ".join(sorted(FFmpegThumbnailsConvertorPP.SUPPORTED_EXTS))}). '
00bbc5f1 1666 'You can specify multiple rules using similar syntax as --remux-video'))
72755351 1667 postproc.add_option(
1668 '--split-chapters', '--split-tracks',
1669 dest='split_chapters', action='store_true', default=False,
1670 help=(
1671 'Split video into multiple files based on internal chapters. '
1672 'The "chapter:" prefix can be used with "--paths" and "--output" to '
1673 'set the output filename for the split files. See "OUTPUT TEMPLATE" for details'))
1674 postproc.add_option(
1675 '--no-split-chapters', '--no-split-tracks',
1676 dest='split_chapters', action='store_false',
1677 help='Do not split video based on chapters (default)')
7a340e0d
NA
1678 postproc.add_option(
1679 '--remove-chapters',
1680 metavar='REGEX', dest='remove_chapters', action='append',
2d9ec704 1681 help=(
1682 'Remove chapters whose title matches the given regular expression. '
5ec1b6b7 1683 'The syntax is the same as --download-sections. This option can be used multiple times'))
7a340e0d
NA
1684 postproc.add_option(
1685 '--no-remove-chapters', dest='remove_chapters', action='store_const', const=None,
1686 help='Do not remove any chapters from the file (default)')
1687 postproc.add_option(
1688 '--force-keyframes-at-cuts',
1689 action='store_true', dest='force_keyframes_at_cuts', default=False,
1690 help=(
5ec1b6b7 1691 'Force keyframes at cuts when downloading/splitting/removing sections. '
1692 'This is slow due to needing a re-encode, but the resulting video may have fewer artifacts around the cuts'))
7a340e0d
NA
1693 postproc.add_option(
1694 '--no-force-keyframes-at-cuts',
1695 action='store_false', dest='force_keyframes_at_cuts',
1696 help='Do not force keyframes around the chapters when cutting/splitting (default)')
3ae5e797 1697 _postprocessor_opts_parser = lambda key, val='': (
1698 *(item.split('=', 1) for item in (val.split(';') if val else [])),
1699 ('key', remove_end(key, 'PP')))
1700 postproc.add_option(
1701 '--use-postprocessor',
1702 metavar='NAME[:ARGS]', dest='add_postprocessors', default=[], type='str',
1703 action='callback', callback=_list_from_options_callback,
1704 callback_kwargs={
1705 'delim': None,
1706 'process': lambda val: dict(_postprocessor_opts_parser(*val.split(':', 1)))
1707 }, help=(
1708 'The (case sensitive) name of plugin postprocessors to be enabled, '
e75bb0d6 1709 'and (optionally) arguments to be passed to it, separated by a colon ":". '
3ae5e797 1710 'ARGS are a semicolon ";" delimited list of NAME=VALUE. '
1711 'The "when" argument determines when the postprocessor is invoked. '
09b49e1f 1712 'It can be one of "pre_process" (after video extraction), "after_filter" (after video passes filter), '
1713 '"before_dl" (before each video download), "post_process" (after each video download; default), '
1714 '"after_move" (after moving video file to it\'s final locations), '
ebed8b37 1715 '"after_video" (after downloading and processing all formats of a video), '
09b49e1f 1716 'or "playlist" (at end of playlist). '
3ae5e797 1717 'This option can be used multiple times to add different postprocessors'))
34a741a8 1718
7a340e0d
NA
1719 sponsorblock = optparse.OptionGroup(parser, 'SponsorBlock Options', description=(
1720 'Make chapter entries for, or remove various segments (sponsor, introductions, etc.) '
1721 'from downloaded YouTube videos using the SponsorBlock API (https://sponsor.ajay.app)'))
1722 sponsorblock.add_option(
1723 '--sponsorblock-mark', metavar='CATS',
1724 dest='sponsorblock_mark', default=set(), action='callback', type='str',
8157a09d
NA
1725 callback=_set_from_options_callback, callback_kwargs={
1726 'allowed_values': SponsorBlockPP.CATEGORIES.keys(),
1727 'aliases': {'default': ['all']}
1728 }, help=(
7a340e0d 1729 'SponsorBlock categories to create chapters for, separated by commas. '
2dd5a2e3 1730 f'Available categories are {", ".join(SponsorBlockPP.CATEGORIES.keys())}, all and default (=all). '
1731 'You can prefix the category with a "-" to exclude it. See [1] for description of the categories. '
62b58c09 1732 'E.g. --sponsorblock-mark all,-preview [1] https://wiki.sponsor.ajay.app/w/Segment_Categories'))
7a340e0d
NA
1733 sponsorblock.add_option(
1734 '--sponsorblock-remove', metavar='CATS',
1735 dest='sponsorblock_remove', default=set(), action='callback', type='str',
8157a09d
NA
1736 callback=_set_from_options_callback, callback_kwargs={
1737 'allowed_values': set(SponsorBlockPP.CATEGORIES.keys()) - set(SponsorBlockPP.POI_CATEGORIES.keys()),
1738 # Note: From https://wiki.sponsor.ajay.app/w/Types:
1739 # The filler category is very aggressive.
1740 # It is strongly recommended to not use this in a client by default.
1741 'aliases': {'default': ['all', '-filler']}
1742 }, help=(
7a340e0d
NA
1743 'SponsorBlock categories to be removed from the video file, separated by commas. '
1744 'If a category is present in both mark and remove, remove takes precedence. '
8157a09d
NA
1745 'The syntax and available categories are the same as for --sponsorblock-mark '
1746 'except that "default" refers to "all,-filler" '
1747 f'and {", ".join(SponsorBlockPP.POI_CATEGORIES.keys())} is not available'))
7a340e0d
NA
1748 sponsorblock.add_option(
1749 '--sponsorblock-chapter-title', metavar='TEMPLATE',
1750 default=DEFAULT_SPONSORBLOCK_CHAPTER_TITLE, dest='sponsorblock_chapter_title',
1751 help=(
2dd5a2e3 1752 'An output template for the title of the SponsorBlock chapters created by --sponsorblock-mark. '
1753 'The only available fields are start_time, end_time, category, categories, name, category_names. '
1754 'Defaults to "%default"'))
7a340e0d
NA
1755 sponsorblock.add_option(
1756 '--no-sponsorblock', default=False,
1757 action='store_true', dest='no_sponsorblock',
1758 help='Disable both --sponsorblock-mark and --sponsorblock-remove')
1759 sponsorblock.add_option(
1760 '--sponsorblock-api', metavar='URL',
1761 default='https://sponsor.ajay.app', dest='sponsorblock_api',
1762 help='SponsorBlock API location, defaults to %default')
1763
1764 sponsorblock.add_option(
a9e7f546 1765 '--sponskrub',
165efb82 1766 action='store_true', dest='sponskrub', default=False,
7a340e0d
NA
1767 help=optparse.SUPPRESS_HELP)
1768 sponsorblock.add_option(
a9e7f546 1769 '--no-sponskrub',
1770 action='store_false', dest='sponskrub',
7a340e0d
NA
1771 help=optparse.SUPPRESS_HELP)
1772 sponsorblock.add_option(
a9e7f546 1773 '--sponskrub-cut', default=False,
1774 action='store_true', dest='sponskrub_cut',
7a340e0d
NA
1775 help=optparse.SUPPRESS_HELP)
1776 sponsorblock.add_option(
6623ac34 1777 '--no-sponskrub-cut',
1778 action='store_false', dest='sponskrub_cut',
7a340e0d
NA
1779 help=optparse.SUPPRESS_HELP)
1780 sponsorblock.add_option(
a9e7f546 1781 '--sponskrub-force', default=False,
1782 action='store_true', dest='sponskrub_force',
7a340e0d
NA
1783 help=optparse.SUPPRESS_HELP)
1784 sponsorblock.add_option(
6623ac34 1785 '--no-sponskrub-force',
1786 action='store_true', dest='sponskrub_force',
7a340e0d
NA
1787 help=optparse.SUPPRESS_HELP)
1788 sponsorblock.add_option(
a9e7f546 1789 '--sponskrub-location', metavar='PATH',
1790 dest='sponskrub_path', default='',
7a340e0d
NA
1791 help=optparse.SUPPRESS_HELP)
1792 sponsorblock.add_option(
c76eb41b 1793 '--sponskrub-args', dest='sponskrub_args', metavar='ARGS',
1b77b347 1794 help=optparse.SUPPRESS_HELP)
a9e7f546 1795
78895bd3 1796 extractor = optparse.OptionGroup(parser, 'Extractor Options')
62bff2c1 1797 extractor.add_option(
1798 '--extractor-retries',
d6e51845 1799 dest='extractor_retries', metavar='RETRIES', default=3,
62bff2c1 1800 help='Number of retries for known extractor errors (default is %default), or "infinite"')
78895bd3 1801 extractor.add_option(
6623ac34 1802 '--allow-dynamic-mpd', '--no-ignore-dynamic-mpd',
78895bd3 1803 action='store_true', dest='dynamic_mpd', default=True,
8a51f564 1804 help='Process dynamic DASH manifests (default) (Alias: --no-ignore-dynamic-mpd)')
78895bd3 1805 extractor.add_option(
6623ac34 1806 '--ignore-dynamic-mpd', '--no-allow-dynamic-mpd',
78895bd3 1807 action='store_false', dest='dynamic_mpd',
8a51f564 1808 help='Do not process dynamic DASH manifests (Alias: --no-allow-dynamic-mpd)')
310c2ed2 1809 extractor.add_option(
1810 '--hls-split-discontinuity',
1811 dest='hls_split_discontinuity', action='store_true', default=False,
1812 help='Split HLS playlists to different formats at discontinuities such as ad breaks'
1813 )
1814 extractor.add_option(
1815 '--no-hls-split-discontinuity',
1816 dest='hls_split_discontinuity', action='store_false',
1817 help='Do not split HLS playlists to different formats at discontinuities such as ad breaks (default)')
042931a5 1818 _extractor_arg_parser = lambda key, vals='': (key.strip().lower().replace('-', '_'), [
1819 val.replace(r'\,', ',').strip() for val in re.split(r'(?<!\\),', vals)])
5d3a0e79 1820 extractor.add_option(
1821 '--extractor-args',
1822 metavar='KEY:ARGS', dest='extractor_args', default={}, type='str',
1823 action='callback', callback=_dict_from_options_callback,
1824 callback_kwargs={
1825 'multiple_keys': False,
1826 'process': lambda val: dict(
4bb6b02f 1827 _extractor_arg_parser(*arg.split('=', 1)) for arg in val.split(';'))
dbf5416a 1828 }, help=(
5d3a0e79 1829 'Pass these arguments to the extractor. See "EXTRACTOR ARGUMENTS" for details. '
4bb6b02f 1830 'You can use this option multiple times to give arguments for different extractors'))
e409895f 1831 extractor.add_option(
1832 '--youtube-include-dash-manifest', '--no-youtube-skip-dash-manifest',
1833 action='store_true', dest='youtube_include_dash_manifest', default=True,
5d3a0e79 1834 help=optparse.SUPPRESS_HELP)
e409895f 1835 extractor.add_option(
1836 '--youtube-skip-dash-manifest', '--no-youtube-include-dash-manifest',
1837 action='store_false', dest='youtube_include_dash_manifest',
5d3a0e79 1838 help=optparse.SUPPRESS_HELP)
e409895f 1839 extractor.add_option(
1840 '--youtube-include-hls-manifest', '--no-youtube-skip-hls-manifest',
1841 action='store_true', dest='youtube_include_hls_manifest', default=True,
5d3a0e79 1842 help=optparse.SUPPRESS_HELP)
e409895f 1843 extractor.add_option(
1844 '--youtube-skip-hls-manifest', '--no-youtube-include-hls-manifest',
1845 action='store_false', dest='youtube_include_hls_manifest',
5d3a0e79 1846 help=optparse.SUPPRESS_HELP)
78895bd3 1847
34a741a8 1848 parser.add_option_group(general)
be4a824d 1849 parser.add_option_group(network)
0aa10994 1850 parser.add_option_group(geo)
34a741a8
PH
1851 parser.add_option_group(selection)
1852 parser.add_option_group(downloader)
1853 parser.add_option_group(filesystem)
cfb56d1a 1854 parser.add_option_group(thumbnail)
732044af 1855 parser.add_option_group(link)
34a741a8
PH
1856 parser.add_option_group(verbosity)
1857 parser.add_option_group(workarounds)
1858 parser.add_option_group(video_format)
1859 parser.add_option_group(subtitles)
1860 parser.add_option_group(authentication)
1861 parser.add_option_group(postproc)
7a340e0d 1862 parser.add_option_group(sponsorblock)
78895bd3 1863 parser.add_option_group(extractor)
34a741a8 1864
06e57990 1865 return parser
7303f84a 1866
e66dca5e 1867
06e57990 1868def _hide_login_info(opts):
1869 write_string(
1870 'DeprecationWarning: "yt_dlp.options._hide_login_info" is deprecated and may be removed in a future version. '
1871 'Use "yt_dlp.utils.Config.hide_login_info" instead\n')
1872 return Config.hide_login_info(opts)