yt-dlp subtitles: the commands that work, and 3 traps that cost me an afternoon

2026-11-05来源 dev.to TutorialEnglish

If you only want the subtitles from a YouTube video, yt-dlp can do it without downloading the video. The flags look simple. Then you run them on a real channel and get a 429, a folder full of junk languages, or a re-run that starts again from zero.

Everything below was run with yt-dlp 2026.07.04 on real videos this week.

The one command most people want

yt-dlp --skip-download --write-subs --write-auto-subs \ --sub-langs en --sub-format srt \ -o "%(id)s.%(ext)s" \ "https://www.youtube.com/watch?v=dQw4w9WgXcQ" 

What each part does:

  • --skip-download keeps the video off your disk. You only get the subtitle file.
  • --write-subs takes subtitles the creator uploaded.
  • --write-auto-subs takes YouTube's auto-generated captions.
  • With both set, yt-dlp prefers the creator's track and falls back to the auto one. On the video above it picked the uploaded track, which has proper punctuation and the ♪ marks.
  • --sub-format srt asks YouTube for SRT directly, so no ffmpeg step is needed.

To see what a video has before downloading anything:

yt-dlp --list-subs "https://www.youtube.com/watch?v=dQw4w9WgXcQ" 

Trap 1: --sub-langs "en.*" gets you a 429

The yt-dlp help text uses en.* as an example, so it's the first thing everyone tries. On a popular video, --list-subs shows why it's a bad idea: the automatic captions include dozens of machine-translated tracks, and the codes look like this:

en-en English from English ab-en Abkhazian from English en-de-DE ... 

en.* matches en, en-orig, en-en, en-de-DE and more. yt-dlp requests every one of them back to back, and YouTube answered my test with:

ERROR: Unable to download video subtitles for 'en-de-DE': HTTP Error 429: Too Many Requests 

The fix is to ask for exactly what you want:

--sub-langs en # just English --sub-langs "en,es" # English and Spanish --sub-langs "en,-live_chat" # English, never the live-chat replay 

Trap 2: auto-caption VTT files are not readable text

If you grab auto captions as VTT and open the file, you see this:

00:00:21.800 --> 00:00:25.950 align:start position:0% We're no strangers to love.<00:00:22.800><c> You</c><00:00:23.039><c> know</c><00:00:23.279><c> the</c> 

Each word has its own timing tag, and every line appears twice, because auto captions "roll" on screen. Feed that to an LLM and you pay for every word twice.

This turns it into clean text:

import re, sys def vtt_to_text(path): lines = [] for line in open(path, encoding="utf-8"): line = line.strip() if not line or "-->" in line or line.startswith(("WEBVTT", "Kind:", "Language:")): continue line = re.sub(r"<[^>]+>", "", line) # drop the per-word timing tags  if line and (not lines or line != lines[-1]): # auto captions repeat each line  lines.append(line) return " ".join(lines) print(vtt_to_text(sys.argv[1])) 

Output:

[Music] We're no strangers to love. You know the rules and so do I. ... 

If you want timestamps, ask for --sub-format srt instead. The SRT version of the same captions doesn't have the rolling duplicates.

Trap 3: --download-archive does nothing with --skip-download

For a whole channel you want re-runs to skip what you already have, so you add --download-archive done.txt. I ran it on two videos from a channel, and done.txt was never created.

yt-dlp only writes the archive when it downloads the video, and --skip-download means it never does. You need one more flag:

yt-dlp --skip-download --write-subs --write-auto-subs \ --sub-langs en --sub-format srt \ --download-archive done.txt --force-write-archive \ --sleep-subtitles 2 \ -o "subs/%(upload_date)s %(title).80s [%(id)s].%(ext)s" \ "https://www.youtube.com/@veritasium/videos" 

The second run printed has already been recorded in the archive for both videos and skipped them.

The other flags in there:

  • --sleep-subtitles 2 waits between subtitle requests. On a big channel this is what keeps you clear of trap 1's 429.
  • -I 1:50 (not shown) limits the run to the newest 50 videos, which is handy for testing.
  • The output template puts the date first, so files sort chronologically, and keeps the video id in brackets so you can always find the source.

When yt-dlp stops being the right tool

All of this works from a laptop on a home connection. From a cloud server it usually stops. YouTube blocks most datacenter IP ranges, and you start seeing Sign in to confirm you're not a bot. Then you're dealing with cookies, residential proxies and PO tokens. I wrote about that in an earlier post.

I build BulkTranscripts, which runs yt-dlp behind residential proxies so you don't have to. You paste a channel or playlist and get SRT, VTT, TXT or JSON for up to 1,000 videos. It's paid after the first 30, so if the commands above work for you, keep using them. They're free.

If you hit a yt-dlp subtitle error that isn't covered here, paste it in the comments and I'll take a look.

原文:https://www.a8q9.cn/en/article/yt-dlp-subtitles-the-commands-that-work-and-3-traps-that-cost-me-an-afternoon-245fd9.html

相关文章