SPlayer 5 分钟上手指南:支持逐字歌词、桌面歌词与 API 控制的跨平台音乐播放器
【免费下载链接】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 是一个基于 Vue 3 + TypeScript + Naïve UI + Electron 的跨平台音乐播放器,支持逐字歌词、桌面歌词、本地音乐管理、云盘音乐与 Subsonic 流媒体服务,网页端和桌面客户端两种形态都能用,适合普通用户自用,也适合想自托管音乐站或做二次开发的玩家。项目采用 AGPL-3.0 协议开源,运行需要 Node.js >= 20 与 pnpm >= 10。
需要提醒一点:仓库 README 开头明确标注项目已进入维护模式,后续只做必要维护与重大问题修复,不再主动开发新功能。想跟进新特性要去看 SPlayer-Next。但这不影响你现在部署和使用它。
第一次打开 SPlayer 是什么体验
启动后左侧导航把功能分得很清楚:发现、歌单、搜索、流媒体、本地、历史、下载。登录网易云账号可以用扫码或手机号两种方式,对应界面在 LoginQRCode.vue 和 LoginPhone.vue,登录接口封装在 src/api/login.ts。登录之后,私人 FM、每日推荐、云盘音乐的上传与删除这些功能才完整可用,接口分别落在 src/api/radio.ts、src/api/rec.ts 和 src/api/cloud.ts。
SPlayer 播放页面与逐字歌词效果
播放页是 SPlayer 最能体现差异化的一块。歌词支持逐字高亮,播放时一个字一个字亮过去,类似 Apple Music 的效果,底层用的是@applemusic-like-lyrics组件,封装在 src/components/AMLL/LyricPlayer.vue。歌词解析器放在 src/utils/lyric/ 下,LRC、QRC 逐字格式、TTML 字幕各有一个解析文件,另外还有翻译与屏蔽词过滤(lyricProfanity.ts、lyricStripper.ts)。
桌面歌词是一个独立的置顶透明窗口,可以拖动位置、调整字号,窗口创建逻辑在 electron/main/windows/lyric-window.ts。在 Windows 上还有一项加分功能:歌词直接渲染进任务栏,由 native/taskbar-lyric/ 这个 Rust 原生模块实现,通过 UI Automation 定位系统托盘区域嵌入歌词,Windows 10 和 11 各有独立策略文件。
SPlayer 本地音乐管理界面
把光标停在歌曲上,界面底色会悄悄向封面主题色靠拢,这是"全站着色"。取色逻辑在 src/utils/color.ts,配合@material/material-color-utilities生成整套 Material 配色;明暗模式(Light / Dark / Auto)由 src/stores/setting.ts 管理。
本地音乐库支持目录扫描、按歌手/专辑/文件夹分类,还能直接编辑 ID3 标签和替换封面。扫描与数据持久化在 LocalMusicService.ts 和 LocalMusicDB.ts(better-sqlite3),标签读写靠music-metadata库,入口在 MusicMetadataService.ts。
下载走 DownloadService.ts,支持单曲和批量,最高 Hi-Res 音质(需要相应会员账号),进度在 src/views/Download/ 下的页面里查看。
5 分钟把 SPlayer 跑起来
只想要网页版,本地三条命令就够(需要 Node.js >= 20 和 pnpm >= 10):
git clone https://gitcode.com/GitHub_Trending/spl/SPlayer cd SPlayer && pnpm install cp .env.example .env && pnpm build构建产物在out/renderer,用任意静态服务器托管即可。注意默认构建会编译native/下的 Rust 原生模块,如果不需要系统媒体控件、Discord RPC 这些能力,设置环境变量SKIP_NATIVE_BUILD=true再构建,就可以省掉 Rust 工具链。
Docker 一条命令启动 SPlayer Web 版
🐳 不想本地装 Node 环境的话,Docker 路线更省事。Dockerfile 是两阶段构建:node:22-alpine里构建前端(同样跳过原生模块),nginx:1.27-alpine-slim里托管页面,并把网易云 API 和解锁服务作为运行时依赖一起装进镜像。
docker build -t splayer . docker run -d --name SPlayer -p 25884:25884 splayer启动后访问http://localhost:25884。也可以直接docker-compose up -d,docker-compose.yml 里预置了一批可选环境变量,比如UNBLOCK_SOURCES(解锁音源,示例为kugou kuwo bilibili)、ENABLE_FLAC、SELECT_MAX_BR。
给每个系统打包桌面客户端
要出安装包,按系统选命令,产物落在dist/:
| 命令 | 系统 |
|---|---|
pnpm build:win | Windows |
pnpm build:linux | Linux |
pnpm build:mac | macOS |
默认只构建当前架构,需要同时出 x64 和 arm64 时追加参数:pnpm build:win -- --x64 --arm64。
云端部署走 Vercel 或服务器都行,共同前提是:SPlayer 依赖 NeteaseCloudMusicApi Enhanced 这类第三方 API 服务,先把它部署好,再把.env里的VITE_API_URL指向它。服务器部署时静态目录设为out/renderer,nginx.conf 里可以直接参考/api/netease/反代到 API 服务、/music/unblock/反代解锁源的写法。
内部分工:网页、主进程、本地服务与 Rust 模块
SPlayer 的代码按运行位置分成四层,各管一摊事:
- 渲染进程 src/:Vue 3 + Pinia + Vue Router 的全部界面,发现、歌单、搜索、本地、流媒体等页面都在
src/views/。 - 主进程 electron/main/:窗口(windows/)、托盘、系统快捷键、本地 SQLite 数据库(database/)、下载与本地音乐等服务(services/)。
- 本地服务 electron/server/:基于 Fastify 的 HTTP 服务,index.ts 里可以看到它注册了云音乐代理(netease)、解锁(unblock)、控制(control)和 QQ 音乐(qqmusic)四组路由,监听
127.0.0.1的 25884 端口(可用VITE_SERVER_PORT覆盖),端口被占用时由 port.ts 自动换端口。 - 原生模块 native/:Rust + napi-rs 编译的 Node.js 扩展,负责系统媒体控件、任务栏歌词等桌面深度集成,docs/native.md 有完整说明。
播放核心在 src/core/audio-player/,定义了统一的IPlaybackEngine接口后挂了三套引擎:
AudioElementPlayer:标准 HTML5 音频,覆盖绝大多数在线音源;FFmpegAudioPlayer:基于 ffmpeg.wasm 在 Web Worker 里解码(ffmpeg-engine/),用来播 FLAC、ALAC 这类浏览器原生不支持的格式;MpvPlayer:客户端里调用外部 MPV 进程播放。
README 功能列表里的"音乐渐入渐出"对应 src/core/automix/ 的 AutomixManager,配合 Web Audio 做曲目切换时的交叉淡入淡出,IPlaybackEngine.ts里的fadeIn/fadeOut/FadeCurve就是给这套机制用的。
进阶集成:HTTP API、WebSocket 与系统媒体控件
SPlayer 把播放器本身当成一个本地服务来开放。完整清单见 API 文档 和 WebSocket 文档,这里挑实际会用到的。
HTTP 控制接口(默认http://localhost:25884,统一返回{ code, message, data }):
curl http://localhost:25884/api/control/play curl http://localhost:25884/api/control/status除play/pause/toggle/next/prev/status外,还有/api/netease/*(云音乐 API 代理)和/api/unblock/*(网易云 / 酷我 / 波点解锁,源码在 electron/server/unblock/)。API 文档特别警告:不要用/api/control/song-info高频轮询获取进度,实时进度应该走 WebSocket,否则软件性能会异常。
WebSocket 实时通道默认监听ws://localhost:25885(端口可在设置里改),实现是 SocketService.ts。连上后会先收到welcome,之后播放器变化会主动广播status-change、song-change、progress-change(约 500ms 一次)、lyric-change;反向控制发送一条 JSON 即可:
const ws = new WebSocket("ws://localhost:25885"); ws.onopen = () => ws.send(JSON.stringify({ type: "control", data: { command: "next" } }));保持连接建议定期发PING,服务端回PONG。
系统级集成由 native/external-media-integration/(简称 EMI)承担:Windows 接 SMTC(任务栏缩略图按钮 + 锁屏控制)、Linux 走 MPRIS(GNOME/KDE 都认)、macOS 接控制中心与MPNowPlayingInfoCenter。播放状态、封面、进度双向同步,系统的媒体按键也能反向控制播放器。另一块是 Discord RPC,在个人资料里显示正在播什么,还带一个 "Listen" 跳转按钮。
接入自己的流媒体音乐库
如果你有 Navidrome、Subsonic、Airsonic 这类自建音乐服务器(docs/streaming.md),在"设置 → 流媒体服务"里添加地址、用户名密码即可。渲染进程侧的适配在 src/api/streaming/,除了 Subsonic 协议,还有 Emby 和 Jellyfin 两套实现。
几个实用细节:
- 支持配置多台服务器并自由切换,启动时自动连回上次使用的那台;
- 服务端返回的 Plain / Structured 歌词会自动转成 LRC 显示;
- 流媒体歌曲可以像本地歌曲一样加歌单、收藏、播放;
- 服务端歌单可以读进来,但客户端新建的歌单暂不同步回去。
避坑与注意事项
⚠️ 部署和二次开发前,这几件事值得先看清楚:
- 维护模式:README 与官网首页都声明了只修 bug 不加功能,做深度二开前建议评估 SPlayer-Next;
- 协议约束:AGPL-3.0 要求修改、分发、派生项目必须同样开源并保留版权信息,商用或售卖有法律风险,README 里有专门的"严肃警告"段落;
- 原生模块:默认构建依赖 Rust 工具链(Windows 还要 Visual Studio Build Tools 的 C++ 桌面开发组件与 Windows SDK),报
The specified module could not be found时先跑pnpm build:native,确认 x64 / arm64 架构匹配; - 端口占用:HTTP 默认 25884、WebSocket 默认 25885,改端口分别用
VITE_SERVER_PORT环境变量和应用内设置; - 第三方依赖:在线功能依赖网易云音乐的第三方 API 服务,仅供个人学习研究,禁止商业用途;Docker 镜像和 Web 部署都要先把 API 服务跑起来或配好
VITE_API_URL。
本地开发常用命令:pnpm dev启动开发模式(Electron + Vite HMR,含原生模块),pnpm lint代码检查,pnpm typecheck类型检查。更多排障(macOS 签名、Windows 7 等)可以看 docs/troubleshooting/ 目录下的文档。
【免费下载链接】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),仅供参考