Skip to main content
How to Download Online Videos with yt-dlp featured

How to Download Online Videos with yt-dlp

August 02, 2026

7 min read
CLIToolsVideo
Photo by Taylor Vick

If you've ever wanted to save a video — a conference talk, a music video, a documentary that keeps disappearing — yt-dlp is the tool I keep coming back to. It supports a huge range of sites, handles most formats cleanly, and has enough flags for tricky cases.

What yt-dlp is

yt-dlp is a fork of the older youtube-dl project, maintained at a much faster pace with broader site support, better format selection, and active bug fixes. Despite the name, it handles far more than YouTube — Vimeo, Twitter/X, Twitch, Reddit, TikTok, BBC iPlayer, and hundreds more.1

It's a CLI tool: no GUI, no browser extension required. You give it a URL, it figures out the available streams, and it downloads what you asked for.

Installation

If a package manager is not your preferred route, you can download the standalone binary from the releases page. On Windows and macOS, download the build for the correct operating system and CPU architecture, then place the executable in a directory on your PATH.

Windows

The simplest route is winget:

winget install yt-dlp

macOS

The simplest route is Homebrew:

brew install yt-dlp

Linux

Most package managers have it:

# Debian/Ubuntu
sudo apt install yt-dlp

# Arch
sudo pacman -S yt-dlp

# Fedora
sudo dnf install yt-dlp

Or install via pip if you want the latest version regardless of distro:

python3 -m pip install -U yt-dlp

Keeping it up to date

yt-dlp updates frequently — sites change their internals and extractors need to keep up. Run this to update in place:

yt-dlp -U

ffmpeg

Install ffmpeg alongside yt-dlp. Without it, format merging and post-processing won't work — you'll be stuck with whatever single stream the site serves rather than the best video merged with the best audio.2

Basic usage

Downloading a video is one command:

yt-dlp "https://www.youtube.com/watch?v=VIDEO_ID"

By default, yt-dlp picks the best available quality and saves the file to the current directory with an auto-generated filename. That's often exactly what you want.

Format selection

YouTube and many other sites serve video and audio as separate streams. yt-dlp merges them automatically, but you can control exactly what you get with --format (short: -f).

List all available formats for a URL before downloading:

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

This outputs a table of format codes, resolutions, codecs, and file sizes. You can then pass a specific format code:

yt-dlp -f 137+140 "https://www.youtube.com/watch?v=VIDEO_ID"

Or use yt-dlp's format selection syntax for something more readable:

# Best video + best audio, merged into mp4
yt-dlp -f "bv*+ba/b" --merge-output-format mp4 "https://www.youtube.com/watch?v=VIDEO_ID"

# Best quality up to 1080p
yt-dlp -f "bv*[height<=1080]+ba/b[height<=1080]" "https://www.youtube.com/watch?v=VIDEO_ID"

# Prefer VP9/opus over AVC/AAC (better compression)
yt-dlp -f "bv[vcodec^=vp9]+ba[acodec^=opus]/bv*+ba/b" "https://www.youtube.com/watch?v=VIDEO_ID"

Audio-only downloads

To extract just the audio and convert it to mp3:

yt-dlp --extract-audio --audio-format mp3 --audio-quality 0 "https://www.youtube.com/watch?v=VIDEO_ID"

--audio-quality 0 means best quality (VBR)3. For a specific bitrate, pass a value like 192K.

For formats that don't need conversion (e.g., keeping the native audio stream as m4a or opus):

yt-dlp -f "ba" "https://www.youtube.com/watch?v=VIDEO_ID"

Subtitles

Download a video with its subtitles:

# List available subtitles first
yt-dlp --list-subs "https://www.youtube.com/watch?v=VIDEO_ID"

# Download with English subtitles embedded
yt-dlp --write-subs --sub-lang en --embed-subs "https://www.youtube.com/watch?v=VIDEO_ID"

# Auto-generated subtitles (YouTube's auto-captions)
yt-dlp --write-auto-subs --sub-lang en "https://www.youtube.com/watch?v=VIDEO_ID"

Subtitles are saved as .vtt or .srt files alongside the video unless you use --embed-subs to bake them in.

Playlists

Pass a playlist URL and yt-dlp downloads every video in it:

yt-dlp "https://www.youtube.com/playlist?list=PLAYLIST_ID"

Useful playlist options:

# Download only items 5 through 10
yt-dlp --playlist-start 5 --playlist-end 10 "PLAYLIST_URL"

# Download specific items by index
yt-dlp --playlist-items 1,3,5-7 "PLAYLIST_URL"

# Skip videos you've already downloaded (safe to re-run)
yt-dlp --download-archive archive.txt "PLAYLIST_URL"

The --download-archive flag is especially useful for ongoing playlists or channels — it writes downloaded video IDs to a file and skips them on subsequent runs.

Output templates

Control where files are saved and what they're named with --output (short: -o):

# Save to a Videos folder, named by uploader and title
yt-dlp -o "~/Videos/%(uploader)s/%(title)s.%(ext)s" "https://www.youtube.com/watch?v=VIDEO_ID"

# Include upload date
yt-dlp -o "%(upload_date)s - %(title)s.%(ext)s" "https://www.youtube.com/watch?v=VIDEO_ID"

Available template fields include %(title)s, %(uploader)s, %(upload_date)s, %(id)s, %(ext)s, %(resolution)s, and many more.

Rate limiting

If a site throttles you or you want to be polite:

# Limit download speed to 2 MB/s
yt-dlp --limit-rate 2M "https://www.youtube.com/watch?v=VIDEO_ID"

# Add a random sleep between downloads in a playlist
yt-dlp --sleep-interval 2 --max-sleep-interval 8 "PLAYLIST_URL"

Using cookies

Some content requires you to be logged in — age-restricted videos, members-only content, private videos. yt-dlp can use your browser's cookies:

yt-dlp --cookies-from-browser chrome "https://www.youtube.com/watch?v=VIDEO_ID"

Supported browsers: chrome, firefox, edge, safari, brave, and opera.

Alternatively, export cookies to a Netscape-format file from a browser extension and pass it directly:

yt-dlp --cookies cookies.txt "https://www.youtube.com/watch?v=VIDEO_ID"

Embedding metadata and thumbnails

yt-dlp --embed-metadata --embed-thumbnail "https://www.youtube.com/watch?v=VIDEO_ID"

This writes title, uploader, description, chapters, and other metadata into the file container, and embeds the thumbnail as cover art — useful if you're building a local media library.

A configuration file

If you find yourself repeating the same flags, put them in a config file. yt-dlp reads from %APPDATA%\yt-dlp\config.txt on Windows and ~/.config/yt-dlp/config on Linux/macOS.

Set a default download location

Add these lines to your config file so every download lands in the same place with predictable names.

Windows

--paths home:C:/Users/<your-username>/Downloads/yt-dlp
--output %(uploader)s/%(upload_date)s - %(title)s [%(id)s].%(ext)s

Linux/macOS

--paths home:~/Downloads/yt-dlp
--output %(uploader)s/%(upload_date)s - %(title)s [%(id)s].%(ext)s

You can verify your configured destination without downloading anything:

yt-dlp --simulate --print after_move:filepath "https://www.youtube.com/watch?v=BaW_jenozKc"

If the printed path points to your folder, your default location is set correctly.

A reasonable default config:

--format bv*+ba/b
--merge-output-format mp4
--embed-metadata
--embed-thumbnail
--output ~/Downloads/%(uploader)s - %(title)s.%(ext)s
--no-playlist

--no-playlist is worth calling out: if you pass a URL that could be interpreted as either a single video or a playlist (e.g., a YouTube video that's part of a playlist), this flag ensures you only get the video.

Real-world examples

# Download a YouTube video at 1080p as mp4 with embedded subtitles and metadata
yt-dlp \
  -f "bv*[height<=1080]+ba/b" \
  --merge-output-format mp4 \
  --write-subs --sub-lang en --embed-subs \
  --embed-metadata --embed-thumbnail \
  -o "%(title)s.%(ext)s" \
  "https://www.youtube.com/watch?v=VIDEO_ID"

# Download audio only from a playlist, skipping already-downloaded items
yt-dlp \
  --extract-audio --audio-format mp3 --audio-quality 0 \
  --download-archive archive.txt \
  -o "%(playlist_index)s - %(title)s.%(ext)s" \
  "PLAYLIST_URL"

# Download from a site that needs login cookies
yt-dlp --cookies-from-browser firefox --limit-rate 1M "https://example.com/video"

Batch downloads

If you have multiple URLs, put one link per line in urls.txt and run:

yt-dlp -a urls.txt --download-archive downloaded.txt

-a reads URLs from a file, and --download-archive prevents re-downloading items you already fetched.

Troubleshooting

ffmpeg not found (merge or conversion fails). Install FFmpeg and make sure it is available on your PATH.

ffmpeg -version

Age-restricted or member-only content fails. Reuse your browser session cookies:

yt-dlp --cookies-from-browser chrome "https://www.youtube.com/watch?v=VIDEO_ID"

Rate limits (for example, HTTP Error 429). Slow requests and add jitter:

yt-dlp --sleep-interval 2 --max-sleep-interval 8 "https://www.youtube.com/watch?v=VIDEO_ID"

Extractor breaks after a site update. Update yt-dlp to the latest release:

yt-dlp -U

Tips

Check the extractor list before assuming a site isn't supported. Run yt-dlp --list-extractors or search the supported sites list. It's longer than you'd expect.

Use --simulate --verbose to debug without downloading. This prints everything yt-dlp resolves without writing any files — useful when a download fails and you need to understand why.

The --sponsorblock-remove flag skips sponsor segments in YouTube videos using SponsorBlock data. Pass --sponsorblock-remove sponsor,selfpromo,interaction to cut the most common filler.

For large playlists, --concurrent-fragments speeds things up by downloading multiple fragments of a single video in parallel:

yt-dlp --concurrent-fragments 4 "PLAYLIST_URL"

Keep it reasonable — pushing this too high on rate-limited connections won't help and may get you throttled.

The yt-dlp README is worth reading end to end at least once. It's dense, but it answers most of the questions you run into later.

Start with a simple command, then move your most-used flags into config as your workflow grows. That small habit keeps downloads consistent and saves a lot of repetitive typing over time.

Footnotes

  1. The full list of supported sites is maintained in supportedsites.md in the repository. It currently runs to over a thousand entries. ↩

  2. On YouTube, the highest-resolution streams (1080p60 and above) are only available as separate video and audio streams. Without ffmpeg to merge them, yt-dlp falls back to a lower-quality combined format. ↩

  3. VBR means variable bitrate: the encoder uses more bits for complex audio sections and fewer for simpler ones, which usually improves perceived quality at a given file size. ↩

Marc Santos

Marc Santos

Full-Stack Engineer & Product Developer

I write about building things—from site features to developer tooling—alongside travel, photography, and occasional personal reflections.

When I’m not building, I’m exploring—whether that’s a new place with a camera, a mountainside, or somewhere underwater.

About MarcBuild a product together
Designed and developed by Marc Santos.
This website is a work in progress made with .
© 2011–2026. All Rights Reserved. Hikari v4.9.2.