diff --git a/lib/hooks/useRecording.ts b/lib/hooks/useRecording.ts index a5115e1..b94f11d 100644 --- a/lib/hooks/useRecording.ts +++ b/lib/hooks/useRecording.ts @@ -36,6 +36,7 @@ export function useRecording(): UseRecordingReturn { const startTimeRef = React.useRef(0); const animationFrameRef = React.useRef(0); const selectedDeviceIdRef = React.useRef(''); + const isMonitoringRef = React.useRef(false); // Request microphone permission const requestPermission = React.useCallback(async (): Promise => { @@ -73,6 +74,8 @@ export function useRecording(): UseRecordingReturn { const dataArray = new Uint8Array(analyser.frequencyBinCount); const updateLevel = () => { + if (!isMonitoringRef.current) return; + analyser.getByteTimeDomainData(dataArray); // Calculate RMS level @@ -85,13 +88,11 @@ export function useRecording(): UseRecordingReturn { setState((prev) => ({ ...prev, inputLevel: rms })); - if (state.isRecording && !state.isPaused) { - animationFrameRef.current = requestAnimationFrame(updateLevel); - } + animationFrameRef.current = requestAnimationFrame(updateLevel); }; updateLevel(); - }, [state.isRecording, state.isPaused]); + }, []); // Start recording const startRecording = React.useCallback(async (): Promise => { @@ -141,6 +142,7 @@ export function useRecording(): UseRecordingReturn { }); // Start monitoring input level + isMonitoringRef.current = true; monitorInputLevel(); } catch (error) { console.error('Failed to start recording:', error); @@ -172,6 +174,7 @@ export function useRecording(): UseRecordingReturn { const audioBuffer = await audioContext.decodeAudioData(arrayBuffer); // Clean up + isMonitoringRef.current = false; if (audioContextRef.current) { await audioContextRef.current.close(); } @@ -203,6 +206,7 @@ export function useRecording(): UseRecordingReturn { mediaRecorderRef.current.pause(); setState((prev) => ({ ...prev, isPaused: true })); + isMonitoringRef.current = false; if (animationFrameRef.current) { cancelAnimationFrame(animationFrameRef.current); } @@ -214,6 +218,7 @@ export function useRecording(): UseRecordingReturn { if (mediaRecorderRef.current && state.isRecording && state.isPaused) { mediaRecorderRef.current.resume(); setState((prev) => ({ ...prev, isPaused: false })); + isMonitoringRef.current = true; monitorInputLevel(); } }, [state.isRecording, state.isPaused, monitorInputLevel]); @@ -233,6 +238,7 @@ export function useRecording(): UseRecordingReturn { // Cleanup on unmount React.useEffect(() => { return () => { + isMonitoringRef.current = false; if (streamRef.current) { streamRef.current.getTracks().forEach((track) => track.stop()); }