Spotube 中文文档 下载 App

Spotube 插件是什么、如何工作——v5 插件架构入门

一句话概念

Spotube 的插件是 Kotlin/JS 库,打包成 .smplug 文件,在 Cash App 的 Zipline runtime 沙箱里运行,通过 Spotube 宿主暴露的 Bridge 调用 UI、网络、存储等能力,实现元数据搜索、音频流获取、歌词、scrobbling 等可替换功能。

插件不是 Dart/Flutter 代码,不是传统的 .so / .dylib / .dll 动态库,而是在一个 JS 虚拟机里跑的 Kotlin 编译产物。

宿主与插件的边界

Spotube 宿主(Flutter 写的部分)负责:

插件负责:

四类插件接口

Spotube 预定义了四个接口(interface),每个插件可以实现其中一个或多个:

接口用途典型插件
MetadataSearchAPI搜索曲目、专辑、歌手、歌单,返回元数据Spotify、MusicBrainz、JioSaavn、Spotube(Spotube 官方元数据聚合插件)
AudioAPI根据 Track 元数据拿到音频流 URLYouTube、Piped、Invidious、Qobuz、v5.1 新增自定义源
LyricsAPI根据曲目信息获取时间同步歌词LRCLib
ScrobbleAPI把播放记录上报到外部服务ListenBrainz、Last.fm

v5.1.0 还新增了 Dab(广播电台)和 FLAC 无损 AudioAPI 支持。

.smplug 文件结构

一个 .smplug 本质上是 ZIP 包,内部结构:

my-plugin.smplug  (ZIP)
├── plugin.json           # manifest:插件元信息、声明实现哪些接口
├── index.zipline.js      # 编译好的 Kotlin/JS 主文件
└── deps/                 # 可能的依赖 JS 库
    └── ...

plugin.json 大致长这样:

{
  "id": "dev.krtirtho.spotify-metadata",
  "name": "Spotify Metadata",
  "version": "1.0.0",
  "author": "Spotube Team",
  "description": "Spotify 元数据服务",
  "abilities": ["metadata"]
}

插件加载流程

  1. Spotube 启动时扫描插件目录(桌面端通常在 ~/.local/share/spotube/plugins/ 或应用支持目录;Android 在应用私有目录)
  2. 加载每个 .smplug 里的 plugin.json,显示给用户看
  3. 点击启用 → Spotube 把插件代码喂给 Zipline runtime
  4. Zipline 创建沙箱 → 插件 main() 函数被调用
  5. 插件通过 Zipline.get() 拿到宿主 Bridge 实例
  6. 插件向宿主注册自己实现的接口
  7. 搜索/播放/歌词/scrobble 请求发生时,Spotube 调插件注册的方法

与 Dart 扩展的对比

传统 Flutter 扩展(比如很多桌面端应用的 .so 插件)是原生动态库,和宿主在同一个进程空间,能做任何事。Spotube 的 Kotlin/JS 插件跑在 Zipline 沙箱里,只能通过宿主暴露的 Bridge 做事——插件不能直接访问文件系统、网络、传感器,所有操作都要走宿主授权。这是安全边界。

想自己写插件?从 Kotlin/JS + Zipline 环境搭建 开始。