Spotube 中文文档 下载 App

Spotube 插件构建与打包——Gradle 编译 Kotlin/JS 成 .smplug

构建流程总览

Spotube 插件的构建链路:

Kotlin/JS 源码
      ↓ (Gradle + Kotlin Multiplatform)
编译成 JavaScript (node.js target)
      ↓ (spotube-gradle-plugin)
与 plugin.json manifest + deps 一起打包
      ↓
.smplug 文件(ZIP 格式)

build.gradle.kts 配置要点

plugins {
    kotlin("multiplatform") version "2.0.20"
    id("dev.krtirtho.spotube.gradle-plugin") version "5.1.0"  // 版本跟 Spotube 主版本走
}

kotlin {
    js(IR) {
        nodejs()  // Zipline 运行在 Node.js runtime 里
        binaries.executable()
    }
}

dependencies {
    jsMainImplementation("dev.krtirtho.spotube:plugin_interfaces:5.1.0")
    jsMainImplementation("app.cash.zipline:zipline-kotlin:9.0.0")
}

spotubePlugin {
    // plugin.json 会自动从这里生成(也可以手写放在 src/jsMain/resources/plugin.json)
    pluginName = "My Awesome Plugin"
    pluginId = "com.example.myplugin"
    pluginVersion = "1.0.0"
    author = "Your Name"
    description = "Does something useful for Spotube users"
    abilities = listOf("metadata", "audio")  // 声明实现了哪些接口
}

执行构建:

./gradlew spotubePlugin

产物位置:build/distributions/<plugin-name>-<version>.smplug

plugin.json manifest

spotube-gradle-plugin 会自动从 Gradle DSL 生成 plugin.json,也可以手写放在 src/jsMain/resources/plugin.json(会覆盖自动生成的):

{
  "id": "com.example.myplugin",
  "name": "My Awesome Plugin",
  "version": "1.0.0",
  "author": "Your Name",
  "description": "Does something useful",
  "abilities": ["metadata", "audio"],
  "entrypoint": "index.zipline.js"
}

关键字段:

字段必填说明
id✅全局唯一,建议用反向域名(com.xxx.yyy)
name✅插件页显示的名称
version✅semver
abilities✅Spotube 用这个做能力过滤(v5.1 新特性)
entrypoint❌默认是 index.zipline.js,除非你改了编译产物名

.smplug 文件实际结构

解压一个 .smplug 会看到:

myplugin-1.0.0.smplug
├── plugin.json           # manifest
├── index.zipline.js      # 编译好的 Kotlin/JS 主文件(通常 50~200KB)
└── deps/                 # 外部 JS 依赖(如果有)
    ├── lib_a.js
    └── lib_b.js

index.zipline.js 是编译器产出的"单文件"——Gradle 把所有 Kotlin 代码 + Zipline runtime 打进了这一个文件,Spotube 加载时直接 eval() 或 new Function() 这个 JS 字符串。

手动调试技巧

Spotube 侧调试

Spotube 设置 → Debug → Export debug log → 保存日志文件。插件里用 host.logger.d("my debug message") 打的日志会出现在里面。

开发者模式

Spotube 有一个隐藏的开发者模式:

# 桌面端
spotube --developer-mode

# Android:安装 Magisk 模块或用 patch 过
# 不推荐,主要给 Spotube 自身开发用

开发者模式下会显示插件加载耗时、Bridge 调用时长等内部信息。

用 console.log 直接打

由于 Zipline runtime 跑在 Node.js JS 环境里,插件里可以直接用 println() 或 console.log()(Kotlin/JS 会把 println 编译成 console.log)。Spotube 宿主会拦截这些输出写到 debug log。

手动安装 .smplug 进行调试

  1. 构建出 .smplug
  2. 复制到 Spotube 插件目录:
  1. 启动 Spotube → 插件页 → 应该能看到你的插件
  2. 启用它 → 搜索 / 播放测试

热更新

Spotube 目前不支持热更新插件——改完代码需要重新构建 .smplug,然后重启 Spotube。社区讨论过为开发者模式加 reload 按钮,但还没实现。

常见构建问题

Kotlin 版本不匹配

plugin_interfaces:5.1.0 需要 Kotlin 2.0+。如果 Gradle 报兼容性错误,升级 Kotlin 版本号。

spotube-gradle-plugin 找不到

确认版本号(5.1.0 对应 Spotube v5.1),Maven Central 上可能有延迟。可以加 maven { url = uri("jitpack") } 作为备用。

index.zipline.js 不是单文件

需要在 kotlin.js { binaries.executable() } 里加 applyBinaryOptimize("binaryOptimizer") 或者手动配置 webpack 打包。spotube-gradle-plugin 默认应该帮你做了这件事。