]> jfr.im git - yt-dlp.git/blobdiff - yt_dlp/options.py
[extractor/uktv] Improve _VALID_URL
[yt-dlp.git] / yt_dlp / options.py
index 1e23e2b98cda6327f751fbebd2c5ab77b1cbcc2a..9d75c397690ee914c09a386a4df08bf1d879cdd0 100644 (file)
 from .downloader.external import list_external_downloaders
 from .postprocessor import (
     FFmpegExtractAudioPP,
+    FFmpegMergerPP,
     FFmpegSubtitlesConvertorPP,
     FFmpegThumbnailsConvertorPP,
     FFmpegVideoRemuxerPP,
     SponsorBlockPP,
 )
 from .postprocessor.modify_chapters import DEFAULT_SPONSORBLOCK_CHAPTER_TITLE
-from .update import detect_variant
+from .update import detect_variant, is_non_updateable
 from .utils import (
     OUTTMPL_TYPES,
     POSTPROCESS_WHEN,
     Config,
     expand_path,
+    format_field,
     get_executable_path,
     join_nonempty,
     remove_end,
@@ -75,7 +77,7 @@ def add_config(label, path, user=False):
         if root.parse_known_args()[0].ignoreconfig:
             return False
         # Multiple package names can be given here
-        # Eg: ('yt-dlp', 'youtube-dlc', 'youtube-dl') will look for
+        # E.g. ('yt-dlp', 'youtube-dlc', 'youtube-dl') will look for
         # the configuration file of any of these three packages
         for package in ('yt-dlp',):
             if user:
@@ -332,11 +334,13 @@ def _alias_callback(option, opt_str, value, parser, opts, nargs):
     general.add_option(
         '-U', '--update',
         action='store_true', dest='update_self',
-        help='Update this program to latest version')
+        help=format_field(
+            is_non_updateable(), None, 'Check if updates are available. %s',
+            default='Update this program to the latest version'))
     general.add_option(
         '--no-update',
         action='store_false', dest='update_self',
-        help='Do not update (default)')
+        help='Do not check for updates (default)')
     general.add_option(
         '-i', '--ignore-errors',
         action='store_true', dest='ignoreerrors',
@@ -370,7 +374,7 @@ def _alias_callback(option, opt_str, value, parser, opts, nargs):
         dest='default_search', metavar='PREFIX',
         help=(
             'Use this prefix for unqualified URLs. '
-            'Eg: "gvsearch2:python" downloads two videos from google videos for the search term "python". '
+            'E.g. "gvsearch2:python" downloads two videos from google videos for the search term "python". '
             'Use the value "auto" to let yt-dlp guess ("auto_warning" to emit a warning when guessing). '
             '"error" just throws an error. The default value "fixup_error" repairs broken URLs, '
             'but emits an error if this is not possible instead of searching'))
@@ -455,7 +459,7 @@ def _alias_callback(option, opt_str, value, parser, opts, nargs):
         help=(
             'Create aliases for an option string. Unless an alias starts with a dash "-", it is prefixed with "--". '
             'Arguments are parsed according to the Python string formatting mini-language. '
-            'Eg: --alias get-audio,-X "-S=aext:{0},abr -x --audio-format {0}" creates options '
+            'E.g. --alias get-audio,-X "-S=aext:{0},abr -x --audio-format {0}" creates options '
             '"--get-audio" and "-X" that takes an argument (ARG0) and expands to '
             '"-S=aext:ARG0,abr -x --audio-format ARG0". All defined aliases are listed in the --help output. '
             'Alias options can trigger more aliases; so be careful to avoid defining recursive options. '
@@ -467,8 +471,8 @@ def _alias_callback(option, opt_str, value, parser, opts, nargs):
         '--proxy', dest='proxy',
         default=None, metavar='URL',
         help=(
-            'Use the specified HTTP/HTTPS/SOCKS proxy. To enable SOCKS proxy, specify a proper scheme. '
-            'Eg: socks5://user:pass@127.0.0.1:1080/. Pass in an empty string (--proxy "") for direct connection'))
+            'Use the specified HTTP/HTTPS/SOCKS proxy. To enable SOCKS proxy, specify a proper scheme, '
+            'e.g. socks5://user:pass@127.0.0.1:1080/. Pass in an empty string (--proxy "") for direct connection'))
     network.add_option(
         '--socket-timeout',
         dest='socket_timeout', type=float, default=None, metavar='SECONDS',
@@ -533,7 +537,7 @@ def _alias_callback(option, opt_str, value, parser, opts, nargs):
             'Comma separated playlist_index of the videos to download. '
             'You can specify a range using "[START]:[STOP][:STEP]". For backward compatibility, START-STOP is also supported. '
             'Use negative indices to count from the right and negative STEP to download in reverse order. '
-            'Eg: "-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'))
+            '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'))
     selection.add_option(
         '--match-title',
         dest='matchtitle', metavar='REGEX',
@@ -545,17 +549,17 @@ def _alias_callback(option, opt_str, value, parser, opts, nargs):
     selection.add_option(
         '--min-filesize',
         metavar='SIZE', dest='min_filesize', default=None,
-        help='Do not download any videos smaller than SIZE (e.g. 50k or 44.6m)')
+        help='Do not download any videos smaller than SIZE, e.g. 50k or 44.6M')
     selection.add_option(
         '--max-filesize',
         metavar='SIZE', dest='max_filesize', default=None,
-        help='Do not download any videos larger than SIZE (e.g. 50k or 44.6m)')
+        help='Do not download any videos larger than SIZE, e.g. 50k or 44.6M')
     selection.add_option(
         '--date',
         metavar='DATE', dest='date', default=None,
         help=(
             'Download only videos uploaded on this date. The date can be "YYYYMMDD" or in the format '
-            '[now|today|yesterday][-N[day|week|month|year]]. Eg: --date today-2weeks'))
+            '[now|today|yesterday][-N[day|week|month|year]]. E.g. --date today-2weeks'))
     selection.add_option(
         '--datebefore',
         metavar='DATE', dest='datebefore', default=None,
@@ -581,11 +585,11 @@ def _alias_callback(option, opt_str, value, parser, opts, nargs):
         metavar='FILTER', dest='match_filter', action='append',
         help=(
             'Generic video filter. Any "OUTPUT TEMPLATE" field can be compared with a '
-            'number or a string using the operators defined in "Filtering formats". '
+            'number or a string using the operators defined in "Filtering Formats". '
             'You can also simply specify a field to match if the field is present, '
             'use "!field" to check if the field is not present, and "&" to check multiple conditions. '
             'Use a "\\" to escape "&" or quotes if needed. If used multiple times, '
-            'the filter matches if atleast one of the conditions are met. Eg: --match-filter '
+            'the filter matches if atleast one of the conditions are met. E.g. --match-filter '
             '!is_live --match-filter "like_count>?100 & description~=\'(?i)\\bcats \\& dogs\\b\'" '
             'matches only videos that are not live OR those that have a like count more than 100 '
             '(or the like field is not available) and also has a description '
@@ -781,9 +785,9 @@ def _alias_callback(option, opt_str, value, parser, opts, nargs):
         '--merge-output-format',
         action='store', dest='merge_output_format', metavar='FORMAT', default=None,
         help=(
-            'If a merge is required (e.g. bestvideo+bestaudio), '
-            'output to given container format. One of mkv, mp4, ogg, webm, flv. '
-            'Ignored if no merge is required'))
+            'Containers that may be used when merging formats, separated by "/", e.g. "mp4/mkv". '
+            'Ignored if no merge is required. '
+            f'(currently supported: {", ".join(sorted(FFmpegMergerPP.SUPPORTED_EXTS))})'))
     video_format.add_option(
         '--allow-unplayable-formats',
         action='store_true', dest='allow_unplayable_formats', default=False,
@@ -821,14 +825,14 @@ def _alias_callback(option, opt_str, value, parser, opts, nargs):
     subtitles.add_option(
         '--sub-format',
         action='store', dest='subtitlesformat', metavar='FORMAT', default='best',
-        help='Subtitle format; accepts formats preference, Eg: "srt" or "ass/srt/best"')
+        help='Subtitle format; accepts formats preference, e.g. "srt" or "ass/srt/best"')
     subtitles.add_option(
         '--sub-langs', '--srt-langs',
         action='callback', dest='subtitleslangs', metavar='LANGS', type='str',
         default=[], callback=_list_from_options_callback,
         help=(
-            'Languages of the subtitles to download (can be regex) or "all" separated by commas. (Eg: --sub-langs "en.*,ja") '
-            'You can prefix the language code with a "-" to exclude it from the requested languages. (Eg: --sub-langs all,-live_chat) '
+            'Languages of the subtitles to download (can be regex) or "all" separated by commas, e.g. --sub-langs "en.*,ja". '
+            'You can prefix the language code with a "-" to exclude it from the requested languages, e.g. --sub-langs all,-live_chat. '
             'Use --list-subs for a list of available language tags'))
 
     downloader = optparse.OptionGroup(parser, 'Download Options')
@@ -839,11 +843,11 @@ def _alias_callback(option, opt_str, value, parser, opts, nargs):
     downloader.add_option(
         '-r', '--limit-rate', '--rate-limit',
         dest='ratelimit', metavar='RATE',
-        help='Maximum download rate in bytes per second (e.g. 50K or 4.2M)')
+        help='Maximum download rate in bytes per second, e.g. 50K or 4.2M')
     downloader.add_option(
         '--throttled-rate',
         dest='throttledratelimit', metavar='RATE',
-        help='Minimum download rate in bytes per second below which throttling is assumed and the video data is re-extracted (e.g. 100K)')
+        help='Minimum download rate in bytes per second below which throttling is assumed and the video data is re-extracted, e.g. 100K')
     downloader.add_option(
         '-R', '--retries',
         dest='retries', metavar='RETRIES', default=10,
@@ -861,14 +865,14 @@ def _alias_callback(option, opt_str, value, parser, opts, nargs):
         dest='retry_sleep', metavar='[TYPE:]EXPR', default={}, type='str',
         action='callback', callback=_dict_from_options_callback,
         callback_kwargs={
-            'allowed_keys': 'http|fragment|file_access',
+            'allowed_keys': 'http|fragment|file_access|extractor',
             'default_key': 'http',
         }, help=(
-            'An expression for the time to sleep between retries in seconds (optionally) prefixed '
-            'by the type of retry (file_access, fragment, http (default)) to apply the sleep to. '
+            'Time to sleep between retries in seconds (optionally) prefixed by the type of retry '
+            '(http (default), fragment, file_access, extractor) to apply the sleep to. '
             'EXPR can be a number, linear=START[:END[:STEP=1]] or exp=START[:END[:BASE=2]]. '
-            'This option can be used multiple times to set the sleep for the different retry types. '
-            'Eg: --retry-sleep linear=1::2 --retry-sleep fragment:exp=1:20'))
+            'This option can be used multiple times to set the sleep for the different retry types, '
+            'e.g. --retry-sleep linear=1::2 --retry-sleep fragment:exp=1:20'))
     downloader.add_option(
         '--skip-unavailable-fragments', '--no-abort-on-unavailable-fragment',
         action='store_true', dest='skip_unavailable_fragments', default=True,
@@ -888,7 +892,7 @@ def _alias_callback(option, opt_str, value, parser, opts, nargs):
     downloader.add_option(
         '--buffer-size',
         dest='buffersize', metavar='SIZE', default='1024',
-        help='Size of download buffer (e.g. 1024 or 16K) (default is %default)')
+        help='Size of download buffer, e.g. 1024 or 16K (default is %default)')
     downloader.add_option(
         '--resize-buffer',
         action='store_false', dest='noresizebuffer',
@@ -901,7 +905,7 @@ def _alias_callback(option, opt_str, value, parser, opts, nargs):
         '--http-chunk-size',
         dest='http_chunk_size', metavar='SIZE', default=None,
         help=(
-            'Size of a chunk for chunk-based HTTP downloading (e.g. 10485760 or 10M) (default is disabled). '
+            'Size of a chunk for chunk-based HTTP downloading, e.g. 10485760 or 10M (default is disabled). '
             'May be useful for bypassing bandwidth throttling imposed by a webserver (experimental)'))
     downloader.add_option(
         '--test',
@@ -959,8 +963,8 @@ def _alias_callback(option, opt_str, value, parser, opts, nargs):
         help=(
             'Download only chapters whose title matches the given regular expression. '
             'Time ranges prefixed by a "*" can also be used in place of chapters to download the specified range. '
-            'Eg: --download-sections "*10:15-15:00" --download-sections "intro". '
-            'Needs ffmpeg. This option can be used multiple times to download multiple sections'))
+            'Needs ffmpeg. This option can be used multiple times to download multiple sections, '
+            'e.g. --download-sections "*10:15-15:00" --download-sections "intro"'))
     downloader.add_option(
         '--downloader', '--external-downloader',
         dest='external_downloader', metavar='[PROTO:]NAME', default={}, type='str',
@@ -972,9 +976,9 @@ def _alias_callback(option, opt_str, value, parser, opts, nargs):
         }, help=(
             'Name or path of the external downloader to use (optionally) prefixed by '
             'the protocols (http, ftp, m3u8, dash, rstp, rtmp, mms) to use it for. '
-            f'Currently supports native, {", ".join(list_external_downloaders())}. '
+            f'Currently supports native, {", ".join(sorted(list_external_downloaders()))}. '
             'You can use this option multiple times to set different downloaders for different protocols. '
-            'For example, --downloader aria2c --downloader "dash,m3u8:native" will use '
+            'E.g. --downloader aria2c --downloader "dash,m3u8:native" will use '
             'aria2c for http/ftp downloads, and the native downloader for dash/m3u8 downloads '
             '(Alias: --external-downloader)'))
     downloader.add_option(
@@ -1184,7 +1188,7 @@ def _alias_callback(option, opt_str, value, parser, opts, nargs):
             'Template for progress outputs, optionally prefixed with one of "download:" (default), '
             '"download-title:" (the console title), "postprocess:",  or "postprocess-title:". '
             'The video\'s fields are accessible under the "info" key and '
-            'the progress attributes are accessible under "progress" key. E.g.: '
+            'the progress attributes are accessible under "progress" key. E.g. '
             # TODO: Document the fields inside "progress"
             '--console-title --progress-template "download-title:%(info.id)s-%(progress.eta)s"'))
     verbosity.add_option(
@@ -1469,7 +1473,7 @@ def _alias_callback(option, opt_str, value, parser, opts, nargs):
         '--audio-format', metavar='FORMAT', dest='audioformat', default='best',
         help=(
             'Format to convert the audio to when -x is used. '
-            f'(currently supported: best (default), {", ".join(FFmpegExtractAudioPP.SUPPORTED_EXTS)}). '
+            f'(currently supported: best (default), {", ".join(sorted(FFmpegExtractAudioPP.SUPPORTED_EXTS))}). '
             'You can specify multiple rules using similar syntax as --remux-video'))
     postproc.add_option(
         '--audio-quality', metavar='QUALITY',
@@ -1484,7 +1488,7 @@ def _alias_callback(option, opt_str, value, parser, opts, nargs):
             'Remux the video into another container if necessary '
             f'(currently supported: {", ".join(FFmpegVideoRemuxerPP.SUPPORTED_EXTS)}). '
             'If target container does not support the video/audio codec, remuxing will fail. You can specify multiple rules; '
-            'Eg. "aac>m4a/mov>mp4/mkv" will remux aac to m4a, mov to mp4 and anything else to mkv'))
+            'e.g. "aac>m4a/mov>mp4/mkv" will remux aac to m4a, mov to mp4 and anything else to mkv'))
     postproc.add_option(
         '--recode-video',
         metavar='FORMAT', dest='recodevideo', default=None,
@@ -1509,7 +1513,7 @@ def _alias_callback(option, opt_str, value, parser, opts, nargs):
             'You can also specify "PP+EXE:ARGS" to give the arguments to the specified executable '
             'only when being used by the specified postprocessor. Additionally, for ffmpeg/ffprobe, '
             '"_i"/"_o" can be appended to the prefix optionally followed by a number to pass the argument '
-            'before the specified input/output file. Eg: --ppa "Merger+ffmpeg_i1:-v quiet". '
+            'before the specified input/output file, e.g. --ppa "Merger+ffmpeg_i1:-v quiet". '
             'You can use this option multiple times to give different arguments to different '
             'postprocessors. (Alias: --ppa)'))
     postproc.add_option(
@@ -1652,13 +1656,13 @@ def _alias_callback(option, opt_str, value, parser, opts, nargs):
         metavar='FORMAT', dest='convertsubtitles', default=None,
         help=(
             'Convert the subtitles to another format (currently supported: %s) '
-            '(Alias: --convert-subtitles)' % ', '.join(FFmpegSubtitlesConvertorPP.SUPPORTED_EXTS)))
+            '(Alias: --convert-subtitles)' % ', '.join(sorted(FFmpegSubtitlesConvertorPP.SUPPORTED_EXTS))))
     postproc.add_option(
         '--convert-thumbnails',
         metavar='FORMAT', dest='convertthumbnails', default=None,
         help=(
             'Convert the thumbnails to another format '
-            f'(currently supported: {", ".join(FFmpegThumbnailsConvertorPP.SUPPORTED_EXTS)}). '
+            f'(currently supported: {", ".join(sorted(FFmpegThumbnailsConvertorPP.SUPPORTED_EXTS))}). '
             'You can specify multiple rules using similar syntax as --remux-video'))
     postproc.add_option(
         '--split-chapters', '--split-tracks',
@@ -1725,7 +1729,7 @@ def _alias_callback(option, opt_str, value, parser, opts, nargs):
             'SponsorBlock categories to create chapters for, separated by commas. '
             f'Available categories are {", ".join(SponsorBlockPP.CATEGORIES.keys())}, all and default (=all). '
             'You can prefix the category with a "-" to exclude it. See [1] for description of the categories. '
-            'Eg: --sponsorblock-mark all,-preview [1] https://wiki.sponsor.ajay.app/w/Segment_Categories'))
+            'E.g. --sponsorblock-mark all,-preview [1] https://wiki.sponsor.ajay.app/w/Segment_Categories'))
     sponsorblock.add_option(
         '--sponsorblock-remove', metavar='CATS',
         dest='sponsorblock_remove', default=set(), action='callback', type='str',