






















@@ -3,18 +3,16 @@
33 * 音频格式转换工具。
44 *
55 * Handles SILK ↔ PCM ↔ WAV ↔ MP3 conversions for QQ Bot voice messaging.
6- * Prefers ffmpeg when available; falls back to WASM decoders (silk-wasm,
7- * mpg123-decoder) for environments without native tooling.
6+ * Uses WASM decoders (silk-wasm, mpg123-decoder) and direct QQ-native uploads
7+ * without launching native subprocesses.
88 *
99 * Self-contained within engine/ — no framework SDK dependency.
1010 */
111112-import { execFile } from "node:child_process";
1312import * as fs from "node:fs";
1413import * as path from "node:path";
1514import { formatErrorMessage } from "./format.js";
1615import { debugLog, debugError, debugWarn } from "./log.js";
17-import { detectFfmpeg, isWindows } from "./platform.js";
1816import { normalizeLowercaseStringOrEmpty as normalizeLowercase } from "./string-normalize.js";
19172018type SilkWasm = typeof import("silk-wasm");
@@ -184,7 +182,7 @@ function normalizeFormats(formats: string[]): string[] {
184182/**
185183 * Convert a local audio file to Base64-encoded SILK for QQ API upload.
186184 *
187- * Attempts conversion via ffmpeg → WASM decoders → null fallback chain.
185+ * Attempts conversion via direct QQ-native upload → WASM decoders → null fallback chain.
188186 */
189187export async function audioFileToSilkBase64(
190188filePath: string,
@@ -234,25 +232,6 @@ export async function audioFileToSilkBase64(
234232235233const targetRate = 24000;
236234237-const ffmpegCmd = await detectFfmpeg();
238-if (ffmpegCmd) {
239-try {
240-debugLog(
241-`[audio-convert] ffmpeg (${ffmpegCmd}): converting ${ext} (${buf.length} bytes) → PCM s16le ${targetRate}Hz`,
242-);
243-const pcmBuf = await ffmpegToPCM(ffmpegCmd, filePath, targetRate);
244-if (pcmBuf.length === 0) {
245-debugError(`[audio-convert] ffmpeg produced empty PCM output`);
246-return null;
247-}
248-const { silkBuffer } = await pcmToSilk(pcmBuf, targetRate);
249-debugLog(`[audio-convert] ffmpeg: ${ext} → SILK done (${silkBuffer.length} bytes)`);
250-return silkBuffer.toString("base64");
251-} catch (err) {
252-debugError(`[audio-convert] ffmpeg conversion failed: ${formatErrorMessage(err)}`);
253-}
254-}
255-256235debugLog(`[audio-convert] fallback: trying WASM decoders for ${ext}`);
257236258237if (ext === ".pcm") {
@@ -278,12 +257,9 @@ export async function audioFileToSilkBase64(
278257}
279258}
280259281-const installHint = isWindows()
282- ? "Install ffmpeg with choco install ffmpeg, scoop install ffmpeg, or from https://ffmpeg.org"
283- : process.platform === "darwin"
284- ? "Install ffmpeg with brew install ffmpeg"
285- : "Install ffmpeg with sudo apt install ffmpeg or sudo yum install ffmpeg";
286-debugError(`[audio-convert] unsupported format: ${ext} (no ffmpeg available). ${installHint}`);
260+debugError(
261+`[audio-convert] unsupported format without native subprocess conversion: ${ext}. Use QQ-native voice formats or WAV/MP3/PCM inputs.`,
262+);
287263return null;
288264}
289265@@ -386,48 +362,7 @@ async function pcmToSilk(
386362};
387363}
388364389-/** Use ffmpeg to convert any audio to mono 24 kHz PCM s16le. */
390-function ffmpegToPCM(
391-ffmpegCmd: string,
392-inputPath: string,
393-sampleRate: number = 24000,
394-): Promise<Buffer> {
395-return new Promise((resolve, reject) => {
396-const args = [
397-"-i",
398-inputPath,
399-"-f",
400-"s16le",
401-"-ar",
402-String(sampleRate),
403-"-ac",
404-"1",
405-"-acodec",
406-"pcm_s16le",
407-"-v",
408-"error",
409-"pipe:1",
410-];
411-execFile(
412-ffmpegCmd,
413-args,
414-{
415-maxBuffer: 50 * 1024 * 1024,
416-encoding: "buffer",
417- ...(isWindows() ? { windowsHide: true } : {}),
418-},
419-(err, stdout) => {
420-if (err) {
421-reject(new Error(`ffmpeg failed: ${err.message}`));
422-return;
423-}
424-resolve(stdout as unknown as Buffer);
425-},
426-);
427-});
428-}
429-430-/** Decode MP3 to PCM via mpg123-decoder WASM (fallback when ffmpeg is unavailable). */
365+/** Decode MP3 to PCM via mpg123-decoder WASM. */
431366async function wasmDecodeMp3ToPCM(buf: Buffer, targetRate: number): Promise<Buffer | null> {
432367try {
433368const { MPEGDecoder } = await import("mpg123-decoder");
@@ -502,7 +437,7 @@ async function wasmDecodeMp3ToPCM(buf: Buffer, targetRate: number): Promise<Buff
502437}
503438}
504439505-/** Parse a standard PCM WAV and extract mono 24 kHz PCM data (fallback without ffmpeg). */
440+/** Parse a standard PCM WAV and extract mono 24 kHz PCM data. */
506441export function parseWavFallback(buf: Buffer): Buffer | null {
507442if (buf.length < 44) {
508443return null;
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。