music-download
Download personal playlists / search hits with musicdl, then prepare an
import-ready folder (audio + same-name .lrc) for local players.
Language: match the user. Prefer Chinese when the user writes Chinese.
Hard rules
- Personal / educational use only. Do not help mass redistribution or commercial piracy. Remind the user to respect copyright and platform ToS.
- Never print, commit, or paste full Cookie values into chat, git, or logs.
Store cookies only in a local file with mode
600(e.g.qq-cookies.txt). - Default quality is “good enough to listen” (compact MP3 ~192 kbps after download), not lossless. Only keep FLAC / pass VIP cookies when the user explicitly asks for high quality / Hi-Res.
- Prefer writing files under a clear library root, e.g.
$MUSIC_LIBRARYor~/Music/musicdl-library/or a path the user chooses. - After work, always give the user the absolute path of the folder to import.
OneMusic import contract (verified)
OneMusic accepts:
| Item | Detail |
|---|---|
| Audio | mp3, m4a, flac, wav, aac, aiff, alac, caf — not ogg (convert first) |
| Import | Folder (recursive) or ZIP via Import Music |
| Lyrics | Sidecar same-basename.lrc next to the audio (preferred), or embedded lyrics tags |
| Dedupe | Content hash — re-importing the same files is safe |
Workflow for the user:
- Open OneMusic (Mac/iOS).
- Import Music → select the prepared folder.
- Play a track → open lyrics panel to verify
.lrcsync.
Setup (first run)
Skill scripts live in ${SKILL_DIR}/scripts (directory containing this SKILL.md
plus scripts/).
SKILL_DIR="$(cd "$(dirname "$0")/.." 2>/dev/null; pwd)" # when inside scripts/
# From agent: resolve path of this skill's SKILL.md parent as SKILL_DIR
bash "${SKILL_DIR}/scripts/setup.sh"
# creates ${SKILL_DIR}/.venv and installs musicdl + browser-cookie3
Requirements:
- Python 3.10+
ffmpegon PATH (for ogg→mp3 and compact re-encode)- Network access to music platforms
Optional env:
export MUSIC_LIBRARY="$HOME/Music/musicdl-library"
Default quality policy
| Goal | What to do |
|---|---|
| Default (recommended) | Download → compress_for_import.py → 192 kbps MP3 + copy .lrc |
| User wants smaller | --bitrate 128k |
| User wants better | --bitrate 256k or skip compress (keep platform file) |
| User wants lossless / VIP | Keep FLAC; optionally extract cookies (below) |
Cookie / login is optional, not required for basic downloads. Only use when:
- Many tracks fail without login, or
- User explicitly wants higher platform quality
Workflow A — QQ / NetEase playlist (primary)
User provides a share URL, e.g.
https://y.qq.com/n/ryqq_v2/playlist/4211293243
source "${SKILL_DIR}/.venv/bin/activate"
python "${SKILL_DIR}/scripts/download_playlist.py" "PLAYLIST_URL" \
--out "${MUSIC_LIBRARY:-$HOME/Music/musicdl-library}/from-playlists"
Then compact for import (default path import-ready/):
python "${SKILL_DIR}/scripts/compress_for_import.py" \
--src "${MUSIC_LIBRARY:-$HOME/Music/musicdl-library}/from-playlists" \
--out "${MUSIC_LIBRARY:-$HOME/Music/musicdl-library}/import-ready" \
--bitrate 192k
Tell the user to import the absolute --out path (or the subfolder named after the playlist).
Workflow B — keyword / popular songs batch
# songs.txt: one query per line, prefer "歌名 歌手"; # comments allowed
python "${SKILL_DIR}/scripts/download_songs.py" \
--list "${SKILL_DIR}/references/songs.example.txt" \
--out "${MUSIC_LIBRARY:-$HOME/Music/musicdl-library}/popular" \
--limit 40
python "${SKILL_DIR}/scripts/compress_for_import.py" \
--src "${MUSIC_LIBRARY:-$HOME/Music/musicdl-library}/popular" \
--out "${MUSIC_LIBRARY:-$HOME/Music/musicdl-library}/import-ready/popular" \
--bitrate 192k
Optional cookies (higher quality / harder playlists)
Only when needed:
# macOS Chrome logged into y.qq.com — may prompt Keychain access
python "${SKILL_DIR}/scripts/extract_cookies.py" --domain qq.com \
--out "${MUSIC_LIBRARY:-$HOME/Music/musicdl-library}/qq-cookies.txt"
download_playlist.py auto-loads qq-cookies.txt next to the out dir or
MUSIC_LIBRARY if present. Do not echo cookie contents.
Manual fallback: user pastes Cookie header from DevTools into that file themselves.
Interactive search (musicdl CLI)
source "${SKILL_DIR}/.venv/bin/activate"
musicdl -k "晴天 周杰伦" -m NeteaseMusicClient,QQMusicClient,MiguMusicClient
Post-download checklist
- Count audio vs
.lrc(lyrics optional but preferred) - Convert any
.ogg(OneMusic cannot import ogg) - Run compress unless user asked for lossless
- Report absolute import path + size
- Remind: Import Music → select folder
Troubleshooting
| Symptom | Fix |
|---|---|
No module named musicdl |
bash scripts/setup.sh |
| Playlist empty | Check share link; try cookies; ensure playlist is public/shareable |
| Only VIP tracks fail | Optional cookies + user subscription; or search alternate source |
| OneMusic no lyrics | Ensure song.mp3 + song.lrc same basename |
| Files huge (~FLAC) | Run compress_for_import.py |
| Keychain denied for cookies | User allows Chrome cookie access, or paste Cookie manually |
References
references/onemusic-import.md— OneMusic detailsreferences/songs.example.txt— sample keyword list- Upstream: https://github.com/CharlesPikachu/musicdl