Restored to '84d7de2da64f8f2fd1e2d64959817c64c8fb7c04'
Replit-Restored-To: 84d7de2da6
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* React hook for voice recording using MediaRecorder API.
|
||||
* Records audio in WebM/Opus format for efficient streaming.
|
||||
*/
|
||||
import { useRef, useCallback, useState } from "react";
|
||||
|
||||
export type RecordingState = "idle" | "recording" | "stopped";
|
||||
|
||||
export function useVoiceRecorder() {
|
||||
const [state, setState] = useState<RecordingState>("idle");
|
||||
const mediaRecorderRef = useRef<MediaRecorder | null>(null);
|
||||
const chunksRef = useRef<Blob[]>([]);
|
||||
|
||||
const startRecording = useCallback(async (): Promise<void> => {
|
||||
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
|
||||
const recorder = new MediaRecorder(stream, {
|
||||
mimeType: "audio/webm;codecs=opus",
|
||||
});
|
||||
|
||||
mediaRecorderRef.current = recorder;
|
||||
chunksRef.current = [];
|
||||
|
||||
recorder.ondataavailable = (e) => {
|
||||
if (e.data.size > 0) chunksRef.current.push(e.data);
|
||||
};
|
||||
|
||||
recorder.start(100); // Collect chunks every 100ms
|
||||
setState("recording");
|
||||
}, []);
|
||||
|
||||
const stopRecording = useCallback((): Promise<Blob> => {
|
||||
return new Promise((resolve) => {
|
||||
const recorder = mediaRecorderRef.current;
|
||||
if (!recorder || recorder.state !== "recording") {
|
||||
resolve(new Blob());
|
||||
return;
|
||||
}
|
||||
|
||||
recorder.onstop = () => {
|
||||
const blob = new Blob(chunksRef.current, { type: "audio/webm" });
|
||||
recorder.stream.getTracks().forEach((t) => t.stop());
|
||||
setState("stopped");
|
||||
resolve(blob);
|
||||
};
|
||||
|
||||
recorder.stop();
|
||||
});
|
||||
}, []);
|
||||
|
||||
return { state, startRecording, stopRecording };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user