mirror of
https://github.com/webadderallorg/Recordly.git
synced 2026-09-24 14:55:37 +00:00
Fix: stop mic fallback recorder when cancelling native recording
Cancelling a native-capture recording (clicking the "X"/cancel button) never stopped the mic fallback recorder's getUserMedia stream. The stale mic track stayed open, so starting the next recording opened a second concurrent mic stream and produced silent/dead audio until the user manually reselected the microphone. cancelRecording's native-capture branch now stops the mic fallback recorder alongside discarding the native capture, mirroring the cleanup stopRecording already performs. Fixes #699 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
49926862f8
commit
aafa44014c
@@ -397,6 +397,7 @@ function cancelRecording(
|
||||
chunks: { current: Blob[] },
|
||||
webcamRecorder?: ReturnType<typeof createMockMediaRecorder> | null,
|
||||
webcamChunks?: { current: Blob[] },
|
||||
stopMicFallbackRecorder?: () => Promise<Blob | null>,
|
||||
) {
|
||||
if (webcamChunks) webcamChunks.current = [];
|
||||
if (webcamRecorder && webcamRecorder.state !== "inactive") {
|
||||
@@ -404,6 +405,7 @@ function cancelRecording(
|
||||
}
|
||||
|
||||
if (isNativeRecording) {
|
||||
void stopMicFallbackRecorder?.();
|
||||
return { cancelled: true, wasNative: true };
|
||||
}
|
||||
|
||||
@@ -740,6 +742,23 @@ describe("useScreenRecorder state machine", () => {
|
||||
expect(recorder.stop).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("stops the mic fallback recorder when cancelling native recording", () => {
|
||||
const chunks = { current: [] as Blob[] };
|
||||
const stopMicFallbackRecorder = vi.fn(() => Promise.resolve(null));
|
||||
|
||||
const result = cancelRecording(
|
||||
recorder,
|
||||
true,
|
||||
chunks,
|
||||
null,
|
||||
undefined,
|
||||
stopMicFallbackRecorder,
|
||||
);
|
||||
|
||||
expect(result.wasNative).toBe(true);
|
||||
expect(stopMicFallbackRecorder).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("handles cancel when recorder is already inactive", () => {
|
||||
const inactiveRecorder = createMockMediaRecorder("inactive");
|
||||
const chunks = { current: [new Blob(["data"])] };
|
||||
|
||||
@@ -2394,7 +2394,7 @@ export function useScreenRecorder(): UseScreenRecorderReturn {
|
||||
setRecording(false);
|
||||
window.electronAPI?.setRecordingState(false);
|
||||
void (async () => {
|
||||
await discardActiveNativeCapture();
|
||||
await Promise.allSettled([discardActiveNativeCapture(), stopMicFallbackRecorder()]);
|
||||
})();
|
||||
return;
|
||||
}
|
||||
@@ -2408,7 +2408,13 @@ export function useScreenRecorder(): UseScreenRecorderReturn {
|
||||
setRecording(false);
|
||||
window.electronAPI?.setRecordingState(false);
|
||||
}
|
||||
}, [cleanupCapturedMedia, discardActiveNativeCapture, markRecordingResumed, recording]);
|
||||
}, [
|
||||
cleanupCapturedMedia,
|
||||
discardActiveNativeCapture,
|
||||
markRecordingResumed,
|
||||
recording,
|
||||
stopMicFallbackRecorder,
|
||||
]);
|
||||
|
||||
const toggleRecording = async () => {
|
||||
if (starting || countdownActive || finalizing) {
|
||||
|
||||
Reference in New Issue
Block a user