Download one part of a YouTube video, not the whole thing
A 40-second clip out of a two-hour stream, in about two seconds, without fetching the two hours. The flag most people have never heard of — and the one format that makes it fail with 403.
You need forty seconds from the middle of a two-hour livestream. The usual approach is to download all two hours, open an editor, cut, export.
You do not have to.
yt-dlp --download-sections "*3:40-7:15" "URL"
That fetches roughly the bytes covering that range and nothing else. On a test run on 2026-07-31, pulling ten seconds out of a ten-minute 4K video produced a 93 KB file in about two seconds. The whole video at that quality is 1.27 GB.
The syntax
The * prefix means “a time range”. Without it, the argument is read as a
chapter name.
yt-dlp --download-sections "*30-40" "URL" # seconds
yt-dlp --download-sections "*3:40-7:15" "URL" # mm:ss
yt-dlp --download-sections "*1:02:00-1:05:30" # hh:mm:ss
yt-dlp --download-sections "*90-inf" "URL" # 90s to the end
Negative numbers count back from the end, which is the clean way to grab an ending without knowing the duration:
yt-dlp --download-sections "*-20-0" "URL" # the last 20 seconds
Several ranges at once, each becoming its own file:
yt-dlp --download-sections "*0-30" --download-sections "*5:00-5:30" "URL"
By chapter, instead of by timestamp
Without the *, the argument is a regular expression matched against chapter
titles. Far better than reading timestamps off the description by hand.
See the chapters first:
yt-dlp --print "%(chapters)j" "URL" | python3 -m json.tool
Then take one:
yt-dlp --download-sections "break the tension" "URL"
Verified: on a video whose chapter ran from 88 s to 176 s, that produced an 88.1-second file. The match is a regex, so anchor it when titles are similar:
yt-dlp --download-sections "^Introduction$" "URL"
Splitting every chapter into its own file
Different job — you want the whole video, cut up:
yt-dlp --split-chapters \
-o "chapter:%(section_number)02d - %(section_title)s.%(ext)s" \
"URL"
This downloads everything and then splits, so it saves no bandwidth. It gave
four chapter files plus the full one in testing. The chapter: prefix on -o
sets the template for the pieces; add a plain -o to control the full file’s
name too.
The gotcha that will cost you an hour
--download-sections does not work like the rest of yt-dlp. Instead of
downloading the file itself, it asks FFmpeg to fetch a byte range from
YouTube’s server directly. That is what makes it fast, and it is also where it
breaks.
With the legacy combined format 18 (360p, video and audio in one file), the same command fails:
[https @ 0x…] HTTP error 403 Forbidden
Error opening input file https://rr5---sn-….googlevideo.com/videoplayback?…
ERROR: ffmpeg exited with code 8
Those URLs are bound to the client and address that requested them, and FFmpeg’s request does not carry what YouTube expects. With the modern DASH formats — the separate video-only and audio-only streams — the identical command works.
So if you get ffmpeg exited with code 8 and a 403, the section flag is not
broken, your format selection is. Ask for DASH streams explicitly:
yt-dlp -f "bestvideo[vcodec^=avc1]+bestaudio[ext=m4a]" \
--download-sections "*3:40-7:15" "URL"
Frame-accurate cuts
By default the cut lands on the nearest keyframe, which can be a second or two off. Usually fine. When it is not:
yt-dlp --download-sections "*3:40-7:15" \
--force-keyframes-at-cuts "URL"
That re-encodes around the cut points to land exactly where you asked. It is slower and it recompresses the boundary, so use it when the timing matters and skip it when it does not.
Audio only
Grabbing one track out of a long mix:
yt-dlp -f bestaudio[ext=m4a] --download-sections "*32:10-36:45" "URL"
No re-encoding, no editor. Related: getting the audio out without re-encoding it.
What this replaces
This flag is the free equivalent of the trimming feature that paid Mac
downloaders advertise — Pulltube’s headline feature is picking a start and an
end before downloading. The command does the same job, and does it better in
one respect that matters: those apps generally download the full video and trim
afterwards, so you wait for the whole file. --download-sections never fetches
the rest.
What you give up is obvious enough: you are typing timestamps rather than dragging handles on a waveform, and you cannot see what you are cutting.
For what it is worth, the app I build does not expose this yet — it downloads whole videos. When a range is what you want, the command above is the right tool, and I would rather say so than pretend otherwise.
The short version
| You want | Command |
|---|---|
| A time range | --download-sections "*3:40-7:15" |
| The last 20 seconds | --download-sections "*-20-0" |
| From a point to the end | --download-sections "*90-inf" |
| A named chapter | --download-sections "chapter name" (no *) |
| Every chapter separately | --split-chapters |
| An exact cut | add --force-keyframes-at-cuts |
| To see the chapters | --print "%(chapters)j" |
And the one to remember: 403 plus ffmpeg exited with code 8 means pick a
DASH format, not that the flag is broken.