SPlayer 音乐播放器快速上手:架构拆解与部署指南
【免费下载链接】SPlayer🎵 A cross-platform music player with Jellyfin / Navidrome / Emby media server support, word-by-word lyrics, desktop & taskbar lyrics, cloud music drive, local library management, audio spectrum visualization and mobile-friendly UI. 简约的跨平台音乐播放器,支持逐字歌词、桌面歌词、任务栏歌词、云盘音乐、本地音乐管理及流媒体播放项目地址: https://gitcode.com/GitHub_Trending/spl/SPlayer
SPlayer 是一个基于 Electron 的跨平台音乐播放器,同时提供网页端与桌面客户端,支持在线听歌、逐字桌面歌词、本地音乐库和 Navidrome 等流媒体接入。适合想在自有服务器上跑一个私有音乐库、或想二次开发桌面播放器的开发者。结论:Docker 一条命令即可跑通 Web 版,桌面版需自备 Node.js >= 20 与 pnpm >= 10,另需 Rust 工具链处理原生模块。
- 定位:简约跨平台音乐播放器,网页端 / 桌面端同一套代码
- 技术栈:Vue 3 + TypeScript + Naïve UI + Electron,服务端 Fastify,原生模块 Rust(napi-rs)
- 最大亮点:内置本地 HTTP API(25884)+ WebSocket(25885)实时控制,可当远程遥控的常驻播放服务用
- 运行环境:Node.js >= 20、pnpm >= 10;仅网页端可设
SKIP_NATIVE_BUILD=true跳过 Rust - 许可证:AGPL-3.0,部分功能依赖网易云第三方 API,仅限个人学习研究
- 状态:已进入维护模式,新功能请移步 SPlayer-Next
10 分钟跑通 Web 版
不想碰 Node 环境的话,Docker 是最短路径,镜像内置了网页端、网易云 API 和解锁服务三个运行时组件:
git clone https://gitcode.com/GitHub_Trending/spl/SPlayer cd SPlayer docker build -t splayer . docker run -d --name SPlayer -p 25884:25884 splayer成功信号:浏览器访问http://localhost:25884能看到登录页与首页;终端另起一个窗口执行curl http://localhost:25884/api/control/status,返回code: 200即 API 正常。
SPlayer 音乐播放器主界面
想从源码启动 Electron 桌面版,则克隆后pnpm install、复制.env.example为.env(默认VITE_WEB_PORT=14558、VITE_SERVER_PORT=25884),然后pnpm dev。注意pnpm dev会先执行build:native编译全部 Rust 模块,没有 Rust 工具链时请设SKIP_NATIVE_BUILD=true再跑,详见 使用指南。
架构一张表看懂
| 层 | 目录 | 职责 | 关键事实 |
|---|---|---|---|
| 渲染进程 | src/ | 全部 UI 与播放调度 | Vue 3 + Pinia + Naïve UI |
| 主进程 | electron/main/ | 窗口、托盘、快捷键、better-sqlite3 数据库 | 含下载、MPV 等服务 |
| 本地服务端 | electron/server/ | Fastify HTTP + WebSocket | HTTP 默认 25884,WS 默认 25885 |
| 原生扩展 | native/ | 系统媒体控件、Discord RPC、任务栏歌词 | Rust napi-rs 编译为 Node 插件 |
| Web 文档 | docs/ | VitePress 站点 | 构建命令pnpm docs:build |
数据流一句话:界面里点播放,请求走src/api/到本地 Fastify 服务(electron/server/),该服务再代理到外部网易云 API(路径/api/netease/*)和解锁服务(/api/unblock/*);播放状态则经主进程SocketService以 WebSocket 事件广播给所有连接方。目录上记住这几行就够:
src/core/player/ 播放内核(PlayerController 调度音频、歌词、模式) src/api/streaming/ 流媒体协议适配(subsonic / emby / jellyfin) electron/server/ 内置 HTTP API 与解锁代理 native/ Rust 原生模块(外部媒体、任务栏歌词等) docs/ 官方文档(API、WebSocket、流媒体、排障)功能深潜:跟着使用场景走
在线听歌与无版权歌曲解锁
界面上扫码登录(qrKey/qrCreate/checkQr三个接口轮询扫码状态)后即可正常播放。遇到灰色无版权歌曲时,播放地址会改走/api/unblock/*,服务端按「网易云 → 酷我 → 波点」顺序匹配替代音源并返回可用 URL。
实现落在 electron/server/unblock/,音源与匹配策略在 docs/api.md 的 Unblock API 一节有完整参数说明。
桌面歌词与逐字高亮
开启桌面歌词后会弹出一个独立透明窗口,样式、位置、字号均可调;支持逐字歌词(YRC)逐字点亮,也支持歌词翻译与滚动。
原理是 src/components/AMLL/ 封装的逐字渲染引擎,配合 src/utils/lyric/ 下的parseLrc/parseQrc/parseTTML解析器处理不同格式;窗口本身由 electron/main/windows/lyric-window.ts 创建,另有taskbar-lyric原生模块在 Windows 任务栏显示当前歌词。
本地音乐库:扫描、改标签、换封面
在设置里添加目录后,SPlayer 会扫描本地文件并按歌手、专辑、文件夹分类,直接双击即可播放,且支持离线模式(不连接网络)。标签与封面修改会写回文件本身。
原理:扫描与持久化在 electron/main/services/LocalMusicService.ts,数据存于 better-sqlite3 的 electron/main/database/LocalMusicDB.ts,元数据读写依赖music-metadata库。官方建议先用外部工具匹配好标签再导入。
接入 Navidrome / Emby / Jellyfin
设置 → 流媒体服务中添加服务器地址、账号密码并选择 Navidrome 或 Subsonic 类型,即可按单曲、歌手、专辑、歌单浏览私有曲库,流媒体歌曲可像在线歌曲一样加入播放队列。
客户端适配在 src/api/streaming/(subsonic.ts/emby.ts/jellyfin.ts),配置界面见 StreamingServerConfig.vue;多服务器可同时保存,启动时自动连回上次使用的那台,细节参考 docs/streaming.md。
扩展与集成:API、WebSocket 与原生插件
本地 HTTP API 速查
默认监听http://localhost:25884,前缀/api,统一响应{ code, message, data }(200 成功 / 500 失败),可用GET /api获取模块清单。
| 接口 | 说明 |
|---|---|
GET /api/control/playpausetoggle | 播放 / 暂停 / 切换 |
GET /api/control/nextprev | 下一曲 / 上一曲 |
GET /api/control/status | 版本号、运行环境、窗口状态 |
GET /api/control/song-info | 当前歌曲信息(禁止高频轮询进度) |
GET /api/netease/* | 代理 NeteaseCloudMusicApi Enhanced 全部接口 |
GET /api/unblock/netease?id= | 按歌曲 ID 返回解锁播放 URL |
GET /api/unblock/kuwo?keyword=bodian?keyword= | 按「歌曲名-歌手」解锁 |
WebSocket 实时控制
实时进度别用 HTTP 轮询,连ws://localhost:25885(端口可在设置中修改)。客户端发送{ "type": "control", "data": { "command": "toggle|play|pause|next|prev" } }即可遥控;服务器端会广播welcome、status-change、song-change、progress-change(约 500ms 一次)、lyric-change事件,心跳用PING/PONG。实现见 electron/main/services/SocketService.ts,完整消息格式在 docs/socket.md。
原生插件:系统级存在感
锁屏、任务栏显示正在播放的歌曲,本质是 Rust 插件 native/external-media-integration/(下称 EMI)在干活:Windows 走 SMTC(WinRT 的SystemMediaTransportControls),Linux 走 MPRIS(GNOME/KDE 可识别),macOS 走MPNowPlayingInfoCenter;Discord RPC 则在个人状态里展示歌名、封面和进度。pnpm build:native一次性编译native/下全部模块,各平台加载失败与媒体控件不显示的排查步骤见 docs/native.md。
部署方案怎么选
| 方式 | 适用场景 | 难度 | 入口命令 / 配置 |
|---|---|---|---|
| Docker | 服务器私有音乐库,免环境 | 低 | docker build -t splayer . && docker run -d -p 25884:25884 splayer |
| Vercel | 纯静态网页版 | 低 | vercel.json已配好:构建SKIP_NATIVE_BUILD=true ... electron-vite build,产物目录out/renderer |
| 自建服务器 | 需要完整 API 代理 | 中 | pnpm build后以out/renderer为站点目录 + Nginx |
| 本地源码 | 二次开发 / 桌面客户端 | 中 | pnpm dev;打包pnpm build:winbuild:macbuild:linux,产物在dist/ |
推荐 Docker:Dockerfile 第一阶段用node:22-alpine构建渲染产物并设SKIP_NATIVE_BUILD=true,第二阶段nginx:1.27-alpine-slim托管静态页,同时全局安装@neteasecloudmusicapienhanced/api与@unblockneteasemusic/server作为运行时依赖。docker-compose.yml 暴露了常用环境变量,如NETEASE_SERVER_IP(宿主机ping music.163.com可获得)、UNBLOCK_SOURCES(默认kugou kuwo bilibili)、ENABLE_FLAC、SELECT_MAX_BR。
Vercel 与自建服务器都要求你先有一个可访问的 NeteaseCloudMusicApi Enhanced 地址,把.env里的VITE_API_URL指过去即可;自建时 nginx.conf 已写好/api/netease/反代和/music/unblock/的 163 源站代理,可直接参考。桌面客户端按平台选pnpm build:win / mac / linux,默认只构建当前架构,追加-- --x64 --arm64可双架构。
二次开发与高频坑
常用命令一览(对应 package.json scripts):
| 命令 | 说明 |
|---|---|
pnpm dev | 先build:native再启动 Electron + Vite HMR |
pnpm build | 清理 dist → 构建原生模块 → 类型检查 → 构建 Web 产物 |
pnpm build:native | 仅构建native/下全部 Rust 模块 |
pnpm build:win / mac / linux | 打包对应平台客户端,产物在dist/ |
pnpm lint/pnpm typecheck | ESLint 检查 / TS + vue-tsc 类型检查 |
pnpm docs:build | 构建 VitePress 文档站 |
原生模块加载失败怎么办?
报The specified module could not found时,先确认执行过pnpm build:native,且编译架构与系统一致(x64 / arm64)。Windows 上 SMTC 还依赖 Visual Studio Build Tools 的「C++ 桌面开发」组件与 Windows SDK,缺失会报LNK1181链接错误。只想跑网页端就设SKIP_NATIVE_BUILD=true,从源头绕开。
端口被占用会怎样?
HTTP 端口由VITE_SERVER_PORT控制(默认 25884),electron/server/port.ts 用get-port在启动时探测,冲突会自动顺延到可用端口;WebSocket 默认 25885,若被占用则启动前校验失败并抛「端口不可用」。另注意 API 服务只绑定127.0.0.1(见 electron/server/index.ts),跨机器访问需要 Docker 端口映射或反向代理兜住。
为什么构建慢、CI 上编译失败?
默认构建链路里build会串行执行 native 编译、tsc+vue-tsc双重类型检查和产物打包,慢是正常的。CI 或纯 Web 场景把SKIP_NATIVE_BUILD=true写进环境变量即可,vercel.json与 Dockerfile 都这么做的。
一句话总结:SPlayer 把「在线音乐 + 本地曲库 + 私有流媒体」装进同一套 Vue 3 / Electron 代码里,再附赠一套可遥控的本地 API,是私有化部署音乐播放器的现成底座。项目基于 AGPL-3.0 开源、依赖网易云第三方 API 仅限个人学习研究,功能清单与边界以 docs/guide.md 为准;接口细节看 docs/api.md、docs/socket.md、docs/streaming.md 与 docs/native.md。
【免费下载链接】SPlayer🎵 A cross-platform music player with Jellyfin / Navidrome / Emby media server support, word-by-word lyrics, desktop & taskbar lyrics, cloud music drive, local library management, audio spectrum visualization and mobile-friendly UI. 简约的跨平台音乐播放器,支持逐字歌词、桌面歌词、任务栏歌词、云盘音乐、本地音乐管理及流媒体播放项目地址: https://gitcode.com/GitHub_Trending/spl/SPlayer
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考