// Plugin Developer Guide

插件开发概览

Mio Music 的在线内容全部来自插件。插件是一个自包含的 JavaScript 文件,在应用内的受限沙箱里运行,不需要编译,也不需要任何构建工具。

快速上手

十分钟写出并安装第一个列表插件,看到它出现在来源菜单里。

列表插件参考

元数据、来源与能力、配置表单,以及每个方法的参数与返回值。

运行时 API

cerumusic.request、存储、配置、加密工具与全部限制。

调试与发布

读日志、排错清单,以及把插件提交到内置插件仓库的约定。

两类插件

音乐列表插件音源插件
解决什么问题「有什么歌」:搜索、歌单、专辑、发现、歌手、歌词、评论、封面。还可以自己提供播放与下载地址。「怎么播」:给定来源、歌曲与音质,返回一个可播放的地址。
入口module.exports = { listPlugin: {…} }pluginInfo + sources + musicUrl(澜音),或洛雪脚本(自动转换)
文件名通常 *.list.js任意 .js
能否多个同时启用可以同一时间使用一个,需显式切换
配置表单支持(config)不支持
持久化存储cerumusic.storage无
参考列表插件参考音源插件
该写哪一种? 要对接一个自托管服务器(Subsonic、Jellyfin、你自己的服务……),或者想提供搜索、歌单、歌手页,写列表插件,并在其中同时实现 musicUrl,一个文件就够了。只有当你已经有一份「根据歌曲 ID 解析地址」的脚本(例如洛雪脚本)时,才需要音源插件。

运行环境

插件由宿主内嵌的 QuickJS(通过 rquickjs)执行。它是一个标准的 ECMAScript 引擎,async / await、Promise、解构、模板字符串、Map / Set 都可以直接使用。与浏览器和 Node.js 的差别需要特别注意:

每次调用都是全新的上下文 宿主为每一次方法调用新建一个 JS 运行时,再执行你的整个脚本。模块顶层的变量(缓存、登录态)不会在两次调用之间保留。需要保留的东西——会话令牌、缓存——写进 cerumusic.storage。这是写插件时最常见的误区。

开发流程

  1. 写脚本

    按 快速上手 搭好骨架,对照 列表插件参考 与 数据结构 实现方法。

  2. 安装

    设置 → 插件 → 音乐列表插件 → 安装列表插件,选择本地文件或输入 URL。同名重装即更新,配置保留。

  3. 配置并测试

    在插件卡片上填写配置、点「测试连接」(如果声明了),然后到搜索页实际使用。

  4. 看日志

    插件卡片上的「插件日志」会显示你的 console.* 输出和宿主记录的失败原因。

  5. 发布

    分享一个 .js 文件即可;想随应用内置,向 mio-music-plugins 提交,见 调试与发布。

最小的例子

module.exports = {
  listPlugin: {
    name: 'Hello',
    version: '1.0.0',
    author: 'you',
    sources: {
      hello: { name: 'Hello', capabilities: ['search'] },
    },
    async search(source, { keyword, page, limit }) {
      return {
        list: [{ songmid: '1', name: keyword, singer: 'Mio', albumName: '', img: '', interval: '03:00' }],
        allPage: 1, limit, total: 1, source,
      };
    },
  },
};

安全与合规

阅读路线

  1. 快速上手:先让一个插件跑起来。
  2. 列表插件参考:要实现哪些方法、各自接收什么。
  3. 数据结构:返回值的字段与类型,以及常见的类型陷阱。
  4. 运行时 API:能用什么、不能用什么。
  5. 音源插件:只需要解析播放地址时。
  6. 调试与发布:排错与提交。