koishi-plugin-chatsound 0.0.2 → 0.0.3
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 +10 -0
- package/lib/index.js +70 -7
- package/package.json +6 -2
package/lib/index.d.ts
CHANGED
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
import { Context, Schema } from 'koishi';
|
|
2
|
+
import SilkService from 'koishi-plugin-silk';
|
|
3
|
+
declare module 'koishi' {
|
|
4
|
+
interface Context {
|
|
5
|
+
silk: SilkService;
|
|
6
|
+
}
|
|
7
|
+
}
|
|
2
8
|
export declare const name = "chatsound";
|
|
9
|
+
export declare const inject: {
|
|
10
|
+
required: string[];
|
|
11
|
+
};
|
|
3
12
|
export interface Config {
|
|
4
13
|
soundPath: string[];
|
|
5
14
|
defaultPitch: number;
|
|
6
15
|
minPitch: number;
|
|
7
16
|
maxPitch: number;
|
|
17
|
+
audioType: "mp3" | "silk";
|
|
8
18
|
}
|
|
9
19
|
export declare const Config: Schema<Config>;
|
|
10
20
|
export declare function apply(ctx: Context, config: Config): void;
|
package/lib/index.js
CHANGED
|
@@ -22,6 +22,7 @@ var src_exports = {};
|
|
|
22
22
|
__export(src_exports, {
|
|
23
23
|
Config: () => Config,
|
|
24
24
|
apply: () => apply,
|
|
25
|
+
inject: () => inject,
|
|
25
26
|
name: () => name
|
|
26
27
|
});
|
|
27
28
|
module.exports = __toCommonJS(src_exports);
|
|
@@ -32,11 +33,15 @@ var import_child_process = require("child_process");
|
|
|
32
33
|
var import_util = require("util");
|
|
33
34
|
var execAsync = (0, import_util.promisify)(import_child_process.exec);
|
|
34
35
|
var name = "chatsound";
|
|
36
|
+
var inject = {
|
|
37
|
+
required: ["silk"]
|
|
38
|
+
};
|
|
35
39
|
var Config = import_koishi.Schema.object({
|
|
36
40
|
soundPath: import_koishi.Schema.array(import_koishi.Schema.string()).description("用于搜索的音频路径"),
|
|
37
41
|
defaultPitch: import_koishi.Schema.number().default(100).description("默认的语音音调(百分比)"),
|
|
38
42
|
minPitch: import_koishi.Schema.number().default(80).min(0).description("最小Pitch,不小于0"),
|
|
39
|
-
maxPitch: import_koishi.Schema.number().default(200).description("最大Pitch")
|
|
43
|
+
maxPitch: import_koishi.Schema.number().default(200).description("最大Pitch"),
|
|
44
|
+
audioType: import_koishi.Schema.union(["mp3", "silk"]).default("mp3").description("最终发送的类型,QQ及微信选择SILK")
|
|
40
45
|
});
|
|
41
46
|
var AUDIO_EXTENSIONS = [".mp3", ".wav", ".ogg", ".flac", ".m4a", ".aac"];
|
|
42
47
|
async function findAudioFile(trigger, soundPaths) {
|
|
@@ -59,11 +64,63 @@ async function findAudioFile(trigger, soundPaths) {
|
|
|
59
64
|
return null;
|
|
60
65
|
}
|
|
61
66
|
__name(findAudioFile, "findAudioFile");
|
|
62
|
-
async function
|
|
67
|
+
async function runFFmpeg(commandArgs) {
|
|
68
|
+
return new Promise((resolve, reject) => {
|
|
69
|
+
const ffmpeg = (0, import_child_process.spawn)("ffmpeg", commandArgs);
|
|
70
|
+
const chunks = [];
|
|
71
|
+
ffmpeg.stdout.on("data", (chunk) => chunks.push(chunk));
|
|
72
|
+
ffmpeg.stderr.on("data", (chunk) => {
|
|
73
|
+
});
|
|
74
|
+
ffmpeg.on("close", (code) => {
|
|
75
|
+
if (code === 0) {
|
|
76
|
+
resolve(Buffer.concat(chunks));
|
|
77
|
+
} else {
|
|
78
|
+
reject(new Error(`FFmpeg exited with code ${code}`));
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
ffmpeg.on("error", reject);
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
__name(runFFmpeg, "runFFmpeg");
|
|
85
|
+
async function applyPitch(inputPath, pitch, audioType) {
|
|
63
86
|
const pitchFactor = pitch / 100;
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
87
|
+
if (audioType === "mp3") {
|
|
88
|
+
const args = [
|
|
89
|
+
"-i",
|
|
90
|
+
inputPath,
|
|
91
|
+
"-vn",
|
|
92
|
+
"-sn",
|
|
93
|
+
"-dn",
|
|
94
|
+
"-filter:a",
|
|
95
|
+
`rubberband=pitch=${pitchFactor}`,
|
|
96
|
+
"-f",
|
|
97
|
+
"mp3",
|
|
98
|
+
"-y",
|
|
99
|
+
"pipe:1"
|
|
100
|
+
];
|
|
101
|
+
const data = await runFFmpeg(args);
|
|
102
|
+
return { data, mimeType: "audio/mp3" };
|
|
103
|
+
} else {
|
|
104
|
+
const args = [
|
|
105
|
+
"-i",
|
|
106
|
+
inputPath,
|
|
107
|
+
"-vn",
|
|
108
|
+
"-sn",
|
|
109
|
+
"-dn",
|
|
110
|
+
"-filter:a",
|
|
111
|
+
`rubberband=pitch=${pitchFactor}`,
|
|
112
|
+
"-f",
|
|
113
|
+
"s16le",
|
|
114
|
+
"-ac",
|
|
115
|
+
"1",
|
|
116
|
+
"-ar",
|
|
117
|
+
"24000",
|
|
118
|
+
"-y",
|
|
119
|
+
"pipe:1"
|
|
120
|
+
];
|
|
121
|
+
const data = await runFFmpeg(args);
|
|
122
|
+
return { data, mimeType: "audio/pcm" };
|
|
123
|
+
}
|
|
67
124
|
}
|
|
68
125
|
__name(applyPitch, "applyPitch");
|
|
69
126
|
function apply(ctx, config) {
|
|
@@ -77,8 +134,13 @@ function apply(ctx, config) {
|
|
|
77
134
|
return `没有这种音频`;
|
|
78
135
|
}
|
|
79
136
|
try {
|
|
80
|
-
const
|
|
81
|
-
|
|
137
|
+
const { data, mimeType } = await applyPitch(audioPath, actualPitch, config.audioType);
|
|
138
|
+
if (config.audioType === "silk") {
|
|
139
|
+
const silkResult = await ctx.silk.encode(data, 24e3);
|
|
140
|
+
await session.send(import_koishi.h.audio(silkResult.data, "audio/silk"));
|
|
141
|
+
} else {
|
|
142
|
+
await session.send(import_koishi.h.audio(data, mimeType));
|
|
143
|
+
}
|
|
82
144
|
} catch (error) {
|
|
83
145
|
ctx.logger.error("发送音频失败:", error);
|
|
84
146
|
return "发送音频失败";
|
|
@@ -90,5 +152,6 @@ __name(apply, "apply");
|
|
|
90
152
|
0 && (module.exports = {
|
|
91
153
|
Config,
|
|
92
154
|
apply,
|
|
155
|
+
inject,
|
|
93
156
|
name
|
|
94
157
|
});
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"contributors": [
|
|
5
5
|
"Dr.Abc <me@drabc.net>"
|
|
6
6
|
],
|
|
7
|
-
"version": "0.0.
|
|
7
|
+
"version": "0.0.3",
|
|
8
8
|
"homepage": "https://github.com/DrAbcOfficial/koishi-plugin-chatsound",
|
|
9
9
|
"repository": {
|
|
10
10
|
"type": "git",
|
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
"main": "lib/index.js",
|
|
14
14
|
"typings": "lib/index.d.ts",
|
|
15
15
|
"files": [
|
|
16
|
-
"lib"
|
|
16
|
+
"lib",
|
|
17
|
+
"dist"
|
|
17
18
|
],
|
|
18
19
|
"license": "MIT",
|
|
19
20
|
"scripts": {},
|
|
@@ -31,6 +32,9 @@
|
|
|
31
32
|
"en": "发送预定的噪音,可以变调,依赖ffmpeg",
|
|
32
33
|
"zh": "发送预定的噪音,可以变调,依赖ffmpeg"
|
|
33
34
|
},
|
|
35
|
+
"service":{
|
|
36
|
+
"required": ["silk"]
|
|
37
|
+
},
|
|
34
38
|
"preview": true
|
|
35
39
|
}
|
|
36
40
|
}
|