Skip to content

Commit 39b6a93

Browse files
committed
Use a ref for audioStream instead of state to fix audio stream leak after component unmount
1 parent 085b57f commit 39b6a93

File tree

1 file changed

+5
-5
lines changed

1 file changed

+5
-5
lines changed

src/hooks/useVoiceVisualizer.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ function useVoiceVisualizer({
2323
}: useVoiceVisualizerParams = {}): Controls {
2424
const [isRecordingInProgress, setIsRecordingInProgress] = useState(false);
2525
const [isPausedRecording, setIsPausedRecording] = useState(false);
26-
const [audioStream, setAudioStream] = useState<MediaStream | null>(null);
2726
const [audioData, setAudioData] = useState<Uint8Array>(new Uint8Array(0));
2827
const [isProcessingAudioOnComplete, _setIsProcessingAudioOnComplete] =
2928
useState(false);
@@ -43,6 +42,7 @@ function useVoiceVisualizer({
4342
const [isProcessingStartRecording, setIsProcessingStartRecording] =
4443
useState(false);
4544

45+
const audioStreamRef = useRef<MediaStream | null>(null);
4646
const mediaRecorderRef = useRef<MediaRecorder | null>(null);
4747
const audioContextRef = useRef<AudioContext | null>(null);
4848
const analyserRef = useRef<AnalyserNode | null>(null);
@@ -160,7 +160,7 @@ function useVoiceVisualizer({
160160
setIsProcessingStartRecording(false);
161161
setIsRecordingInProgress(true);
162162
setPrevTime(performance.now());
163-
setAudioStream(stream);
163+
audioStreamRef.current = stream;
164164
audioContextRef.current = new window.AudioContext();
165165
analyserRef.current = audioContextRef.current.createAnalyser();
166166
dataArrayRef.current = new Uint8Array(
@@ -228,7 +228,7 @@ function useVoiceVisualizer({
228228
handleDataAvailable
229229
);
230230
}
231-
audioStream?.getTracks().forEach((track) => track.stop());
231+
audioStreamRef.current?.getTracks().forEach((track) => track.stop());
232232
if (rafRecordingRef.current) cancelAnimationFrame(rafRecordingRef.current);
233233
if (sourceRef.current) sourceRef.current.disconnect();
234234
if (audioContextRef.current && audioContextRef.current.state !== "closed") {
@@ -258,7 +258,8 @@ function useVoiceVisualizer({
258258
mediaRecorderRef.current = null;
259259
}
260260

261-
audioStream?.getTracks().forEach((track) => track.stop());
261+
audioStreamRef.current?.getTracks().forEach((track) => track.stop());
262+
audioStreamRef.current = null;
262263
if (audioRef?.current) {
263264
audioRef.current.removeEventListener("ended", onEndedRecordedAudio);
264265
audioRef.current.pause();
@@ -270,7 +271,6 @@ function useVoiceVisualizer({
270271
dataArrayRef.current = null;
271272
sourceRef.current = null;
272273

273-
setAudioStream(null);
274274
setIsProcessingStartRecording(false);
275275
setIsRecordingInProgress(false);
276276
setIsPreloadedBlob(false);

0 commit comments

Comments
 (0)