Switch bundled yt-dlp to a Python venv with curl_cffi for impersonation

The previous standalone PyInstaller binary couldn't run `--impersonate`
because curl_cffi isn't packaged into it. Bundled mode lost the
bot-detection bypass as a result.

Install layout is now:
  ~/.local/share/yt-offline/
    bin/deno              ← unchanged: prepended to PATH for JS deciphering
    venv/bin/yt-dlp       ← new: pip-installed yt-dlp[default] + curl_cffi

The install script:
- Errors clearly if python3 or the `venv` module isn't available
  (the latter is split out on Debian as `python3-venv`).
- Creates the venv if missing, otherwise reuses it for upgrades.
- pip-installs `yt-dlp[default]` and `curl_cffi`, both with PyPI's
  built-in SHA-256 verification.
- Cleans up the legacy `bin/yt-dlp` PyInstaller binary if a prior
  install left one behind.
- Probes `--list-impersonate-targets` at the end and logs whether
  curl_cffi loaded successfully.

Downloader::apply_impersonation now passes --impersonate
unconditionally — both bundled (via the venv) and system yt-dlp (via
pip-installed curl_cffi) honor it.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Luna 2026-05-24 23:17:27 -07:00
parent 26bf619a23
commit 770ef66623
3 changed files with 148 additions and 124 deletions

View file

@ -184,14 +184,13 @@ impl Downloader {
}
}
/// Append `--impersonate Chrome-146:Macos-26` only when the active yt-dlp
/// supports it. The standalone PyInstaller binary we ship as the bundled
/// option doesn't include `curl_cffi`, so passing `--impersonate` to it
/// errors out with `Impersonate target "chrome-146:macos-26" is not
/// available`. System yt-dlp (typically pip-installed with curl_cffi)
/// works fine.
/// Append `--impersonate Chrome-146:Macos-26` to bypass YouTube's bot
/// detection. Both the bundled venv (which pip-installs `curl_cffi` via
/// [`ytdlp_bin::install_command`]) and a system yt-dlp with curl_cffi
/// support this. We leave it on unconditionally now; yt-dlp's
/// `--list-impersonate-targets` warning surfaces in the install log if
/// curl_cffi is unavailable, so the user has a clear path forward.
fn apply_impersonation(&self, cmd: &mut Command) {
if self.use_bundled_ytdlp { return; }
cmd.arg("--impersonate").arg("Chrome-146:Macos-26");
}