fix: restore passing checks for webcam overlay changes

This commit is contained in:
Marcus Schiesser
2026-03-17 20:29:13 +08:00
parent c3e4c86b33
commit 1591f7dfcb
5 changed files with 66 additions and 63 deletions
@@ -970,8 +970,7 @@ const VideoPlayback = forwardRef<VideoPlaybackRef, VideoPlaybackProps>(
const activeSpeedRegion =
speedRegions.find(
(region) =>
currentTime * 1000 >= region.startMs && currentTime * 1000 < region.endMs,
(region) => currentTime * 1000 >= region.startMs && currentTime * 1000 < region.endMs,
) ?? null;
webcamVideo.playbackRate = activeSpeedRegion ? activeSpeedRegion.speed : 1;
+14 -14
View File
@@ -399,26 +399,26 @@ export function useScreenRecorder(): UseScreenRecorderReturn {
}
}
if (webcamEnabled) {
try {
webcamStream.current = await navigator.mediaDevices.getUserMedia({
audio: false,
video: {
if (webcamEnabled) {
try {
webcamStream.current = await navigator.mediaDevices.getUserMedia({
audio: false,
video: {
width: { ideal: WEBCAM_TARGET_WIDTH },
height: { ideal: WEBCAM_TARGET_HEIGHT },
frameRate: { ideal: WEBCAM_TARGET_FRAME_RATE, max: WEBCAM_TARGET_FRAME_RATE },
},
});
} catch (cameraError) {
console.warn("Failed to get webcam access:", cameraError);
if (webcamStream.current) {
webcamStream.current.getTracks().forEach((track) => track.stop());
webcamStream.current = null;
}
setWebcamEnabledState(false);
toast.error("Camera access denied. Recording will continue without webcam.");
});
} catch (cameraError) {
console.warn("Failed to get webcam access:", cameraError);
if (webcamStream.current) {
webcamStream.current.getTracks().forEach((track) => track.stop());
webcamStream.current = null;
}
setWebcamEnabledState(false);
toast.error("Camera access denied. Recording will continue without webcam.");
}
}
stream.current = new MediaStream();
const videoTrack = screenMediaStream.getVideoTracks()[0];
+25 -23
View File
@@ -170,30 +170,32 @@ export class GifExporter {
let webcamDecodeError: Error | null = null;
const webcamDecodePromise =
this.webcamDecoder && webcamFrameQueue
? this.webcamDecoder
.decodeAll(
this.config.frameRate,
this.config.trimRegions,
this.config.speedRegions,
async (webcamFrame) => {
while (webcamFrameQueue.length >= 12 && !this.cancelled) {
await new Promise((resolve) => setTimeout(resolve, 2));
? (() => {
const queue = webcamFrameQueue;
return this.webcamDecoder
.decodeAll(
this.config.frameRate,
this.config.trimRegions,
this.config.speedRegions,
async (webcamFrame) => {
while (queue.length >= 12 && !this.cancelled) {
await new Promise((resolve) => setTimeout(resolve, 2));
}
queue.enqueue(webcamFrame);
},
)
.catch((error) => {
webcamDecodeError = error instanceof Error ? error : new Error(String(error));
throw error;
})
.finally(() => {
if (webcamDecodeError) {
queue.fail(webcamDecodeError);
} else {
queue.close();
}
webcamFrameQueue.enqueue(webcamFrame);
},
)
.catch((error) => {
webcamDecodeError =
error instanceof Error ? error : new Error(String(error));
throw error;
})
.finally(() => {
if (webcamDecodeError) {
webcamFrameQueue.fail(webcamDecodeError);
} else {
webcamFrameQueue.close();
}
})
});
})()
: null;
// Stream decode and process frames — no seeking!
+25 -23
View File
@@ -121,30 +121,32 @@ export class VideoExporter {
let webcamDecodeError: Error | null = null;
const webcamDecodePromise =
this.webcamDecoder && webcamFrameQueue
? this.webcamDecoder
.decodeAll(
this.config.frameRate,
this.config.trimRegions,
this.config.speedRegions,
async (webcamFrame) => {
while (webcamFrameQueue.length >= 12 && !this.cancelled) {
await new Promise((resolve) => setTimeout(resolve, 2));
? (() => {
const queue = webcamFrameQueue;
return this.webcamDecoder
.decodeAll(
this.config.frameRate,
this.config.trimRegions,
this.config.speedRegions,
async (webcamFrame) => {
while (queue.length >= 12 && !this.cancelled) {
await new Promise((resolve) => setTimeout(resolve, 2));
}
queue.enqueue(webcamFrame);
},
)
.catch((error) => {
webcamDecodeError = error instanceof Error ? error : new Error(String(error));
throw error;
})
.finally(() => {
if (webcamDecodeError) {
queue.fail(webcamDecodeError);
} else {
queue.close();
}
webcamFrameQueue.enqueue(webcamFrame);
},
)
.catch((error) => {
webcamDecodeError =
error instanceof Error ? error : new Error(String(error));
throw error;
})
.finally(() => {
if (webcamDecodeError) {
webcamFrameQueue.fail(webcamDecodeError);
} else {
webcamFrameQueue.close();
}
})
});
})()
: null;
// Stream decode and process frames — no seeking!
+1 -1
View File
@@ -28,6 +28,6 @@ describe("computeWebcamOverlayLayout", () => {
expect(layout).not.toBeNull();
expect(layout!.width).toBeLessThanOrEqual(Math.round(1280 * 0.18) + 1);
expect(layout!.height).toBeLessThanOrEqual(Math.round(720 * 0.18) + 1);
expect(layout!.width / layout!.height).toBeCloseTo(1920 / 1080, 2);
expect(Math.abs(layout!.width * 1080 - layout!.height * 1920)).toBeLessThanOrEqual(1920);
});
});