fix: restore passing checks for webcam overlay changes
This commit is contained in:
@@ -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;
|
||||
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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!
|
||||
|
||||
@@ -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!
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user