cheat sheet
yt-dlp
Downloading video and audio from YouTube and hundreds of other sites with yt-dlp — formats, playlists, subtitles, post-processing, and config.
yt-dlp
What it is
yt-dlp is a free, open-source command-line video downloader — a feature-rich, actively maintained fork of youtube-dl — that supports YouTube and hundreds of other streaming sites. It offers faster downloads, a more expressive format-selection language, SponsorBlock integration, and active bugfixes compared to the original project. Reach for yt-dlp whenever you need to download video or audio from a streaming site, extract audio tracks, or archive content with embedded metadata, thumbnails, and subtitles.
Install
Via winget:
winget install --id yt-dlp.yt-dlp
Via pip (keeps it on PATH inside the active Python env):
pip install yt-dlp
Upgrade at any time:
yt-dlp -U
Output:
Current version: 2026.05.03
Latest version: 2026.05.24
Updating to 2026.05.24 ...
Updated yt-dlp to version 2026.05.24
Verify install:
yt-dlp --version
Output:
2026.05.24
YouTube JavaScript runtime requirement (2026)
As of 2026 yt-dlp requires an external JavaScript runtime installed on the host to solve the JavaScript challenges YouTube presents during player decryption — the in-process JS engine yt-dlp used previously is no longer sufficient. Without a JS runtime, YouTube downloads fail with WARNING: Failed to extract any player response or signature-decryption errors. Install Deno (recommended) or Node.js once per machine:
winget install --id DenoLand.Deno
# or: winget install --id OpenJS.NodeJS
Output:
Successfully installed
yt-dlp auto-detects the runtime; no further configuration is needed. Confirm it sees the runtime:
yt-dlp --verbose "https://www.youtube.com/watch?v=dQw4w9WgXcQ" 2>&1 | findstr /I "deno"
Output:
[debug] Using JavaScript interpreter: deno (2.x.x)
Basic download
Download the best available quality:
yt-dlp "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
Output:
[youtube] Extracting URL: https://www.youtube.com/watch?v=dQw4w9WgXcQ
[youtube] dQw4w9WgXcQ: Downloading webpage
[youtube] dQw4w9WgXcQ: Downloading ios player API JSON
[info] dQw4w9WgXcQ: Downloading 1 format(s): 616+251
[download] Destination: Rick Astley - Never Gonna Give You Up (Official Music Video) [dQw4w9WgXcQ].webm
[download] 100% of 56.29MiB in 00:00:14 at 3.92MiB/s
[Merger] Merging formats into "Rick Astley - Never Gonna Give You Up (Official Music Video) [dQw4w9WgXcQ].mp4"
List available formats
See every stream a URL offers before committing to a download:
yt-dlp -F "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
Output:
ID EXT RESOLUTION FPS │ FILESIZE TBR PROTO │ VCODEC VBR ACODEC ABR
────────────────────────────────────────────────────────────────────────────────────────────
sb3 mhtml 48x27 1 │ mhtml │ images
sb2 mhtml 80x45 1 │ mhtml │ images
...
139 m4a audio only │ 3.33MiB 49k https │ audio only mp4a.40.5 49k
249 webm audio only │ 2.44MiB 36k https │ audio only opus 36k
250 webm audio only │ 3.20MiB 47k https │ audio only opus 47k
140 m4a audio only │ 8.67MiB 128k https │ audio only mp4a.40.2 128k
251 webm audio only │ 6.32MiB 93k https │ audio only opus 93k
394 mp4 256x144 24 │ 2.55MiB 38k https │ av01.0.00M.08 38k video only
...
616 webm 1920x1080 24 │ ~ 56.24MiB 828k https │ vp09.00.51.08 828k video only
337 webm 3840x2160 24 │ ~173.32MiB 2550k https │ vp09.00.51.08 2550k video only
Download a specific format by ID:
yt-dlp -f 140 "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
Format selection
yt-dlp's -f flag accepts a mini-language for format selection.
Best video + best audio, merged to MP4:
yt-dlp -f "bv+ba/b" --merge-output-format mp4 "URL"
Best video up to 1080p + best audio:
yt-dlp -f "bv[height<=1080]+ba/b[height<=1080]" --merge-output-format mp4 "URL"
Best MP4 video + best M4A audio (avoids transcoding):
yt-dlp -f "bv[ext=mp4]+ba[ext=m4a]/b[ext=mp4]" --merge-output-format mp4 "URL"
Best AV1 video + opus audio:
yt-dlp -f "bv[vcodec^=av01]+ba[acodec=opus]/b" --merge-output-format mkv "URL"
Audio only — best quality:
yt-dlp -f "ba/b" -x "URL"
Extract audio
Download and convert to MP3 (requires ffmpeg):
yt-dlp -x --audio-format mp3 --audio-quality 0 "URL"
Extract as FLAC:
yt-dlp -x --audio-format flac "URL"
Extract as Opus (smallest file, best quality-per-bit):
yt-dlp -x --audio-format opus "URL"
Download best audio without conversion (fastest):
yt-dlp -f "ba" "URL"
Output filename template
-o controls the output path. Placeholders use %(field)s syntax.
Common fields: %(title)s, %(uploader)s, %(upload_date)s, %(id)s, %(ext)s, %(resolution)s, %(playlist_title)s, %(playlist_index)s.
Save to a folder named after the channel:
yt-dlp -o "%(uploader)s/%(title)s [%(id)s].%(ext)s" "URL"
Date-prefix the filename:
yt-dlp -o "%(upload_date>%Y-%m-%d)s %(title)s.%(ext)s" "URL"
Sanitize the title for Windows filenames automatically (default behavior — shown for clarity):
yt-dlp --windows-filenames -o "%(title)s.%(ext)s" "URL"
Playlist with zero-padded index:
yt-dlp -o "%(playlist_index)03d - %(title)s.%(ext)s" "PLAYLIST_URL"
Playlist & channel downloads
Download an entire playlist:
yt-dlp "https://www.youtube.com/playlist?list=PLxxxxxxxx"
Download only items 5 through 10 of a playlist:
yt-dlp --playlist-start 5 --playlist-end 10 "PLAYLIST_URL"
Download items matching a title pattern:
yt-dlp --match-title "episode" "PLAYLIST_URL"
Download all videos from a channel:
yt-dlp "https://www.youtube.com/@ChannelName/videos"
Skip already-downloaded files (archive file):
yt-dlp --download-archive archive.txt "PLAYLIST_URL"
Output (with archive):
[download] 1/50: https://www.youtube.com/watch?v=AAAAAAAAA
[download] Downloading item 1 of 50
[download] AAAAAAAAA has already been recorded in the archive
[download] 2/50: https://www.youtube.com/watch?v=BBBBBBBBB
...
Subtitles
List available subtitle languages:
yt-dlp --list-subs "URL"
Output:
[info] Available subtitles for dQw4w9WgXcQ:
Language Name Formats
en English vtt, ttml, srv3, srv2, srv1, json3
es Spanish vtt, ttml, srv3, srv2, srv1, json3
fr French vtt, ttml, srv3, srv2, srv1, json3
Download with English subtitles (embedded as SRT):
yt-dlp --write-subs --sub-langs en --convert-subs srt "URL"
Download auto-generated subtitles:
yt-dlp --write-auto-subs --sub-langs en "URL"
Embed subtitles into the video file (requires ffmpeg):
yt-dlp --embed-subs --sub-langs en "URL"
Thumbnails
Write the thumbnail to a separate file:
yt-dlp --write-thumbnail "URL"
Embed the thumbnail into the audio file (useful for podcasts/music):
yt-dlp -x --audio-format mp3 --embed-thumbnail "URL"
Convert the thumbnail to JPEG (some players prefer it):
yt-dlp --write-thumbnail --convert-thumbnails jpg "URL"
Metadata & tagging
Embed metadata (title, artist, etc.) into the file:
yt-dlp --embed-metadata "URL"
Write a separate .info.json metadata file:
yt-dlp --write-info-json "URL"
Full "archive quality" download — metadata, thumbnail, subtitles, chapters:
yt-dlp --embed-metadata --embed-thumbnail --embed-chapters --write-subs --sub-langs en "URL"
Rate limiting & throttling
Limit download speed (useful on metered connections):
yt-dlp --limit-rate 2M "URL"
Add a sleep between downloads in a playlist to avoid rate-limiting:
yt-dlp --sleep-interval 3 --max-sleep-interval 8 "PLAYLIST_URL"
Retry on failure:
yt-dlp --retries 10 --fragment-retries 10 "URL"
Cookies & authentication
Use cookies exported from your browser (for age-gated or members-only content):
yt-dlp --cookies cookies.txt "URL"
Pull cookies directly from a running browser (Chrome, Firefox, Edge):
yt-dlp --cookies-from-browser chrome "URL"
yt-dlp --cookies-from-browser firefox "URL"
yt-dlp --cookies-from-browser edge "URL"
Username/password login (supported on some sites):
yt-dlp -u "alice@example.com" -p "password" "URL"
Post-processing with ffmpeg
Remux to MKV without re-encoding:
yt-dlp --remux-video mkv "URL"
Re-encode video to H.264 + AAC:
yt-dlp --recode-video mp4 --postprocessor-args "ffmpeg:-c:v libx264 -crf 18 -c:a aac -b:a 192k" "URL"
Split a video by its chapters into separate files:
yt-dlp --split-chapters "URL"
Output:
[SplitChapters] Chapter 01 - Introduction: chapter-01-introduction.mp4
[SplitChapters] Chapter 02 - Deep Dive: chapter-02-deep-dive.mp4
[SplitChapters] Chapter 03 - Wrap Up: chapter-03-wrap-up.mp4
Sponsorblock integration
Skip or mark sponsor segments automatically (community-sourced data):
yt-dlp --sponsorblock-remove sponsor "URL"
Remove multiple segment types:
yt-dlp --sponsorblock-remove "sponsor,intro,outro,selfpromo" "URL"
Mark segments in chapters instead of removing them:
yt-dlp --sponsorblock-mark all "URL"
Simulate & inspect
Simulate without downloading (dry run):
yt-dlp --simulate "URL"
Print only the final download URL:
yt-dlp -g "URL"
Output:
https://rr1---sn-xxxx.googlevideo.com/videoplayback?expire=...
https://rr1---sn-xxxx.googlevideo.com/videoplayback?expire=...
Print video title only:
yt-dlp --print title "URL"
Print JSON metadata without downloading:
yt-dlp -j "URL"
Configuration file
yt-dlp reads options from a config file so you don't repeat them every time.
Location on Windows: %APPDATA%\yt-dlp\config.txt
Create with:
New-Item -ItemType File -Force "$env:APPDATA\yt-dlp\config.txt"
notepad "$env:APPDATA\yt-dlp\config.txt"
Example config.txt:
# Default output template
-o %(uploader)s/%(upload_date>%Y-%m-%d)s %(title)s [%(id)s].%(ext)s
# Always merge to MP4
--merge-output-format mp4
# Embed everything useful
--embed-metadata
--embed-thumbnail
--embed-chapters
# English subtitles, embedded
--write-auto-subs
--sub-langs en
--embed-subs
# Sponsorblock: cut sponsors
--sponsorblock-remove sponsor
# Retry on transient failures
--retries 10
--fragment-retries 10
# Sleep between playlist items
--sleep-interval 2
--max-sleep-interval 6
# Use browser cookies for auth
--cookies-from-browser chrome
Multiple URLs from a file
Download everything listed in urls.txt (one URL per line):
yt-dlp -a urls.txt
Useful one-liners
Download a YouTube Music playlist as tagged MP3s:
yt-dlp -x --audio-format mp3 --audio-quality 0 --embed-metadata --embed-thumbnail `
-o "%(playlist_index)02d - %(title)s.%(ext)s" "PLAYLIST_URL"
Download a channel's latest 10 uploads:
yt-dlp --playlist-end 10 "https://www.youtube.com/@ChannelName/videos"
Download 1080p MP4 and keep going if one video fails:
yt-dlp -f "bv[height<=1080][ext=mp4]+ba[ext=m4a]/b[height<=1080]" `
--merge-output-format mp4 --ignore-errors "PLAYLIST_URL"
Re-download only missing items in a synced playlist:
yt-dlp --download-archive downloaded.txt --ignore-errors "PLAYLIST_URL"
Common errors
| Error | Fix |
|---|---|
ERROR: Sign in to confirm your age | Use --cookies-from-browser chrome |
HTTP Error 429: Too Many Requests | Add --sleep-interval 5 --max-sleep-interval 15 |
ffmpeg not found | Install ffmpeg via winget install --id Gyan.FFmpeg |
Requested format not available | Run -F first and pick a valid format ID |
ERROR: [youtube] Video unavailable | Video is region-locked, private, or deleted |
WARNING: unable to obtain file audio codec | Upgrade yt-dlp: yt-dlp -U |
WARNING: Failed to extract any player response | Install a JS runtime (Deno or Node) — required as of 2026 |
outdated quickjs-ng warning | Upgrade yt-dlp (2026.05+ uses ejs / external runtimes) |
2026 security and breaking changes
The 2026.05 release line shipped a security fix and one runtime change worth flagging in any automation:
--netrc-cmdargument injection fix — the command argument is now restricted to a safe subset of characters and cookies with control characters are ignored. Scripts that previously relied on shell-quoted commands here should verify their netrc helper still runs.- External JS runtime is mandatory for YouTube — see the section above. Headless CI runners must install Deno or Node before yt-dlp can fetch YouTube videos.
- PO Token may be required for sustained YouTube playlist downloads — when prompted, generate one with
--extractor-args "youtube:player-client=web;po_token=web+<TOKEN>".
Sources
github.com/yt-dlp/yt-dlp/releases · github.com/yt-dlp/yt-dlp · pypi.org/project/yt-dlp