我有一个使用MediaRecorder
api:
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()
有关如何实现这一目标的任何提示都表示赞赏。干杯!
答案 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);
}