
SPlayer WebSocket 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 Electron 的跨平台音乐播放器内置的 WebSocket 本地服务通过ws://localhost:25885建立双向实时通信客户端既可以下发play/pause/next/prev等控制命令远程操纵播放器也能实时订阅歌曲切换、播放进度、歌词数据等状态广播。阅读本文后你将能够编写自己的 WebSocket 客户端如桌面小组件、智能家居面板、脚本或移动端遥控器在数分钟内接入 SPlayer 的播放控制与状态监控能力。WebSocket API 概览SPlayer 在 Electron 主进程中内置了一个基于ws库的 WebSocket 服务器核心实现见 SocketService.ts专门用于对外提供实时双向通信能力基础路径ws://localhost:25885默认端口可在设置中修改范围为 165535服务模式仅在 Electron 桌面端生效监听127.0.0.1回环地址属于本地服务默认状态默认关闭需在「设置 → 网络 → WebSocket 配置」中手动开启开启后每次启动应用会自动拉起服务消息载体所有业务消息均为 JSON 文本帧心跳检测使用裸文本PING/PONG从 electron/main/store/index.ts 与defaults配置可见WebSocket 相关状态在本地持久化存储中的结构为websocket: { enabled: false, // 是否启用 port: 25885, // 监听端口 }在设置界面启用并配置服务WebSocket 服务默认不启动。在 SPlayer 的「设置 → 网络」分组中找到WebSocket 配置区块实现见 network.ts包含三个配置项配置项类型说明启用 WebSocket开关开启后可通过 WebSocket 获取状态或控制播放器WebSocket 端口数字输入165535更改后需要测试并保存才能生效服务运行时该输入框被禁用测试端口配置按钮测试并保存仅在端口值与已保存值不一致时显示启用流程遵循先测试、再启用的安全逻辑对应 network.ts输入新的端口号点击测试并保存应用会通过 IPC 通道socket-test-port调用主进程的testPort()检测端口是否可绑定实现见 SocketService.ts检测到EADDRINUSE端口被占用或EACCES权限不足即判定不可用测试成功才把配置写入本地存储打开启用 WebSocket开关应用通过 IPC 通道socket-start启动服务见 ipc-socket.ts启动成功后持久化{ enabled: true, port }此后每次应用启动都会调用SocketService.tryAutoStart()自动恢复服务见 electron/main/index.ts。如果启动时端口已被占用服务会自动把websocket.enabled重置为false避免下次启动再次失败见 SocketService.ts。建立连接在服务已开启的前提下任意 WebSocket 客户端都可以直连const ws new WebSocket(ws://localhost:25885);连接成功后服务器会自动发送一条welcome欢迎消息见handleClientConnection中的sendWelcomeSocketService.ts客户端可据此确认握手完成。提示服务绑定的是127.0.0.1因此仅本机可访问如需局域网内遥控播放器需要在系统层面做端口转发或反向代理SPlayer 默认不开放外部访问。消息协议总览所有业务消息统一采用如下 JSON 信封格式{ type: 消息类型, data: {} }其中type为必填字段data为可选载荷。按方向划分协议包含三类消息客户端 → 服务器请求control播放控制、get-song-info获取当前歌曲信息服务器 → 客户端响应control-response、song-info、error服务器 → 客户端广播welcome、status-change、song-change、progress-change、lyric-change心跳客户端发送文本PING服务器回复文本PONG。服务端对消息的解析与分发逻辑位于 SocketService.ts先做PING判定再尝试JSON.parse接着校验根对象必须是非数组对象、必须包含type字段最后按type分发到对应的处理函数未知类型会返回error。控制播放器消息类型control请求格式{ type: control, data: { command: toggle|play|pause|next|prev } }命令说明命令作用底层 IPC 事件toggle播放/暂停切换playOrPauseplay播放playpause暂停pausenext下一曲playNextprev上一曲playPrev命令到 IPC 事件的映射关系见 SocketService.tshandleControlCommand收到命令后通过mainWin.webContents.send(ipcEvent)把指令转发给渲染进程由前端播放器状态机真正执行操作。执行前会校验主窗口是否存在未初始化或已销毁则报错应用程序未找到或已销毁。成功响应{ type: control-response, data: { success: true, command: toggle, message: 播放/暂停切换命令已执行 } }错误响应{ type: error, data: { message: 错误信息 } }获取当前播放信息消息类型get-song-info无需data字段{ type: get-song-info }服务端收到后会通过 IPC 链路向渲染进程请求当前曲目快照见 track-info.ts 与 initIpc.ts主进程发送request-track-info渲染进程汇总播放状态、当前歌曲对象与歌词数据后以return-track-info回复整个过程有 2 秒超时保护超时返回获取当前播放信息失败。成功响应{ type: song-info, data: { playStatus: play, playName: 歌曲名, artistName: 歌手名, albumName: 专辑名, currentTime: 123.45, volume: 1, playRate: 1, id: 123456, name: 歌曲名, artists: 歌手名, album: 专辑名, cover: http://..., duration: 300, lrcData: [], yrcData: [] } }字段含义补充说明依据 initIpc.ts 的组装逻辑字段含义来源playStatus播放状态如play/pause播放器状态 storeplayName/artistName/albumName当前曲目的名称/歌手/专辑格式化展示用getPlayerInfoObj()currentTime当前播放进度秒播放器状态 storevolume音量01播放器状态 storeplayRate播放倍率播放器状态 storeid/name/artists/album/cover/duration当前歌曲对象的原始字段展开playSong音乐 storelrcData/yrcData普通歌词 / 逐字歌词数组歌词 store歌词未加载完成时返回空数组lyricLoading/lyricIndex歌词加载状态与当前行索引附加字段歌词 store错误响应{ type: error, data: { message: 获取当前播放信息失败 } }事件广播当播放器状态发生变化时服务器会向所有已连接客户端广播消息。广播统一走SocketService.broadcast()SocketService.ts其内部会遍历客户端集合仅向OPEN状态的连接发送并统计成功/失败数量写入日志。广播的触发入口集中在 ipc-socket.ts由渲染进程通过play-status-change、play-song-change、play-lyric-change、set-progress等 IPC 事件驱动。欢迎消息连接成功后服务器自动发送{ type: welcome, data: { message: 欢迎连接到 SPlayer WebSocket 服务, timestamp: 1234567890123 } }播放状态更新当播放/暂停状态改变时触发渲染进程sendPlayStatus→play-status-change见 PlayerIpc.ts{ type: status-change, data: { status: true, timestamp: 1234567890123 } }status为布尔值true表示播放中false表示暂停。歌曲信息更新当切换歌曲或歌曲信息加载完成时触发渲染进程sendSongChange→play-song-change见 PlayerIpc.ts{ type: song-change, data: { title: 歌曲名 - 歌手, name: 歌曲名, artist: 歌手, album: 专辑名, duration: 240000, timestamp: 1234567890123 } }注意duration单位为毫秒ms与song-info中按秒计量的duration不同。播放进度更新播放过程中实时触发。渲染进程通过sendSocketProgress以500ms 节流的频率推送见 PlayerIpc.ts因此实际广播间隔约 500ms{ type: progress-change, data: { currentTime: 12000, duration: 240000, timestamp: 1234567890123 } }currentTime与duration单位均为毫秒。服务端收到set-progress时会校验currentTime与duration是否都已提供缺一即丢弃见 ipc-socket.ts。歌词更新当歌词数据加载或改变时触发渲染进程sendLyric→play-lyric-change同样带 500ms 节流见 PlayerIpc.ts{ type: lyric-change, data: { lrcData: [], yrcData: [], timestamp: 1234567890123 } }lrcData为普通逐行歌词数据yrcData为逐字歌词数据。服务端只有在两者之一非空时才进行广播见 ipc-socket.ts避免无歌词时产生无意义消息。心跳检测为避免长连接被中间设备或操作系统回收客户端可以定期发送文本消息PING服务器会立即自动回复文本消息PONG// 发送心跳建议每 2030 秒一次 ws.send(PING); // 服务器自动回复 PONG ws.onmessage (event) { if (event.data PONG) { console.log(心跳正常); } };服务端的实现非常轻量在handleMessage中对消息做trim().toUpperCase()后直接与PING比较匹配则向该连接回发PONG并提前返回不进入 JSON 解析流程见 SocketService.ts。客户端可以据此实现断线自动重连逻辑。错误处理与常见错误服务端在以下场景会向客户端发送error消息{ type: error, data: { message: 错误描述信息 } }常见错误及触发条件汇总错误消息触发条件应用程序未找到或已销毁主窗口未初始化或已被销毁控制命令无法转发到渲染进程缺少 command 参数control消息的data中没有command字段未知的控制命令command不在toggle/play/pause/next/prev之内消息格式错误请发送有效的 JSON 格式消息消息无法被JSON.parse解析附带原始消息前 100 字符便于排查消息格式错误根对象必须是对象类型根对象是数组或非对象类型消息格式错误缺少 type 字段对象中没有type字段未知的消息类型: xxxtype不在control/get-song-info之内获取当前播放信息失败渲染进程未返回歌曲信息或 2 秒内超时客户端最佳实践收到error后检查data.message做对应处理连接意外关闭时onclose结合PING/PONG心跳做指数退避重连。完整客户端示例以下代码演示一个可直接运行的 WebSocket 控制端连接后自动获取当前歌曲信息发送控制命令并实时打印各类状态广播。const ws new WebSocket(ws://localhost:25885); // 连接成功后获取歌曲信息 执行播放/暂停切换 ws.onopen () { console.log(已连接 SPlayer WebSocket 服务); // 获取当前播放信息 ws.send(JSON.stringify({ type: get-song-info })); // 播放/暂停切换 ws.send( JSON.stringify({ type: control, data: { command: toggle }, }), ); // 下一曲 ws.send( JSON.stringify({ type: control, data: { command: next }, }), ); }; // 接收消息 ws.onmessage (event) { // 心跳回复是纯文本 PONG先做文本判断 if (event.data PONG) return; const message JSON.parse(event.data); switch (message.type) { case welcome: console.log(欢迎消息:, message.data.message); break; case song-info: console.log(当前歌曲:, message.data.playName, -, message.data.artistName); break; case control-response: console.log(控制命令已执行:, message.data.command); break; case status-change: console.log(播放状态:, message.data.status ? 播放中 : 已暂停); break; case song-change: console.log(切换歌曲:, message.data.title); break; case progress-change: console.log(进度:, message.data.currentTime, /, message.data.duration, ms); break; case lyric-change: console.log(歌词已更新:, message.data.lrcData, message.data.yrcData); break; case error: console.error(发生错误:, message.data.message); break; default: console.log(收到消息:, message); } }; // 心跳每 25 秒发送一次 PING setInterval(() { if (ws.readyState WebSocket.OPEN) ws.send(PING); }, 25000); // 断线自动重连简单实现 ws.onclose () { console.log(连接断开3 秒后重连...); setTimeout(() { location.reload(); // 在浏览器/Node 场景改为重新 new WebSocket(...) }, 3000); };底层实现要点单例服务SocketService采用单例模式SocketService.getInstance()全局唯一isRunning()/getPort()分别暴露运行状态与当前端口供 IPC 层查询SocketService.ts。端口可用性预检启动前先用net.createServer()探测端口捕获EADDRINUSE/EACCES即判定不可用SocketService.ts避免WebSocketServer启动即报错。连接生命周期管理服务用SetWebSocket维护在线客户端连接建立时加入集合、发送欢迎消息close时移除stop()时先逐个关闭客户端再关闭服务并清理SocketService.ts。全链路广播链路渲染进程Vue 播放器→ IPCplay-status-change/play-song-change/play-lyric-change/set-progress→ 主进程 ipc-socket.ts →SocketService.broadcast()→ 所有 WebSocket 客户端。换言之客户端收到的每条广播最终都源自播放器状态 store 的变更数据一致性有保障。配套 HTTP APIWebSocket 服务与 SPlayer 的本地 HTTP API 服务默认端口25884见 docs/api.md并存互补——HTTP 适合一次性请求/轮询WebSocket 适合实时控制与订阅。两者共享同一套播放控制能力可混合使用。相关文档SPlayer 使用指南播放器整体功能与操作说明本地 HTTP API 接口文档25884端口的 REST 控制接口SocketService 核心实现WebSocket 服务端完整源码WebSocket IPC 桥接层IPC 事件与广播消息的映射网络设置含 WebSocket 配置设置界面中 WebSocket 开关、端口与测试逻辑渲染进程 IPC 封装request-track-info/return-track-info的歌曲信息组装逻辑【免费下载链接】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),仅供参考