yt-dlp, the ultimate youtube-dl successor

ryanmaynard

Administrator
Staff member
I use yt-dlp infrequently enough that I have to look up all of the options and features every single time I use it. So I'm putting a few of the most useful options here to be easily accessible to others. While it has YouTube in the name, here is the list of currently supported sites.

And now, the top 25 best uses of yt-dlp

  1. Basic Video Download
    Code:
    yt-dlp <URL>
    Downloads the video from the provided URL.
  2. Download with Best Quality
    Code:
    yt-dlp -f 'best' <URL>
    Selects and downloads the best available quality of the video.
  3. Download Audio Only
    Code:
    yt-dlp -f 'bestaudio' <URL>
    Downloads only the best available audio from the video.
  4. Output Filename Template
    Code:
    yt-dlp -o '%(title)s.%(ext)s' <URL>
    Specifies the output filename template for the downloaded video.
  5. Extract Audio and Convert to MP3
    Code:
    yt-dlp --extract-audio --audio-format mp3 <URL>
    Extracts the audio and converts it to MP3 format.
  6. Specify Download Directory
    Code:
    yt-dlp -o '~/Downloads/%(title)s.%(ext)s' <URL>
    Downloads the video to the specified directory.
  7. Download Playlist
    Code:
    yt-dlp -o '%(playlist_index)s - %(title)s.%(ext)s' <URL>
    Downloads all videos from a playlist, with filenames reflecting the playlist index.
  8. Download Specific Video Format
    Code:
    yt-dlp -f '137+bestaudio' <URL>
    Downloads a specific video and audio format combination, such as 1080p video with the best available audio.
  9. Restrict Filenames
    Code:
    yt-dlp --restrict-filenames <URL>
    Restricts filenames to only ASCII characters.
  10. Limit Download Rate
    Code:
    yt-dlp -r 1M <URL>
    Limits the download rate to 1 Megabyte per second.
  11. Embed Subtitles
    Code:
    yt-dlp --embed-subs <URL>
    Embeds available subtitles into the video.
  12. Download Subtitles
    Code:
    yt-dlp --write-subs <URL>
    Downloads the subtitles along with the video.
  13. Skip Download if File Exists
    Code:
    yt-dlp -ic <URL>
    Skips downloading the video if the file already exists.
  14. Download Part of a Video
    Code:
    yt-dlp --download-sections '*10:00-20:00' <URL>
    Downloads a specific section of the video between 10:00 and 20:00.
  15. Verbose Mode
    Code:
    yt-dlp -v <URL>
    Increases the verbosity of the output for debug purposes.
  16. List Formats Available for Download
    Code:
    yt-dlp -F <URL>
    Lists all available formats for download.
  17. Authenticate with Username and Password
    Code:
    yt-dlp --username <USERNAME> --password <PASSWORD> <URL>
    Authenticates using the specified username and password (useful for private videos).
  18. Ignore Errors
    Code:
    yt-dlp --ignore-errors <URL>
    Continues downloading if errors occur.
  19. Download Age-Restricted Videos
    Code:
    yt-dlp --age-limit 18 <URL>
    Bypasses age restrictions when downloading videos.
  20. Proxy Server
    Code:
    yt-dlp --proxy <PROXY_URL> <URL>
    Uses the specified proxy server for downloading.
  21. Concurrent Downloads
    Code:
    yt-dlp -N 3 <URL>
    Specifies the number of concurrent downloads.
  22. Post Processing Options
    Code:
    yt-dlp --postprocessor-args "-strict -2" <URL>
    Passes specified arguments to postprocessors.
  23. Custom User Agent
    Code:
    yt-dlp --user-agent "<USER_AGENT>" <URL>
    Specifies a custom user agent.
  24. Add Metadata
    Code:
    yt-dlp --add-metadata <URL>
    Embeds metadata into the video file.
  25. Limit File Size
    Code:
    yt-dlp --max-filesize 50M <URL>
    Specifies the maximum file size for the downloaded video.

For more, check out the repo. What others am I leaving out?
 
My go-to command for yt-dlp is this one:

Bash:
% yt-dlp                            \
  --ffmpeg-location /usr/bin/ffmpeg \
  --concurrent-fragments 2          \
  -S 'vcodec:h264,res,acodec:aac'   \
  --merge-output-format mp4         \
  --embed-metadata                  \
  '<URL>'
  • --ffmpeg-location /usr/bin/ffmpeg This tells yt-dlp where to find ffmpeg in case it needs to merge or transcode.
  • --concurrent-fragments 2 This concurrently downloads 2 fragments of the video at a time. For my machine + network, I've found that 2 is a good choice, but it'd be worth trying different values for your machine + network.
  • -S 'vcodec:h264,res,acodec:aac' This sets the sort order for preferred codecs (after which, yt-dlp grabs the best option available). Here I'm saying I prefer a video codec of h264, then if there are multiple streams of that codec, sort by resolution (taking the highest resolution available). If there are multiple streams of h264 with the highest resolution, then prefer the one with an audio codec of aac.
  • --merge-output-format mp4 This ensures mp4 as the container for the resulting output file.
  • --embed-metadata This does exactly what you'd think it does: embeds the title, description, etc as metadata in the output file.
  • I keep the URL in single quotes in case of characters like & or ? are present in the URL (which is quite likely).


I'm definitely interested to hear from others on what flags they find most useful! There're so many options that I'm sure would be useful, but I haven't taken the time to deeply read the documentation or otherwise just haven't come across a reason to use them yet.
 
Last edited:
Thanks for posting @ryanmaynard . I need to setup a pipeline so that I can throw YouTube URLs at _something_ and have it automatically archive them offline for me.
I would be surprised if something like that doesn't exist, but just a simple "take URL, pass it to yt-dlp, stash it somewhere for Jellyfin/Plex to serve it".

Bonus points if I can also tell it "hey, just store the audio of this, actually" so I can tag it and put it in place for Navidrome to serve it as music.
 
@brb3 It's not quite the same as what you're looking for, but I have the following setup currently:

  • I have a systemd timer that kicks off a service every 4 hours.
  • The systemd service just run a little bash script.
  • The bash script reads a text file with each line containing a YouTube channel URL, a space, then a destination directory.
    • For each, I run a yt-dlp command similar to the one I posted above.
    • The extra flags I include are:
      • --lazy-playlist to avoid enumerating a channel's entire list of videos (particularly important for creators that post daily.
      • --match-filter !is_live[/CODE] avoid any live videos [*][ICODE]--download-archive archive.txt to avoid re-downloading an already-downloaded video
      • --part to name the in-progress download files with a .part suffix, so they aren't mistaken for ready-to-view videos.
I'm with you though, I want to setup a similar pipeline where I can just toss a URL at a webpage or send a Telegram message to a bot to fetch videos for me. Lately I've just been begrudgingly logging into my home server via SSH on my phone and running my little script.
 
I spent some time this weekend setting up a rudimentary "click button in browser extension" → yt-dlp pipeline and I learned a few things:

  1. -f best is not always a desirable option. It selects for downloading pre-muxed files which have both the highest quality audio and video at the same time, which (a) is not necessarily the highest quality available if you were to download separate tracks and stitch them together, and (b) is not available at all on some sites. For example, some Vimeo embeds offer no formats with both audio and video together, only individual tracks. For now, it seems like omitting the -f flag and using the default behavior is good enough for me. From the docs:

    Code:
    FORMAT SELECTION
    
    By default, yt-dlp tries to download the best available quality if you don't pass any options.
    This is generally equivalent to using -f bestvideo*+bestaudio/best.

  2. --cookies-from-browser. For downloading private videos, instead of manually specifying a username/password on the command line, I've found that I am typically already logged in to most sites in my current browser. In that case, I can instruct yt-dlp to just fetch my existing cookie for the site and use it alongside any requests. It even supports specifying different containers or browser profiles.

    Bash:
    $ yt-dlp --cookies-from-browser firefox
    $ yt-dlp --cookies-from-browser chrome

  3. --dump-json. I use this to fetch JSON metadata about the video so that I can organize / rename the downloaded file properly. Yes, I know there is the --output option where you can specify a format string, but this doesn't quite give me the logic flexibility or level of control I want over the resulting file names.
 
Back
Top