youtube-downloader (1.0.0)
Installation
pip install --index-url youtube-downloaderAbout this package
CLI tool to download YouTube playlists, liked videos, and individual videos
youtube-downloader
CLI tool to download YouTube playlists, your Liked Videos list, or individual videos with resumable re-runs and clear reporting of deleted/private videos.
Install
uv sync
This creates .venv and installs the package with its dev dependencies (pytest, ruff, mypy, pre-commit). Without uv, fall back to pip 25.1+:
python3 -m venv .venv
.venv/bin/pip install -e . --group dev
One-time setup
Your Liked Videos list is private, so the tool needs to read cookies from a browser you're logged into YouTube with:
uv run youtube-downloader config set-cookies-browser firefox
Supported browser values: chrome, firefox, edge, brave, and others supported by yt-dlp's --cookies-from-browser.
Usage
Prefix commands with uv run (e.g. uv run youtube-downloader liked) unless the venv is activated.
youtube-downloader liked # download your Liked Videos
youtube-downloader liked -n 20 # only download 20 new videos this run
youtube-downloader liked --start 1 --end 50 # only consider the first 50 liked videos
youtube-downloader liked --dry-run # preview what would download, no downloading
youtube-downloader playlist <URL> # download a playlist
youtube-downloader playlist <URL> -n 10 # only download 10 new videos from it
youtube-downloader video <URL> [<URL> ...] # download one or more individual videos
youtube-downloader config show # see current defaults
video accepts full URLs (https://www.youtube.com/watch?v=..., https://youtu.be/...) or bare video IDs, and any number of them in one call.
Options
All three download commands (liked, playlist, video) accept:
| Option | Default | Description |
|---|---|---|
-o, --output-dir <path> |
~/Videos/YouTube |
Directory to save videos into. |
--browser <name> |
config default | Browser to read cookies from (chrome, firefox, edge, brave, ...). Required for liked. |
--format-preset <mp4|best|audio-only> |
mp4 |
mp4 (best mp4-compatible video+audio), best (best available, any container), or audio-only (extract to mp3). |
--archive-file <path> |
<output-dir>/.youtube-downloader/archive.txt |
Download-archive file used to track already-downloaded videos. |
--dry-run |
off | List what would be downloaded without downloading anything. |
--no-progress |
off | Suppress per-file progress output (quiet mode). |
liked and playlist additionally accept:
| Option | Default | Description |
|---|---|---|
-n, --limit <n> |
unlimited | Stop after this many new videos are downloaded (already-archived videos don't count against it). |
--start <n> |
1 | 1-based position in the list to start enumerating from. |
--end <n> |
end of list | 1-based position in the list to stop enumerating at. |
Any option can also be set as a persistent default (see Configuration) so you don't have to repeat --browser/--output-dir/--format-preset on every run.
Re-running any command skips videos already downloaded (tracked via the archive file) and only fetches new ones. Deleted/private/unavailable videos are skipped automatically and listed in the end-of-run summary — they'll be retried automatically if they ever become available again. --dry-run runs are never recorded to the archive file or the run log.
Configuration
youtube-downloader config show prints the resolved config file path (~/.config/youtube-downloader/config.toml) and current defaults. youtube-downloader config set-cookies-browser <browser> is the only setting with a dedicated command; other defaults (output_dir, format_preset, archive_file) can be set by editing the TOML file directly:
[defaults]
browser = "firefox"
output_dir = "/home/you/Videos/YouTube"
format_preset = "mp4"
archive_file = "/home/you/Videos/YouTube/.youtube-downloader/archive.txt"
Command-line flags always override config file defaults.
Development
uv run pytest # run tests
uv run ruff check . # lint
uv run ruff format . # format
uv run mypy # type-check
Unit tests cover config parsing, unavailable-video classification, and summary formatting. End-to-end downloading (auth, real playlists) requires manual verification against a real YouTube account/browser.
pre-commit hooks are configured in .pre-commit-config.yaml; run pre-commit install once after cloning to enable them.
Releasing
Pushing a tag matching v*.*.* triggers .forgejo/workflows/publish.yml, which builds the package, creates a Forgejo release with the built sdist/wheel attached, and uploads them to this instance's package registry. To cut a release:
- Bump
versioninpyproject.toml. - Commit and push to
main. - Tag the commit and push the tag, e.g.
git tag v1.1.0 && git push origin v1.1.0.
The workflow refuses to publish if the tag doesn't match pyproject.toml's version. Requires a repo secret PUBLISH_TOKEN set in the repo settings; a personal access token scoped to both write:package (registry upload) and write:repository (release creation).