bumblebee-hotword-node热词触发失败问题求助
解决Discord音频流无法触发Bumblebee热词识别的问题
核心排查方向:音频格式匹配与流处理
1. 修正Discord音频输入格式参数
Discord的语音流实际是48kHz、16位立体声(s16le),你的converter.js中默认输入采样率写为44100,这会导致FFmpeg解码错误,输出失真音频。修改inputArray的默认值:
function createConverter( stream, // 修正采样率为48000,匹配Discord实际流格式 inputArray = ["-f s16le", "-ac 2", "-ar 48000"], outputArray = ["-ac 1", "-ar 16000"], formatType = "s16le" ) { // ... 原有代码 }
2. 验证转换后的音频有效性
将转换后的流保存为文件,用Audacity等工具检查参数是否符合要求(16kHz、单声道、16位PCM):
const fs = require('fs'); const testStream = createConverter(listenStream, ["-f s16le", "-ac 2", "-ar 48000"], ["-ac 1", "-ar 16000"], 'wav'); testStream.pipe(fs.createWriteStream('test_audio.wav'));
播放该文件,确认你的声音清晰无杂音、速度正常——如果音频失真,Porcupine绝对无法识别热词。
3. 确认Bumblebee/Porcupine的参数匹配
- 确保使用的热词模型是16kHz采样率版本(默认的"bumblebee"模型符合要求,但自定义模型需对应)
- 检查Bumblebee初始化时是否指定了正确的采样率:
// 在VoiceRecognitionService内部确认初始化逻辑 const bumblebee = new BumbleBee({ sampleRate: 16000, // 必须与转换后的流一致 // 其他配置... });
4. 处理音频流的帧对齐问题
Porcupine要求输入固定大小的音频帧(16kHz、16位单声道下,每帧为640字节,对应20ms音频)。如果流的chunk大小不匹配,需手动缓冲分割:
let audioBuffer = Buffer.alloc(0); const FRAME_SIZE = 640; // 16000Hz * 2字节/采样 * 1声道 * 0.02秒 voiceRecorderStream.on('data', (chunk) => { audioBuffer = Buffer.concat([audioBuffer, chunk]); while (audioBuffer.length >= FRAME_SIZE) { const frame = audioBuffer.slice(0, FRAME_SIZE); audioBuffer = audioBuffer.slice(FRAME_SIZE); // 手动将帧传给Bumblebee处理 bumblebee.process(frame); } });
如果VoiceRecognitionService内部已处理帧分割,需确认其逻辑是否正确生成了符合要求的帧。
5. 检查麦克风输入音量
低音量会导致Porcupine识别失败:
- 在Discord设置中测试麦克风音量,确保说话时音量条明显波动
- 调整系统麦克风增益,保证转换后的音频文件中你的声音清晰响亮
内容的提问来源于stack exchange,提问作者Jack blundell
相关产品推荐
相关产品推荐

