mirror of
https://github.com/yt-dlp/yt-dlp.git
synced 2024-12-13 14:37:43 +01:00
Allow --print
to be run at any post-processing stage
This commit is contained in:
parent
e88e1febd8
commit
ed5835b451
17
README.md
17
README.md
@ -667,11 +667,13 @@ ## Verbosity and Simulation Options:
|
|||||||
--skip-download Do not download the video but write all
|
--skip-download Do not download the video but write all
|
||||||
related files (Alias: --no-download)
|
related files (Alias: --no-download)
|
||||||
-O, --print [WHEN:]TEMPLATE Field name or output template to print to
|
-O, --print [WHEN:]TEMPLATE Field name or output template to print to
|
||||||
screen per video. Prefix the template with
|
screen, optionally prefixed with when to
|
||||||
"playlist:" to print it once per playlist
|
print it, separated by a ":". Supported
|
||||||
instead. Implies --quiet and --simulate
|
values of "WHEN" are the same as that of
|
||||||
(unless --no-simulate is used). This option
|
--use-postprocessor, and "video" (default).
|
||||||
can be used multiple times
|
Implies --quiet and --simulate (unless
|
||||||
|
--no-simulate is used). This option can be
|
||||||
|
used multiple times
|
||||||
-j, --dump-json Quiet, but print JSON information for each
|
-j, --dump-json Quiet, but print JSON information for each
|
||||||
video. Simulate unless --no-simulate is
|
video. Simulate unless --no-simulate is
|
||||||
used. See "OUTPUT TEMPLATE" for a
|
used. See "OUTPUT TEMPLATE" for a
|
||||||
@ -1221,6 +1223,11 @@ # OUTPUT TEMPLATE
|
|||||||
|
|
||||||
- `urls` (string): The URLs of all requested formats, one in each line
|
- `urls` (string): The URLs of all requested formats, one in each line
|
||||||
- `filename` (string): Name of the video file. Note that the actual filename may be different due to post-processing. Use `--exec echo` to get the name after all postprocessing is complete
|
- `filename` (string): Name of the video file. Note that the actual filename may be different due to post-processing. Use `--exec echo` to get the name after all postprocessing is complete
|
||||||
|
- `formats_table` (table): The video format table as printed by `--list-formats`
|
||||||
|
- `thumbnails_table` (table): The thumbnail format table as printed by `--list-thumbnails`
|
||||||
|
- `subtitles_table` (table): The subtitle format table as printed by `--list-subs`
|
||||||
|
- `automatic_captions_table` (table): The automatic subtitle format table as printed by `--list-subs`
|
||||||
|
|
||||||
|
|
||||||
Available only in `--sponsorblock-chapter-title`:
|
Available only in `--sponsorblock-chapter-title`:
|
||||||
|
|
||||||
|
@ -1772,13 +1772,8 @@ def get_entry(i):
|
|||||||
self.prepare_filename(ie_copy, 'pl_infojson'), overwrite=True) is None:
|
self.prepare_filename(ie_copy, 'pl_infojson'), overwrite=True) is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
for tmpl in self.params['forceprint'].get('playlist', []):
|
ie_result = self.run_all_pps('playlist', ie_result)
|
||||||
self._forceprint(tmpl, ie_result)
|
self.to_screen(f'[download] Finished downloading playlist: {playlist}')
|
||||||
|
|
||||||
for pp in self._pps['playlist']:
|
|
||||||
ie_result = self.run_pp(pp, ie_result)
|
|
||||||
|
|
||||||
self.to_screen('[download] Finished downloading playlist: %s' % playlist)
|
|
||||||
return ie_result
|
return ie_result
|
||||||
|
|
||||||
@__handle_extraction_exceptions
|
@__handle_extraction_exceptions
|
||||||
@ -2600,8 +2595,7 @@ def is_wellformed(f):
|
|||||||
self.record_download_archive(info_dict)
|
self.record_download_archive(info_dict)
|
||||||
|
|
||||||
info_dict['requested_downloads'] = formats_to_download
|
info_dict['requested_downloads'] = formats_to_download
|
||||||
for pp in self._pps['after_video']:
|
info_dict = self.run_all_pps('after_video', info_dict)
|
||||||
info_dict = self.run_pp(pp, info_dict)
|
|
||||||
if max_downloads_reached:
|
if max_downloads_reached:
|
||||||
raise MaxDownloadsReached()
|
raise MaxDownloadsReached()
|
||||||
|
|
||||||
@ -3228,6 +3222,26 @@ def filter_requested_info(info_dict, actually_filter=True):
|
|||||||
''' Alias of sanitize_info for backward compatibility '''
|
''' Alias of sanitize_info for backward compatibility '''
|
||||||
return YoutubeDL.sanitize_info(info_dict, actually_filter)
|
return YoutubeDL.sanitize_info(info_dict, actually_filter)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def post_extract(info_dict):
|
||||||
|
def actual_post_extract(info_dict):
|
||||||
|
if info_dict.get('_type') in ('playlist', 'multi_video'):
|
||||||
|
for video_dict in info_dict.get('entries', {}):
|
||||||
|
actual_post_extract(video_dict or {})
|
||||||
|
return
|
||||||
|
|
||||||
|
post_extractor = info_dict.get('__post_extractor') or (lambda: {})
|
||||||
|
extra = post_extractor().items()
|
||||||
|
info_dict.update(extra)
|
||||||
|
info_dict.pop('__post_extractor', None)
|
||||||
|
|
||||||
|
original_infodict = info_dict.get('__original_infodict') or {}
|
||||||
|
original_infodict.update(extra)
|
||||||
|
original_infodict.pop('__post_extractor', None)
|
||||||
|
|
||||||
|
actual_post_extract(info_dict or {})
|
||||||
|
|
||||||
|
|
||||||
def run_pp(self, pp, infodict):
|
def run_pp(self, pp, infodict):
|
||||||
files_to_delete = []
|
files_to_delete = []
|
||||||
if '__files_to_move' not in infodict:
|
if '__files_to_move' not in infodict:
|
||||||
@ -3257,44 +3271,27 @@ def run_pp(self, pp, infodict):
|
|||||||
del infodict['__files_to_move'][old_filename]
|
del infodict['__files_to_move'][old_filename]
|
||||||
return infodict
|
return infodict
|
||||||
|
|
||||||
@staticmethod
|
def run_all_pps(self, key, info, *, additional_pps=None):
|
||||||
def post_extract(info_dict):
|
for tmpl in self.params['forceprint'].get(key, []):
|
||||||
def actual_post_extract(info_dict):
|
self._forceprint(tmpl, info)
|
||||||
if info_dict.get('_type') in ('playlist', 'multi_video'):
|
for pp in (additional_pps or []) + self._pps[key]:
|
||||||
for video_dict in info_dict.get('entries', {}):
|
info = self.run_pp(info)
|
||||||
actual_post_extract(video_dict or {})
|
return info
|
||||||
return
|
|
||||||
|
|
||||||
post_extractor = info_dict.get('__post_extractor') or (lambda: {})
|
|
||||||
extra = post_extractor().items()
|
|
||||||
info_dict.update(extra)
|
|
||||||
info_dict.pop('__post_extractor', None)
|
|
||||||
|
|
||||||
original_infodict = info_dict.get('__original_infodict') or {}
|
|
||||||
original_infodict.update(extra)
|
|
||||||
original_infodict.pop('__post_extractor', None)
|
|
||||||
|
|
||||||
actual_post_extract(info_dict or {})
|
|
||||||
|
|
||||||
def pre_process(self, ie_info, key='pre_process', files_to_move=None):
|
def pre_process(self, ie_info, key='pre_process', files_to_move=None):
|
||||||
info = dict(ie_info)
|
info = dict(ie_info)
|
||||||
info['__files_to_move'] = files_to_move or {}
|
info['__files_to_move'] = files_to_move or {}
|
||||||
for pp in self._pps[key]:
|
info = self.run_all_pps(key, info)
|
||||||
info = self.run_pp(pp, info)
|
|
||||||
return info, info.pop('__files_to_move', None)
|
return info, info.pop('__files_to_move', None)
|
||||||
|
|
||||||
def post_process(self, filename, info, files_to_move=None):
|
def post_process(self, filename, info, files_to_move=None):
|
||||||
"""Run all the postprocessors on the given file."""
|
"""Run all the postprocessors on the given file."""
|
||||||
info['filepath'] = filename
|
info['filepath'] = filename
|
||||||
info['__files_to_move'] = files_to_move or {}
|
info['__files_to_move'] = files_to_move or {}
|
||||||
|
info = self.run_all_pps('post_process', info, additional_pps=info.get('__postprocessors'))
|
||||||
for pp in info.get('__postprocessors', []) + self._pps['post_process']:
|
|
||||||
info = self.run_pp(pp, info)
|
|
||||||
info = self.run_pp(MoveFilesAfterDownloadPP(self), info)
|
info = self.run_pp(MoveFilesAfterDownloadPP(self), info)
|
||||||
del info['__files_to_move']
|
del info['__files_to_move']
|
||||||
for pp in self._pps['after_move']:
|
return self.run_all_pps('after_move', info)
|
||||||
info = self.run_pp(pp, info)
|
|
||||||
return info
|
|
||||||
|
|
||||||
def _make_archive_id(self, info_dict):
|
def _make_archive_id(self, info_dict):
|
||||||
video_id = info_dict.get('id')
|
video_id = info_dict.get('id')
|
||||||
|
@ -910,13 +910,13 @@ def _dict_from_options_callback(
|
|||||||
metavar='[WHEN:]TEMPLATE', dest='forceprint', default={}, type='str',
|
metavar='[WHEN:]TEMPLATE', dest='forceprint', default={}, type='str',
|
||||||
action='callback', callback=_dict_from_options_callback,
|
action='callback', callback=_dict_from_options_callback,
|
||||||
callback_kwargs={
|
callback_kwargs={
|
||||||
'allowed_keys': 'video|playlist',
|
'allowed_keys': 'video|' + '|'.join(map(re.escape, POSTPROCESS_WHEN)),
|
||||||
'default_key': 'video',
|
'default_key': 'video',
|
||||||
'multiple_keys': False,
|
'multiple_keys': False,
|
||||||
'append': True,
|
'append': True,
|
||||||
}, help=(
|
}, help=(
|
||||||
'Field name or output template to print to screen per video. '
|
'Field name or output template to print to screen, optionally prefixed with when to print it, separated by a ":". '
|
||||||
'Prefix the template with "playlist:" to print it once per playlist instead. '
|
'Supported values of "WHEN" are the same as that of --use-postprocessor, and "video" (default). '
|
||||||
'Implies --quiet and --simulate (unless --no-simulate is used). This option can be used multiple times'))
|
'Implies --quiet and --simulate (unless --no-simulate is used). This option can be used multiple times'))
|
||||||
verbosity.add_option(
|
verbosity.add_option(
|
||||||
'-g', '--get-url',
|
'-g', '--get-url',
|
||||||
|
Loading…
Reference in New Issue
Block a user