如何从 Blob 创建 AudioBuffer?

问题描述 投票:0回答:5

我有一个使用

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
    ,我可以使用
    AudioBuffer
     将其复制到 
    AudioBuffer.copyToChannel()

任何有关如何实现这一目标的提示都将受到赞赏。干杯!

blob web-audio-api audiobuffer web-mediarecorder
5个回答
17
投票

要将

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

let fileReader = new FileReader();
let arrayBuffer;

fileReader.onloadend = () => {
    arrayBuffer = fileReader.result;
}

fileReader.readAsArrayBuffer(superBlob);

10
投票

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

const audioContext = new 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”的热门搜索,我会为下一个进入这个兔子洞的人添加一些有用的信息。


6
投票

所有答案都是正确的。然而,在 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;
}

3
投票

使用异步函数的简化版本:

async function blobToAudioBuffer(audioContext, blob) {
  const arrayBuffer = await blob.arrayBuffer();
  return await audioContext.decodeAudioData(arrayBuffer);
}

我将

audioContext
作为参数,因为我建议重用实例。


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);
}
© www.soinside.com 2019 - 2024. All rights reserved.