Skip to content

Start typing. Errors match on their exact yt-dlp output.

to move, to open esc to close

yt-dlp Format Selection: -f, -S and Getting Exactly What You Want

Tested on yt-dlp 2026.07.28 Updated

Quick answer

Format selection decides resolution, codec, file size and whether the download works at all. It is the one yt-dlp concept worth learning properly. Two selectors cover most needs — the first is a hard requirement, the second a preference that never errors:

cap at 1080p, always works
yt-dlp -f "bv*[height<=1080]+ba/b[height<=1080]/b" "URL"
prefer 1080p, accept less
yt-dlp -S "res:1080,vcodec:h264" "URL"

Start by looking

Every question about format selection is answerable from the format table:

bash
yt-dlp -F "URL"

Rows marked video only and audio only mean the site splits its streams — that is where + selectors apply and where ffmpeg becomes mandatory. Rows showing both mean it does not, and bv* is required for anything to match.

Reading a selector

Four pieces of syntax carry almost all of it:

PieceMeans
bv / bestvideoBest stream with video and no audio
bv*Best stream with video, audio optional
ba / bestaudioBest audio-only stream
b / bestBest stream that already has both
+Download both and merge them
/Fallback: try the left, else the right
[key=value]Filter — only formats matching this

So bv*[height<=1080]+ba/b[height<=1080]/b reads as: the best video stream at or below 1080p plus the best audio, merged; failing that, the best combined stream at or below 1080p; failing that, anything at all. Three attempts, so it cannot produce Requested format is not available.

The trap in the word "best"

-f best does not mean best quality. It means the best pre-merged file, which on YouTube is format 18 — 360p. This is the most-copied wrong command in the ecosystem, and it is behind a large share of "yt-dlp only downloads 360p".

yt-dlp's default, with no -f at all, already merges. If you are not sure, pass nothing.

Filters worth knowing

FilterSelects
[height<=1080]1080p or below
[fps>30]High frame rate only
[ext=mp4]mp4 container
[vcodec^=avc1]Codec starts with avc1 — that is H.264
[vcodec!*=av01]Anything that is not AV1
[filesize<500M]Under 500 MB, where the site reports a size
[protocol^=http]Plain HTTP rather than HLS or DASH

Each filter narrows the set that can match. Three at once frequently leaves nothing, which is the usual reason an elaborate selector errors on a video that plays fine in a browser.

-S, and why it is usually the better tool

-f is a requirement. -S is a ranking over whatever exists, so it always picks something:

bash
yt-dlp -S "res:1080,fps,vcodec:h264,acodec:m4a" "URL"

Read as: prefer 1080p, then higher frame rate, then H.264, then AAC audio. A 720p-only video downloads at 720p instead of erroring.

Useful sort keys: res, fps, vcodec, acodec, ext, size, br. Prefix with + to reverse — -S "+size" gets the smallest file, which is the quickest way to check a video is the one you meant before committing to 4 GB.

Codecs, in practice

CodecTrade-off
H.264 (avc1)Plays on everything, hardware-decoded everywhere, largest files
VP9~30% smaller at equal quality; decodes in software on older hardware
AV1 (av01)Smallest; stutters badly without hardware support

For a file destined for a TV, an older laptop or a phone, ask for H.264 and accept the size:

bash
yt-dlp -S "res:1080,vcodec:h264" --merge-output-format mp4 "URL"

A note on resolution and quality

They are not the same thing. A 1080p AV1 stream at a low bitrate can look worse than 720p H.264 at a high one, and YouTube allocates bitrate unevenly across codecs. If a download "looks soft" despite reporting 1080p, the codec is usually why — which is what the -S above addresses.

Selectors worth keeping

GoalSelector
Best available, any container-f "bv*+ba/b"
Best that is already mp4-f "bv*[ext=mp4]+ba[ext=m4a]/b[ext=mp4]/b"
Cap at 1080p-f "bv*[height<=1080]+ba/b[height<=1080]/b"
Prefer 1080p, accept less-S "res:1080"
Maximum compatibility-S "res:1080,vcodec:h264,acodec:m4a" --merge-output-format mp4
Smallest file-S "+size"
Audio only, no re-encode-f "ba/b" -x --audio-format best
Avoid AV1-S "vcodec:h264,vcodec:vp9"

Testing without downloading

--simulate runs the whole selection and writes nothing — the right way to check a selector before pointing it at 900 videos:

bash
yt-dlp --simulate --print "%(format_id)s %(height)sp %(vcodec)s %(filesize_approx)s" -f "bv*[height<=1080]+ba/b" "URL"

Making it permanent

Once a selector works, it belongs in your config file rather than in the one command you remember to type:

yt-dlp.conf
-S res:1080,vcodec:h264,acodec:m4a
--merge-output-format mp4

With the corollary that a forgotten -f line in that file is behind a good number of confusing results later — --ignore-config is the one-run way to rule it out.

Frequently asked

What is the difference between best and bestvideo?
best means the best single file that already contains video and audio — on YouTube, 360p. bestvideo means the best video-only stream, which has to be paired with bestaudio and merged. The names suggest a hierarchy that does not exist.
Why bv* and not bv?
bv requires a stream with no audio track. bv* accepts one with or without. On sites that only serve combined files — Twitter, Reddit, most news sites — bv matches nothing and the whole selector fails.
Should I use -f or -S?
Use -S unless you need a hard requirement. -f states what is acceptable and errors when nothing matches; -S ranks whatever exists and always picks something. Most complicated -f expressions are attempts to express a preference, which is what -S is for.
How do I avoid AV1?
-S "vcodec:h264" prefers H.264 without forbidding anything else. Worth it on older hardware and on TVs, where AV1 decodes in software and stutters.