- name
- youtube-downloader
- description
- Download YouTube videos when yt-dlp's normal authentication methods fail (DPAPI errors, App-Bound Encryption, expired cookies, bot detection). Uses Chrome CDP to extract live cookies from a pre-configured Chrome profile, combined with bgutil PoToken provider. Triggers when user mentions "download YouTube", "yt-dlp failed", "youtube cookie", "can't download youtube", "sign in to confirm you're not a bot", or any YouTube download that hits authentication walls.
# YouTube Downloader via CDP + PoToken
When yt-dlp fails with "Sign in to confirm you're not a bot" or DPAPI errors,
this skill provides a reliable fallback: extract live authentication cookies
from a pre-configured Chrome profile via CDP, combine with bgutil PoToken
provider, and download with yt-dlp.
## Prerequisites
- **Chrome** with a pre-configured profile that is logged into YouTube
- **bgutil PoToken server** running on port 4416 (see Step 0)
- **yt-dlp** installed and configured with bgutil plugin
- **websocket-client** Python package (`pip install websocket-client`)
## Workflow
### Step 0: Ensure bgutil server is running
The bgutil PoToken provider MUST be running for yt-dlp to bypass bot detection.
Check and start if needed:
```bash
bgutil-start
```
This script (at `E:\tools\bin\bgutil-start.cmd`) checks if the server is already
running on port 4416, and starts it if not. The bgutil HTTP plugin
(`bgutil:http`) auto-registers with yt-dlp.
### Step 1: Launch Chrome with CDP
Launch Chrome using a pre-configured profile that is **already logged into YouTube**.
The profile path is configurable; default is `G:\chrome_data\remote_debug`.
**Command (Windows PowerShell):**
```powershell
# Kill existing Chrome first if needed
Get-Process chrome -ErrorAction SilentlyContinue | Stop-Process -Force
Start-Sleep 2
# Launch with remote debugging
$chromePath = "C:\Program Files\Google\Chrome\Application\chrome.exe"
$profilePath = $env:CDP_CHROME_PROFILE ?? "G:\chrome_data\remote_debug"
Start-Process $chromePath -ArgumentList `
"--remote-debugging-port=9223",
"--user-data-dir=`"$profilePath`"",
"--remote-allow-origins=*",
"about:blank"
Start-Sleep 4
# Verify CDP is responding
Invoke-WebRequest -Uri "http://127.0.0.1:9223/json/version" -UseBasicParsing
```
**Important**: The profile must already be logged into YouTube.
YouTube's bot detection blocks login attempts from automated browsers,
so you cannot log in through CDP — the login session must already exist.
### Step 2: Extract cookies via CDP
Use the bundled script `scripts/extract_cookies.py` to pull live YouTube
cookies through CDP's `Network.getCookies` API:
```bash
python scripts/extract_cookies.py \
--port 9223 \
--output G:\cookies\youtube_cdp.txt \
--domain youtube.com
```
**What this script does:**
1. Connects to Chrome CDP WebSocket
2. Navigates to YouTube to ensure the cookie jar is populated
3. Calls `Network.getCookies` for youtube.com
4. Converts to Netscape format (compatible with yt-dlp `--cookies`)
5. Saves to the specified output file
### Step 3: Download with yt-dlp
With cookies extracted and bgutil running, yt-dlp should succeed:
```bash
yt-dlp "https://www.youtube.com/watch?v=VIDEO_ID" \
-o "output.mp4" \
--no-playlist \
-f "best[ext=mp4]/best" \
--cookies "G:\cookies\youtube_cdp.txt"
```
The bgutil HTTP plugin (`bgutil:http`) is auto-detected by yt-dlp when the
plugin is installed in `%APPDATA%\yt-dlp\plugins\extractor\`. It connects
to `http://127.0.0.1:4416` for PoToken generation.
## Configuration
| Environment Variable | Default | Description |
|---|---|---|
| `CDP_CHROME_PROFILE` | `G:\chrome_data\remote_debug` | Chrome profile path with YouTube login |
| `CDP_PORT` | `9223` | Chrome DevTools Protocol port |
## Troubleshooting
### "Chrome CDP not responding"
- Ensure no other Chrome instance is using the same profile
- Kill all Chrome processes and retry
- Verify the profile path exists and contains a valid Chrome session
### "bgutil server not available"
- Run `bgutil-start` to check/start the server
- Verify `http://127.0.0.1:4416/ping` returns JSON
- Check the plugin is installed: `%APPDATA%\yt-dlp\plugins\extractor\getpot_bgutil_http.py`
### "Cookies expired / not authenticated"
- The Chrome profile's YouTube login session may have expired
- Open Chrome normally with that profile, log into YouTube, then close Chrome
- Re-run from Step 1
### "Sign in to confirm you're not a bot" (despite cookies)
- Ensure bgutil server IS running (Step 0 was skipped?)
- Try `--extractor-args "youtube:player-client=mweb"` for different client
- The IP may be rate-limited; wait a few minutes
## Why This Works
1. **Cookies via CDP** bypasses Chrome's App-Bound Encryption (v20 cookies)
which prevents yt-dlp's `--cookies-from-browser` from decrypting cookies
2. **Pre-logged-in profile** avoids YouTube's automated-browser detection
(we only extract existing cookies, never attempt login via CDP)
3. **bgutil PoToken** provides the GVS PO Token that modern YouTube clients
require, complementing the authentication cookies
4. **Netscape format** is the standard cookie format yt-dlp expects
Ver en GitHub