【问题标题】:How to create an AudioBuffer from a Blob?如何从 Blob 创建 AudioBuffer?
【发布时间】:2017-03-14 18:50:16
【问题描述】:

我有一个使用MediaRecorder api 创建的音频文件/blob:

let recorder = new MediaRecorder(this.stream)
let data = [];
recorder.ondataavailable = event => data.push(event.data);

然后在录制完成后:

let superBlob = new Blob(data, { type: "video/webm" });

如何使用此 blob 创建AudioBuffer?我需要:

  • Blob 对象转换为ArrayBuffer,我可以将其与AudioContext.decodeAudioData 一起使用(返回AudioBuffer)或
  • Blob 对象转换为Float32Array,我可以将其复制到AudioBufferAudioBuffer.copyToChannel()

感谢您提供有关如何实现这一目标的任何提示。干杯!

【问题讨论】:

    标签: blob web-audio-api audiobuffer web-mediarecorder


    【解决方案1】:

    所有答案都是正确的。但是,在 Chrome 76 和 Firefox 69 等现代网络浏览器中,有一种更简单的方法:使用 Blob.arrayBuffer()

    由于Blob.arrayBuffer() 返回一个 Promise,你可以做任何一个

    superBlob.arrayBuffer().then(arrayBuffer => {
      // Do something with arrayBuffer
    });
    

    async function doSomethingWithAudioBuffer(blob) {
      var arrayBuffer = await blob.arrayBuffer();
      // Do something with arrayBuffer;
    }
    

    【讨论】:

    • 刚刚试了一下,得到的是arrayBuffer,不是audioBuffer
    • @Will59 你会仔细阅读这个问题吗?提问者知道如何将 ArrayBuffer 转换为 AudioBuffer。问题不在于从 Blob 中获取 AudioBuffer。
    • 然后更仔细地阅读你的代码......不要在你实际上得到一个arrayBuffer的地方写'audioBuffer'。
    • 感谢您抽出宝贵时间
    【解决方案2】:

    两个答案都是正确的,有一些小的变化。这是我最后使用的函数:

    function convertBlobToAudioBuffer(myBlob) {
    
      const audioContext = new AudioContext();
      const fileReader = new FileReader();
    
      fileReader.onloadend = () => {
    
        let myArrayBuffer = fileReader.result;
    
        audioContext.decodeAudioData(myArrayBuffer, (audioBuffer) => {
    
          // Do something with audioBuffer
    
        });
      };
    
      //Load blob
      fileReader.readAsArrayBuffer(myBlob);
    }
    

    【讨论】:

      【解决方案3】:

      接受的答案很好,但只给出了一个不是音频缓冲区的数组缓冲区。您需要使用音频上下文将数组缓冲区转换为音频缓冲区。

      const audioContext = AudioContext()
      const fileReader = new FileReader()
      
      // Set up file reader on loaded end event
      fileReader.onloadend = () => {
      
          const arrayBuffer = fileReader.result as ArrayBuffer
      
          // Convert array buffer into audio buffer
          audioContext.decodeAudioData(arrayBuffer, (audioBuffer) => {
      
            // Do something with audioBuffer
            console.log(audioBuffer)
      
          })
      
      }
      
      //Load blob
      fileReader.readAsArrayBuffer(blob)
      

      我希望答案包括使用decodeAudioData 的示例。我不得不在其他地方找到它,我想既然这是“Blob to Audio Buffer”的热门搜索,我会为下一个进入这个兔子洞的人添加一些有用的信息。

      【讨论】:

        【解决方案4】:

        要将Blob 对象转换为ArrayBuffer,请使用FileReader.readAsArrayBuffer

        let fileReader = new FileReader();
        let arrayBuffer;
        
        fileReader.onloadend = () => {
            arrayBuffer = fileReader.result;
        }
        
        fileReader.readAsArrayBuffer(superBlob);
        

        【讨论】:

        • 我在我的实现中使用它,但fileReader.result 总是返回一个空的ArrayBuffer - 你知道会发生什么吗?更多详情可以在this question that I asked中找到
        • 您确定要在onloadend 事件中检查fileReader.result 吗?
        • 是的,我已经设法让它工作了,这对我来说是一个微不足道的错误,对此我深表歉意。非常感谢您发布此答案,它非常有帮助!
        • 不确定这个错误有多小。我发现您无法直接访问生成的数组缓冲区。我用 data = new Uint8Array(reader.result);
        • 如 PAT-O-MATION 所述,这将返回一个 arrayBuffer,而不是 audioBuffer
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-30
        • 1970-01-01
        • 2020-07-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多