- kg: login_by_token 续期(AES-256-CBC + RSA 裸加密,参考其 refresh/kg.py),新 token 回写 data/auth.json - tx: 新增 sdk/auth/tx.ts —— cookie 解析、VIP 检测(vip_login_base)、 music.login.LoginServer 续期(走既有 musicu.fcg 未签名通道,最佳努力) - 调度:启动 10s 后首刷 + 每 24h 一次(对齐参考项目 86400s + next_run_time=now) - /login/tx 支持可选 App 抓包凭据(openId/accessToken/refreshToken/refreshKey) - 新增 POST /login/refresh 手动续期;/login/status 增补 tx 字段与更新时间 - 补充 /login/tx 文档行与 smoke 测试
118 lines
6.2 KiB
Markdown
118 lines
6.2 KiB
Markdown
# MusicServer 聚合音乐 API
|
||
|
||
多平台音乐聚合接口:搜索、播放地址、歌词、封面、榜单、歌单。支持平台:**kw**(酷我)/ **kg**(酷狗)/ **tx**(QQ音乐)/ **wy**(网易云)。
|
||
|
||
> 本文档为静态速查版。交互式文档以服务器实际输出为准:
|
||
>
|
||
> - **Swagger UI**:`http://localhost:16688/docs`(可直接调试)
|
||
> - **ReDoc**:`http://localhost:16688/redoc`
|
||
> - **OpenAPI 3.1**:`http://localhost:16688/openapi.json`(可生成各语言客户端)
|
||
|
||
## 约定
|
||
|
||
- 默认端口 **16688**(可用 `PORT` 环境变量修改)。
|
||
- 仅支持 `GET` 方法;服务器支持 CORS(`Access-Control-Allow-Origin: *`)。
|
||
- **成功**:`200` + `{"code": 0, "data": ...}`
|
||
- **失败**:对应 HTTP 状态码 + `{"code": <状态码>, "msg": "...", "detail": ...}`
|
||
- `422` 参数校验失败(缺失、非法音质、页码越界等,FastAPI 风格)
|
||
- `404` 接口不存在 / 平台不支持该能力
|
||
- `405` 方法不允许(响应带 `Allow` 头)
|
||
- `502` 上游平台请求失败
|
||
- `500` 服务器内部错误
|
||
- 资源类接口统一为**路径参数风格**;`/search`、`/find` 搜索类接口使用 query 参数。
|
||
- 平台歌曲 id 形态:kw/tx/wy 用 `songmid`,kg 用 `hash`。
|
||
|
||
## 接口速查
|
||
|
||
### 系统
|
||
|
||
| 方法 | 路径 | 说明 |
|
||
| --- | --- | --- |
|
||
| GET | `/health` | 健康检查(status / uptime / 平台数) |
|
||
| GET | `/sources` | 支持的平台及其音质、能力(search/url/lyric/pic/boards/hotSearch/songList/singer/album) |
|
||
| GET | `/` | 302 重定向到 `/docs` |
|
||
| GET | `/docs` | Swagger UI 文档页 |
|
||
| GET | `/redoc` | ReDoc 阅读版文档 |
|
||
| GET | `/openapi.json` | OpenAPI 3.1 规范文档 |
|
||
|
||
### 搜索
|
||
|
||
| 方法 | 路径 | 说明 |
|
||
| --- | --- | --- |
|
||
| GET | `/search?name=稻香&singer=周杰伦&source=kw&page=1&limit=20` | 搜索歌曲;`source` 省略时聚合全部平台,失败的平台跳过 |
|
||
| GET | `/find?name=稻香&singer=周杰伦&albumName=魔杰座&interval=03:43&excludeSource=kw` | 跨平台精确匹配,按歌手/歌名/专辑/时长综合排序 |
|
||
|
||
### 歌曲资源
|
||
|
||
| 方法 | 路径 | 说明 |
|
||
| --- | --- | --- |
|
||
| GET | `/url/:source/:id` | 播放地址;query 可带 `quality`(128k/320k/flac/flac24bit,默认 128k)与 `albumId`(kg 需要) |
|
||
| GET | `/lyric/:source/:id` | 歌词;可带 `name`/`interval`(部分平台搜索歌词时需要) |
|
||
| GET | `/pic/:source/:id` | 封面;可带 `albumId`(kg 需要) |
|
||
|
||
### 榜单
|
||
|
||
| 方法 | 路径 | 说明 |
|
||
| --- | --- | --- |
|
||
| GET | `/boards/:source` | 榜单列表 |
|
||
| GET | `/boards/:source/:boardId` | 榜单详情;可带 `page`。`boardId` 兼容榜单列表的带前缀 `id`(`kw__93`)与裸 `bangid`(`93`) |
|
||
|
||
### 歌单 & 热搜
|
||
|
||
| 方法 | 路径 | 说明 |
|
||
| --- | --- | --- |
|
||
| GET | `/hot-search/:source` | 热搜词 |
|
||
| GET | `/song-list/:source` | 歌单列表;可带 `page`/`sortId`/`tagId`。`sortId`/`tagId` 各平台词汇不同(kw `new`/`hot`、tx `5`/`2`、kw 标签为 `173-digest` 形态等),`sortId` 省略时用平台默认 |
|
||
|
||
### 歌手 & 专辑
|
||
|
||
| 方法 | 路径 | 说明 |
|
||
| --- | --- | --- |
|
||
| GET | `/singer/:source/:id` | 歌手信息(name/desc/avatar 与歌曲/专辑数量)。支持 kg/tx/wy |
|
||
| GET | `/singer/:source/:id/songs` | 歌手歌曲列表;可带 `page`/`limit`(默认 20)。支持 kg/tx/wy |
|
||
| GET | `/singer/:source/:id/albums` | 歌手专辑列表;可带 `page`/`limit`。支持 kg/tx/wy |
|
||
| GET | `/album/:source/:id` | 专辑详情与曲目列表;可带 `page`/`limit`(limit 仅 kg 生效,kw 单页固定 1000 条)。支持 kg/kw/tx;tx 的专辑名/作者由曲目数据合成(desc 为空) |
|
||
|
||
歌手/专辑 id 来源:搜索结果条目包含 `albumId`;歌手 id 需从平台方获取(不在搜索结果中)。
|
||
|
||
### 登录
|
||
|
||
| 方法 | 路径 | 说明 |
|
||
| --- | --- | --- |
|
||
| POST | `/login/wy/qr` | 获取网易云扫码登录二维码(返回 `key`/`qrurl`/`qrimg`,`qrimg` 为 data URL 可直接展示) |
|
||
| POST | `/login/wy/qr/check` | 轮询扫码状态,body 传 `{ "key": "..." }`。返回 `code`:800 过期 / 801 等待 / 802 已扫码 / 803 登录成功(自动保存凭据) |
|
||
| POST | `/login/wy/cellphone` | 网易云手机号登录;body 传 `phone` + `password`(明文,服务端 MD5 后提交)或 `captcha`,可带 `countrycode`(默认 86) |
|
||
| DELETE | `/login/wy` | 退出网易云登录 |
|
||
| POST | `/login/kg` | 绑定酷狗 token;body 传 `{ "token": "...", "userid": ... }`(App 抓包获取),服务端向用户中心验证后存储 |
|
||
| DELETE | `/login/kg` | 退出酷狗登录 |
|
||
| POST | `/login/tx` | 绑定 QQ 音乐 cookie;body 传 `{ "cookie": "..." }`(需含 `uin` 与 `qm_keyst` 字段)。可选附 App 抓包的 `openId`/`accessToken`/`refreshToken`/`refreshKey` 供自动续期 |
|
||
| DELETE | `/login/tx` | 退出 QQ 音乐登录 |
|
||
| POST | `/login/refresh` | 手动触发 kg/tx 登录态续期(与自动任务同一逻辑;未登录平台跳过,单平台失败不影响其他) |
|
||
| GET | `/login/status` | 登录状态(wy 实时校验 / kg、tx 已存凭据,含 `vipType` 与最近更新时间) |
|
||
|
||
- 登录态持久化于 `data/auth.json`(不入库),登录后取流与平台请求自动携带凭据。
|
||
- **登录态自动续期**:服务器启动 10s 后自动对 kg/tx 执行一次续期,此后每 24h 一次(kg 走 `login_by_token` AES/RSA 协议换新 token;tx 走 `music.login.LoginServer`,仅浏览器 cookie 时可能被网关拒绝,需在 `/login/tx` 附 App 抓包的完整凭据才可靠),结果输出到控制台日志。
|
||
- VIP 歌曲完整播放地址暂不在支持范围;登录态目前用于提升请求稳定性与为后续能力预留。
|
||
|
||
## 响应示例
|
||
|
||
```jsonc
|
||
// GET /url/kw/228908?quality=320k
|
||
{ "code": 0, "data": { "type": "320k", "url": "https://..." } }
|
||
|
||
// GET /lyric/kw/228908
|
||
{ "code": 0, "data": { "lyric": "[00:00.00]...", "tlyric": "", "yrc": "" } }
|
||
|
||
// 参数缺失
|
||
// 422
|
||
{ "code": 422, "msg": "querystring must have required property 'name'", "detail": [...] }
|
||
|
||
// 平台不支持该能力
|
||
// 404
|
||
{ "code": 404, "msg": "不支持的平台: xx" }
|
||
|
||
// 方法不允许
|
||
// 405 + Allow: GET
|
||
{ "code": 405, "msg": "方法 POST 不允许,请使用 GET" }
|
||
```
|