in src/frontends/live_api_react/frontend/src/utils/audio-recorder.ts [48:93]
async start() {
if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
throw new Error("Could not request user media");
}
this.starting = new Promise(async (resolve, reject) => {
this.stream = await navigator.mediaDevices.getUserMedia({ audio: true });
this.audioContext = await audioContext({ sampleRate: this.sampleRate });
this.source = this.audioContext.createMediaStreamSource(this.stream);
const workletName = "audio-recorder-worklet";
const src = createWorketFromSrc(workletName, AudioRecordingWorklet);
await this.audioContext.audioWorklet.addModule(src);
this.recordingWorklet = new AudioWorkletNode(
this.audioContext,
workletName,
);
this.recordingWorklet.port.onmessage = async (ev: MessageEvent) => {
// worklet processes recording floats and messages converted buffer
const arrayBuffer = ev.data.data.int16arrayBuffer;
if (arrayBuffer) {
const arrayBufferString = arrayBufferToBase64(arrayBuffer);
this.emit("data", arrayBufferString);
}
};
this.source.connect(this.recordingWorklet);
// vu meter worklet
const vuWorkletName = "vu-meter";
await this.audioContext.audioWorklet.addModule(
createWorketFromSrc(vuWorkletName, VolMeterWorket),
);
this.vuWorklet = new AudioWorkletNode(this.audioContext, vuWorkletName);
this.vuWorklet.port.onmessage = (ev: MessageEvent) => {
this.emit("volume", ev.data.volume);
};
this.source.connect(this.vuWorklet);
this.recording = true;
resolve();
this.starting = null;
});
}