mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2025-12-18 20:30:08 +08:00
Refactor PCM conversion to return result and sample rate
Updated the FFmpeg adapter interfaces and implementations so that PCM conversion methods now return an object containing the conversion result and sample rate, instead of a Buffer. Adjusted audio processing logic to accommodate this change and improved error logging. Updated native ffmpeg addon binaries.
This commit is contained in:
parent
28ce5d3cb4
commit
caaf8be3b2
@ -30,7 +30,8 @@ async function handleWavFile(
|
||||
): Promise<{ input: Buffer; sampleRate: number }> {
|
||||
const { fmt } = getWavFileInfo(file);
|
||||
if (!ALLOW_SAMPLE_RATE.includes(fmt.sampleRate)) {
|
||||
return { input: await FFmpegService.convert(filePath, pcmPath), sampleRate: 24000 };
|
||||
const result = await FFmpegService.convert(filePath, pcmPath);
|
||||
return { input: await fsPromise.readFile(pcmPath), sampleRate: result.sampleRate };
|
||||
}
|
||||
return { input: file, sampleRate: fmt.sampleRate };
|
||||
}
|
||||
@ -42,9 +43,18 @@ export async function encodeSilk(filePath: string, TEMP_DIR: string, logger: Log
|
||||
if (!isSilk(file)) {
|
||||
logger.log(`语音文件${filePath}需要转换成silk`);
|
||||
const pcmPath = `${pttPath}.pcm`;
|
||||
const { input, sampleRate } = isWav(file)
|
||||
? await handleWavFile(file, filePath, pcmPath)
|
||||
: { input: await FFmpegService.convert(filePath, pcmPath), sampleRate: 24000 };
|
||||
// const { input, sampleRate } = isWav(file) ? await handleWavFile(file, filePath, pcmPath): { input: await FFmpegService.convert(filePath, pcmPath) ? await fsPromise.readFile(pcmPath) : Buffer.alloc(0), sampleRate: 24000 };
|
||||
let input: Buffer;
|
||||
let sampleRate: number;
|
||||
if (isWav(file)) {
|
||||
const result = await handleWavFile(file, filePath, pcmPath);
|
||||
input = result.input;
|
||||
sampleRate = result.sampleRate;
|
||||
} else {
|
||||
const result = await FFmpegService.convert(filePath, pcmPath);
|
||||
input = await fsPromise.readFile(pcmPath);
|
||||
sampleRate = result.sampleRate;
|
||||
}
|
||||
const silk = await runTask<EncodeArgs, EncodeResult>(getWorkerPath(), { input: input, sampleRate: sampleRate });
|
||||
fsPromise.unlink(pcmPath).catch((e) => logger.logError('删除临时文件失败', pcmPath, e));
|
||||
await fsPromise.writeFile(pttPath, Buffer.from(silk.data));
|
||||
@ -69,7 +79,7 @@ export async function encodeSilk(filePath: string, TEMP_DIR: string, logger: Log
|
||||
};
|
||||
}
|
||||
} catch (error: unknown) {
|
||||
logger.logError('convert silk failed', (error as Error).stack);
|
||||
logger.logError('convert silk failed', error);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
@ -49,7 +49,7 @@ export interface IFFmpegAdapter {
|
||||
* @param pcmPath 输出 PCM 文件路径
|
||||
* @returns PCM 数据 Buffer
|
||||
*/
|
||||
convertToPCM(filePath: string, pcmPath: string): Promise<Buffer>;
|
||||
convertToPCM(filePath: string, pcmPath: string): Promise<{ result: boolean, sampleRate: number }>;
|
||||
|
||||
/**
|
||||
* 转换音频文件
|
||||
|
||||
@ -88,14 +88,11 @@ export class FFmpegAddonAdapter implements IFFmpegAdapter {
|
||||
/**
|
||||
* 转换为 PCM
|
||||
*/
|
||||
async convertToPCM(filePath: string, pcmPath: string): Promise<Buffer> {
|
||||
async convertToPCM(filePath: string, pcmPath: string): Promise<{ result: boolean, sampleRate: number }> {
|
||||
const addon = this.ensureAddon();
|
||||
const result = await addon.decodeAudioToPCM(filePath);
|
||||
const result = await addon.decodeAudioToPCM(filePath, pcmPath, 24000);
|
||||
|
||||
// 写入文件
|
||||
await writeFile(pcmPath, result.pcm);
|
||||
|
||||
return result.pcm;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -67,5 +67,5 @@ export interface FFmpeg {
|
||||
/**
|
||||
* Decode audio file to raw PCM data
|
||||
*/
|
||||
decodeAudioToPCM(filePath: string): Promise<AudioPCMResult>;
|
||||
decodeAudioToPCM(filePath: string, pcmPath: string, sampleRate?: number): Promise<{ result: boolean, sampleRate: number }>;
|
||||
}
|
||||
@ -157,7 +157,7 @@ export class FFmpegExecAdapter implements IFFmpegAdapter {
|
||||
/**
|
||||
* 转换为 PCM
|
||||
*/
|
||||
async convertToPCM(filePath: string, pcmPath: string): Promise<Buffer> {
|
||||
async convertToPCM(filePath: string, pcmPath: string): Promise<{ result: boolean, sampleRate: number }> {
|
||||
try {
|
||||
ensureDirExists(pcmPath);
|
||||
|
||||
@ -174,7 +174,7 @@ export class FFmpegExecAdapter implements IFFmpegAdapter {
|
||||
throw new Error('转换PCM失败,输出文件不存在');
|
||||
}
|
||||
|
||||
return readFileSync(pcmPath);
|
||||
return { result: true, sampleRate: 24000 };
|
||||
} catch (error: any) {
|
||||
throw new Error(`FFmpeg处理转换出错: ${error.message}`);
|
||||
}
|
||||
|
||||
@ -93,7 +93,7 @@ export class FFmpegService {
|
||||
/**
|
||||
* 转换为 PCM 格式
|
||||
*/
|
||||
public static async convert(filePath: string, pcmPath: string): Promise<Buffer> {
|
||||
public static async convert(filePath: string, pcmPath: string): Promise<{ result: boolean, sampleRate: number }> {
|
||||
const adapter = await this.getAdapter();
|
||||
return adapter.convertToPCM(filePath, pcmPath);
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue
Block a user