/**
* 实时音频流处理类
* 用于捕获和处理麦克风音频数据
*/
class RealTimeAudioStream {
constructor(options = {}) {
// 合并默认配置和用户配置
this.config = {
sampleRate: 16000, // 采样率
bufferSize: 1024, // 缓冲区大小
onAudioData: () => {}, // 音频数据回调
onError: () => {}, // 错误回调
...options
};
this.audioContext = null; // Web Audio API上下文
this.microphone = null; // 麦克风输入源
this.processor = null; // 音频处理节点
this.isStreaming = false; // 是否正在采集
this.audioStream = null; // 音频流对象
}
/**
* 启动音频采集
* @returns {Promise<boolean>} 是否启动成功
*/
async start() {
try {
// 获取麦克风权限
this.audioStream = await navigator.mediaDevices.getUserMedia({
audio: {
sampleRate: this.config.sampleRate,
echoCancellation: true,//消除回声
noiseSuppression: true,//降噪
channelCount: 1,//单声道
}
});
// 创建音频上下文
const AudioContext = window.AudioContext || window.webkitAudioContext;
this.audioContext = new AudioContext({
sampleRate: this.config.sampleRate
});
// 创建处理管道
this.microphone = this.audioContext.createMediaStreamSource(this.audioStream);
this.processor = this.audioContext.createScriptProcessor(
this.config.bufferSize, 1, 1
);
// 设置音频处理回调
this.processor.onaudioprocess = (event) => {
if (!this.isStreaming) return;
// 获取音频数据并传递给回调函数
const audioData = event.inputBuffer.getChannelData(0);
this.config.onAudioData(new Float32Array(audioData));
};
// 连接音频节点
this.microphone.connect(this.processor);
this.processor.connect(this.audioContext.destination);
this.isStreaming = true;
console.log("音频采集已启动");
return true;
} catch (error) {
console.error("音频启动失败:", error);
this.config.onError(error);
return false;
}
}
/**
* 停止音频采集
*/
stop() {
if (!this.isStreaming) return;
this.isStreaming = false;
// 断开所有音频节点连接
if (this.processor) this.processor.disconnect();
if (this.microphone) this.microphone.disconnect();
// 停止音频轨道
if (this.audioStream) {
this.audioStream.getTracks().forEach(track => track.stop());
}
// 关闭音频上下文
if (this.audioContext) {
this.audioContext.close();
}
console.log("音频采集已停止");
}
}
开始采集音频时调用:
`async function startAudioCapture() {
if (audioStream) return; // 避免重复启动
// 创建并启动音频流
audioStream = new RealTimeAudioStream({
onAudioData: (data) => {
// 只打印前3个样本值避免刷屏
console.log("音频数据:",
Array.from(data.slice(0, 3)).map(v => v.toFixed(4)));
},
onError: (err) => {
console.error("音频错误:", err);
}
});
await audioStream.start();
}`
停止采集音频
function stopAudioCapture() { if (audioStream) { audioStream.stop(); audioStream = null; } }
监听到的音频流