@zaofan/dsh-qqbot 0.6.0 → 0.8.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.
Files changed (41) hide show
  1. package/README.md +17 -0
  2. package/README_EN.md +17 -0
  3. package/client/qqbot-settings.js +1385 -28
  4. package/dist/api/group-admin.d.ts +13 -0
  5. package/dist/api/group-admin.d.ts.map +1 -1
  6. package/dist/api/group-admin.js +23 -0
  7. package/dist/api/group-admin.js.map +1 -1
  8. package/dist/channel-tools.d.ts.map +1 -1
  9. package/dist/channel-tools.js +58 -1
  10. package/dist/channel-tools.js.map +1 -1
  11. package/dist/config.d.ts +2 -0
  12. package/dist/config.d.ts.map +1 -1
  13. package/dist/config.js +1 -0
  14. package/dist/config.js.map +1 -1
  15. package/dist/features/chat-ledger.d.ts.map +1 -1
  16. package/dist/features/chat-ledger.js +54 -3
  17. package/dist/features/chat-ledger.js.map +1 -1
  18. package/dist/features/qq-approval.d.ts +43 -1
  19. package/dist/features/qq-approval.d.ts.map +1 -1
  20. package/dist/features/qq-approval.js +167 -17
  21. package/dist/features/qq-approval.js.map +1 -1
  22. package/dist/features/qq-user-questions.d.ts +69 -0
  23. package/dist/features/qq-user-questions.d.ts.map +1 -0
  24. package/dist/features/qq-user-questions.js +214 -0
  25. package/dist/features/qq-user-questions.js.map +1 -0
  26. package/dist/features/session-registry.d.ts +51 -0
  27. package/dist/features/session-registry.d.ts.map +1 -0
  28. package/dist/features/session-registry.js +95 -0
  29. package/dist/features/session-registry.js.map +1 -0
  30. package/dist/gateway/bootstrap.d.ts.map +1 -1
  31. package/dist/gateway/bootstrap.js +88 -1
  32. package/dist/gateway/bootstrap.js.map +1 -1
  33. package/dist/session/session-manager.d.ts.map +1 -1
  34. package/dist/session/session-manager.js +9 -14
  35. package/dist/session/session-manager.js.map +1 -1
  36. package/dist/transport/outbound-buffer.d.ts +2 -0
  37. package/dist/transport/outbound-buffer.d.ts.map +1 -1
  38. package/dist/transport/outbound-buffer.js.map +1 -1
  39. package/package.json +6 -3
  40. package/settings-host.js +962 -5
  41. package/voice-convert.mjs +45 -0
@@ -0,0 +1,45 @@
1
+ // voice-convert.mjs — QQ/微信 SILK v3 语音 → 浏览器可播 mp3(纯 JS, 零系统依赖, 通用插件可直接打包)
2
+ // 依赖: silk-wasm(SILK 解码 → pcm_s16le) + lamejs(纯 JS mp3 编码)。
3
+ // QQ 语音文件头 "#!SILK_V3"; 采样率 24000/16000/12000/8000 逐试(QQ 常见 24k)。
4
+ import { decode } from 'silk-wasm';
5
+ import { createRequire } from 'node:module';
6
+ const require = createRequire(import.meta.url);
7
+ const lamejs = require('lamejs-fixed'); // CJS 加载(1.2.2 fixed 版, 修官方 1.2.1 循环引用 bug)
8
+
9
+ const SILK_HEAD_RE = /^#!SILK/i;
10
+
11
+ /** 是否 SILK 语音(头 "#!SILK", 允许 QQ 前导字节) */
12
+ export function isSilk(buf) {
13
+ try {
14
+ const u = buf instanceof Uint8Array ? buf : new Uint8Array(buf);
15
+ return u.subarray(0, 24).toString('latin1').indexOf('#!SILK') >= 0;
16
+ } catch { return false; }
17
+ }
18
+
19
+ /**
20
+ * SILK → mp3(buffer)。返回 { mp3: Buffer, ms: number }
21
+ * @param {Uint8Array|Buffer} silkBytes
22
+ */
23
+ export async function silkToMp3(silkBytes) {
24
+ const data = silkBytes instanceof Uint8Array ? silkBytes : new Uint8Array(silkBytes);
25
+ let lastErr = null;
26
+ for (const rate of [24000, 16000, 12000, 8000]) {
27
+ try {
28
+ const dec = await decode(data, rate); // pcm_s16le mono
29
+ const pcm16 = new Int16Array(dec.data.buffer, dec.data.byteOffset, dec.data.length / 2);
30
+ const enc = new lamejs.Mp3Encoder(1, rate, 48);
31
+ const CHUNK = 1152 * 4;
32
+ const parts = [];
33
+ for (let i = 0; i < pcm16.length; i += CHUNK) {
34
+ const blk = enc.encodeBuffer(pcm16.subarray(i, Math.min(i + CHUNK, pcm16.length)));
35
+ if (blk.length) parts.push(Buffer.from(blk));
36
+ }
37
+ const last = enc.flush();
38
+ if (last.length) parts.push(Buffer.from(last));
39
+ return { mp3: Buffer.concat(parts), ms: dec.duration };
40
+ } catch (e) { lastErr = e; }
41
+ }
42
+ throw new Error('SILK 解码失败: ' + String((lastErr && lastErr.message) || lastErr).slice(0, 160));
43
+ }
44
+
45
+ export default { isSilk, silkToMp3 };