- 桌面应用
- 音视频
- 插件系统
【免费下载链接】pear-desktop
Pear 🍐 is extension for music player
Pear Desktop 是 GitHub 推荐项目精选 / yo 下的开源项目,其核心定位是「YouTube Music 桌面应用 + 自定义插件体系」。本文以仓库根目录下的 changelog.md 为骨架,完整梳理该项目从 v1.0.0 到 v3.12.0 的版本演进脉络,并结合 src 目录下的真实源码(如 api-server 插件、插件配置系统)逐层解读每个里程碑背后的技术含义。读完本文,你将掌握该项目的插件架构、远程控制 API、构建工具链演进路线,并能基于 changelog 快速定位任意功能对应的源码实现。
一、版本总览:三年 26 个里程碑的演进节奏
changelog.md 记录了从 v1.0.0(初始提交,仅含 4 个插件)到 v3.12.0 的全部版本。以下按时间线整理的主要里程碑(日期均为 UTC):
| 版本 | 发布日期 | 核心主题 |
|---|---|---|
| v1.0.0 | 2021 年左右 | 初始提交:应用 + 4 个插件 |
| v1.7.0 | 2024-02 | 配置系统重构,支持高级自定义插件选项 |
| v2.0.0 | 2024 前后 | 全面迁移 TypeScript,rollup 打包 |
| v2.1.2 | 2024 | 源码迁移至src目录,npm → pnpm |
| v3.0.0 | 2025-02 | 引入 i18n 国际化、electron-vite 构建、context-isolation 安全加固 |
| v3.7.0 | 2024-12 | API Server 加入重复模式与 seek 时间 API、Equalizer 均衡器插件 |
| v3.10.0 | 2025-07 | ESM 化、代码分割、原生 HTML → JSX(SolidJS)迁移 |
| v3.12.0 | 2026-06 | WebSocket 授权、透明播放器支持 Linux/macOS、eslint → oxlint |
从版本号节奏可以看出,该项目采用语义化版本 + 高频补丁(patch)更新的维护策略,依赖更新与功能开发并行推进,这与其renovate.json自动依赖更新配置和 package.json 中的auto-changelog生成脚本("changelog": "pnpm dlx auto-changelog")一致。
二、插件体系的演进:从 4 个到 30+ 个功能模块
changelog 中频率最高的关键词是feat(plugin)和feat(...),插件化是该项目最核心的架构决策。结合源码目录 src/plugins,可以看到插件按功能域组织为独立目录,每个插件通常包含index.ts(插件定义)、menu.ts(菜单配置)、renderer.tsx(渲染进程组件)等文件。
2.1 经典播放控制类插件
- Skip Silences(跳过静默):v1.15.0 引入,源码位于 src/plugins/skip-silences,v1.15.0 中还修复了该插件与
skip only at the beginning选项的配合。 - Precise Volume(精确音量):v1.12.0 引入,src/plugins/precise-volume 中通过 override.ts 重写音量滑块行为,changelog 中多次记录其 UI 同步与 HUD 定位修复。
- Audio Compressor(音频压缩器):v1.14.0 引入,src/plugins/audio-compressor.ts,v3.11.0 修复了实时行为与重复音频 bug。
- Exponential Volume(指数音量):v1.15.0 引入,src/plugins/exponential-volume,v3.11.0 修复了音量失步(desync)问题。
- Equalizer(均衡器):v3.7.0 引入,支持预设(如 Bass Booster),源码位于 src/plugins/equalizer,其中 presets.ts 存放预设定义。
2.2 信息与联动类插件
- Discord Rich Presence:v1.9.0 引入(Discord 富状态),后续版本持续演进:v1.16.0 加入专辑封面与暂停图标、v3.11.0 增加「在状态中显示艺术家/标题」与歌曲 URL、v3.11.1 修复 RPC 重复失败导致的内存泄漏。核心实现在 src/plugins/discord 的 discord-service.ts 与 timer-manager.ts。
- Synced Lyrics(同步歌词):v3.5.0 引入,是 changelog 中迭代最密集的插件之一:v3.5.2 提高歌词搜索可靠性、v3.7.0 支持多歌词源、v3.8.0 加入罗马音化(Romanization)、v3.10.0 加入虚拟滚动与 Musixmatch 源、v3.11.0 支持首选歌词源与「spacer」、v3.11.3 支持印地语/孟加拉语罗马音与简繁转换。源码见 src/plugins/synced-lyrics,其中 providers 目录枚举了 LRCLib、LyricsGenius、MusixMatch 等多个歌词源实现。
- Scrobbler(Last.fm / ListenBrainz 记录):v1.12.0 引入 Last.fm 支持,v3.8.0 支持使用替代歌曲标题记录,服务层实现于 src/plugins/scrobbler/services。
- Music Together(同步收听):v3.2.0 引入,基于 PeerJS 的队列同步,源码见 src/plugins/music-together/queue。
2.3 界面增强类插件
- Ambient Mode(环境光):v3.3.3 前后引入,v3.3.0 支持专辑色彩主题,源码 src/plugins/album-color-theme 与 src/plugins/ambient-mode。
- Blur Navigation Bar:v1.14.0 引入,src/plugins/blur-nav-bar。
- In-App Menu(应用内菜单):历经多轮重构(v1.12.0 插件化、v2.1.0 Windows 默认启用、v3.3.0 重构),源码见 src/plugins/in-app-menu,其 renderer 目录中包含了自绘的 TitleBar.tsx 与 WindowController.tsx。
- Picture-in-Picture(画中画):v1.17.0 引入,v1.20.0 增加
useNativePiP选项,源码 src/plugins/picture-in-picture。 - Transparent Player(透明播放器):v3.11.0 引入,支持 Acrylic / Mica / Tabbed 效果,v3.12.0 扩展至 Linux 与 macOS,源码见 src/plugins/transparent-player。
- Clock Widget(时钟组件):v3.11.1 引入,src/plugins/clock。
2.4 下载与媒体控制类插件
- Downloader(下载器):v1.6.2 引入(video → mp3),是迭代最久的插件:v1.20.0 支持元数据清理、v2.1.0 支持音频格式自动检测、v3.4.0 支持「播放完成后自动下载」、v3.11.4 通过更新 youtubei.js 修复下载功能。核心实现见 src/plugins/downloader/main/index.ts。
- Taskbar Media Control(任务栏媒体控制):v1.12.0 引入,v3.12.0 移除了 jimp 依赖以减小体积,源码 src/plugins/taskbar-mediacontrol。
- MPRIS(Linux 媒体控制):v1.13.0 引入,后续修复了音量同步(v3.8.1)、位置信息(v3.4.1)等,实现依赖
@jellybrick/mpris-service。
三、API Server 插件源码级解析:把播放器变成可编程服务
changelog 中feat(api-server)出现 9 次以上,这是 v3.x 阶段最重要的功能方向。从 v3.6.0「remote control api」到 v3.12.0「WebSocket authorization」,API Server 已经演化为一个完整的远程控制 + 实时推送基础设施。
3.1 架构与配置
API Server 插件默认关闭(enabled: false),其默认配置定义在 src/plugins/api-server/config.ts:
export enum AuthStrategy { AUTH_AT_FIRST = 'AUTH_AT_FIRST', NONE = 'NONE', } export const defaultAPIServerConfig: APIServerConfig = { enabled: false, hostname: '0.0.0.0', port: 26538, authStrategy: AuthStrategy.AUTH_AT_FIRST, secret: Date.now().toString(36), authorizedClients: [], useHttps: false, certPath: '', keyPath: '', };关键参数说明:
hostname/port:监听地址与端口,默认 0.0.0.0:26538;authStrategy:认证策略,AUTH_AT_FIRST(首次访问需授权)或NONE(无需认证);secret:JWT 签名密钥,默认以当前时间戳生成;authorizedClients:已授权的客户端 ID 列表;useHttps/certPath/keyPath:v3.11.1 引入的 HTTPS 与自定义证书配置。
后端使用 Hono + Zod OpenAPI 构建,路由注册见 src/plugins/api-server/backend/routes/index.ts,分别导出 control(控制)、auth(认证)、websocket(实时推送)三个模块。
3.2 HTTP 控制端点
control.ts 中通过app.openapi()声明了完整的 REST API,全部挂载在/api/v1前缀(版本号定义于 api-version.ts):
| 方法 | 路径 | 功能 |
|---|---|---|
| POST | /api/v1/previous//next | 上一首 / 下一首 |
| POST | /api/v1/play//pause//toggle-play | 播放 / 暂停 / 切换 |
| GET | /api/v1/like-state | 查询喜欢状态 |
| POST | /api/v1/like//dislike | 喜欢 / 不喜欢当前歌曲 |
| POST | /api/v1/seek-to | 跳转到指定秒数 |
| POST | /api/v1/go-back//go-forward | 前进 / 后退若干秒 |
| GET/POST | /api/v1/shuffle | 查询 / 切换随机播放 |
| GET/POST | /api/v1/repeat-mode//switch-repeat | 查询 / 切换重复模式(NONE/ALL/ONE) |
| GET/POST | /api/v1/volume | 查询 / 设置音量(含 isMuted) |
| GET/POST | /api/v1/fullscreen | 查询 / 设置全屏 |
| POST | /api/v1/toggle-mute | 切换静音 |
| GET | /api/v1/song | 获取当前歌曲信息(v3.11.1 起移除了 image 字段以减小响应体) |
| GET | /api/v1/queue | 获取队列 |
| POST | /api/v1/queue | 添加歌曲到队列(v3.7.2 支持insertPosition) |
| PATCH | /api/v1/queue/{index} | 移动队列中的歌曲 |
| DELETE | /api/v1/queue/{index} | 移除队列中的歌曲 |
| PATCH | /api/v1/queue | 设置队列当前索引 |
| DELETE | /api/v1/queue | 清空队列 |
| GET | /api/v1/queue/next | 获取下一首歌曲信息(v3.11.1 引入) |
| POST | /api/v1/search | 搜索歌曲(v3.10.0 支持可选参数与 continuation) |
从实现上看,控制端点通过getSongControls(window)拿到播放控制句柄(定义于 src/providers/song-controls.ts),而状态查询类端点(如 shuffle、fullscreen、queue)则通过ipcMain.once()等待渲染进程的peard:系列应答事件,形成「HTTP → IPC → 播放器」的完整链路。这与 changelog 中 v3.6.1「Various fixes and improvements」、v3.7.0「add absolute seek endpoint」等记录相互印证。
3.3 WebSocket 实时推送与授权
v3.11.0 引入/api/v1/ws端点后,v3.12.0 为其加入了 JWT 授权。websocket.ts 的实现在连接建立时完成鉴权:
if (config.authStrategy !== AuthStrategy.NONE) { const token = ctx.req.query('token'); if (!token) { ws.close(1008, 'Unauthorized'); return; } const payload = await verify(token, config.secret, 'HS256'); const parsedPayload = await JWTPayloadSchema.safeParseAsync(payload); if (!parsedPayload.success || !config.authorizedClients.includes(parsedPayload.data.id)) { ws.close(1008, 'Unauthorized'); return; } }连接建立后立即推送一条PLAYER_INFO快照,之后持续广播以下事件类型:
| 事件类型 | 触发时机 |
|---|---|
VIDEO_CHANGED | 切歌(VideoSrcChanged) |
PLAYER_STATE_CHANGED | 播放 / 暂停切换,含应用退出前(before-quit)的最终状态 |
POSITION_CHANGED | 播放进度更新(TimeChanged / seek) |
VOLUME_CHANGED | 音量变化 |
REPEAT_CHANGED | 重复模式变化 |
SHUFFLE_CHANGED | 随机播放状态变化 |
推送的数据源来自registerCallback(src/providers/song-info.ts 的歌曲信息事件回调)以及ipc.on('peard:volume-changed')等 IPC 事件。v3.12.0 还通过electronApp.once('before-quit')在应用退出时向所有已连接客户端广播暂停状态,这对应 changelog 中feat(websocket): handle player state on app quit。
3.4 认证流程
auth.ts 实现了客户端授权握手:客户端首次访问时通过/auth/端点提交客户端 ID,主进程弹出确认提示,用户确认后该 ID 被加入authorizedClients并签发 JWT。changelog 中 v3.11.1 的「Fixes the error 500 for /auth/ endpoint」和 v3.12.0 的「add required 'alg' option to JWT middleware」均为这条链路的修复记录。
四、工程化与构建体系的三次跃迁
changelog 清晰记录了项目构建工具的演进路径,这在 electron.vite.config.mts 中得到了最终体现。
4.1 rollup → electron-vite → rolldown
- v1.x:基于 rollup + spectron 测试,v1.15.0 将测试框架从 spectron 切换到 Playwright(仓库中 tests/index.test.js 与
@playwright/test依赖可验证); - v2.0.0:全面 TypeScript 化(
feat: I guess it's TypeScript),并应用 rollup; - v3.0.0:迁移到 electron-vite,启用
context-isolation安全隔离(对应 preload.ts); - v3.10.0:开启 rolldown 原生插件,并让主进程支持 ESM(
feat: enable the ESM for main); - v3.12.0:修复 rolldown 打包(
fix(rolldown): fix bundling)。
4.2 前端框架与 UI 层
- v3.10.0:将原生 HTML 模板迁移为 TSX / SolidJS(
feat: migrate from raw HTML to JSX (TSX / SolidJS)),对应 vite 配置中的vite-plugin-solid; - v3.11.1:引入 Material UI 3 组件库(
@mdui/icons+mdui,仓库 assets/mdui.css 可验证); - v3.12.0:代码质量工具从 ESLint 迁移到 oxlint + oxfmt(package.json 中的
lint/format脚本即为pnpm oxlint --type-aware src与pnpm oxfmt --write src)。
4.3 包管理与发布
- v2.1.2:从 npm 迁移到 pnpm,仓库根目录的 pnpm-workspace.yaml 与 pnpm-lock.yaml 是迁移完成后的产物;
- package.json的
engines要求 Node >= 22、pnpm >= 11; - 构建脚本覆盖全平台:
dist:linux(含 deb/rpm、arm64 支持,见 v3.3.7 的Enable arm64 for deb and rpm)、dist:mac(含 arm64)、dist:win(含 IA32 与 arm,v2.0.0/v1.20.0 分别添加)。
五、跨平台与系统集成:从托盘到 MPRIS
changelog 中大量fix(mpris)、fix(flatpak)、fix(wayland)记录表明,项目在 Linux/macOS/Windows 的系统集成上投入了持续维护:
- 托盘(Tray):v1.3.1 引入托盘与选项,v3.2.2 为托盘加入歌曲信息与暂停图标(src/tray.ts,图标资源在 assets 下的
tray.png、tray-paused.png、tray-white.png等); - MPRIS:v1.13.0 引入 Linux 媒体控制,v3.8.1 保持音量同步,v1.18.0 支持循环与音量变化;
- Flatpak:v3.7.0 明确指定 Flatpak 运行时并为 MPRIS/托盘补充权限,v3.11.1 为 rpm 构建补充 libuuid 依赖(对应 patches/@malept__flatpak-bundler@0.4.0.patch);
- Wayland / X11:v3.3.3 添加 Wayland 支持,v3.7.0 修复 X11/Wayland 窗口类名,v3.12.0 更新 WM_CLASS 提升兼容性;
- 多显示器:v3.4.2/v3.5.1 修复缩放显示器上的窗口尺寸与离屏问题。
六、广告拦截与安全更新
Adblocker 是贯穿全生命周期的插件:v1.3.1 从 adblock-rs 迁移到 Cliqz 实现,v1.7.5 加入 uBlock Origin 过滤源,v3.11.2 恢复并修复 adblocker 插件。当前依赖为@ghostery/adblocker-electron与@ghostery/adblocker-electron-preload(package.json),对应注入实现位于 src/plugins/do-not-track 与 adblocker 相关的 injector 逻辑。changelog 中[security]标记的依赖更新(如@xmldom/xmldom、hono、vite等)记录了安全修复的时序,这也是该项目依赖更新频繁的直接原因。
七、如何高效利用 changelog 与源码联动排障
结合本文内容,推荐以下定位问题的路径:
- 按版本定位功能引入:在 changelog.md 中搜索
feat(插件名),得到引入版本后,对照 src/plugins 下同名目录查看当前实现; - 按插件定位配置项:每个插件目录下的
config.ts或插件定义中的config字段(如 api-server/config.ts)即为其可配置项,结合 src/config/plugins.ts 的setOptions/getOptions/isEnabled工具函数可理解配置的读取与合并逻辑(enabled字段默认排除在外,避免覆盖); - 按菜单定位交互:各插件目录下的
menu.ts(如 api-server/menu.ts、discord/menu.ts)定义了用户在应用菜单中的开关入口,与setMenuOptions(配置变更后可触发重启,见options.restartOnConfigChanges)配合。
结语
从 changelog.md 这份文件出发,我们可以完整还原 Pear Desktop 三年来的演进逻辑:以插件化为核心架构承载功能扩展,以 API Server 为枢纽打通外部控制与实时数据流,以 Electron/electron-vite 工具链的更迭保持工程现代化,再以高频依赖更新守住安全与稳定性底线。对于想深入理解该项目或基于它二次开发的开发者而言,把 changelog 当「功能索引」、把 src 当「实现字典」,是最快且最准确的切入点。
- 桌面应用
- 音视频
- 插件系统
【免费下载链接】pear-desktop
Pear 🍐 is extension for music player
相关推荐
pyenv 版本演进全解析:从 CHANGELOG 看 Python 版本管理工具的十年技术迭代
pyenv 版本演进全解析:从 CHANGELOG 看 Python 版本管理工具的十年技术迭代 pyenv 是一款遵循 UNIX 单一职责哲学的 Python
开发工具CLIGraphQL Playground Electron 桌面客户端演进全览:CHANGELOG 驱动的版本历史与技术实现解读
GraphQL Playground Electron 桌面客户端演进全览:CHANGELOG 驱动的版本历史与技术实现解读 GraphQL Playgroun
开发工具后端API设计Ktor 3.x 版本演进全景:从 CHANGELOG 解读 Ktor 客户端/服务端框架的技术迭代路线
Ktor 3.x 版本演进全景:从 CHANGELOG 解读 Ktor 客户端/服务端框架的技术迭代路线 本文以 CHANGELOG.md https://li
后端Web框架微服务
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考