I am using MediaRecorder to record chunks of WebM audio data. These chunks are given to me as blobs. I am trying to transform them into base64 strings and send them over the wire. I would also accept the concept of transforming them into anything and send them over the wire.
Here's my code for the UI
private attachRecorderDataAvailableListener(): void {
if (!this.mediaRecorder) {
return;
}
const blobtoBase64 = (blob: Blob): Promise<string> =>
new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onloadend = () => resolve(reader.result as string);
reader.readAsDataURL(blob);
});
const base64ToBlob = (dataURI: string) => {
// convert base64 to raw binary data held in a string
// doesn't handle URLEncoded DataURIs - see SO answer #6850276 for code that does this
const byteString = atob(dataURI.split(",")[1]);
// separate out the mime component
const mimeString = dataURI.split(",")[0].split(":")[1].split(";")[0];
// write the bytes of the string to an ArrayBuffer
const ab = new ArrayBuffer(byteString.length);
// create a view into the buffer
const ia = new Uint8Array(ab);
// set the bytes of the buffer to the correct values
for (let i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
// write the ArrayBuffer to a blob, and you're done
const blob = new Blob([ab], { type: "audio/webm;codecs=opus" });
return blob;
};
this.mediaRecorder.addEventListener(
"dataavailable",
async (event: BlobEvent) => {
console.log("Media Recorder Blob: ", event.data);
const base64Str = await blobtoBase64(event.data);
const dt = new Date().getTime();
saveAs(event.data, `original-${dt}.webm`);
saveAs(base64ToBlob(base64Str), `modified-${dt}.webm`);
if (event.data.size > 0) {
const input: any = {
data: await event.data.text(),
};
const decoder = new TextDecoder("utf-8");
await store.dispatch(
"WebsocketModule/emitMeetingSocketEvent",
{
eventType:
MEETING_WEBSOCKET_EVENT_TYPE.TRANSCRIPTION_AUDIO_RECEIVED,
eventPayload: input,
},
{
root: true,
}
);
}
}
);
}
The problem is that the blob is not serializing correctly. When I open the original file in VLC, I get a short clip of my audio. When I open the modified (which has been translated there and back), I get an unplayable audio file due to a "demux error". This is consistent with what happens on my backend.
Does anyone know how to correctly serialize this blob so that I can send it over a websocket.
I might just be an idiot who didn't read what I copied/pasted correctly. Gimme a sec
EDIT
Yeah I'm an idiot. I need to call fetch on the data URI to serialize it correctly.