@dgck81lnn/koishi-plugin-music 0.1.5 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.d.ts +3 -2
- package/lib/index.js +20 -10
- package/lib/locales/zh.json +1 -1
- package/package.json +1 -1
- package/browser/index.html +0 -8
package/lib/index.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { Computed, Context, Schema } from "koishi";
|
|
2
|
-
export declare const name = "
|
|
2
|
+
export declare const name = "musicjs";
|
|
3
3
|
export declare const inject: string[];
|
|
4
4
|
export interface Config {
|
|
5
|
-
evalCommand:
|
|
5
|
+
evalCommand: string;
|
|
6
|
+
evalReturnMethod: "expr" | "process.stdout";
|
|
6
7
|
noise: Computed<boolean>;
|
|
7
8
|
}
|
|
8
9
|
export declare const Config: Schema<Config>;
|
package/lib/index.js
CHANGED
|
@@ -3,14 +3,21 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.Config = exports.inject = exports.name = void 0;
|
|
4
4
|
exports.apply = apply;
|
|
5
5
|
const koishi_1 = require("koishi");
|
|
6
|
+
const promises_1 = require("fs/promises");
|
|
6
7
|
const path_1 = require("path");
|
|
7
|
-
|
|
8
|
-
exports.name = "music";
|
|
8
|
+
exports.name = "musicjs";
|
|
9
9
|
exports.inject = ["puppeteer"];
|
|
10
10
|
exports.Config = koishi_1.Schema.object({
|
|
11
|
-
evalCommand: koishi_1.Schema.
|
|
12
|
-
.
|
|
11
|
+
evalCommand: koishi_1.Schema.string()
|
|
12
|
+
.role("textarea")
|
|
13
|
+
.default("glot --language=javascript")
|
|
13
14
|
.description("用于安全执行 js 代码的指令。"),
|
|
15
|
+
evalReturnMethod: koishi_1.Schema.union([
|
|
16
|
+
koishi_1.Schema.from("process.stdout").description("process.stdout.write()(适用 glot 等指令)"),
|
|
17
|
+
koishi_1.Schema.from("expr").description("表达式(适用 eval 等指令)"),
|
|
18
|
+
])
|
|
19
|
+
.default("process.stdout")
|
|
20
|
+
.description("在 js 代码执行指令中返回结果的方式。"),
|
|
14
21
|
noise: koishi_1.Schema.computed(Boolean)
|
|
15
22
|
.default(true)
|
|
16
23
|
.description("是否添加白噪音来尝试规避 QQ 的语音编码杂音问题。"),
|
|
@@ -88,11 +95,12 @@ const gutterFunc = (f) => {
|
|
|
88
95
|
};
|
|
89
96
|
function apply(ctx, config) {
|
|
90
97
|
ctx.i18n.define("zh", require("./locales/zh"));
|
|
98
|
+
const synthCode = (0, promises_1.readFile)((0, path_1.resolve)(__dirname, "../browser/synth.js"), "utf-8");
|
|
91
99
|
ctx
|
|
92
100
|
.command("musicjs <code:rawtext>", { strictOptions: true })
|
|
93
101
|
.action(async ({ session }, code) => {
|
|
94
102
|
if (!code)
|
|
95
|
-
return session.
|
|
103
|
+
return session.i18n(".require-code");
|
|
96
104
|
try {
|
|
97
105
|
new Function(code);
|
|
98
106
|
}
|
|
@@ -100,9 +108,9 @@ function apply(ctx, config) {
|
|
|
100
108
|
return koishi_1.h.text(String(e));
|
|
101
109
|
}
|
|
102
110
|
let gutteredCode = `(${gutterFunc})(function($){with($){\n${code}\n}})`;
|
|
103
|
-
if (config.
|
|
111
|
+
if (config.evalReturnMethod === "process.stdout")
|
|
104
112
|
gutteredCode = `process.stdout.write(${gutteredCode})`;
|
|
105
|
-
ctx.logger.debug(config.evalCommand, gutteredCode);
|
|
113
|
+
ctx.logger.debug("%o (%s) %o", config.evalCommand, config.evalReturnMethod, gutteredCode);
|
|
106
114
|
const evalArgv = koishi_1.Argv.parse(config.evalCommand);
|
|
107
115
|
evalArgv.tokens.push({
|
|
108
116
|
content: koishi_1.h.escape(gutteredCode),
|
|
@@ -112,7 +120,7 @@ function apply(ctx, config) {
|
|
|
112
120
|
});
|
|
113
121
|
const data = (0, koishi_1.h)("", await session.execute(evalArgv, true)).toString(true);
|
|
114
122
|
if (!data)
|
|
115
|
-
session.
|
|
123
|
+
return session.i18n(".no-note");
|
|
116
124
|
try {
|
|
117
125
|
ctx.logger.debug(JSON.parse(data));
|
|
118
126
|
}
|
|
@@ -120,11 +128,13 @@ function apply(ctx, config) {
|
|
|
120
128
|
return koishi_1.h.text(data);
|
|
121
129
|
}
|
|
122
130
|
const page = await ctx.puppeteer.page();
|
|
123
|
-
await page.goto((0, url_1.pathToFileURL)((0, path_1.resolve)(__dirname, "../browser/index.html")).href);
|
|
124
131
|
const opt = {
|
|
125
132
|
noise: session.resolve(config.noise),
|
|
126
133
|
};
|
|
127
|
-
|
|
134
|
+
ctx.logger.debug("synth options: %o", opt);
|
|
135
|
+
const base64 = (await page.evaluate(
|
|
136
|
+
// prettier-ignore
|
|
137
|
+
`${await synthCode}; synth(${data}, ${JSON.stringify(opt)}).then(encodeWav).then(arrayBufferToBase64)`));
|
|
128
138
|
page.close().catch(() => { });
|
|
129
139
|
return koishi_1.h.audio("data:audio/wav;base64," + base64);
|
|
130
140
|
});
|
package/lib/locales/zh.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"commands":{"musicjs":{"description":"用 JavaScript 代码演奏旋律","usage":"函数及其参数说明:\n note(tone: number, beats: number, temperament = 12) 创建平均律音符\n tone 音符相对于基准音的偏移(默认情况下,单位为半音)\n beats 音符时长(拍)\n temperament 平均律的音阶数;决定了多少 tone 为一个八度\n noteJust(ratio: number, beats: number) 创建纯律音符\n ratio 音符音高与基准音频率的比值\n beats 音符时长(拍)\n noteHz(frequency: number, beats: number) 创建指定频率音高的音符\n frequency 频率(赫兹)\n beats 音符时长(拍)\n rest(beats: number) 休止\n beats 休止时长(拍)\n变量说明——修改这些变量会影响后续创建音符的属性:\n bpm: Number = 120 每分钟拍数\n
|
|
1
|
+
{"commands":{"musicjs":{"description":"用 JavaScript 代码演奏旋律","usage":"函数及其参数说明:\n note(tone: number, beats: number, temperament = 12) 创建平均律音符\n tone 音符相对于基准音的偏移(默认情况下,单位为半音)\n beats 音符时长(拍)\n temperament 平均律的音阶数;决定了多少 tone 为一个八度\n noteJust(ratio: number, beats: number) 创建纯律音符\n ratio 音符音高与基准音频率的比值\n beats 音符时长(拍)\n noteHz(frequency: number, beats: number) 创建指定频率音高的音符\n frequency 频率(赫兹)\n beats 音符时长(拍)\n rest(beats: number) 休止\n beats 休止时长(拍)\n变量说明——修改这些变量会影响后续创建音符的属性:\n bpm: Number = 120 每分钟拍数\n 由于历史原因,该变量的初始值是一个可以被隐式转换成数字的函数;\n 对其进行有效的赋值后,才会变成普通数字。\n baseFrequency = 440 基准音频率\n gain = 0.5 音量\n time = 0 当前时间(秒)\n 调用 note、rest 等函数后此变量的值会自动增加。\n 手动减少此值后再添加音符,可以使不同音符同时播放。","messages":{"require-code":"缺少代码。","no-note":"未定义任何音符。"}}}}
|
package/package.json
CHANGED