feat: 添加网易云音乐同步到Navidrome的功能
新增NetEase-sync模块,实现将网易云音乐歌单同步到Navidrome的功能 修复iOS设备自动播放问题,优化播放器体验
This commit is contained in:
141
Netease-sync/需求.md
Normal file
141
Netease-sync/需求.md
Normal file
@@ -0,0 +1,141 @@
|
||||
# Netease-sync 需求文档
|
||||
|
||||
## 项目概述
|
||||
在当前目录下新建一个简单的 Node.js 项目,实现和 Navidrome 的联动,将网易云音乐歌单同步到 Navidrome。
|
||||
|
||||
## 核心功能
|
||||
|
||||
### 1. 歌单输入
|
||||
- 前台页面支持输入网易云音乐的歌单 ID 或分享链接
|
||||
- 支持从歌单 URL 中提取 ID(如 `https://music.163.com/#/playlist?id=123456` 提取 `123456`)
|
||||
- 只支持网易云音乐平台
|
||||
|
||||
### 2. 歌单读取
|
||||
- 调用 TuneHub API 获取歌单详情
|
||||
- API: `GET /api/?source=netease&id={playlistId}&type=playlist`
|
||||
- 获取歌单名称、封面、描述、歌曲列表等元数据
|
||||
|
||||
### 3. 歌曲下载
|
||||
- 调用现有的 sync-server 下载逻辑
|
||||
- 包括元数据写入(title, artist, album, cover)
|
||||
- **不创建歌单缓存 JSON 文件**,避免和主 app 混淆
|
||||
- 下载到 sync-server 的 music 目录(Navidrome 也读取此目录)
|
||||
- 如果下载失败,尝试换源(根据 api.md 支持的平台:netease, kuwo, qq)
|
||||
- **不重试**,失败则跳过
|
||||
|
||||
### 4. Navidrome 歌单创建
|
||||
- 使用 Navidrome 的 Subsonic API
|
||||
- 在 Navidrome 中创建同名歌单
|
||||
- 将下载的歌曲加入歌单
|
||||
- 同步歌单的所有元数据(封面、描述等)
|
||||
|
||||
### 5. 同步策略
|
||||
- **增量同步**:只新增歌曲,不删除已有歌曲
|
||||
- 通过网易云音乐歌曲 ID 判断,在本地维护一个映射表(netease_song_id -> navidrome_song_id)
|
||||
- **定时同步**:每 300 秒自动同步一次(可配置)
|
||||
- 支持手动立即同步
|
||||
|
||||
### 6. 前端界面
|
||||
- 显示已添加的歌单列表
|
||||
- 显示每个歌单的同步状态(同步中/成功/失败)
|
||||
- 显示上次同步时间
|
||||
- 提供立即同步按钮
|
||||
- 支持添加/删除歌单
|
||||
|
||||
## 配置项
|
||||
|
||||
### Docker 环境变量
|
||||
- `NAVIDROME_URL`: Navidrome 服务器地址(如 `http://navidrome:4533`)
|
||||
- `NAVIDROME_USERNAME`: Navidrome 用户名
|
||||
- `NAVIDROME_PASSWORD`: Navidrome 密码
|
||||
- `SYNC_INTERVAL`: 同步间隔(秒),默认 300
|
||||
- `SYNC_SERVER_URL`: sync-server 地址(如 `http://sync-service:3001`)
|
||||
- `SYNC_SERVER_TOKEN`: sync-server 的 token(用于 KV API)
|
||||
- `TUNEHUB_API_URL`: TuneHub API 地址(如 `https://music-dl.sayqz.com`)
|
||||
|
||||
## 技术架构
|
||||
|
||||
### 后端
|
||||
- Node.js + Express
|
||||
- 调用 sync-server 的 KV API 传递歌曲列表
|
||||
- 调用 Navidrome Subsonic API 创建歌单
|
||||
- 定时任务:每 N 秒检查并同步歌单
|
||||
- 数据持久化:JSON 文件存储歌单列表和映射表
|
||||
|
||||
### 前端
|
||||
- 简单的 HTML + JavaScript 页面
|
||||
- 实时显示同步状态(WebSocket 或轮询)
|
||||
- 添加/删除歌单功能
|
||||
|
||||
## Subsonic API 集成
|
||||
|
||||
### 认证
|
||||
所有 API 请求需要包含以下参数:
|
||||
- `u`: 用户名
|
||||
- `p`: 密码(明文或 hex 格式)
|
||||
- `v`: API 版本(如 `1.16.0`)
|
||||
- `c`: 客户端名称(如 `netease-sync`)
|
||||
|
||||
### 主要端点
|
||||
1. **创建歌单**: `createPlaylist`
|
||||
- 参数:`name`(歌单名称)、`songId`(歌曲 ID 列表,逗号分隔)
|
||||
- 返回:创建的歌单 ID
|
||||
|
||||
2. **更新歌单**: `updatePlaylist`
|
||||
- 参数:`playlistId`(歌单 ID)、`songIdToAdd`(要添加的歌曲 ID)
|
||||
|
||||
3. **获取歌单列表**: `getPlaylists`
|
||||
|
||||
4. **搜索歌曲**: `search3`
|
||||
- 参数:`query`(搜索关键词)
|
||||
- 用于根据文件名查找 Navidrome 中的歌曲 ID
|
||||
|
||||
## 歌曲匹配策略
|
||||
|
||||
参考 sync-server 的去重逻辑,文件名格式为:`Artist - Name [source_id].ext`
|
||||
|
||||
匹配步骤:
|
||||
1. 下载完成后,Navidrome 会自动扫描新歌曲
|
||||
2. 通过 `search3` 搜索文件名(如 `Artist - Name [netease_id]`)来获取 Navidrome 的歌曲 ID
|
||||
3. 将网易云音乐歌曲 ID 映射到 Navidrome 歌曲 ID
|
||||
|
||||
## 数据结构
|
||||
|
||||
### 歌单列表 (playlists.json)
|
||||
```json
|
||||
{
|
||||
"playlists": [
|
||||
{
|
||||
"id": "netease_123456",
|
||||
"neteaseId": "123456",
|
||||
"name": "歌单名称",
|
||||
"cover": "封面URL",
|
||||
"description": "歌单描述",
|
||||
"navidromePlaylistId": "navidrome_playlist_id",
|
||||
"lastSyncTime": "2025-01-12T10:00:00Z",
|
||||
"syncStatus": "success",
|
||||
"songMapping": {
|
||||
"netease_song_id_1": "navidrome_song_id_1",
|
||||
"netease_song_id_2": "navidrome_song_id_2"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 换源逻辑
|
||||
|
||||
如果网易云音乐下载失败,尝试换源:
|
||||
- 优先级:kuwo -> qq
|
||||
- 每个平台只尝试一次,不重试
|
||||
|
||||
## 错误处理
|
||||
|
||||
- 某首歌下载失败,跳过继续下载其他歌曲
|
||||
- 不重试
|
||||
- 错误日志输出到 Docker 控制台,不存储
|
||||
|
||||
## Navidrome 扫描延迟
|
||||
|
||||
- Navidrome 扫描新歌曲很快,不处理延迟
|
||||
- 在添加到歌单时直接搜索歌曲 ID
|
||||
Reference in New Issue
Block a user