A command-line tool to download music by artist or album, with automatic metadata tagging and album artwork.
Built with Python, yt-dlp, and the MusicBrainz API.
- Search any artist by name
- Browse their full discography instantly
- Download a specific album or entire discography
- YouTube + SoundCloud as sources (automatic fallback)
- Automatically embeds metadata (title, artist, album, track number, year)
- Downloads album artwork and embeds it in files
- Skips already-downloaded tracks automatically
- Caches MusicBrainz lookups so repeat searches are instant
- Organizes files into
Music/Artist/Album (Year)/folders - Handles explicit track names (profanity filter for search queries)
- SQLite library to track everything you've downloaded
- Pretty tables and progress bars (with
rich)
- Python 3.8+
- FFmpeg — required for audio conversion
1. Clone the repo
git clone https://github.com/knullxx/musicdl.git
cd musicdl2. Install Python dependencies
pip install -r requirements.txt3. Install FFmpeg
- Windows:
winget install ffmpeg
- Mac:
brew install ffmpeg
- Linux:
sudo apt install ffmpeg
4. Verify setup
python test_setup.pypython main.py helppython main.py download "Drake" --album "Take Care"python main.py download "Drake" --track "God's Plan"python main.py download "Drake"python main.py download "Drake" --album "Take Care" --dry-runpython main.py download "Drake" --album "Take Care" --format flacpython main.py download "Drake" --album "Take Care" --output "D:\Music"python main.py download "Drake" --type album
python main.py download "Drake" --type ep
python main.py download "Drake" --type singlepython main.py download "Drake" --limit 3python main.py download "Drake" --album "Take Care" --retag# Search without downloading
python main.py search "Kendrick Lamar"
# List your downloaded library
python main.py list
# Search your library
python main.py list --query "take care"
# Library stats
python main.py stats
# Find similar artists
python main.py similar "Drake"
# Find duplicate tracks
python main.py duplicates
# Import existing music folder
python main.py scan --dir "C:\Users\you\Music"
# Show current config
python main.py configFiles are saved to ~/Music/ by default:
Music/
└── Drake/
└── Take Care (2011)/
├── cover.jpg
├── 01 Take Care.mp3
├── 02 Crew Love.mp3
└── ...
musicdl/
├── core/
│ ├── models.py # Data classes (Artist, Album, Track, etc.)
│ └── exceptions.py # Custom exceptions
├── config/
│ └── settings.py # Configuration
├── metadata/
│ ├── musicbrainz.py # MusicBrainz API client
│ ├── tagger.py # Embeds ID3/MP4/FLAC/OGG tags
│ ├── artwork.py # Downloads album art
│ ├── cache.py # Disk-based metadata cache
│ └── similar.py # Similar artist suggestions
├── download/
│ ├── pipeline.py # Orchestrates the full download flow
│ ├── downloader.py # Async yt-dlp downloader
│ └── organizer.py # Builds folder structure and file paths
├── resolvers/
│ ├── base.py # Abstract resolver base class
│ ├── ytdlp.py # YouTube resolver
│ ├── soundcloud.py # SoundCloud resolver (fallback)
│ └── spotify.py # Spotify URL parser
├── library/
│ ├── database.py # SQLite library database
│ └── manager.py # Library search, scan, dedup, stats
├── ui/
│ └── progress.py # Pretty tables and progress bars
└── utils/
└── __init__.py # Shared helpers
main.py # CLI entry point
test_setup.py # Dependency checker
Settings live in ~/.musicdl/config.yaml:
output_dir: ~/Music
audio_format: mp3 # mp3, m4a, flac, opus
audio_quality: 320k
max_threads: 4
skip_existing: true
download_artwork: true
embed_metadata: trueNo releases found — Try picking a different number from the artist list. There may be multiple artists with the same name.
FFmpeg not found — Install FFmpeg and make sure it's on your PATH.
Track skipped — The track couldn't be found on YouTube or SoundCloud. Try again later or check if it's available online.
Slow first run — MusicBrainz is rate-limited to 1 req/sec. Results are cached after the first run so it's instant next time.
This tool is for personal and educational use only. Only download music you have the right to access.
Found a bug? Open an issue on GitHub
MIT