我有一个使用
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
对象转换为 ArrayBuffer
,请使用 FileReader.readAsArrayBuffer
。
let fileReader = new FileReader();
let arrayBuffer;
fileReader.onloadend = () => {
arrayBuffer = fileReader.result;
}
fileReader.readAsArrayBuffer(superBlob);
接受的答案很好,但只提供了一个数组缓冲区,而不是音频缓冲区。您需要使用音频上下文将数组缓冲区转换为音频缓冲区。
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”的热门搜索,我会为下一个进入这个兔子洞的人添加一些有用的信息。
所有答案都是正确的。然而,在 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;
}
使用异步函数的简化版本:
async function blobToAudioBuffer(audioContext, blob) {
const arrayBuffer = await blob.arrayBuffer();
return await audioContext.decodeAudioData(arrayBuffer);
}
我将
audioContext
作为参数,因为我建议重用实例。
两个答案都是正确的,有一些细微的变化。这是我最终使用的功能:
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);
}