ytmdl
A terminal UI for downloading audio from YouTube / YouTube Music video, playlist, and album URLs, built on Textual and yt-dlp.
Requirements
- Python 3.10+
- ffmpeg on your
PATH(used for audio extraction, thumbnailembedding, and metadata tagging)
- A Nerd Font in your terminal — the folder browser, the
queue status column, and the command palette all use Nerd Font glyphs; without one they'll show as missing-glyph boxes
Install
python3 -m venv .venv
.venv/bin/pip install -e .
Run
.venv/bin/ytmdl
Or without installing the entry point:
.venv/bin/python -m ytmdl
Paste a video, playlist, or album URL into the input field and press Enter. Playlists and albums are expanded into individual tracks, each downloaded and tagged separately, with up to 2 downloads running concurrently.
The "Saving to:" link below the URL box shows where files are saved. Click it (or press Ctrl+O) to open a folder browser and pick a new destination for any downloads queued from that point on (in-flight downloads keep going to the old directory).
The "Create a folder per playlist/album" switch (on by default) controls whether tracks from a playlist or album URL get saved directly into the save directory, or nested in a subfolder named after the playlist/album title. Single-video URLs are never nested.
Options
ytmdl [-o OUTPUT_DIR] [-f {mp3,m4a,flac,opus,wav,vorbis}]
-o/--output-dir— where files are saved (default~/Music/ytmdl)-f/--format— output audio format (defaultmp3)
Keybindings
Enter— submit the URL in the input boxCtrl+O— open the folder browser to change the download directoryBackspaceor theUpbutton — go to the parent folderEsc— cancel without changing the directory
Ctrl+N— clear finished: remove every completed/errored row from the queue in one go,so you can start a fresh batch. Works no matter what has focus. Also available from the command palette (
Ctrl+P→ "Clear finished").d/Delete— remove the selected queue entry (not while it's actively downloading;select a row first by clicking the table or pressing
Tabuntil it's focused)r— retry a queue entry that errored (same focus requirement as above)q— quit