mirror of
https://github.com/yt-dlp/yt-dlp.git
synced 2025-08-02 08:08:44 +02:00
Improved progress reporting (See desc) (#1125)
* Separate `--console-title` and `--no-progress` * Add option `--progress` to show progress-bar even in quiet mode * Fix and refactor `minicurses` * Use `minicurses` for all progress reporting * Standardize use of terminal sequences and enable color support for windows 10 * Add option `--progress-template` to customize progress-bar and console-title * Add postprocessor hooks and progress reporting Closes: #906, #901, #1085, #1170
This commit is contained in:
parent
fee3f44f5f
commit
819e05319b
14 changed files with 301 additions and 206 deletions
|
@ -1,5 +1,6 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
import copy
|
||||
import functools
|
||||
import os
|
||||
|
||||
|
@ -11,7 +12,26 @@ from ..utils import (
|
|||
)
|
||||
|
||||
|
||||
class PostProcessor(object):
|
||||
class PostProcessorMetaClass(type):
|
||||
@staticmethod
|
||||
def run_wrapper(func):
|
||||
@functools.wraps(func)
|
||||
def run(self, info, *args, **kwargs):
|
||||
self._hook_progress({'status': 'started'}, info)
|
||||
ret = func(self, info, *args, **kwargs)
|
||||
if ret is not None:
|
||||
_, info = ret
|
||||
self._hook_progress({'status': 'finished'}, info)
|
||||
return ret
|
||||
return run
|
||||
|
||||
def __new__(cls, name, bases, attrs):
|
||||
if 'run' in attrs:
|
||||
attrs['run'] = cls.run_wrapper(attrs['run'])
|
||||
return type.__new__(cls, name, bases, attrs)
|
||||
|
||||
|
||||
class PostProcessor(metaclass=PostProcessorMetaClass):
|
||||
"""Post Processor class.
|
||||
|
||||
PostProcessor objects can be added to downloaders with their
|
||||
|
@ -34,7 +54,9 @@ class PostProcessor(object):
|
|||
_downloader = None
|
||||
|
||||
def __init__(self, downloader=None):
|
||||
self._downloader = downloader
|
||||
self._progress_hooks = []
|
||||
self.add_progress_hook(self.report_progress)
|
||||
self.set_downloader(downloader)
|
||||
self.PP_NAME = self.pp_key()
|
||||
|
||||
@classmethod
|
||||
|
@ -68,6 +90,10 @@ class PostProcessor(object):
|
|||
def set_downloader(self, downloader):
|
||||
"""Sets the downloader for this PP."""
|
||||
self._downloader = downloader
|
||||
if not downloader:
|
||||
return
|
||||
for ph in downloader._postprocessor_hooks:
|
||||
self.add_progress_hook(ph)
|
||||
|
||||
@staticmethod
|
||||
def _restrict_to(*, video=True, audio=True, images=True):
|
||||
|
@ -115,6 +141,39 @@ class PostProcessor(object):
|
|||
return _configuration_args(
|
||||
self.pp_key(), self.get_param('postprocessor_args'), exe, *args, **kwargs)
|
||||
|
||||
def _hook_progress(self, status, info_dict):
|
||||
if not self._progress_hooks:
|
||||
return
|
||||
info_dict = dict(info_dict)
|
||||
for key in ('__original_infodict', '__postprocessors'):
|
||||
info_dict.pop(key, None)
|
||||
status.update({
|
||||
'info_dict': copy.deepcopy(info_dict),
|
||||
'postprocessor': self.pp_key(),
|
||||
})
|
||||
for ph in self._progress_hooks:
|
||||
ph(status)
|
||||
|
||||
def add_progress_hook(self, ph):
|
||||
# See YoutubeDl.py (search for postprocessor_hooks) for a description of this interface
|
||||
self._progress_hooks.append(ph)
|
||||
|
||||
def report_progress(self, s):
|
||||
s['_default_template'] = '%(postprocessor)s %(status)s' % s
|
||||
|
||||
progress_dict = s.copy()
|
||||
progress_dict.pop('info_dict')
|
||||
progress_dict = {'info': s['info_dict'], 'progress': progress_dict}
|
||||
|
||||
progress_template = self.get_param('progress_template', {})
|
||||
tmpl = progress_template.get('postprocess')
|
||||
if tmpl:
|
||||
self._downloader.to_stdout(self._downloader.evaluate_outtmpl(tmpl, progress_dict))
|
||||
|
||||
self._downloader.to_console_title(self._downloader.evaluate_outtmpl(
|
||||
progress_template.get('postprocess-title') or 'yt-dlp %(progress._default_template)s',
|
||||
progress_dict))
|
||||
|
||||
|
||||
class AudioConversionError(PostProcessingError):
|
||||
pass
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue