Web Audio API获取麦克风音频数据全是0怎么办?
我在用Web Audio API处理麦克风输入时遇到问题。想实时获取音频波形数据,按照教程写了代码,但getByteTimeDomainData返回的数组全是0。
具体步骤是先用navigator.mediaDevices.getUserMedia获取麦克风流,创建了AudioContext和AnalyserNode,然后连接了音频节点。代码看起来没问题:
const audioCtx = new AudioContext();
const analyser = audioCtx.createAnalyser();
navigator.mediaDevices.getUserMedia({ audio: true })
.then(stream => {
const source = audioCtx.createMediaStreamSource(stream);
source.connect(analyler); // 注意这里拼写错误了吗?
analyser.connect(audioCtx.destination);
analyser.fftSize = 2048;
const data = new Uint8Array(analyser.frequencyBinCount);
analyser.getByteTimeDomainData(data);
console.log(data); // 打印全是0
});
明明麦克风有声音输入,但数据一直是0数组。试过在按钮点击事件里执行,也确认了音频上下文已resume,还是没解决。是不是哪里连接顺序错了?
第一个是拼写错误:
source.connect(analyler)这行里的analyler拼错了,应该是analyser。这行代码实际上没连上 AnalyserNode,所以后面拿不到数据。第二个是数据获取时机不对。你当前的写法是直接执行
getByteTimeDomainData,但这时候音频处理流程还没真正开始,得在音频上下文运行起来之后才能拿到数据。Web Audio API 的处理需要一定时间,不能刚连接完就拿数据。应该改成在音频流开始后,用
requestAnimationFrame或者自定义循环函数来持续获取数据。下面是一个能跑的代码片段:另外,别忘了在用户手势事件中启动 AudioContext(比如点击按钮),否则移动端可能不会播放声音。比如:
搞完这些,再对着麦克风说话,应该就能看到数据变化了。
analyser写成了analyler,改过来就能用了。另外确保音频上下文已经resume,还有就是getByteTimeDomainData要在音频数据实际流动之后再调用,直接放个定时器简单搞定。最简单的办法就是加个延时,让音频先流一会儿再获取数据。