Discord.js v12录制语音会话时用户停发言录音就终止该如何解决
问题原因
你当前的代码存在两个核心问题导致停止发言后录音异常:
- Discord.JS v12的
receiver.createStream()生成的音频流,会在对应用户停止发言时自动关闭,你没有做流的续接处理,用户再次发言时的新音频数据没有正确写入到文件中 - 你直接用
wav.FileWriter写入多路独立的PCM流,没有做音频混音处理,多个用户发言时的音频会互相覆盖,且每次新流写入时会重复写入WAV头信息,导致最终文件损坏无法正常播放
修复步骤
第一步:安装依赖
需要安装audio-mixer库处理多流混音,执行以下命令安装:
npm install audio-mixer
第二步:修改核心代码
修改createNewChunk函数
改为先写入原始PCM数据,避免提前写入WAV头导致文件异常,同时初始化混音器统一处理多用户音频:
const { Mixer } = require('audio-mixer'); const fs = require('fs'); const wav = require('wav'); createNewChunk(name) { // 混音器参数匹配Discord语音输出规格:16位采样、双声道、48000采样率 const mixer = new Mixer({ bitDepth: 16, channels: 2, sampleRate: 48000, clearInterval: 250 }); // 创建临时PCM文件写入流 const pcmStream = fs.createWriteStream(`./records/temp-${name}.pcm`); mixer.pipe(pcmStream); // 返回混音器和相关文件信息,录音结束后再封装为WAV return { mixer, pcmStream, name }; }
修改speaking事件监听逻辑
给音频流添加手动结束配置,避免用户停止发言时流自动关闭:
flux.on('speaking', (user, speaking) => { // 忽略机器人用户的音频 if (user.bot) return; // 用户开始发言且还没有创建对应输入流时再创建 if (speaking && !audioChunk.mixer.inputs.find(i => i.userId === user.id)) { // 添加end: 'manual'参数,禁止用户停止发言时自动关闭流 const audioStream = receiver.createStream(user, { mode: 'pcm', end: 'manual' }); audioStream.userId = user.id; // 将用户音频流加入混音器 const input = audioChunk.mixer.createInput(); audioStream.pipe(input); // 捕获流错误避免程序崩溃 audioStream.on('error', console.error); } });
修改录音结束逻辑
录音停止后将临时PCM文件封装为标准WAV格式:
case 'off': let f = this.vocals.find(r => r.c === c.id && r.u === message.author.id); if(!f){ return message.channel.send("Vous n'avez aucun enregistrement de démarré."); } // 销毁混音器 f.r.mixer.destroy(); // 关闭PCM写入流 f.r.pcmStream.end(() => { // 读取临时PCM文件转成WAV格式 const reader = fs.createReadStream(`./records/temp-${f.r.name}.pcm`); const writer = new wav.FileWriter(`./records/record-${f.r.name}.wav`, { channels: 2, sampleRate: 48000, bitDepth: 16 }); reader.pipe(writer); writer.on('finish', () => { // 转换完成后删除临时PCM文件 fs.unlinkSync(`./records/temp-${f.r.name}.pcm`); // 从录音列表中移除已结束的任务 this.vocals = this.vocals.filter(v => v !== f); message.channel.send("L'enregistrement s'est bien terminé avec succès !"); }); }); break;
额外说明
如果你不需要多用户混音,只需要分别保存每个用户的录音,可以去掉混音器逻辑,给每个用户单独创建WAV写入流即可。
内容的提问来源于stack exchange,提问作者Pioupia
相关产品推荐
相关产品推荐

