Updated yt_dlp version; added extremly basic dumb cache setup in thumbnailer; moved build and script as well as deb folder to build

This commit is contained in:
2026-01-07 17:34:32 -06:00
parent f58bc53c24
commit 5c808c579a
243 changed files with 6397 additions and 5957 deletions

View File

@@ -42,6 +42,8 @@ from .globals import (
plugin_pps,
all_plugins_loaded,
plugin_dirs,
supported_js_runtimes,
supported_remote_components,
)
from .minicurses import format_text
from .networking import HEADRequest, Request, RequestDirector
@@ -533,6 +535,18 @@ class YoutubeDL:
See "EXTRACTOR ARGUMENTS" for details.
Argument values must always be a list of string(s).
E.g. {'youtube': {'skip': ['dash', 'hls']}}
js_runtimes: A dictionary of JavaScript runtime keys (in lower case) to enable
and a dictionary of additional configuration for the runtime.
Currently supported runtimes are 'deno', 'node', 'bun', and 'quickjs'.
If None, the default runtime of "deno" will be enabled.
The runtime configuration dictionary can have the following keys:
- path: Path to the executable (optional)
E.g. {'deno': {'path': '/path/to/deno'}
remote_components: A list of remote components that are allowed to be fetched when required.
Supported components:
- ejs:npm (external JavaScript components from npm)
- ejs:github (external JavaScript components from yt-dlp-ejs GitHub)
By default, no remote components are allowed to be fetched.
mark_watched: Mark videos watched (even with --simulate). Only for YouTube
The following options are deprecated and may be removed in the future:
@@ -581,7 +595,7 @@ class YoutubeDL:
'width', 'height', 'asr', 'audio_channels', 'fps',
'tbr', 'abr', 'vbr', 'filesize', 'filesize_approx',
'timestamp', 'release_timestamp', 'available_at',
'duration', 'view_count', 'like_count', 'dislike_count', 'repost_count',
'duration', 'view_count', 'like_count', 'dislike_count', 'repost_count', 'save_count',
'average_rating', 'comment_count', 'age_limit',
'start_time', 'end_time',
'chapter_number', 'season_number', 'episode_number',
@@ -717,6 +731,13 @@ class YoutubeDL:
else:
raise
# Note: this must be after plugins are loaded
self.params['js_runtimes'] = self.params.get('js_runtimes', {'deno': {}})
self._clean_js_runtimes(self.params['js_runtimes'])
self.params['remote_components'] = set(self.params.get('remote_components', ()))
self._clean_remote_components(self.params['remote_components'])
self.params['compat_opts'] = set(self.params.get('compat_opts', ()))
self.params['http_headers'] = HTTPHeaderDict(std_headers, self.params.get('http_headers'))
self._load_cookies(self.params['http_headers'].get('Cookie')) # compat
@@ -829,6 +850,36 @@ class YoutubeDL:
self.archive = preload_download_archive(self.params.get('download_archive'))
def _clean_js_runtimes(self, runtimes):
if not (
isinstance(runtimes, dict)
and all(isinstance(k, str) and (v is None or isinstance(v, dict)) for k, v in runtimes.items())
):
raise ValueError('Invalid js_runtimes format, expected a dict of {runtime: {config}}')
if unsupported_runtimes := runtimes.keys() - supported_js_runtimes.value.keys():
self.report_warning(
f'Ignoring unsupported JavaScript runtime(s): {", ".join(unsupported_runtimes)}.'
f' Supported runtimes: {", ".join(supported_js_runtimes.value.keys())}.')
for rt in unsupported_runtimes:
runtimes.pop(rt)
def _clean_remote_components(self, remote_components: set):
if unsupported_remote_components := set(remote_components) - set(supported_remote_components.value):
self.report_warning(
f'Ignoring unsupported remote component(s): {", ".join(unsupported_remote_components)}.'
f' Supported remote components: {", ".join(supported_remote_components.value)}.')
for rt in unsupported_remote_components:
remote_components.remove(rt)
@functools.cached_property
def _js_runtimes(self):
runtimes = {}
for name, config in self.params.get('js_runtimes', {}).items():
runtime_cls = supported_js_runtimes.value.get(name)
runtimes[name] = runtime_cls(path=config.get('path')) if runtime_cls else None
return runtimes
def warn_if_short_id(self, argv):
# short YouTube ID starting with dash?
idxs = [
@@ -2975,6 +3026,10 @@ class YoutubeDL:
format_selector = self.format_selector
while True:
if interactive_format_selection:
if not formats:
# Bypass interactive format selection if no formats & --ignore-no-formats-error
formats_to_download = None
break
req_format = input(self._format_screen('\nEnter format selector ', self.Styles.EMPHASIS)
+ '(Press ENTER for default, or Ctrl+C to quit)'
+ self._format_screen(': ', self.Styles.EMPHASIS))
@@ -4064,6 +4119,18 @@ class YoutubeDL:
join_nonempty(*get_package_info(m)) for m in available_dependencies.values()
})) or 'none'))
if not self.params.get('js_runtimes'):
write_debug('JS runtimes: none (disabled)')
else:
write_debug('JS runtimes: %s' % (', '.join(sorted(
f'{name} (unknown)' if runtime is None
else join_nonempty(
runtime.info.name,
runtime.info.version + (' (unsupported)' if runtime.info.supported is False else ''),
)
for name, runtime in self._js_runtimes.items() if runtime is None or runtime.info is not None
)) or 'none'))
write_debug(f'Proxy map: {self.proxies}')
write_debug(f'Request Handlers: {", ".join(rh.RH_NAME for rh in self._request_director.handlers.values())}')