# 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