npx skills add ...
npx skills add daymade/claude-code-skills --skill youtube-downloader
Download YouTube videos and HLS streams (m3u8) from platforms like Mux, Vimeo, etc. using yt-dlp and ffmpeg. Use this skill when users request downloading videos, extracting audio, handling protected streams with authentication headers, or troubleshooting download issues like nsig extraction failures, 403 errors, or cookie extraction problems.
npx skills add daymade/claude-code-skills --skill youtube-downloader
Enable reliable video and audio downloads from YouTube and HLS streaming platforms (Mux, Vimeo, etc.) using yt-dlp and ffmpeg. This skill provides workflows for:
Assume the user is non-technical. Do not ask them to run commands. Execute everything yourself and report progress in plain language. Avoid mentioning tooling unless the user asks.
Default flow:
Offer choices in user-friendly terms:
Always render the thumbnail when available:
.Ask before doing extra work:
Legal/Safety reminder (brief):
Response template (use plain language, no commands):
If the user says “just download”:
Follow this SOP to avoid common failures and confusion:
? as a glob). Example: 'https://www.youtube.com/watch?v=VIDEO_ID'.web_safari player client. Otherwise prefer mweb for PO tokens.scripts/download_video.py URL --info (add --cookies-from-browser chrome if permission granted) to fetch metadata and thumbnail.--subtitles and the requested --sub-lang.web_safari.--auto-po-token default). Fail fast if it cannot start.host.docker.internal for Docker.This skill should be invoked when users:
If not installed or outdated (< 2025.10.22):
Critical: Outdated yt-dlp versions cause nsig extraction failures and missing formats.
Before downloading, check available formats:
If only format 18 (360p) appears: PO token provider setup needed for high-quality access.
For 1080p/1440p/4K access, install a PO token provider plugin into yt-dlp's Python environment:
Verification: Run yt-dlp -F "VIDEO_URL" again. Look for formats 137 (1080p), 271 (1440p), or 313 (4K).
See references/po-token-setup.md for detailed setup instructions and troubleshooting.
Once PO token provider is installed:
Expected output for 1080p:
If PO token provider setup is problematic, use browser cookies:
Benefits: Access to age-restricted and members-only content. Requirements:
Extract audio as MP3:
YouTube high-quality downloads often use WebM format (VP9 codec). Convert to MP4 for wider compatibility:
Parameters explained:
-c:v libx264: Use H.264 video codec (widely compatible)-preset medium: Balance between encoding speed and file size-crf 23: Constant Rate Factor for quality (18-28 range, lower = better quality)-c:a aac: Use AAC audio codec-b:a 128k: Audio bitrate 128 kbpsTip: Conversion maintains 1080p resolution and provides ~6x encoding speed on modern hardware.
Cause: Missing PO token provider or outdated yt-dlp.
Solution:
brew upgrade yt-dlpCause: YouTube requires authentication to proceed.
Solution:
--cookies-from-browser chrome).web_safari client if needed.Cause: PO tokens not applied or provider/browser verification failed.
Solution:
web_safari client and retry.Symptoms:
Solution:
yt-dlp --extractor-args "youtube:player_client=android" "VIDEO_URL"Cause: Proxy or network instability.
Solution:
For users in China or behind restrictive proxies:
Action: Ignore if download succeeds. This indicates Android client has limited format access without PO tokens.
Use this convenience wrapper to auto-start a PO Token provider by default for high-quality downloads. Use it yourself and report results to the user without asking them to run commands.
Basic usage:
Arguments:
url - YouTube video URL (required)-o, --output-dir - Output directory--output-template - Output filename template (yt-dlp syntax)-f, --format - Format specification-q, --quality - Quality preset (best, 1080p, 720p, 480p, 360p, worst). Default: best (skipped for --audio-only)-a, --audio-only - Extract audio as MP3--subtitles - Download subtitles if available--sub-lang - Subtitle languages (comma-separated, default: en)--cookies-from-browser - Load cookies from a browser (e.g., chrome, firefox)--cookies-file - Load cookies from a cookies.txt file--player-client - Use a specific YouTube player client (e.g., web_safari)--auto-po-token - Auto-start PO Token provider (default; uses Docker if available, otherwise switches to browser-based provider)--no-auto-po-token - Disable auto PO Token setup--proxy - Proxy URL for yt-dlp and the PO Token provider (e.g., http://127.0.0.1:1082)--wpc-browser-path - Browser executable path for WPC provider-F, --list-formats - List available formats--merge-format - Merge output container (e.g., mp4, mkv). Default: mp4--playlist - Allow playlist downloads (default: single video only)--info - Print title/uploader/duration/thumbnail and exit--no-android-client - Disable Android client fallbackNote: Use the Android client only when PO tokens are disabled. Keep PO tokens enabled for high quality.
| Setup | 360p | 720p | 1080p | 1440p | 4K |
|---|---|---|---|---|---|
| Auto PO token (default) | ✓ | ✓ | ✓ | ✓ | ✓ |
| Android client only | ✓ | ✗ | ✗ | ✗ | ✗ |
| PO token provider (manual) | ✓ | ✓ | ✓ | ✓ | ✓ |
| Browser cookies | ✓ | ✓ | ✓ | ✓ | ✓ |
For streaming platforms like Mux, Vimeo, and other HLS-based services, use ffmpeg as the primary tool. These streams often require authentication headers that yt-dlp may not handle correctly.
HLS streams use .m3u8 playlist files:
Get the m3u8 URL from the video source. For protected streams:
Many CDNs require authentication headers:
https://maven.com/)Check the Network tab to see which headers the browser sends.
Use ffmpeg with the -headers flag for protected streams:
Key parameters:
-headers: Set HTTP headers (critical for authentication)-protocol_whitelist: Enable required protocols for HLS-c copy: Stream copy (no re-encoding, faster)-bsf:a aac_adtstoasc: Fix AAC audio compatibilityCommon header patterns:
Some platforms (like Mux) deliver audio and video separately:
Cause: Missing or incorrect authentication headers.
Solution:
Symptom: Extracting cookies from chrome hangs indefinitely.
Solution: Use ffmpeg directly instead of yt-dlp for HLS streams.
Error: Protocol 'https' not on whitelist 'file,crypto,data'
Solution: Add -protocol_whitelist file,http,https,tcp,tls,crypto,httpproxy
Cause: Expired signatures in the m3u8 URLs.
Solution:
-c copy (fastest)references/po-token-setup.md for detailed installation and troubleshootingreferences/internal-sop.md — the short list of yt-dlp failures that look like something else (URLs unquoted in zsh, proxy not reaching the PO Token provider). Read it first when a download fails for no obvious reasonAfter downloading, if the user's goal involves getting text from the video (transcription, subtitles, meeting notes), proactively suggest:
brew upgrade yt-dlp # macOS
# or
pip install --upgrade yt-dlp # Cross-platformyt-dlp -F "https://youtu.be/VIDEO_ID"# Find yt-dlp's Python path (interpreter used by yt-dlp)
head -1 $(which yt-dlp)
# Install plugin using the interpreter from the line above
<YTDLP_PYTHON> -m pip install bgutil-ytdlp-pot-provider# Download best quality up to 1080p
yt-dlp -f "bestvideo[height<=1080]+bestaudio/best" "VIDEO_URL"
# Download best available quality (4K if available)
yt-dlp -f "bestvideo+bestaudio/best" "VIDEO_URL"# Check video resolution
ffprobe -v error -select_streams v:0 -show_entries stream=width,height,codec_name -of default=noprint_wrappers=1 video.mp4codec_name=vp9
width=1920
height=1080# Firefox
yt-dlp --cookies-from-browser firefox -f "bestvideo[height<=1080]+bestaudio/best" "VIDEO_URL"
# Chrome
yt-dlp --cookies-from-browser chrome -f "bestvideo[height<=1080]+bestaudio/best" "VIDEO_URL"yt-dlp -x --audio-format mp3 "VIDEO_URL"yt-dlp -P ~/Downloads/YouTube "VIDEO_URL"yt-dlp --write-subs --sub-lang en "VIDEO_URL"yt-dlp -f "bestvideo[height<=1080]+bestaudio/best" "PLAYLIST_URL"# Check if ffmpeg is installed
which ffmpeg || brew install ffmpeg # macOS
# Convert WebM to MP4 with good quality settings
ffmpeg -i "video.webm" -c:v libx264 -preset medium -crf 23 -c:a aac -b:a 128k "video.mp4"WARNING: [youtube] nsig extraction failed: Some formats may be missingWARNING: android client https formats require a GVS PO Tokenscripts/download_video.py "VIDEO_URL"ffmpeg -headers "Referer: https://example.com/" \
-protocol_whitelist file,http,https,tcp,tls,crypto,httpproxy \
-i "https://cdn.example.com/path/rendition.m3u8?params" \
-c copy -bsf:a aac_adtstoasc \
output.mp4# Single header
-headers "Referer: https://example.com/"
# Multiple headers
-headers "Referer: https://example.com/" \
-headers "User-Agent: Mozilla/5.0..."
# Alternative syntax
-headers $'Referer: https://example.com/\r\nUser-Agent: Mozilla/5.0...'ffmpeg -headers "Referer: https://example.com/" \
-protocol_whitelist file,http,https,tcp,tls,crypto,httpproxy \
-i "https://cdn.example.com/audio/rendition.m3u8" \
-c copy audio.m4affmpeg -headers "Referer: https://example.com/" \
-protocol_whitelist file,http,https,tcp,tls,crypto,httpproxy \
-i "https://cdn.example.com/video/rendition.m3u8" \
-c copy video.mp4ffmpeg -i video.mp4 -i audio.m4a -c copy merged.mp4Download complete: [filename]
If you need the spoken content as text, I can transcribe it for you.
Options:
A) Transcribe with /daymade-audio:asr-transcribe-to-text (Recommended for speech-to-text)
B) No thanks — I just needed the video file