自定义源脚本编写说明
文件请使用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 源可用值为musicUrl 、lyric 、pic ,其他源只支持musicUrl sources[kw/kg/tx/wy/mg/local].qualitys :该源支持的音质列表,有效的值为['128k', '320k', 'flac', 'flac24bit'] ,该字段用于控制应用可用的音质类型,当source 为local 时,传入[] 即可 |
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 值中的一个,source 为local 时该值为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.jsBuffer.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.toString
、Function.prototype.toLocaleString
、Object.prototype.toString
外的其他JavaScript内置属性都会被冻结,所以类似Array.prototype.push = ...
的代码都将无效,但扩展内置对象的行为是允许的,例如:Array.prototype.myPush = ...
以上是自定义源功能在PC端与移动端的区别,目前仅提供以上工具方法,如果需要其他方法可以开issue讨论。