跳到主要内容

自定义源脚本编写说明

文件请使用UTF-8编码格式编写,脚本所用编程语言为JavaScript,可以使用ES6+语法,脚本与应用的交互是使用类似事件收发的方式进行,这是一个基本的脚本例子:

/**
* @name 测试音乐源
* @description 我只是一个测试音乐源哦
* @version 1.0.0
* @author xxx
* @homepage http://xxx
*/


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

const qualitys = {
kw: {
'128k': '128',
'320k': '320',
flac: 'flac',
flac24bit: 'flac24bit',
},
local: {},
}
const httpRequest = (url, options) => new Promise((resolve, reject) => {
request(url, options, (err, resp) => {
if (err) return reject(err)
resolve(resp.body)
})
})

const apis = {
kw: {
musicUrl({ songmid }, quality) {
return httpRequest('http://xxx').then(data => {
return data.url
})
},
},
local: {
musicUrl(info) {
return httpRequest('http://xxx').then(data => {
return data.url
})
},
pic(info) {
return httpRequest('http://xxx').then(data => {
return data.url
})
},
lyric(info) {
return httpRequest('http://xxx').then(data => {
return {
lyric: '...', // 歌曲歌词
tlyric: '...', // 翻译歌词,没有可为 null
rlyric: '...', // 罗马音歌词,没有可为 null
lxlyric: '...', // lx 逐字歌词,没有可为 null,歌词格式为 [分钟:秒.毫秒]<开始时间(基于该句),持续时间>歌词文字
// 例如: [00:00.000]<0,36>测<36,36>试<50,60>歌<80,75>词
}
})
}
}
}

// 注册应用API请求事件
// source 音乐源,可能的值取决于初始化时传入的sources对象的源key值
// info 请求附加信息,内容根据action变化
// action 请求操作类型,目前只有musicUrl,即获取音乐URL链接,
// 当action为musicUrl时info的结构:{type, musicInfo},
// info.type:音乐质量,可能的值有128k / 320k / flac / flac24bit(取决于初始化时对应源传入的qualitys值中的一个)
// 特殊情况:源为local时,该值为 null
// info.musicInfo:音乐信息对象,里面有音乐ID、名字等信息
on(EVENT_NAMES.request, ({ source, action, info }) => {
// 被调用时必须返回 Promise 对象
switch (action) {
// action 为 musicUrl 时需要在 Promise 返回歌曲 url
case 'musicUrl':
return apis[source].musicUrl(info.musicInfo, qualitys[source][info.type]).catch(err => {
console.log(err)
return Promise.reject(err)
})
// action 为 lyric 时需要在 Promise 返回歌词信息
case 'lyric':
return apis[source].musicUrl(info.musicInfo).catch(err => {
console.log(err)
return Promise.reject(err)
})
// action 为 pic 时需要在 Promise 返回歌曲封面 url
case 'pic':
return apis[source].musicUrl(info.musicInfo).catch(err => {
console.log(err)
return Promise.reject(err)
})
}
})

// 脚本初始化完成后需要发送inited事件告知应用
// 注意:初始化事件被发送前,执行脚本的过程中出现任何错误将视为脚本初始化失败
send(EVENT_NAMES.inited, {
openDevTools: false, // 是否打开开发者工具,方便用于调试脚本
sources: { // 当前脚本支持的源
kw: { // 支持的源对象,可用key值:kw/kg/tx/wy/mg/local
name: '酷我音乐',
type: 'music', // 目前固定为 music
actions: ['musicUrl'], // 除了local外,其他的固定为 ['musicUrl']
qualitys: ['128k', '320k', 'flac', 'flac24bit'], // 当前脚本的该源所支持获取的Url音质,有效的值有:['128k', '320k', 'flac', 'flac24bit']
},
// ...
local: {
name: '本地音乐',
type: 'music', // 目前固定为 music
actions: ['musicUrl', 'lyric', 'pic'], // 源为 local 时,支持 ['musicUrl', 'lyric', 'pic']
qualitys: [], // 源为 local 时,该值传入空数组即可
},
},
})

自定义源信息

文件的开头必须包含以下注释:

/**
* @name 测试脚本
* @description 我只是一个测试脚本
* @version 1.0.0
* @author xxx
* @homepage http://xxx
*/

  • @name :源的名字,建议不要过长,24个字符以内
  • @description :源的描述,建议不要过长,36个字符以内,可不填,不填时可以删除 @description
  • @version:源的版本号,可不填,不填时可以删除 @version
  • @author :脚本作者名字,可不填,不填时可以删除 @author
  • @homepage :脚本主页,可不填,不填时可以删除 @homepage

globalThis.lx

应用为脚本暴露的API对象。

globalThis.lx.version

自定义源API版本,API变更时此版本号将会更改

globalThis.lx.env

自定义源运行环境,PC端将固定是 desktop

globalThis.lx.currentScriptInfo

当前自定义源脚本信息(导入时在头部解析到的):

  • globalThis.lx.currentScriptInfo.name:源名字,即 @name 的内容
  • globalThis.lx.currentScriptInfo.description:源描述,即 @description 的内容
  • globalThis.lx.currentScriptInfo.version:源版本,即 @version 的内容
  • globalThis.lx.currentScriptInfo.author:源作者,即 @author 的内容
  • globalThis.lx.currentScriptInfo.homepage:源主页,即 @homepage 的内容
  • globalThis.lx.currentScriptInfo.rawScript:源原始代码

globalThis.lx.EVENT_NAMES

常量事件名称对象,发送、注册事件时传入事件名时使用,可用值:

事件名描述
inited脚本初始化完成后发送给应用的事件名,发送该事件时需要传入以下信息:{ sources, openDevTools }
openDevTools:是否打开DevTools,此选项可用于开发脚本时的调试
sources:支持的源信息对象,
sources[kw/kg/tx/wy/mg/local].name:源的名字(目前非必须)
sources[kw/kg/tx/wy/mg/local].type:源类型,目前固定值需为music
sources[kw/kg/tx/wy/mg/local].actions:支持的actions数组,local源可用值为musicUrllyricpic,其他源只支持musicUrl
sources[kw/kg/tx/wy/mg/local].qualitys:该源支持的音质列表,有效的值为['128k', '320k', 'flac', 'flac24bit'],该字段用于控制应用可用的音质类型,当sourcelocal时,传入[]即可
request应用API请求事件名,回调入参:handler({ source, action, info}),回调必须返回Promise对象
source:音乐源,可能的值取决于初始化时传入的sources对象的源key值
info:请求附加信息,内容根据action变化
action:请求操作类型,取决于发送inited事件时传入的actions数组中的值
当为musicUrl时表示获取音乐URL链接,info的结构:{type, musicInfo}info.type:音乐质量,可能的值有128k / 320k / flac / flac24bit (取决于初始化时对应源传入的qualitys值中的一个,sourcelocal时该值为null),info.musicInfo:音乐信息对象,里面有音乐ID、名字等信息,该操作需要在 Promise 返回http形式的歌曲 url
当为lyric时,表示获取音乐歌词,info的结构:{musicInfo},该操作需要在 Promise 返回歌曲的歌词信息(结构为{lryic,tlryic,rlyric,lxlyric},例如:{lyric:'..',tlryic:...}
当为pic时,表示获取音乐封面图片,info的结构:{musicInfo},该操作需要在 Promise 返回http形式的歌曲封面图片url
updateAlert显示源更新弹窗,发送该事件时的参数:{log, updateUrl}
log:更新日志,必传,字符串类型,内容可以使用\n换行,最大长度1024,超过此长度后将被截取超出的部分
updateUrl:更新地址,用于引导用户去该地址更新源,选传,需为http协议的url地址,最大长度1024
此事件每次运行脚本只能调用一次
例子:lx.send(lx.EVENT_NAMES.updateAlert, { log: 'hello world', updateUrl: 'https://xxx.com' })

注意:初始化事件被发送前,执行脚本的过程中出现任何错误将视为脚本初始化失败

globalThis.lx.on

事件注册方法,应用主动与脚本通信时使用:

/**
* @param event_name 事件名
* @param handler 事件处理回调 -- 注意:注册的回调在被调用时必须返回 Promise 对象
*/
globalThis.lx.on(event_name, handler)

注意: 注册的回调在被调用时必须返回 Promise 对象。

globalThis.lx.send

事件发送方法,脚本主动与应用通信时使用:

/**
* @param event_name 事件名
* @param datas 要传给应用的数据
*/
globalThis.lx.send(event_name, datas)

globalThis.lx.request

HTTP请求方法,用于发送HTTP请求,此HTTP请求方法不受跨域规则限制:

/**
* @param url 请求的URL
* @param options 请求选项,可用选项有 method / headers / body / form / formData / timeout
* @param callback 请求结果的回调 入参:err, resp, body
* @return 返回一个方法,调用此方法可以终止HTTP请求
*/
const cancelHttp = globalThis.lx.request(url, options, callback)

globalThis.lx.utils

应用提供给脚本的工具方法:

  • globalThis.lx.utils.buffer.from:对应Node.js的 Buffer.from
  • globalThis.lx.utils.buffer.bufToString:Buffer转字符串 bufToString(buffer, format)format对应Node.js Buffer.toString的参数
  • globalThis.lx.utils.crypto.aesEncrypt:AES加密 aesEncrypt(buffer, mode, key, iv)
  • globalThis.lx.utils.crypto.md5:MD5加密 md5(str)
  • globalThis.lx.utils.crypto.randomBytes:生成随机字符串 randomBytes(size)
  • globalThis.lx.utils.crypto.rsaEncrypt:RSA加密 rsaEncrypt(buffer, key)
  • globalThis.lx.utils.zlib.inflate:解压 inflate(buffer: Buffer) => Promise<Buffer>
  • globalThis.lx.utils.zlib.deflate:压缩 deflate(buffer: Buffer) => Promise<Buffer>

PC端自定义源与移动端自定义源的区别

  • 移动端 inited 事件无 openDevTools 选项
  • 移动端 lx.utils 的某些方法不可用,对于不可用或部分可用的方法,背后会有括号说明
  • 移动端只有极少部分宿主环境API可用,详情看 可用宿主环境API 说明
  • 移动端由于预加载脚本与自定义脚本运行在同一个环境下,出于对预加载脚本的安全性考虑,除了 Function.prototype.toStringFunction.prototype.toLocaleStringObject.prototype.toString 外的其他JavaScript内置属性都会被冻结,所以类似 Array.prototype.push = ... 的代码都将无效,但扩展内置对象的行为是允许的,例如:Array.prototype.myPush = ...

以上是自定义源功能在PC端与移动端的区别,目前仅提供以上工具方法,如果需要其他方法可以开issue讨论。