我想使用 MediaRecorder 从浏览器录制音频,将其转换为 AudioBuffer 以将其发送到服务器。它将第一个块作为 AudioBuffer 返回,但对于后续块,它会抛出以下错误:
Uncaught (in promise) DOMException: Failed to execute 'decodeAudioData' on 'BaseAudioContext': Unable to decode audio data
代码
let recorder = null;
const record = (stream) => {
recorder = new MediaRecorder(stream, {
mimeType: "audio/webm;codecs=opus"
});
recorder.start(500); // Starting the record
recorder.ondataavailable = (e) => {
var reader = new FileReader()
reader.onloadend = () => {
var audioContext = new AudioContext();
var myArrayBuffer = reader.result;
audioContext.decodeAudioData(myArrayBuffer, (audioBuffer) => {
console.log(audioBuffer);
// Uncaught (in promise) DOMException: Failed to execute 'decodeAudioData' on 'BaseAudioContext': Unable to decode audio data
});
};
reader.readAsArrayBuffer(e.data);
}
}
navigator.getUserMedia({
audio: {
channelCount: 1,
sampleRate: 16000,
}
}, record, (e) => {
console.log(e);
});
问题在于
MediaRecorder
发出的块本身不需要是有效文件。只有所有块组合起来才需要形成一个有效的文件。
另一方面,
decodeAudioData()
仅适用于完整文件。
它与第一个块一起工作的事实可能是因为它看起来像解码器的完整文件。
但看起来您无论如何都想将 PCM 数据发送到服务器。在这种情况下,您可以使用
AudioWorklet
或支持录制 wav 文件的extendable-media-recorder
等库直接录制 PCM 数据。