This is how I got it to work in case anyone else has the same issue:
let mp3Data = [];
let audioContext = new (window.AudioContext || window.webkitAudioContext)();
let audioBuffer = await getPCM();
let samples = getSamples(audioBuffer);
let audioBlob = getBlobMp3(samples);
// pcm: pulse-code modulation, used in audio
async function getPCM() {
// chunks from mediaRecorder
let blob = new Blob(chunks, { type: "audio/webm" });
let arrayBuffer = await blob.arrayBuffer();
return await audioContext.decodeAudioData(arrayBuffer);
}
function getSamples(audioBuffer) {
let channelData = audioBuffer.getChannelData(0); // Mono channel (0 for left)
return float32To16BitPCM(channelData);
}
function float32To16BitPCM(float32Array) {
let int16Array = new Int16Array(float32Array.length);
for (let i = 0; i < float32Array.length; i++) {
int16Array[i] = Math.max(-1, Math.min(1, float32Array[i])) * 0x7fff; // 0x7FFF = 32767
}
return int16Array;
}
function getBlobMp3(samples) {
let mp3encoder = new lamejs.Mp3Encoder(
1, // Mono channel
44100, // 44.1kHz
128, // 128 kbps for MP3 encoding
);
let sampleBlockSize = 1152; // multiple of 576
for (let i = 0; i < samples.length; i += sampleBlockSize) {
let sampleChunk = samples.subarray(i, i + sampleBlockSize);
let bufferMp3 = mp3encoder.encodeBuffer(sampleChunk);
if (bufferMp3.length > 0) {
mp3Data.push(bufferMp3);
}
}
let finalBufferMp3 = mp3encoder.flush();
if (finalBufferMp3.length > 0) {
mp3Data.push(finalBufferMp3);
}
return new Blob(mp3Data, { type: "audio/mp3" });
}
I had to:
audioContextI am not sure if it is the correct answer but it did work for me. If anyone knows a better way to do this, please comment/answer.