Skip to content

音源插件使用教程 ​

拼好歌不提供任何音源插件,也不分发、不推荐具体插件。它只提供运行插件的框架:你把自己准备的 JavaScript 脚本导入客户端,客户端在需要播放时向脚本索取一个可播放的音频地址。

目前只支持一种插件格式:洛雪音乐(lx-music)的音源脚本生态。 这是「遵循同一套脚本协议」,并非「兼容多种格式」—— 拼好歌的插件层按洛雪的 globalThis.lx 协议实现(协议版本 2.0.0,运行环境标识 mobile),其他格式的插件(各平台自研的插件包等)不能直接使用。

这一页讲三件事:支持什么样的脚本、脚本在哪里执行、以及怎么自己写一个。

支持什么样的脚本 ​

拼好歌兼容洛雪音乐音源脚本协议(globalThis.lx,协议版本 2.0.0),与 lx-music 移动版的脚本机制一致。具体支持范围:

项目支持情况
插件生态仅洛雪音乐音源脚本(lx-music),不兼容其他格式
脚本语言JavaScript(ES6+),UTF-8 编码
音乐源六个:kw kg tx wy mg local
音质128k 320k flac flac24bit
操作非 local 源只有 musicUrl;local 源另有 lyric 与 pic
事件inited(初始化上报)、request(应用索取数据)
网络请求只能走 lx.request,它不受跨域限制
宿主 API只有 setTimeout / clearTimeout / setInterval / clearInterval 与部分 Buffer;没有 fetch、XMLHttpRequest、document、window、require

这些脚本跑不起来

  • 依赖浏览器或 Node.js 宿主 API(fetch、XMLHttpRequest、fs、require、npm 模块)的脚本;
  • 部分经过混淆的脚本 —— 这类脚本通常在初始化阶段就抛错,客户端会判定为不可用;
  • 需要 lx.utils.zlib 的脚本可能失败:解压依赖运行时是否带 pako,没带时 inflate / deflate 会直接 reject。

脚本在哪里执行 ​

平台可用的执行位置
Android本机运行 / 专属服务器
Windows / macOS / Linux本机运行 / 专属服务器
iOS / 华为纯血鸿蒙只能专属服务器

「本机运行」是把脚本放进客户端内置的 QuickJS 沙箱执行;「专属服务器」是把脚本放到你自己部署的服务端执行。两者的脚本写法完全一样,区别只在执行位置。详见平台与运行模式。

写一个自己的插件 ​

第 1 步:写好头部注释 ​

文件开头必须有注释块,客户端从里面读名称、版本、作者等信息,缺省时留空:

js
/**
 * @name 我的音源
 * @description 一句话说明这个源做什么
 * @version 1.0.0
 * @author 你的名字
 * @homepage https://example.com
 */

第 2 步:注册 request、发送 inited ​

脚本与客户端通过事件交互:注册 request 接收请求,初始化完成后发送 inited 告诉客户端支持哪些源。

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

// 把 lx.request 包成 Promise 便于链式书写
const httpGet = (url, options = {}) =>
  new Promise((resolve, reject) => {
    request(url, options, (err, resp) => {
      if (err) return reject(err)
      resolve(resp.body)
    })
  })

on(EVENT_NAMES.request, ({ source, action, info }) => {
  if (action !== 'musicUrl') return Promise.reject(new Error('unsupported action'))

  const { musicInfo, type } = info
  return httpGet(`https://api.example.com/url?mid=${musicInfo.songmid}&quality=${type}`)
    .then(body => JSON.parse(body).url) // 必须返回 http(s) 地址字符串
})

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

四条硬规则:

  1. on(request, handler) 的回调必须返回 Promise;
  2. musicUrl 的 Promise 结果必须是能直接播放的 http(s) 地址字符串;
  3. send(inited, ...) 必须在初始化阶段调用一次,在这之前抛任何错都算初始化失败;
  4. inited 里声明的 qualitys 决定客户端能选哪些音质,没声明的音质不会去请求。

第 3 步:按音乐信息取地址 ​

info.musicInfo 是歌曲对象,常见字段:

字段说明
songmid / id / hash各源的主键,不同源用不同名字
name / singer歌名与歌手,适合做搜索兜底
interval时长
albumName专辑名
source来源源标识
meta.songId部分源把主键放在这里

取不到主键时可以退回用 name + singer 搜索。客户端换源时会带上目标源的参数,所以脚本只需要处理自己声明过的 source。

API 参考 ​

globalThis.lx ​

成员说明
version协议版本,当前 2.0.0
env运行环境,固定为 mobile
currentScriptInfo当前脚本信息:name / description / version / author / homepage / rawScript
EVENT_NAMES{ request, inited, updateAlert }
on(event, handler)注册事件。request 的回调必须返回 Promise
send(event, data)发送事件。inited 必须发一次
request(url, options, callback)发 HTTP 请求,返回一个可取消这次请求的函数
utils工具方法,见下表

lx.request 的 options 支持 method、headers、body、form、formData、binary、timeout(毫秒,上限 60 秒)。 回调签名是 callback(err, resp, body),resp 含 statusCode、statusMessage、headers、bytes、raw、body。

lx.utils ​

方法说明
crypto.md5(str)MD5
crypto.aesEncrypt(buffer, mode, key, iv)AES 加密,仅 aes-128-cbc / aes-128-ecb
crypto.rsaEncrypt(buffer, key)RSA 公钥加密(NoPadding)
crypto.randomBytes(size)随机字节
buffer.from(input, encoding)支持 base64 / hex / utf8
buffer.bufToString(buf, format)上一条的反向操作
zlib.inflate(buf) / zlib.deflate(buf)依赖 pako,未加载时不可用

宿主环境 ​

  • 定时器:setTimeout / clearTimeout / setInterval / clearInterval;
  • Buffer:from / alloc / allocUnsafe / concat / isBuffer(部分实现);
  • 内置属性被锁定:可以新增扩展(如 Array.prototype.myPush = ...),但改写已有方法无效。

兼容保留成员 ​

lx.getConsole()、lx.createMainWindow()、lx.getSystemFonts()、lx.proxy 为兼容旧脚本保留,没有实际作用。 updateAlert 事件可以发送,但客户端当前不会弹出更新提示。

调试 ​

  1. 打开设置 → 开发者选项 → 调试日志,客户端会把脚本里的 console.log 收进调试面板;
  2. 先用最小脚本验证 inited 能通过,再逐步加业务逻辑;
  3. 请求失败时把 err 打出来,lx.request 的错误里带状态码;
  4. 播放失败时客户端会自动换源,注意区分「这个插件拿不到地址」和「地址拿到了但放不了」。

常见失败原因 ​

现象通常的原因
导入后显示不可用初始化阶段抛错:语法错误、没发 inited、声明了不支持的源或音质
能搜到歌,播放失败musicUrl 返回的不是 http(s) 地址,或该地址已经失效
部分歌能放、部分不能该源对某些歌曲没有对应音质,脚本里需要做降级
换源总是失败脚本没有实现目标 source,或上游接口已变更
播放几秒后中断拿到的是短时效 URL,需要重新请求而不是复用

合规与责任 ​

  • 项目不提供、不分发、不推荐任何插件,也不提供插件定制服务;
  • 项目不提供任何音频内容,也不提供绕过平台授权或付费机制的方法;本页只说明脚本怎么写,不涉及从哪里获取内容;
  • 插件由你自行编写或获取,来源与授权是否合法由你自行确认,本项目不对第三方插件的内容与行为负责;
  • 请仅用于技术学习与交流,尊重版权、支持正版;因使用插件产生的版权数据请在 24 小时内清除。

参考与致谢 ​

  • 洛雪音乐(lx-music,以 Apache-2.0 许可开源)的音源脚本协议说明:https://lxmusic.toside.cn/mobile/custom-source
  • 拼好歌的插件层遵循该脚本协议实现,插件沙箱与播放器的部分设计也参考了这个项目;拼好歌代码为独立实现,同样以 Apache-2.0 发布,与该项目无隶属或合作关系。
  • 本页的 API 范围按拼好歌实际实现整理(utils/localRunner 与服务端沙箱共用同一份协议层),与上游文档存在个别差异,以上表为准。

相关页面 ​

本站为项目信息索引站点:不提供、不存储、不传输任何音频内容;不内置、不分发任何插件。
反馈请走 联系与反馈,或加入 QQ 群 1016773775。