如何从Blob创建AudioBuffer?

时间:2016-11-01 15:33:09

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

我有一个使用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()

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

4 个答案:

答案 0 :(得分:8)

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

let fileReader = new FileReader();
let arrayBuffer;

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

fileReader.readAsArrayBuffer(superBlob);

答案 1 :(得分:5)

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

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到音频缓冲区的搜索”的首要搜索,所以我将为下一个陷入困境的下一个人添加一些有用的信息。

答案 2 :(得分:2)

所有答案都是正确的。但是,在现代网络浏览器(例如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 :(得分:1)

两个答案都是正确的,但有一些细微的变化。这是我最后使用的功能:

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);
}