diff --git a/README.md b/README.md index 9f8376f592..d4f436d926 100644 --- a/README.md +++ b/README.md @@ -1424,6 +1424,7 @@ #### Not recommended --all-formats -f all --all-subs --sub-langs all --write-subs + --print-json -j --no-simulate --autonumber-size NUMBER Use string formatting. Eg: %(autonumber)03d --autonumber-start NUMBER Use internal field formatting like %(autonumber+NUMBER)s --metadata-from-title FORMAT --parse-metadata "%(title)s:FORMAT" diff --git a/yt_dlp/YoutubeDL.py b/yt_dlp/YoutubeDL.py index 5038087272..acd85af05e 100644 --- a/yt_dlp/YoutubeDL.py +++ b/yt_dlp/YoutubeDL.py @@ -198,7 +198,8 @@ class YoutubeDL(object): (or video) as a single JSON line. force_write_download_archive: Force writing download archive regardless of 'skip_download' or 'simulate'. - simulate: Do not download the video files. + simulate: Do not download the video files. If unset (or None), + simulate only if listsubtitles, listformats or list_thumbnails is used format: Video format code. see "FORMAT SELECTION" for more details. allow_unplayable_formats: Allow unplayable formats to be extracted and downloaded. ignore_no_formats_error: Ignore "No video formats" error. Usefull for @@ -706,7 +707,7 @@ def to_console_title(self, message): def save_console_title(self): if not self.params.get('consoletitle', False): return - if self.params.get('simulate', False): + if self.params.get('simulate'): return if compat_os_name != 'nt' and 'TERM' in os.environ: # Save the title on stack @@ -715,7 +716,7 @@ def save_console_title(self): def restore_console_title(self): if not self.params.get('consoletitle', False): return - if self.params.get('simulate', False): + if self.params.get('simulate'): return if compat_os_name != 'nt' and 'TERM' in os.environ: # Restore the title from stack @@ -1616,7 +1617,7 @@ def can_merge(): return merger.available and merger.can_merge() prefer_best = ( - not self.params.get('simulate', False) + not self.params.get('simulate') and download and ( not can_merge() @@ -2218,20 +2219,22 @@ def is_wellformed(f): info_dict, _ = self.pre_process(info_dict) - list_only = self.params.get('list_thumbnails') or self.params.get('listformats') or self.params.get('listsubtitles') + if self.params.get('list_thumbnails'): + self.list_thumbnails(info_dict) + if self.params.get('listformats'): + if not info_dict.get('formats'): + raise ExtractorError('No video formats found', expected=True) + self.list_formats(info_dict) + if self.params.get('listsubtitles'): + if 'automatic_captions' in info_dict: + self.list_subtitles( + info_dict['id'], automatic_captions, 'automatic captions') + self.list_subtitles(info_dict['id'], subtitles, 'subtitles') + list_only = self.params.get('simulate') is None and ( + self.params.get('list_thumbnails') or self.params.get('listformats') or self.params.get('listsubtitles')) if list_only: + # Without this printing, -F --print-json will not work self.__forced_printings(info_dict, self.prepare_filename(info_dict), incomplete=True) - if self.params.get('list_thumbnails'): - self.list_thumbnails(info_dict) - if self.params.get('listformats'): - if not info_dict.get('formats'): - raise ExtractorError('No video formats found', expected=True) - self.list_formats(info_dict) - if self.params.get('listsubtitles'): - if 'automatic_captions' in info_dict: - self.list_subtitles( - info_dict['id'], automatic_captions, 'automatic captions') - self.list_subtitles(info_dict['id'], subtitles, 'subtitles') return format_selector = self.format_selector @@ -2455,7 +2458,7 @@ def process_info(self, info_dict): # Forced printings self.__forced_printings(info_dict, full_filename, incomplete=('format' not in info_dict)) - if self.params.get('simulate', False): + if self.params.get('simulate'): if self.params.get('force_write_download_archive', False): self.record_download_archive(info_dict) diff --git a/yt_dlp/__init__.py b/yt_dlp/__init__.py index 532d004c3f..7d08120790 100644 --- a/yt_dlp/__init__.py +++ b/yt_dlp/__init__.py @@ -550,7 +550,7 @@ def report_args_compat(arg, name): 'forcejson': opts.dumpjson or opts.print_json, 'dump_single_json': opts.dump_single_json, 'force_write_download_archive': opts.force_write_download_archive, - 'simulate': opts.simulate or any_getting, + 'simulate': (any_getting or None) if opts.simulate is None else opts.simulate, 'skip_download': opts.skip_download, 'format': opts.format, 'allow_unplayable_formats': opts.allow_unplayable_formats, diff --git a/yt_dlp/options.py b/yt_dlp/options.py index e704712825..55c2b9aa3e 100644 --- a/yt_dlp/options.py +++ b/yt_dlp/options.py @@ -190,15 +190,15 @@ def _dict_from_options_callback( general.add_option( '--dump-user-agent', action='store_true', dest='dump_user_agent', default=False, - help='Display the current browser identification') + help='Display the current browser identification and exit') general.add_option( '--list-extractors', action='store_true', dest='list_extractors', default=False, - help='List all supported extractors') + help='List all supported extractors and exit') general.add_option( '--extractor-descriptions', action='store_true', dest='list_extractor_descriptions', default=False, - help='Output descriptions of all supported extractors') + help='Output descriptions of all supported extractors and exit') general.add_option( '--force-generic-extractor', action='store_true', dest='force_generic_extractor', default=False, @@ -532,7 +532,7 @@ def _dict_from_options_callback( video_format.add_option( '-F', '--list-formats', action='store_true', dest='listformats', - help='List all available formats of requested videos') + help='List available formats of each video. Simulate unless --no-simulate is used') video_format.add_option( '--list-formats-as-table', action='store_true', dest='listformats_table', default=True, @@ -583,7 +583,7 @@ def _dict_from_options_callback( subtitles.add_option( '--list-subs', action='store_true', dest='listsubtitles', default=False, - help='List all available subtitles for the video') + help='List available subtitles of each video. Simulate unless --no-simulate is used') subtitles.add_option( '--sub-format', action='store', dest='subtitlesformat', metavar='FORMAT', default='best', @@ -788,8 +788,12 @@ def _dict_from_options_callback( help='Ignore warnings') verbosity.add_option( '-s', '--simulate', - action='store_true', dest='simulate', default=False, + action='store_true', dest='simulate', default=None, help='Do not download the video and do not write anything to disk') + verbosity.add_option( + '--no-simulate', + action='store_false', dest='simulate', + help='Download the video even if printing/listing options are used') verbosity.add_option( '--ignore-no-formats-error', action='store_true', dest='ignore_no_formats_error', default=False, @@ -809,8 +813,8 @@ def _dict_from_options_callback( action='callback', dest='forceprint', type='str', default=[], callback=_list_from_options_callback, callback_kwargs={'delim': None}, help=( - 'Simulate, quiet but print the given fields. Either a field name ' - 'or similar formatting as the output template can be used')) + 'Quiet, but print the given fields for each video. Simulate unless --no-simulate is used. ' + 'Either a field name or same syntax as the output template can be used')) verbosity.add_option( '-g', '--get-url', action='store_true', dest='geturl', default=False, @@ -846,17 +850,17 @@ def _dict_from_options_callback( verbosity.add_option( '-j', '--dump-json', action='store_true', dest='dumpjson', default=False, - help='Simulate, quiet but print JSON information. See "OUTPUT TEMPLATE" for a description of available keys') + help='Quiet, but print JSON information for each video. Simulate unless --no-simulate is used. See "OUTPUT TEMPLATE" for a description of available keys') verbosity.add_option( '-J', '--dump-single-json', action='store_true', dest='dump_single_json', default=False, help=( - 'Simulate, quiet but print JSON information for each command-line argument. ' - 'If the URL refers to a playlist, dump the whole playlist information in a single line')) + 'Quiet, but print JSON information for each url or infojson passed. Simulate unless --no-simulate is used. ' + 'If the URL refers to a playlist, the whole playlist information is dumped in a single line')) verbosity.add_option( '--print-json', action='store_true', dest='print_json', default=False, - help='Be quiet and print the video information as JSON (video is still being downloaded)') + help=optparse.SUPPRESS_HELP) verbosity.add_option( '--force-write-archive', '--force-write-download-archive', '--force-download-archive', action='store_true', dest='force_write_download_archive', default=False, @@ -1127,7 +1131,7 @@ def _dict_from_options_callback( thumbnail.add_option( '--list-thumbnails', action='store_true', dest='list_thumbnails', default=False, - help='Simulate and list all available thumbnail formats') + help='List available thumbnails of each video. Simulate unless --no-simulate is used') link = optparse.OptionGroup(parser, 'Internet Shortcut Options') link.add_option(