CLI tool to download YouTube playlists as audio with metadata
Project description
ytmusic-cli
CLI tool to download YouTube playlists as audio with rich metadata.
ytmusic-cli downloads YouTube playlists as properly tagged audio files. It automatically identifies songs using the iTunes API, strips promotional noise from YouTube titles, deduplicates repeat versions, and embeds cover art and metadata directly into your music library.
Features
- Smart title parsing - Extracts clean artist and song names from messy YouTube titles
- Automatic deduplication - Keeps the best version when the same song appears multiple times (studio > live > acoustic > remix)
- iTunes metadata - Fetches official album art, artist, and album information
- Configurable matching - Adjust similarity threshold to balance accuracy vs. coverage
- Persistent configuration - Set default options in a config file
- Smart caching - SQLite-based cache speeds up repeat downloads
- Clean output - Files named as "Artist - Song Title.m4a" with embedded metadata
Installation
From PyPI (recommended)
pip install ytmusic-cli
Or with pipx (isolated environment):
pipx install ytmusic-cli
From source
git clone https://github.com/ilyeshdz/ytmusic.git
cd ytmusic
pip install -e .
Requirements
- Python 3.10+
- See
pyproject.tomlfor dependencies
Usage
Basic
# Download a playlist
ytmusic "https://www.youtube.com/playlist?list=PLAYLIST_ID"
# Or just the playlist ID
ytmusic "PL..."
Common Options
# Custom output directory
ytmusic "PLAYLIST_URL" -o ~/Music
# Stricter metadata matching (0.0-1.0, default: 0.5)
ytmusic "PLAYLIST_URL" -t 0.7
# Preview what would be downloaded (no actual download)
ytmusic "PLAYLIST_URL" --dry-run
# Skip existing files (sync mode)
ytmusic "PLAYLIST_URL" --sync
# Quiet mode (errors only)
ytmusic "PLAYLIST_URL" -q
Configuration File
Set persistent defaults at ~/.config/ytmusic/config.yaml:
# Show config location
ytmusic --config
Example config:
download:
path: "~/Music" # Output directory
sync: false # Skip existing files
quiet: false # Only show errors
metadata:
threshold: 0.5 # Similarity threshold 0.0-1.0
Config precedence: CLI args > Config file > Built-in defaults
How It Works
- Playlist Fetch - Retrieves all video URLs from the playlist
- Pre-scan - Analyzes titles and detects duplicates before downloading
- Title Parse - Cleans promotional noise and extracts artist/song
- Metadata Search - Queries iTunes API with smart retry and caching
- Similarity Check - Compares titles; skips if below threshold
- Download - Gets highest-quality audio-only stream
- Tag & Save - Embeds metadata and cover art, saves as "Artist - Song.m4a"
Output Organization
music_library/
└── Playlist Name/
├── Artist A - Song One.m4a
├── Artist B - Song Two.m4a
└── ...
All files include embedded cover art and metadata (artist, album, year, genre when available).
Similarity Threshold Guide
| Threshold | Result |
|---|---|
| 0.3 | Lenient - More songs, less accurate matches |
| 0.5 | Balanced (default) - Good mix of coverage and accuracy |
| 0.7 | Strict - Fewer songs, more reliable matches |
| 0.9 | Very strict - Only near-exact matches |
License
MIT © 2026 Ilyes Hernandez
Contributing
Pull requests welcome. Please ensure tests pass:
# Run tests
pytest
# Lint and format
ruff check .
ruff format .
Support
- GitHub Issues - Bug reports and feature requests
- PyPI Project - Package information and releases
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ytmusic_cli-1.6.0.tar.gz.
File metadata
- Download URL: ytmusic_cli-1.6.0.tar.gz
- Upload date:
- Size: 38.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d18364f6f036ef15886767f0095f7aeb83f3eb9703447de434add9d5bb3c823a
|
|
| MD5 |
19f18b76918cf29864eb165b291b7671
|
|
| BLAKE2b-256 |
85ab9d2061a3f52b6022b0592fb2ec9dfd9ecc621cb1a19c4361d2fcc9ebedc2
|
Provenance
The following attestation bundles were made for ytmusic_cli-1.6.0.tar.gz:
Publisher:
release.yml on ilyeshdz/ytmusic
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ytmusic_cli-1.6.0.tar.gz -
Subject digest:
d18364f6f036ef15886767f0095f7aeb83f3eb9703447de434add9d5bb3c823a - Sigstore transparency entry: 1274308384
- Sigstore integration time:
-
Permalink:
ilyeshdz/ytmusic@832df85548d369ee29fd58b7ebf3c98b07fa04aa -
Branch / Tag:
refs/tags/v1.6.0 - Owner: https://github.com/ilyeshdz
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@832df85548d369ee29fd58b7ebf3c98b07fa04aa -
Trigger Event:
push
-
Statement type:
File details
Details for the file ytmusic_cli-1.6.0-py3-none-any.whl.
File metadata
- Download URL: ytmusic_cli-1.6.0-py3-none-any.whl
- Upload date:
- Size: 39.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
497cf0c2b1b0efd30cd3d1b54793613273271aae41931d378c49cffaa0a696a9
|
|
| MD5 |
be636fbc073de5f06382e33badd842d7
|
|
| BLAKE2b-256 |
e202fc06289efde26e2f38bb3beabf325ccf17c87079a42792971169b69de34f
|
Provenance
The following attestation bundles were made for ytmusic_cli-1.6.0-py3-none-any.whl:
Publisher:
release.yml on ilyeshdz/ytmusic
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ytmusic_cli-1.6.0-py3-none-any.whl -
Subject digest:
497cf0c2b1b0efd30cd3d1b54793613273271aae41931d378c49cffaa0a696a9 - Sigstore transparency entry: 1274308457
- Sigstore integration time:
-
Permalink:
ilyeshdz/ytmusic@832df85548d369ee29fd58b7ebf3c98b07fa04aa -
Branch / Tag:
refs/tags/v1.6.0 - Owner: https://github.com/ilyeshdz
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@832df85548d369ee29fd58b7ebf3c98b07fa04aa -
Trigger Event:
push
-
Statement type: