javascript - AudioContext/getChannelData 是确定性的吗?

标签 javascript html html5-audio

我正在分析一个音频文件,以便使用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 确定性的,即它将从同一 channel 的同一 AudioBuffer 中产生相同的 Float32Array(除非您碰巧传输了支持) ArrayBuffer 到另一个线程,在这种情况下,它将返回一个空的 Float32Array,并从那时起具有分离的后备缓冲区)。

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

Is there a way to get consistent data of that sort in the browser?

是的。

您可以直接获取录音结果 (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);
}

注意:使用异步函数和 Promise,此代码会变得更加简单,但它应该给出如何读取整个完整记录的一般概念。

另请注意:由于跨线程数据复制(尤其是涉及 JS 主线程)固有的性能问题,ScriptProcessorNode 已被弃用。首选替代方案是更先进的 AudioWorklet ,但这是一种在 Web 上执行操作的相当新的方式,需要对工作集有深入的了解。

关于javascript - AudioContext/getChannelData 是确定性的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64479064/

相关文章:

javascript - AngularJS,仅在变量为真时过滤

javascript - 编辑存储在服务器上的文本文件

javascript - 数据为空或零时如何继续行?

javascript - 在聊天框中自动滚动 javascript 函数

javascript - Jquery 移动干扰 javascript 填充选择框

php - 如何使用 URL 中的 $_GET 参数重定向到同一页面

javascript - 如何使用javascript检测可播放的音频类型?

html5-audio - HTML5 音频 : createMediaElementSource breaks audio output

javascript - JWPlayer如何插入视频

javascript - 在javascript中播放音频时更改左/右平衡