Download music from Bilibili, YouTube, YouTube Music, Spotify, and Soulseek (P2P) with automatic search, audio conversion, metadata cleanup, and zero-config dependency setup.
MelodyMine runs as a standalone CLI or as a file-based skill for AI assistants โ WorkBuddy, Hermes, and OpenClaw. It auto-detects each platform's bundled Python runtime (WorkBuddy/Hermes ship one; OpenClaw users install Python once), so first-run setup is a single command on any of them.
- Bilibili for Chinese music queries, using direct WBI search plus
yt-dlp. - YouTube for English and international music queries.
- YouTube Music catalog search via
ytmusicapi(no cookies needed for search). - Spotify URL downloads through spotDL.
- Soulseek P2P downloads via
aioslskโ multi-candidate retry with FLACโMP3 fallback. - Automatic, zero-config setup: auto-detects the host assistant's Python runtime (WorkBuddy/Hermes bundled, uv-managed, or system), installs pip packages, and falls back to
imageio-ffmpegfor ffmpeg. - Shared dependency layer (
melodymine_common.py) with a unified venv โ dependencies install once and are reused across both helpers and every supported assistant. - Metadata cleanup with title, artist, album, cover, and
Artist - Titlerenaming. - Proxy and cookies support for restricted networks or YouTube bot checks.
From the repository or skill root:
python scripts/music_helper.py setup
python scripts/music_helper.py download "ๅจๆฐไผฆ ็จป้ฆ"
python scripts/music_helper.py download "The Weeknd Blinding Lights"The only hard prerequisite is Python 3.10+. setup installs the Python packages MelodyMine needs.
Download a Chinese song. Auto mode prefers Bilibili:
python scripts/music_helper.py download "ๅจๆฐไผฆ ็จป้ฆ"Download an English song. Auto mode prefers YouTube:
python scripts/music_helper.py download "The Weeknd Blinding Lights"Download from a Spotify URL:
python scripts/music_helper.py download "https://open.spotify.com/track/..."Download from a NetEase URL (resolved to song name, then Bilibili/YouTube):
python scripts/music_helper.py download "https://music.163.com/song?id=185809"Download from a direct URL (YouTube / SoundCloud / Bandcamp):
python scripts/music_helper.py download "https://www.youtube.com/watch?v=..."
python scripts/music_helper.py download "https://soundcloud.com/artist/song"
python scripts/music_helper.py download "https://artist.bandcamp.com/track/song"Search without downloading:
python scripts/music_helper.py search "ๅจๆฐไผฆ ็จป้ฆ"
python scripts/music_helper.py search "The Weeknd" --platform youtubeForce a platform:
python scripts/music_helper.py download "ๅจๆฐไผฆ ็จป้ฆ" --platform bilibili
python scripts/music_helper.py download "The Weeknd Blinding Lights" --platform youtube
python scripts/music_helper.py download "Air Supply Complete" --platform soulseekChoose format, bitrate, output folder, or search result:
python scripts/music_helper.py download "ๅจๆฐไผฆ ็จป้ฆ" --format flac --bitrate 320K
python scripts/music_helper.py download "็จป้ฆ" --index 2
python scripts/music_helper.py download "Artist Song" --output "D:\Music"Use a proxy for YouTube when direct access fails:
python scripts/music_helper.py download "The Weeknd Blinding Lights" --proxy socks5://HOST:PORTUse cookies when YouTube asks for sign-in or bot confirmation:
python scripts/music_helper.py download "Artist Song" --cookies "D:\path\cookies.txt"Update metadata for an already-downloaded file:
python scripts/music_helper.py meta "D:\Music\song.mp3"
python scripts/music_helper.py meta "D:\Music\song.mp3" --query "ๅจๆฐไผฆ ็จป้ฆ"Check dependencies:
python scripts/music_helper.py checkpython scripts/music_helper.py download "query" [options]
Options:
--platform {auto,bilibili,youtube,ytmusic,soulseek}
Default: auto
--format {auto,mp3,flac,m4a,opus,wav,vorbis}
Default: auto (flac if lossless, else mp3 320K)
--output PATH
--proxy URL e.g. socks5://host:port
--cookies PATH cookies.txt for YouTube checks
--bitrate RATE e.g. 320K
--index N 1-based search result index
--no-thumbnail
--no-metadata
--dry-run Preview command without executing
--json Machine-readable JSON output
--slsk-user USER Soulseek username (or set SLSK_USERNAME env var)
--slsk-pass PASS Soulseek password (or set SLSK_PASSWORD env var)
python scripts/music_helper.py meta "filepath" [options]
Options:
--query QUERY Search query for metadata lookup (default: derive from filename)
--no-thumbnail Skip cover art embedding
--json Machine-readable JSON output
| Input | Default Route | Notes |
|---|---|---|
| Chinese query | Soulseek โ Bilibili โ YouTube | Soulseek first for lossless P2P (~30s timeout), then Bilibili, then YouTube. Use --quick to skip Soulseek. |
| English or non-Chinese query | Soulseek โ YouTube | Soulseek first for lossless P2P, then YouTube. Use --quick to skip Soulseek. |
| Spotify URL | spotDL | Auto-installs spotDL on first use if possible. |
NetEase URL (music.163.com) |
NetEase direct โ Bilibili/YouTube | Song name resolved via NetEase API. Tries NetEase CDN direct download first (free songs), falls back to Bilibili/YouTube if copyrighted. |
| YouTube/SoundCloud/Bandcamp URL | yt-dlp direct | No search step โ downloads the URL directly. YouTube may need --proxy. |
Soulseek P2P (--platform soulseek) |
Soulseek network | Searches direct from sharers. Requires SLSK_USERNAME and SLSK_PASSWORD env vars. Downloads via single persistent session with multi-candidate retry. Auto-fallback after YouTube. Proxy auto-detected from ALL_PROXY/HTTP_PROXY env vars or common Clash ports (7897/7890/1080); proxies all connections (server + peer). |
| Chinese query โ YouTube fail โ Soulseek | Auto-fallback | When Bilibili & YouTube both fail, Soulseek is tried automatically. |
Use scripts/spotify_helper.py for playlist sync, metadata-only saves, URL resolution, or metadata updates:
python scripts/spotify_helper.py sync "https://open.spotify.com/playlist/..." --save-file playlist.spotdl
python scripts/spotify_helper.py save "https://open.spotify.com/album/..." --save-file album.spotdl
python scripts/spotify_helper.py url "Artist - Song"
python scripts/spotify_helper.py meta "D:\Music\song.mp3"
python scripts/spotify_helper.py meta "D:\Music\song.mp3" --query "Artist - Song"See references/usage.md for spotDL option details and references/config.md for spotDL configuration fields.
Copy this folder to your assistant's skills directory:
| Platform | Example path |
|---|---|
| WorkBuddy | ~/.workbuddy/skills/melodymine/ |
| OpenClaw | ~/.openclaw/workspace/skills/melodymine/ |
| Hermes | ~/.hermes/skills/melodymine/ |
| Custom | Any directory your assistant scans for file-based skills |
Runtime note: WorkBuddy and Hermes ship a bundled Python that MelodyMine auto-detects on first run. OpenClaw runs on Node.js and does not bundle Python, so OpenClaw users must install Python 3.10+ from python.org before first use โ
setupwill then locate it.
Then restart the assistant and ask naturally:
ไธ่ฝฝๅจๆฐไผฆ็็จป้ฆ
Download Blinding Lights by The Weeknd
ไธ่ฝฝ่ฟไธช https://open.spotify.com/track/...
The assistant should read SKILL.md, run setup if needed, execute the download command, and report the saved path.
| Problem | Fix |
|---|---|
| No Python found | Install Python 3.10+ from python.org, then rerun setup. |
Bilibili 412 Precondition Failed |
Retry after a few seconds; the helper already retries once. |
| YouTube timeout | Retry with --proxy socks5://HOST:PORT if you have a proxy. |
| YouTube asks for sign-in or bot confirmation | Export YouTube cookies to cookies.txt and pass --cookies PATH. |
Spotify KeyError: 'uri' |
Search by song name instead of Spotify URL, or use spotify_helper.py --use-official-api when appropriate. |
| Metadata is wrong | Retry with a more exact Artist Song query or add --no-metadata. |
MelodyMine/
โโโ SKILL.md
โโโ README.md
โโโ scripts/
โ โโโ melodymine_common.py # Shared infra: Python/venv/pip/ffmpeg/proxy detection
โ โโโ music_helper.py # Main setup/search/download helper
โ โโโ spotify_helper.py # Advanced spotDL operations
โ โโโ soulseek_client.py # Soulseek P2P search/download (aioslsk)
โ โโโ bili_client.py # Bilibili WBI API search (stdlib only)
โ โโโ netease_client.py # NetEase Cloud Music API client (stdlib only)
โ โโโ ytmusic_client.py # YouTube Music API search (ytmusicapi)
โ โโโ mbrainz_client.py # MusicBrainz metadata lookup (stdlib only)
โ โโโ cover_client.py # Cover art downloader (stdlib only)
โ โโโ requirements.txt
โโโ tests/
โ โโโ test_helpers.py # Unit tests for pure functions (stdlib unittest)
โ โโโ test_api_clients.py # Unit tests for API client modules
โ โโโ test_ytmusic_client.py# Unit tests for YouTube Music search
โ โโโ test_soulseek_client.py # Unit tests for Soulseek client helpers
โโโ references/
โโโ usage.md # spotDL CLI reference
โโโ config.md # spotDL config reference
MelodyMine is for personal learning and archival use only. Downloading copyrighted audio may be illegal in your jurisdiction regardless of intent. Do not distribute, share, or monetize downloaded files. You are solely responsible for complying with your local laws and the terms of service of Bilibili, YouTube, and Spotify.
This project:
- does not host, store, or transmit any copyrighted content,
- does not bypass digital rights management (DRM),
- is not affiliated with or endorsed by Bilibili, YouTube, Spotify, NetEase, Apple, or MusicBrainz.
If you are a rights holder and believe this tool facilitates infringement, open an issue. The maintainers will cooperate.
MIT. See LICENSE.