Fetch existing YouTube transcripts/subtitles or archive spoken video content as text, and download YouTube videos/audio or HLS streams (m3u8) with yt-dlp and ffmpeg. Use for transcript/subtitle retrieval, text-first video archiving, video/audio downloads, protected streams with authentication headers, and download failures including nsig, 403 or browser-cookie issues.
87%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Low
Low-risk findings worth noting
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:
Before downloading anything, classify the request:
references/text-first.md FIRST: existing archived transcripts → platform transcript APIs → yt-dlp subtitle-only → authorized audio track + ASR. Do not download the full video just to obtain text.The text-first route never blocks a file request: when the user wants the file, download it with the unchanged flow below.
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):

Title: …
Channel: …
Duration: …
I can help you:
1) Download the video (best quality, MP4)
2) Download audio only (MP3)
3) Pick a specific quality (1080p/720p/480p/360p)
4) Include subtitles (if available)
Where should I save it? (Default: Downloads folder)If the user says “just download”:
Read the download SOP before retrying a failure. Start with the current yt-dlp default clients and the existing network configuration. Do not require a provider, switch to Android, or extract browser cookies merely to begin a download.
scripts/download_video.py URL --info for metadata. It never starts a provider; its oEmbed fallback supplies limited fields when extraction fails.--js-runtimes node when yt-dlp needs it; runtime installation still follows dependency authorization.-F output. An absent requested format, images-only output, 403 or low resolution alone does not establish a token problem.--auto-po-token and finish the original download; do not stop at giving the user a command. This option attempts the native route first, then permits a bounded provider retry and WPC recovery.ffprobe and report its path, size and actual resolution or audio properties. Provider health or a format listing alone is not a completed download.This skill should be invoked when users:
which yt-dlp
yt-dlp --versionIf missing or a current extraction diagnostic requires an update, obtain any missing install/upgrade authorization, then use the existing installation owner:
brew upgrade yt-dlp # macOS
# or
pip install --upgrade yt-dlp # Cross-platformCheck the current EJS setup guide for the JavaScript runtime and challenge-solver requirements of the installed distribution. An installed Node binary may need explicit --js-runtimes node; do not treat an EJS/nsig failure as a PO Token failure.
Before downloading, check available formats:
yt-dlp -F "https://youtu.be/VIDEO_ID"Compare the listed media streams with the requested quality. If only a low-resolution format appears, inspect extraction/runtime warnings and the source availability before choosing recovery.
Keep player_client unset unless there is a specific diagnostic or explicit request. The official extractor guide describes yt-dlp's default attempt with clients that do not require tokens. Available formats depend on the video, account, client, network and current YouTube enforcement.
# Download best quality up to 1080p
scripts/download_video.py "VIDEO_URL" --quality 1080p
# Download best available quality
scripts/download_video.py "VIDEO_URL"
# After an explicit token requirement, with setup already authorized
scripts/download_video.py "VIDEO_URL" --auto-po-tokenFor installation and provider-specific recovery, load PO Token setup. Do not infer a provider requirement from resolution alone.
# Check video resolution
ffprobe -v error -select_streams v:0 -show_entries stream=width,height,codec_name -of default=noprint_wrappers=1 video.mp4Expected output for 1080p:
codec_name=vp9
width=1920
height=1080Use cookies when the content requires the authorized account or a bot check persists, after cookie permission is granted. Cookies authenticate a session; they do not replace a missing PO Token:
# 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"Benefits: Access to age-restricted and members-only content. Requirements:
web_safari only as a targeted retry. Do not combine account cookies with Android/iOS clients that do not support them.Extract audio as MP3:
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"YouTube high-quality downloads often use WebM format (VP9 codec). Convert to MP4 for wider compatibility:
# 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"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.
Inspect -F, the selected format expression, current yt-dlp/EJS/runtime warnings and source availability. These messages have multiple causes. Enter provider setup only when a failed extraction or media request also names a missing/required PO Token. Do not install a provider because a requested height or format ID is absent.
Check that the intended proxy/network is in use. If the challenge persists and cookies are needed, obtain cookie authorization, retain that session, and retry. Stop with the exact authorization gap if it is unavailable; do not silently read browser cookies.
Check the installed yt-dlp version and the EJS runtime and solver instructions. Repair the diagnosed prerequisite within authorization. Android or AndroidVR can be selected explicitly for a bounded diagnostic, but neither is the default recovery or a guaranteed solution.
Distinguish a media 403 from TLS, timeout, proxy and provider-health errors. A generic 403 does not prove a Token requirement. Check the network path first for SSL/timeout failures; retry only after a relevant change. The wrapper's single progressive retry applies to 403/fragment failures with quality presets, and may reduce quality.
For users in China or behind restrictive proxies:
WARNING: android client https formats require a GVS PO TokenAction: A successful, verified download needs no repair for an unused-client warning. On failure, read the full diagnostic and actual formats before choosing a token branch.
Use this wrapper for native-client downloads and bounded diagnostic recovery. It does not install/start providers or read cookies by default. Execute it yourself and report the verified file.
Basic usage:
scripts/download_video.py "VIDEO_URL"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 - Authorize provider setup after a failed explicit missing/required-token diagnostic; try native clients first, then Docker bgutil or browser WPC--no-auto-po-token - Disable provider setup (default); does not disable already-installed yt-dlp plugins--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 - Retained compatibility option; the wrapper already leaves native client selection unchanged--js-runtimes - Pass an installed runtime to yt-dlp, e.g. node or node:/path/to/nodeDo not promise a resolution based on a provider/client/cookie combination. Request the desired quality, inspect available formats, and verify the actual downloaded file. A successful high-resolution download without new provider setup proves only that input and environment; installed plugins or configuration may still contribute. A provider cannot create a resolution absent from the source.
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:
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.mp4Key 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:
# 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...'Some platforms (like Mux) deliver audio and video separately:
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.mp4Cause: 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 reasonTwo situations, two routes:
references/text-first.md (existing archived transcripts → platform transcript APIs → yt-dlp subtitle-only → authorized audio track + ASR).Download 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 filedaymade/claude-code-skills
7029e65
Also appears in
last in sync Jan 28, 2026
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.