Skip to content

yt-dlp Integration

VDL uses yt-dlp for media extraction and playlist resolution. This document explains VDL's strategy for stability and upgrading.

Stable Baseline

VDL pins a minimum yt-dlp version in pyproject.toml:

dependencies = [
    "yt-dlp >= 2024.01.01",
]

This is the tested baseline. VDL should work with newer versions, but the baseline version is the one CI validates against.

yt-dlp Versions

  • Stable (main branch) — released, battle-tested
  • Nightly (master branch) — development builds, latest features

VDL uses the stable channel by default. For latest features:

pip install --upgrade yt-dlp

Or configure the channel:

vdl config set ytdlp_channel nightly

Testing Strategy

Job Channel Purpose
vdl-test Stable (pinned) Required; gates release
vdl-test-ytdlp-latest Latest stable Advisory; detects breakage
vdl-test-ytdlp-nightly Nightly Optional; test upcoming features

YtDlpCapabilities Detection

VDL detects yt-dlp features at runtime:

from vdl.ytdlp import detect_ytdlp_capabilities

caps = detect_ytdlp_capabilities()
print(f"Version: {caps.version}")
print(f"Channel: {caps.channel}")
print(f"Supports concurrent_fragments: {caps.supports_concurrent_fragments}")
print(f"Supports cookies_from_browser: {caps.supports_cookies_from_browser}")

Capabilities detected: - available — yt-dlp can be imported - version — version string - channel — stable, nightly, or unknown - supports_extractor_args — custom per-extractor options - supports_concurrent_fragments — parallel fragment downloads - supports_cookies_from_browser — browser cookie extraction - impersonation — impersonate browser clients - js_runtime — available JS runtime (deno, node, ejs)

YtDlpAdapter

All yt-dlp option construction is encapsulated in YtDlpAdapter:

class YtDlpAdapter:
    def build_download_opts(request, output_dir, ...) -> dict: ...
    def build_resolve_opts(extract_flat, cookies, ...) -> dict: ...
    def is_bot_error(output: str) -> bool: ...
    def initial_retry_level(has_cookies: bool) -> int: ...

This is the only place where yt-dlp's dict-based API is used. All downstream code works with VDL's models.

Quality Mapping

Quality enum values map to yt-dlp format selectors:

VDL Quality yt-dlp Format
BEST bestvideo+bestaudio/best
P2160 Format selector for 2160p
P1440 Format selector for 1440p
P1080 Format selector for 1080p
P720 Format selector for 720p
P480 Format selector for 480p
MEDIUM ~480p fallback
LOW Lowest quality
AUDIO bestaudio (audio only)

Retry Strategy

Downloads use a 3-level retry strategy:

Level 0: Standard options Level 1: Alternate YouTube clients (tv, mweb) — for bot detection Level 2: With cookies — for authentication

Each level escalates only if the previous level fails. This balances fast normal operation with handling difficult sites.

Config Fields Affecting yt-dlp

Config Key yt-dlp Impact
concurrent_fragments --fragment-threads
write_info_json Save .info.json sidecar
extractor_args Per-extractor options
ytdlp_channel Informational; used for versioning
js_runtime_path Path to node/deno for JS extraction

JS Runtime Detection

VDL detects available JavaScript runtimes in this order:

  1. deno (preferred)
  2. node / nodejs
  3. yt-dlp-ejs (embedded fallback)

Override with:

vdl config set js_runtime_path /usr/bin/node

doctor Output

vdl doctor reports yt-dlp status:

Tool       | Status | Version
-----------|--------|----────
yt-dlp     | ✓      | 2024.01.15
js-runtime | ✓      | node 20.1.0

If yt-dlp is missing, exit code is 1.

Updating yt-dlp

Manually

pip install --upgrade yt-dlp
vdl doctor  # Verify

Via Binary Installer

The standalone binary includes a pinned yt-dlp. Reinstall to upgrade:

curl -fsSL https://bildcraft.gitlab.io/products/video-downloader/vdl/install.sh | sh
vdl --version
vdl doctor

In Development

uv sync --upgrade yt-dlp
PYTHONPATH=src uv run pytest -q

When to Upgrade

  • Security fixes — always
  • New site support — if you use that site
  • Feature additions — if you want the feature
  • Major version updates — test thoroughly before relying on new features

Troubleshooting

"yt-dlp not found"

pip install yt-dlp
vdl doctor

"Unsupported URL" or "Age restricted"

Try with cookies:

vdl download "URL" --cookies-from-browser firefox

Or upgrade yt-dlp:

pip install --upgrade yt-dlp

"Bot detected"

VDL will automatically retry with alternate YouTube clients. If still blocked:

vdl download "URL" --cookies-from-browser chrome

See Also