I'm trying to process audio files using the Web Audio API and then to encode the result using the Web Codecs API, here is what a simplified version of my code looks like:
/**
* Encode an audio file using web codecs
*/
async function encodeAudio(url: string) {
const audioBuffer = await fetchAudioBuffer(url); // see function below
const signal = bufferToF32Planar(audioBuffer); // see function below
const encoder = new AudioEncoder({
output: console.log,
error: console.error,
});
encoder.configure({
codec: 'opus',
sampleRate: 44100,
numberOfChannels: 2,
bitrate: 128_000, // 128 kbps
});
const data = new AudioData({
format: 'f32-planar',
sampleRate: audioBuffer.sampleRate,
numberOfChannels: audioBuffer.numberOfChannels,
numberOfFrames: audioBuffer.length,
timestamp: 0,
data: signal,
});
encoder.encode(data);
}
/**
* Convert an audio buffer into a planar float 32 array
* @param input processed audio buffer
* @returns Typed array
*/
function bufferToF32Planar(input: AudioBuffer): Float32Array {
const result = new Float32Array(input.length * input.numberOfChannels);
let offset = 0;
for (let i = 0; i < input.numberOfChannels; i++) {
const data = input.getChannelData(i);
result.set(data, offset);
offset = data.length;
}
return result;
}
/**
* Fetch the audio file and convert it into
* an audio buffer using an audio context
*/
async function fetchAudioBuffer(
input: RequestInfo | URL,
init?: RequestInit | undefined,
): Promise<AudioBuffer> {
const context = new AudioContext();
const res = await fetch(input, init);
const buffer = await res.arrayBuffer();
return await context.decodeAudioData(buffer);
}
await encodeAudio('/audio.mp3');
However when I run this code, I'm getting the error DOMException: Input audio buffer is incompatible with codec parameters
. What did I do wrong?
I guess your source file has a different sample rate than 44.1 kHz. But you could use the Web Audio API to resample your source file when it gets decoded.
const context = new AudioContext({ sampleRate: 44100 });
Calling decodeAudioData()
on that context
will then always produce an AudioBuffer
at 44.1 kHz.