Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/components/video-editor/projectPersistence.ts
Original file line number Diff line number Diff line change
Expand Up @@ -825,6 +825,11 @@ export function normalizeProjectEditor(editor: Partial<ProjectEditorState>): Pro
)
? (webcam as Partial<{ zoomScaleEffect: number }>).zoomScaleEffect
: null;
const normalizedWebcamSize = isFiniteNumber(webcam.width)
? clamp(webcam.width, 10, 100)
: isFiniteNumber(webcam.size)
? clamp(webcam.size, 10, 100)
: DEFAULT_WEBCAM_SIZE;
const normalizedCursorStyle =
typeof editor.cursorStyle === "string" && editor.cursorStyle.trim().length > 0
? editor.cursorStyle === "mono"
Expand Down Expand Up @@ -1031,7 +1036,7 @@ export function normalizeProjectEditor(editor: Partial<ProjectEditorState>): Pro
webcam.corner === "bottom-right"
? webcam.corner
: DEFAULT_WEBCAM_OVERLAY.corner,
size: isFiniteNumber(webcam.size) ? clamp(webcam.size, 10, 100) : DEFAULT_WEBCAM_SIZE,
size: normalizedWebcamSize,
width: isFiniteNumber(webcam.width)
? clamp(webcam.width, 10, 100)
: isFiniteNumber(webcam.size)
Expand Down
5 changes: 3 additions & 2 deletions src/lib/exporter/frameRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import type {
import {
BASE_PREVIEW_HEIGHT,
BASE_PREVIEW_WIDTH,
DEFAULT_WEBCAM_SIZE,
ZOOM_DEPTH_SCALES,
} from "@/components/video-editor/types";
import { DEFAULT_FOCUS } from "@/components/video-editor/videoPlayback/constants";
Expand Down Expand Up @@ -2459,10 +2460,10 @@ export class FrameRenderer {
? webcamFrameSource.videoHeight
: webcamFrameSource.height) || sourceWidth;
const margin = webcam.margin ?? 24;
const widthPercent = webcam.width ?? webcam.size ?? 50;
const widthPercent = webcam.width ?? webcam.size ?? DEFAULT_WEBCAM_SIZE;
const heightPercent = getCropMatchedWebcamHeightPercent(
widthPercent,
webcam.height ?? webcam.size ?? 50,
webcam.height ?? webcam.size ?? DEFAULT_WEBCAM_SIZE,
sourceWidth,
sourceHeight,
webcam.cropRegion,
Expand Down
26 changes: 18 additions & 8 deletions src/lib/exporter/modernFrameRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,11 @@ import type {
ZoomRegion,
ZoomTransitionEasing,
} from "@/components/video-editor/types";
import { getDefaultCaptionFontFamily, ZOOM_DEPTH_SCALES } from "@/components/video-editor/types";
import {
DEFAULT_WEBCAM_SIZE,
getDefaultCaptionFontFamily,
ZOOM_DEPTH_SCALES,
} from "@/components/video-editor/types";
import { DEFAULT_FOCUS } from "@/components/video-editor/videoPlayback/constants";
import {
type CursorFollowCameraState,
Expand Down Expand Up @@ -2916,21 +2920,27 @@ export class FrameRenderer {
}

const margin = webcam.margin ?? 24;
const widthPercent = webcam.width ?? webcam.size ?? 50;
const aspectSourceWidth =
const widthPercent = webcam.width ?? webcam.size ?? DEFAULT_WEBCAM_SIZE;
const cropMatchSourceWidth =
liveSourceDimensions.width > 0
? liveSourceDimensions.width
: renderableWebcamSource.width;
const aspectSourceHeight =
const cropMatchSourceHeight =
liveSourceDimensions.height > 0
? liveSourceDimensions.height
: renderableWebcamSource.height;
const cropMatchRegion =
liveSourceDimensions.width > 0 && liveSourceDimensions.height > 0
? webcam.cropRegion
: isWebcamCropRegionDefault(webcam.cropRegion)
? webcam.cropRegion
: null;
const heightPercent = getCropMatchedWebcamHeightPercent(
widthPercent,
webcam.height ?? webcam.size ?? 50,
aspectSourceWidth,
aspectSourceHeight,
webcam.cropRegion,
webcam.height ?? webcam.size ?? DEFAULT_WEBCAM_SIZE,
cropMatchSourceWidth,
cropMatchSourceHeight,
cropMatchRegion,
);
Comment thread
coderabbitai[bot] marked this conversation as resolved.
const dimensions = getWebcamOverlayDimensionsPx({
containerWidth: this.config.width,
Expand Down
23 changes: 23 additions & 0 deletions src/lib/exporter/modernVideoExporter.nativeStaticLayout.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -739,6 +739,29 @@ describe("ModernVideoExporter native static-layout eligibility", () => {
).toBe("unsupported-rectangular-webcam-overlay");
});

it("skips native static layout for non-finite webcam dimensions", () => {
const exporter = createExporter({
webcam: {
enabled: true,
sourcePath: "C:\\recordly\\webcam.mp4",
size: Number.NaN,
width: Number.NaN,
height: 40,
},
});

expect(
exporter.getNativeStaticLayoutSkipReason(
{
audioMode: "edited-track",
strategy: "offline-render-fallback",
},
videoInfo,
60,
),
).toBe("unsupported-rectangular-webcam-overlay");
});

it("allows native speed timelines with a resolvable webcam source", () => {
const speedRegions: SpeedRegion[] = [
{ id: "speed-1", startMs: 1_000, endMs: 4_000, speed: 1.5 },
Expand Down
15 changes: 12 additions & 3 deletions src/lib/exporter/modernVideoExporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import type {
ZoomRegion,
ZoomTransitionEasing,
} from "@/components/video-editor/types";
import { ZOOM_DEPTH_SCALES } from "@/components/video-editor/types";
import { DEFAULT_WEBCAM_SIZE, ZOOM_DEPTH_SCALES } from "@/components/video-editor/types";
import { DEFAULT_FOCUS } from "@/components/video-editor/videoPlayback/constants";
import {
computeCursorFollowFocus,
Expand Down Expand Up @@ -1502,8 +1502,17 @@ export class ModernVideoExporter {
return false;
}

const width = webcam.width ?? webcam.size ?? 40;
const height = webcam.height ?? webcam.size ?? 40;
if (
(webcam.size != null && !Number.isFinite(webcam.size)) ||
(webcam.width != null && !Number.isFinite(webcam.width)) ||
(webcam.height != null && !Number.isFinite(webcam.height))
) {
return true;
}

const fallbackSize = Number.isFinite(webcam.size) ? webcam.size : DEFAULT_WEBCAM_SIZE;
const width = Number.isFinite(webcam.width) ? webcam.width : fallbackSize;
const height = Number.isFinite(webcam.height) ? webcam.height : fallbackSize;
return Math.abs(width - height) > 0.001 || !isWebcamCropRegionDefault(webcam.cropRegion);
}

Expand Down