Fast, parallel CLI music downloader for lucida.to (Qobuz, Amazon Music) with local transcoding and playlist import.
Project description
lucidadl
Fast, parallel command-line music downloader built on top of lucida.to. Search or paste a URL, download tracks and albums in parallel over plain HTTP, organize them by tags, transcode to the format/bitrate you want, and import playlists.
A vibe-coded project. lucidadl was built quickly and AI-assisted ("vibe coding"). It wraps and automates downloading from lucida.to — inspired by two existing open-source lucida downloaders we looked at (see Credits) and adding the features I wanted on top: parallel downloads, local transcoding, tag-based organization, playlist import, existence-aware dedup, and an interactive menu.
Disclaimer. This is a personal-use tool, similar in spirit to
yt-dlp. You are responsible for complying with the terms of service of lucida.to and of the source services, and with the copyright law of your jurisdiction. The authors are not affiliated with lucida.to or any streaming service. Use it for content you are entitled to download.
Features
- Search or URL —
track "artist - title",album "artist - album", or paste a Qobuz/Amazon URL. - Parallel downloads over HTTP (
--jobs N) — no browser kept open, low RAM. - Albums = track by track, expanded and downloaded in parallel (faster than the native album zip).
- Local transcoding with ffmpeg (
--to mp3 --bitrate 320k) — bundled, nothing to install. Tags and cover art preserved. - Tag-based organization into
Artists/<Artist>/<Album>/…(falls back to the source's artist/album metadata when a file has no embedded tags, so nothing lands in "Unknown"); playlists go underPlaylists/<name>/, kept separate from artists. - Watchlists with dedup (
tracks/albumsread a file, skip what's done — but a file you deleted is re-downloaded;--forceignores the memory entirely). - Playlist import — paste a playlist link and get every track via lucida. Apple Music is wired up today; adding more sources is easy (PRs welcome).
- Interactive search, service fallback (Qobuz → Amazon), retry of failures.
- Interactive menu (
lucida ui, or justlucida) and live progress bars — one bar per parallel download, in any real terminal.
How it works (Cloudflare)
lucida.to is behind Cloudflare and plain HTTP gets a 403. lucidadl solves the
challenge once in a real browser (setup), caches the cf_clearance cookie, then
runs everything else over httpx — no browser stays open. The browser is only
re-opened briefly if the cookie expires. Solving the challenge needs a logged-in
desktop session (it can't run on a locked/headless server).
Requirements
- Python 3.10+
- A desktop session for the one-time Cloudflare
setup(Windows/macOS/Linux).
Install
pip install adds a global lucida command (alias: lucidadl).
Already using lucida-downloader? Its binary is also called
lucida, so the two clash on yourPATH. Just use thelucidadlalias for this tool (e.g.lucidadl track "…",lucidadl ui) — every command below works the same withlucidadlin place oflucida.
Recommended — isolated, on PATH (pipx):
pip install --user pipx && python -m pipx ensurepath # once, if you don't have pipx
git clone https://github.com/Jude-A/lucidadl
pipx install ./lucidadl
pipx run playwright install chromium # one-time: download the browser
Or with plain pip (into your Python; its Scripts/bin must be on PATH):
git clone https://github.com/Jude-A/lucidadl
cd lucidadl
pip install . # or `pip install -e .` to keep editing the code
playwright install chromium
Open a new terminal afterwards so lucida is picked up. ffmpeg is bundled
(imageio-ffmpeg) — nothing to install.
Quick start
lucida setup # once: pass Cloudflare, cache the cookie
lucida # interactive menu (same as `lucida ui`)
lucida track "Red Hot Chili Peppers - Otherside"
lucida album "Red Hot Chili Peppers - Californication" --to mp3 --bitrate 320k -j 8
Prefer a menu? Run lucida with no arguments (or lucida ui): pick an action, type a
query/URL, and watch one progress bar per parallel download. Your menu defaults
(jobs, service, format, folder) are remembered.
Files land in one fixed folder — ~/Downloads/music by default (not the current
directory, so they never scatter). Change it once with lucida config --music "D:/Music"
(or the LUCIDADL_MUSIC env var), or per run with -o.
Commands
Singular = ad-hoc (arguments, always downloads). Plural = watchlist (reads a file, skips already-downloaded items — for unattended/scheduled runs).
| Command | Input | Dedup |
|---|---|---|
lucida / lucida ui |
interactive menu | — |
lucida track "<query|url>" |
argument(s) | no (force) |
lucida album "<query|url>" |
argument(s) | no (force) |
lucida tracks |
./inputs/tracks.txt |
yes |
lucida albums |
./inputs/albums.txt |
yes |
lucida playlist "<apple music url>" |
public playlist | yes |
lucida search "<query>" |
interactive pick | no |
lucida retry |
failed list | yes |
lucida config |
show/set the music folder | — |
lucida setup |
— | — |
lucida doctor |
environment check | — |
A search takes the best-matching result (title + artist, avoiding remix/cover/karaoke/ live/… unless you ask for them). A playlist/album URL downloads all its tracks.
Options (download commands)
-j, --jobs N— parallel downloads, 1–20 (default 3).-s, --service—qobuz(default) oramazon. If the primary finds nothing, it falls back to the other automatically.-F, --format— format requested from lucida (server-side, no bitrate control):original(default) ·flac·mp3·ogg-vorbis·opus·m4a-aac·wav.--to— local ffmpeg transcode (recommended for a precise format/bitrate):mp3·aac/m4a·opus·ogg·flac·wav. Downloads FLAC then converts.--bitrate— e.g.320k,256k,192k(for--to).--keep-original— keep the source FLAC next to the transcoded file.--force— ignore the dedup memory and re-download even items already recorded as done (handy ifstate.jsondrifted out of sync).--organize / --flat— tag-basedArtists/<Artist>/<Album>/(default) vs everything flat in<music folder>/Music/.--country— country code (defaultUSfor Qobuz; Amazon needs none).-o, --out— output directory for this run (default: the configured music folder,~/Downloads/music).--hidden / --visible— if a Cloudflare refresh is needed, open the window off-screen (--hidden) instead of visible.
Watchlists
Copy the example files and edit them — one item per line (a search artist - title,
or a direct URL):
cp inputs/tracks.txt.example inputs/tracks.txt
cp inputs/albums.txt.example inputs/albums.txt
then:
lucida tracks # downloads everything new, skips what's already done
lucida albums
Playlists
lucida playlist "https://music.apple.com/.../pl.xxxxxxxx" [--dry-run] [-j N]
Give it a playlist link: lucidadl reads the track list (title + artist) straight from the
page, then downloads each track through lucida (Qobuz) into Playlists/<playlist name>/.
--dry-run just lists them (and writes ./inputs/playlist.txt) without downloading.
Only Apple Music is implemented today — that's what I use. Adding other sources
(Spotify, Deezer, Tidal…) is straightforward, and contributions are welcome. The playlist
scraping all lives in lucidadl/api.py:
playlist_tracklist()— picks a scraper based on the link's host.applemusic_tracklist()— the working Apple Music scraper (your reference example)._scrape_playlist()+_PLAYLIST_SOURCES— a generic scraper with per-site CSS selectors (best-guess starting points for Spotify/Deezer/Tidal), gated behind the_PLAYLIST_OTHERS_ENABLEDflag.
To add a source: flip _PLAYLIST_OTHERS_ENABLED = True, fix the selectors for your
service in _PLAYLIST_SOURCES, test, and open a PR.
Scheduling / "in the background"
The cookie is cached, so unattended runs open no browser (until it expires). Schedule a
watchlist with your OS scheduler. A Windows example is provided in schedule.ps1.
Where files live
- Music: one fixed folder,
~/Downloads/musicby default. Set it withlucida config --music "<path>"or theLUCIDADL_MUSICenv var;lucida config(no args) prints every path. Everything is saved here and deduped against here only. - App data (browser profile,
clearance.json, dedupstate.json,config.json,run.log,failed.txt): the OS user data dir (%LOCALAPPDATA%\lucidadlon Windows,~/.local/share/lucidadlon Linux,~/Library/Application Support/lucidadlon macOS). Override withLUCIDADL_HOME. - Watchlist inputs (
tracks.txt,albums.txt):./inputs/next to where you run the command, so you can keep them in your project. Override per command with-f.
Troubleshooting
- Everything lands in
Unknown Artist/Unknown Album→mutagenis missing in the Python that runslucida(tags can't be read).pip install mutageninto that interpreter (it's a declared dependency, so a normalpip install ./pipxinstall pulls it). lucidadl now prints a warning when it's absent. - "Cloudflare not cleared" → run
lucida setupagain (the cached cookie expired). - "Executable doesn't exist" → run
playwright install chromium. - Search finds nothing → try a direct URL, or
-s amazon. lucida doctor→ checks Python, Playwright, and reachability.
Credits
lucidadl takes inspiration from two existing open-source lucida.to downloaders we looked at while building it:
- lucida-flow — a Python CLI/API that drives lucida.to through browser automation; the starting point for the browser side.
- lucida-downloader — a fast, multithreaded Rust client; the inspiration for downloading many tracks concurrently.
It's a "vibe-coded" project (built quickly, AI-assisted), so expect rough edges — issues and PRs that sharpen or extend it are very welcome.
Contributing
Bug reports and PRs welcome — see CONTRIBUTING.md for the dev setup and how to run the offline self-tests. Notable changes are tracked in CHANGELOG.md.
License
MIT — see LICENSE.
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 lucidadl-0.1.1.tar.gz.
File metadata
- Download URL: lucidadl-0.1.1.tar.gz
- Upload date:
- Size: 46.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7cc6a64bb0aea39cc7aef47948473703857ec3657ae0a2e5b38ad48ba27f6790
|
|
| MD5 |
5649238c4baecf0b301d811642566058
|
|
| BLAKE2b-256 |
6d16e2fcb9d335267fe637d9e528f45717edb857da18ed0209634a325c4a37d6
|
File details
Details for the file lucidadl-0.1.1-py3-none-any.whl.
File metadata
- Download URL: lucidadl-0.1.1-py3-none-any.whl
- Upload date:
- Size: 46.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
45ae3fca67711306cd816ee3d5ee1d71335d2c0bc267cddf41e6f92e100074a3
|
|
| MD5 |
c351b944e1f726764a57b8df52c8617c
|
|
| BLAKE2b-256 |
3458a401f0d0853faccace9715728e247ce8128ba5f01629c01b005d796146b3
|