Compare commits

...

6 Commits

Author SHA1 Message Date
Simon Sawicki
70f8a36c40
Merge 38b7cf5157 into f2a4983df7 2024-11-13 13:19:12 +09:00
Simon Sawicki
38b7cf5157
docs 2024-11-12 21:27:39 +01:00
Simon Sawicki
429c8cf520
merge master 2024-11-12 21:16:44 +01:00
Simon Sawicki
cc6bb9a343
Add _percent on 'finished' 2024-08-03 23:23:16 +02:00
Simon Sawicki
e3b8dde035
Remove usage of compat_os_name while we are at it 2024-08-03 23:17:39 +02:00
Simon Sawicki
a9c92c4ee4
[core] Support emitting ConEmu progress codes 2024-08-03 23:10:55 +02:00
3 changed files with 50 additions and 23 deletions

View File

@ -26,7 +26,7 @@ import unicodedata
from .cache import Cache
from .compat import urllib # isort: split
from .compat import compat_os_name, urllib_req_to_req
from .compat import urllib_req_to_req
from .cookies import CookieLoadError, LenientSimpleCookie, load_cookies
from .downloader import FFmpegFD, get_suitable_downloader, shorten_protocol_name
from .downloader.rtmp import rtmpdump_version
@ -167,7 +167,7 @@ from .utils.networking import (
)
from .version import CHANNEL, ORIGIN, RELEASE_GIT_HEAD, VARIANT, __version__
if compat_os_name == 'nt':
if os.name == 'nt':
import ctypes
@ -638,20 +638,19 @@ class YoutubeDL:
self.cache = Cache(self)
self.__header_cookies = []
try:
windows_enable_vt_mode()
except Exception as e:
self.write_debug(f'Failed to enable VT mode: {e}')
stdout = sys.stderr if self.params.get('logtostderr') else sys.stdout
self._out_files = Namespace(
out=stdout,
error=sys.stderr,
screen=sys.stderr if self.params.get('quiet') else stdout,
console=None if compat_os_name == 'nt' else next(
filter(supports_terminal_sequences, (sys.stderr, sys.stdout)), None),
console=next(filter(supports_terminal_sequences, (sys.stderr, sys.stdout)), None),
)
try:
windows_enable_vt_mode()
except Exception as e:
self.write_debug(f'Failed to enable VT mode: {e}')
if self.params.get('no_color'):
if self.params.get('color') is not None:
self.params.setdefault('_warnings', []).append(
@ -952,21 +951,18 @@ class YoutubeDL:
self._write_string(f'{self._bidi_workaround(message)}\n', self._out_files.error, only_once=only_once)
def _send_console_code(self, code):
if compat_os_name == 'nt' or not self._out_files.console:
return
if not supports_terminal_sequences(self._out_files.console):
return False
self._write_string(code, self._out_files.console)
return True
def to_console_title(self, message):
if not self.params.get('consoletitle', False):
if not self.params.get('consoletitle'):
return
message = remove_terminal_sequences(message)
if compat_os_name == 'nt':
if ctypes.windll.kernel32.GetConsoleWindow():
# c_wchar_p() might not be necessary if `message` is
# already of type unicode()
ctypes.windll.kernel32.SetConsoleTitleW(ctypes.c_wchar_p(message))
else:
self._send_console_code(f'\033]0;{message}\007')
if not self._send_console_code(f'\033]0;{message}\007'):
if os.name == 'nt' and ctypes.windll.kernel32.GetConsoleWindow():
ctypes.windll.kernel32.SetConsoleTitleW(message)
def save_console_title(self):
if not self.params.get('consoletitle') or self.params.get('simulate'):
@ -980,6 +976,10 @@ class YoutubeDL:
def __enter__(self):
self.save_console_title()
if self.params.get('consoletitle'):
# Set progress to "indeterminate"
# See: https://conemu.github.io/en/AnsiEscapeCodes.html#ConEmu_specific_OSC
self._send_console_code('\033]9;4;3;0\007')
return self
def save_cookies(self):
@ -988,6 +988,10 @@ class YoutubeDL:
def __exit__(self, *args):
self.restore_console_title()
if self.params.get('consoletitle'):
# Set progress to "disabled"
# See: https://conemu.github.io/en/AnsiEscapeCodes.html#ConEmu_specific_OSC
self._send_console_code('\033]9;4;0;0\007')
self.close()
def close(self):

View File

@ -337,6 +337,16 @@ class FileDownloader:
progress_template.get('download-title') or 'yt-dlp %(progress._default_template)s',
progress_dict))
percent = s.get('_percent')
if s['status'] not in ('downloading', 'error', 'finished') or percent is None:
return
# Emit ConEmu progress codes: https://conemu.github.io/en/AnsiEscapeCodes.html#ConEmu_specific_OSC
if s['status'] == 'finished':
self.ydl._send_console_code('\033]9;4;3;0\007')
return
state = 1 if s['status'] == 'downloading' else 2
self.ydl._send_console_code(f'\033]9;4;{state};{int(percent)}\007')
def _format_progress(self, *args, **kwargs):
return self.ydl._format_text(
self._multiline.stream, self._multiline.allow_colors, *args, **kwargs)
@ -359,6 +369,7 @@ class FileDownloader:
'_speed_str': self.format_speed(speed).strip(),
'_total_bytes_str': _format_bytes('total_bytes'),
'_elapsed_str': self.format_seconds(s.get('elapsed')),
'_percent': 100.0,
'_percent_str': self.format_percent(100),
})
self._report_progress_status(s, join_nonempty(
@ -377,13 +388,15 @@ class FileDownloader:
return
self._progress_delta_time += update_delta
progress = try_call(
lambda: 100 * s['downloaded_bytes'] / s['total_bytes'],
lambda: 100 * s['downloaded_bytes'] / s['total_bytes_estimate'],
lambda: s['downloaded_bytes'] == 0 and 0)
s.update({
'_eta_str': self.format_eta(s.get('eta')).strip(),
'_speed_str': self.format_speed(s.get('speed')),
'_percent_str': self.format_percent(try_call(
lambda: 100 * s['downloaded_bytes'] / s['total_bytes'],
lambda: 100 * s['downloaded_bytes'] / s['total_bytes_estimate'],
lambda: s['downloaded_bytes'] == 0 and 0)),
'_percent': progress,
'_percent_str': self.format_percent(progress),
'_total_bytes_str': _format_bytes('total_bytes'),
'_total_bytes_estimate_str': _format_bytes('total_bytes_estimate'),
'_downloaded_bytes_str': _format_bytes('downloaded_bytes'),

View File

@ -192,6 +192,16 @@ class PostProcessor(metaclass=PostProcessorMetaClass):
progress_template.get('postprocess-title') or 'yt-dlp %(progress._default_template)s',
progress_dict))
percent = s.get('_percent')
if s['status'] not in ('downloading', 'error', 'finished') or percent is None:
return
# Emit ConEmu progress codes: https://conemu.github.io/en/AnsiEscapeCodes.html#ConEmu_specific_OSC
if s['status'] == 'finished':
self._downloader._send_console_code('\033]9;4;3;0\007')
return
state = 1 if s['status'] == 'downloading' else 2
self._downloader._send_console_code(f'\033]9;4;{state};{int(percent)}\007')
def _retry_download(self, err, count, retries):
# While this is not an extractor, it behaves similar to one and
# so obey extractor_retries and "--retry-sleep extractor"