Post-processing
giuseppeg opened this issue Ā· comments
Hi there this library looks dope!
How hard would it be to do the conversion later instead of doing it in real time?
I assume I'd need to derive the solution from https://github.com/elsmr/mp3-mediarecorder/blob/master/src/worker/index.ts
I want to encode an audio file acquired with the native MediaRecorder API, so I am using this library worker with a custom "frontend" see implementation below and the issue right after
// Given:
// recording = [Blob]
const worker = new Worker(new URL("../lib/worker.ts", import.meta.url));
const PostMessageType = {
DATA_AVAILABLE: "DATA_AVAILABLE",
START_RECORDING: "START_RECORDING",
STOP_RECORDING: "STOP_RECORDING",
ERROR: "ERROR",
BLOB_READY: "BLOB_READY",
WORKER_RECORDING: "WORKER_RECORDING",
};
let onComplete;
const audioBlobPromise = new Promise((resolve) => {
onComplete = resolve;
});
worker.addEventListener("message", (event) => {
const message = event.data;
switch (message.type) {
case PostMessageType.WORKER_RECORDING: {
// Send the chunks received by the MediaRecorder to the worker for encoding
// recording = [Blob]
const context = new AudioContext();
Promise.all(
recording.map((r) =>
r.arrayBuffer().then((arrayBuffer) => {
let onSuccess, onError;
const decodeAudioDataPromise = new Promise(
(resolve, reject) => {
onSuccess = (buffer) => {
const data = buffer.getChannelData(0);
worker.postMessage({
type: PostMessageType.DATA_AVAILABLE,
data,
});
Promise.resolve().then(() => {
resolve();
});
};
onError = () => {
reject();
};
}
);
context.decodeAudioData(arrayBuffer, onSuccess, onError);
return decodeAudioDataPromise;
})
)
)
.then(() => {
// End the encoding. It will result in PostMessageType.BLOB_READY.
setTimeout(() => {
worker.postMessage({ type: PostMessageType.STOP_RECORDING });
}, 1000);
})
.finally(() => {
context.close();
});
break;
}
case PostMessageType.BLOB_READY: {
mimeType = "audio/mpeg";
onComplete([message.blob]);
break;
}
default: {
console.error(
"An error occured while encoding the recording ",
message.error || "unknown error"
);
onComplete(recording);
}
}
});
// Start the encoder
worker.postMessage({
type: PostMessageType.START_RECORDING,
config: { sampleRate: 44100 },
});
const audioBlob = await audioBlobPromise;
worker.terminate();
console.log({ audioBlob });
new File(audioBlob, `recording.mp3`, {
lastModified: Date.now(),
type: mimeType,
})
With this when I send data to the worker, the handler throws an error here because encodedBytesAmount
is -1
:
mp3-mediarecorder/src/worker/index.ts
Lines 106 to 109 in 2233d4c
{ data: Float32Array(246077)}, dataLength: 246077, encodedBytesAmount: -1 }