AudioContext/getChannelData是否具有确定性



我正在分析一个音频文件,以便使用channelData驱动我的网络应用程序的另一部分(基本上是基于音频文件绘制图形(。回放的回调函数如下所示:

successCallback(mediaStream) {
var audioContext = new (window.AudioContext ||
window.webkitAudioContext)();
source = audioContext.createMediaStreamSource(mediaStream);
node = audioContext.createScriptProcessor(256, 1, 1);
node.onaudioprocess = function(data) {
var monoChannel = data.inputBuffer.getChannelData(0);
..
};

不知怎么的,我想如果我用同一个文件运行上面的代码,它会一直产生相同的结果。但事实并非如此。同一个音频文件会触发onaudioprocess函数,例如,有时70次,有时72次,始终产生不同的数据。有没有办法在浏览器中获得这种一致的数据?

编辑:我从同一页的录音功能中获取音频。录制完成后,生成的文件将被设置为<audio>元素的src。recorder是我的MediaRecorder

recorder.addEventListener("dataavailable", function(e) {
fileurl = URL.createObjectURL(e.data);
document.querySelector("#localaudio").src = fileurl;
..

要回答您最初的问题:getChannelData是确定的,即它将从同一通道的同一AudioBuffer中产生相同的Float32Array(除非您碰巧将后备ArrayBuffer传输到另一个线程,在这种情况下,它将从那时起返回一个空的Float22Array和一个分离的后备缓冲区(。

我想你在这里遇到的问题是线程问题(我的猜测是,在你开始处理来自MediaStream的音频流之前,它已经在播放了(,但如果不调试完整的应用程序,很难准确判断(这里至少有3个线程在工作:MediaStream的音频处理线程、您正在使用的AudioContext的音频处理螺纹,以及运行代码的主线程(。

有办法在浏览器中获得这种类型的一致数据吗?

是。

不需要处理实时音频流进行实时分析,只需获取录制结果(e.data(,将其读取为ArrayBuffer,然后将其解码为AudioBuffer,类似于:

recorder.addEventListener("dataavailable", function (e) {
let reader = new FileReader();

reader.onload = function (e) {
audioContext.decodeAudioData(e.target.result).then(function (audioBuffer) {
var monoChannel = audioBuffer.getChannelData(0);
// monoChannel contains the entire first channel of your recording as a Float32Array
// ...
});
};

reader.readAsArrayBuffer(e.data);
}

注意:使用异步函数和Promises,这段代码会变得简单得多,但它应该给出如何读取整个完整记录的大致想法。

另请注意:由于跨线程数据复制中固有的性能问题,特别是涉及JS主线程,ScriptProcessorNode已被弃用。首选的替代方案是更高级的AudioWorklet,但这是一种在网络上做事的全新方式,需要对Worklet有全面的了解。

最新更新