fix: address native capture review feedback

This commit is contained in:
EtienneLescot
2026-05-05 20:57:52 +02:00
parent c7b43a50ef
commit ab3d38d90f
16 changed files with 260 additions and 27 deletions
+5 -1
View File
@@ -302,7 +302,11 @@ export function LaunchWindow() {
}
if (result.success && result.path) {
await nativeBridgeClient.project.setCurrentVideoPath(result.path);
const setVideoPathResult = await nativeBridgeClient.project.setCurrentVideoPath(result.path);
if (!setVideoPathResult.success) {
console.error("Failed to set current video path:", setVideoPathResult);
return;
}
await window.electronAPI.switchToEditor();
}
};
@@ -119,12 +119,33 @@ function clamp(value: number, min: number, max: number) {
return Math.min(max, Math.max(min, value));
}
function encodePathSegments(pathname: string, keepWindowsDrive = false): string {
return pathname
.split("/")
.map((segment, index) => {
if (!segment) {
return segment;
}
if (keepWindowsDrive && index === 0 && /^[a-zA-Z]:$/.test(segment)) {
return segment;
}
return encodeURIComponent(segment);
})
.join("/");
}
export function toFileUrl(filePath: string): string {
const normalized = filePath.replace(/\\/g, "/");
if (normalized.match(/^[a-zA-Z]:/)) {
return `file:///${encodeURI(normalized)}`;
return `file:///${encodePathSegments(normalized, true)}`;
}
return `file://${encodeURI(normalized)}`;
if (normalized.startsWith("//")) {
const withoutPrefix = normalized.slice(2);
const [host = "", ...segments] = withoutPrefix.split("/");
return `file://${host}/${encodePathSegments(segments.join("/"))}`;
}
const absolutePath = normalized.startsWith("/") ? normalized : `/${normalized}`;
return `file://${encodePathSegments(absolutePath)}`;
}
export function fromFileUrl(fileUrl: string): string {
@@ -721,6 +721,8 @@ export class PixiCursorOverlay {
}
this.cursorMotionBlurFilter.destroy();
this.container.destroy({ children: true });
cursorAssetsPromise = null;
loadedCursorAssets = {};
}
}
+2 -2
View File
@@ -644,7 +644,7 @@ export function useScreenRecorder(): UseScreenRecorderReturn {
finalizing: false,
};
accumulatedDurationMs.current = 0;
segmentStartedAt.current = result.recordingId;
segmentStartedAt.current = Date.now();
allowAutoFinalize.current = true;
setRecording(true);
setPaused(false);
@@ -918,7 +918,7 @@ export function useScreenRecorder(): UseScreenRecorderReturn {
}
accumulatedDurationMs.current = 0;
segmentStartedAt.current = activeRecordingId;
segmentStartedAt.current = Date.now();
allowAutoFinalize.current = true;
setRecording(true);
setPaused(false);
+16 -1
View File
@@ -145,6 +145,7 @@ export class FrameRenderer {
private threeDPass: ThreeDPass | null = null;
private currentRotation3D: Rotation3D = { ...DEFAULT_ROTATION_3D };
private cursorImageCache = new Map<string, HTMLImageElement>();
private warnedKeys = new Set<string>();
private config: FrameRenderConfig;
private animationState: AnimationState;
private layoutCache: LayoutCache | null = null;
@@ -585,7 +586,13 @@ export class FrameRenderer {
1,
activeNativeCursor.sample,
);
const image = await this.getCursorImage(renderAsset);
let image: HTMLImageElement;
try {
image = await this.getCursorImage(renderAsset);
} catch (error) {
this.warnOnce("native-cursor-image-load", "Failed to load native cursor asset", error);
return;
}
const scale = Math.max(0, this.config.cursorScale ?? 1);
const appliedScale = this.animationState.appliedScale;
const canvasX = projectedPoint.x * appliedScale + this.animationState.x;
@@ -616,6 +623,14 @@ export class FrameRenderer {
return image;
}
private warnOnce(key: string, message: string, error: unknown) {
if (this.warnedKeys.has(key)) {
return;
}
this.warnedKeys.add(key);
console.warn(`[FrameRenderer] ${message}:`, error);
}
private updateLayout(webcamFrame?: VideoFrame | null): void {
if (!this.app || !this.videoSprite || !this.maskGraphics || !this.videoContainer) return;