// Source Plugin

音源插件

音源插件只做一件事:给定来源、歌曲和音质,返回一个能播放的地址。如果你的需求是接入一台服务器,或者要提供搜索与歌单,请写 列表插件,那里同样可以实现 musicUrl。

何时需要音源插件

音源插件需要在 设置 → 插件 里显式选择当前使用哪一个;列表插件则可以同时启用多个。音源插件没有配置表单,也没有持久化存储。

澜音(CeruMusic)契约

/**
 * @name 我的音源
 * @version 1.0.0
 * @author you
 * @description 演示用音源插件
 */
module.exports = {
  pluginInfo: {
    name: '我的音源',
    version: '1.0.0',
    author: 'you',
    description: '演示用音源插件',
  },
  sources: {
    git: { name: '示例来源', qualitys: ['128k', '320k', 'flac'] },
  },
  async musicUrl(source, musicInfo, quality) {
    const res = await cerumusic.request(
      `https://example.com/resolve?src=${source}&id=${musicInfo.songmid}&q=${quality}`,
      { timeout: 10000 },
    );
    if (res.statusCode !== 200) throw new Error('解析失败:HTTP ' + res.statusCode);
    const body = typeof res.body === 'string' ? JSON.parse(res.body) : res.body;
    return body.url;
  },
};

字段

字段说明
pluginInfo.name必填,最多 256 个字符。version、author、description 缺失时会回退读取脚本头部注释里的 @version、@author、@description。
sources必填。键是来源 ID,只能是宿主为兼容旧版音源格式保留的 ID(如 git);音源插件不支持自定义 ID,那是列表插件的能力。
sources.<id>.qualitys该来源支持的音质数组,也可以拼作 qualities。只认 已知的音质名称,没有任何有效音质的来源会被丢弃。至少要有一个有效来源,否则安装失败。
sources.<id>.name显示名,最多 128 字符。
musicUrl(source, musicInfo, quality)必填。返回播放地址。

musicUrl

洛雪(LX)脚本

洛雪的事件式脚本(用 lx.on('request', …) 响应、用 lx.send('inited', …) 声明来源)可以直接安装,安装时会被转换成宿主能执行的形式。宿主提供了一个精简的 lx 对象:

const { EVENT_NAMES, request, on, send } = globalThis.lx;

on(EVENT_NAMES.request, ({ source, action, info }) => {
  if (action !== 'musicUrl') return Promise.reject(new Error('不支持的操作'));
  const song = info.musicInfo;       // 歌曲
  const quality = info.type;         // 音质
  return resolveUrl(source, song, quality);   // Promise<string>
});

send(EVENT_NAMES.inited, {
  sources: {
    git: { name: '示例来源', type: 'music', actions: ['musicUrl'], qualitys: ['128k', '320k'] },
  },
});

限制

音源插件使用比列表插件更小的预算:每次调用最多 16 个请求,单个响应体最大 4 MiB,内存 32 MiB,总时限同样是 30 秒,脚本不超过 1 MiB。其它与列表插件相同,见 限制一览。

调试

音源插件的错误信息被有意隐藏 为防止签名地址或凭据通过异常泄露,音源插件的失败只会显示固定文案:网络层失败是「插件网络请求失败或超时」,其它是「插件初始化或播放解析失败」。要定位原因,请在脚本里用 console.log 输出关键步骤,再到插件日志里看。