# 声匣 · Sound Case 自托管的音乐下载 Web 服务:搜索、在线播放、批量下载网易云音乐与 QQ 音乐(VIP Cookie),自动写入歌词、封面与完整标签,按「歌手 / 专辑 / 序号. 歌名」归档,可直接被 Navidrome 等播放器识别。 > 由 `163-music-dl` CLI 重构而来,不再保留命令行模式。仅供个人对已购买 / 已订阅内容的备份使用。 ## 功能 - **搜索**:网易云 / QQ 音乐切换;粘贴任意分享链接(歌曲、专辑、歌单、歌手,含 QQ 短链)直接跳转 - **详情页**:专辑、歌单(可筛选)、歌手(热门歌曲 + 专辑墙);多选 / Shift 区间选 / 只选未下载 - **下载队列**:并发、全局暂停、单曲暂停 / 继续 / 取消 / 重试,SSE 实时进度;重启后自动恢复 - **音质**:标准 / 极高 / 无损 / Hi-Res / 超清母带 / 空间音频 / 高清臻品;不可用时自动降级 - QQ 音乐支持到 Hi-Res(RS01);母带 / 全景声为加密格式,暂不支持 - **播放**:在线曲目经服务端代理(标准 / 极高 / 无损可选),曲库文件直接播放;曲库里已有的歌优先放本地文件。播放队列、顺序 / 列表循环 / 单曲循环 / 随机、滚动歌词(含翻译)、系统媒体键与锁屏控制、空格暂停;队列与进度保存在本机,刷新后可继续 - **歌单**:自建歌单可混排在线曲目与本地文件;从搜索、专辑、歌单、歌手、曲库文件夹或播放队列一键加入,拖动排序,一键下载曲库里还没有的在线曲目 - **曲库**:浏览音乐目录(封面墙)、生成 M3U、打包 ZIP、移入回收站、批量补全标签与歌词 - **历史**:统计(累计、占用、近 30 天、来源与音质分布)、搜索筛选、导出 CSV / JSON - **设置**:QQ 账号(扫码登录 / 导入 Cookie、VIP 校验、musickey 自动续期)、下载默认值、并发与间隔、访问密码、浅色 / 深色 ## 本机运行 需要 Node.js ≥ 22.18(服务端直接以 TypeScript 运行,无需编译)。FLAC 写标签需要 ffmpeg(Windows:`winget install Gyan.FFmpeg`)。 ```bash npm install npm run build # 打包前端到 dist/web npm start # http://localhost:8066 ``` 开发模式:`npm run dev`(后端 :8066 --watch + Vite :5173 热更新,代理 /api)。 默认下载到 `./music`、数据在 `./data`。QQ 音乐 Cookie 会从 `config.json` 的 `qq.cookieFile`(默认 `../cookie.txt`)自动导入,文件更新后重启即重新导入;也可在设置页粘贴。 ## 配置 `config.json`(私有仓库,已包含 chksz apikey),环境变量优先: | 环境变量 | 对应 | | --- | --- | | `PORT` / `HOST` | `server.port`;监听地址默认 `0.0.0.0` | | `MUSIC_DIR` / `DATA_DIR` | `paths.*` | | `CHKSZ_API_KEY` | `netease.apikey` | | `QQ_COOKIE_FILE` | `qq.cookieFile` | | `DEFAULT_QUALITY` | `defaults.quality`:standard / high / lossless / hires / master / spatial / effect | | `DEFAULT_LAYOUT` | `defaults.layout`:`album`(歌手/专辑/NN. 歌名)或 `flat`(歌手 - 歌名) | | `LEGACY_HISTORY_FILE` | 旧版 CLI 的 `download_history.json`,首次启动导入 | `config.json` 中的 `defaults` 只是初始值,网页设置页修改后保存在数据库中。 数据目录内容:`shengxia.db`(历史、队列、设置、加密后的 Cookie)、`secret.key`(本机加密密钥,勿外传)、`.trash/`(曲库回收站)。 ## 标签规则(沿用旧版) - 标题、歌手、专辑取自音源;曲序 `N/总数`、碟号、专辑艺人、合辑标记、发行日期、流派、唱片公司取自平台专辑详情 - 作词 / 作曲 / 编曲 / 制作人 / 混音从歌词头部解析;编曲、制作人、混音写入 TXXX(MP3)或同名字段(FLAC) - 歌词保存为 `.lrc`,有翻译时额外生成 `.合并翻译.lrc`,并内嵌到音频 - 专辑目录写入 `cover.jpg`;人名统一使用 ` / ` 分隔 ## Docker 部署(NAS) ```bash cd /vol1/1000/dockercompose && git clone https://git.draws.qzz.io/jocay/music-hub.git shengxia && cd shengxia docker compose up -d --build # http://NAS:8066 ``` 更新:`git pull && docker compose up -d --build`(以 root 操作 jocay 的仓库时加 `git -c safe.directory=$PWD pull`)。 - 挂载与端口见 `docker-compose.yml` / `.env.example`;容器以 `PUID:PGID`(默认 `1000:1001`)运行 - 构建时 Alpine 走腾讯云源、npm 走 npmmirror(阿里云 Alpine 源在 NAS 容器内极慢) - 运行时 chksz 等境外接口经 `OUTBOUND_PROXY`(默认 `http://192.168.31.8:6152`)访问,QQ / 网易云及其 CDN 直连 —— NAS 直连 Cloudflare 会卡 3–15 秒 - QQ 音乐:网页「设置 → 扫码登录」,之后 musickey 自动续期 ## 进度 - [x] P0 工程骨架、设计 token、Docker 配置 - [x] P1 下载核心与网易云 provider - [x] P2 QQ 音乐 provider(VIP Cookie) - [x] P3 下载队列、SSE 实时进度、设置、访问密码、曲库与历史接口 - [x] P4 完整前端 - [x] P5 QQ 扫码登录与 musickey 自动续期 - [x] P6 NAS 部署(飞牛 `/vol1/1000/dockercompose/shengxia`) - [x] P7 在线播放(播放队列、媒体控制)与自建歌单