11import type { ExportFormat , ExportQuality , GifFrameRate , GifSizePreset } from "@/lib/exporter" ;
22import type { ProjectMedia } from "@/lib/recordingSession" ;
33import { normalizeProjectMedia } from "@/lib/recordingSession" ;
4- import { ASPECT_RATIOS , type AspectRatio } from "@/utils/aspectRatioUtils" ;
4+ import { ASPECT_RATIOS , type AspectRatio , isPortraitAspectRatio } from "@/utils/aspectRatioUtils" ;
55import {
66 type AnnotationRegion ,
77 type CropRegion ,
@@ -78,6 +78,26 @@ function isFiniteNumber(value: unknown): value is number {
7878 return typeof value === "number" && Number . isFinite ( value ) ;
7979}
8080
81+ function computeNormalizedWebcamLayoutPreset (
82+ webcamLayoutPreset : Partial < ProjectEditorState > [ "webcamLayoutPreset" ] ,
83+ normalizedAspectRatio : AspectRatio ,
84+ ) : WebcamLayoutPreset {
85+ switch ( webcamLayoutPreset ) {
86+ case "picture-in-picture" :
87+ return webcamLayoutPreset ;
88+ case "vertical-stack" :
89+ return isPortraitAspectRatio ( normalizedAspectRatio )
90+ ? webcamLayoutPreset
91+ : DEFAULT_WEBCAM_LAYOUT_PRESET ;
92+ case "dual-frame" :
93+ return isPortraitAspectRatio ( normalizedAspectRatio )
94+ ? DEFAULT_WEBCAM_LAYOUT_PRESET
95+ : webcamLayoutPreset ;
96+ default :
97+ return DEFAULT_WEBCAM_LAYOUT_PRESET ;
98+ }
99+ }
100+
81101function clamp ( value : number , min : number , max : number ) {
82102 return Math . min ( max , Math . max ( min , value ) ) ;
83103}
@@ -185,6 +205,26 @@ export function resolveProjectMedia(
185205
186206export function normalizeProjectEditor ( editor : Partial < ProjectEditorState > ) : ProjectEditorState {
187207 const validAspectRatios = new Set < AspectRatio > ( ASPECT_RATIOS ) ;
208+ const normalizedAspectRatio : AspectRatio = validAspectRatios . has (
209+ editor . aspectRatio as AspectRatio ,
210+ )
211+ ? ( editor . aspectRatio as AspectRatio )
212+ : "16:9" ;
213+ const normalizedWebcamLayoutPreset = computeNormalizedWebcamLayoutPreset (
214+ editor . webcamLayoutPreset ,
215+ normalizedAspectRatio ,
216+ ) ;
217+ const normalizedWebcamPosition : WebcamPosition | null =
218+ normalizedWebcamLayoutPreset === "picture-in-picture" &&
219+ editor . webcamPosition &&
220+ typeof editor . webcamPosition === "object" &&
221+ isFiniteNumber ( ( editor . webcamPosition as WebcamPosition ) . cx ) &&
222+ isFiniteNumber ( ( editor . webcamPosition as WebcamPosition ) . cy )
223+ ? {
224+ cx : clamp ( ( editor . webcamPosition as WebcamPosition ) . cx , 0 , 1 ) ,
225+ cy : clamp ( ( editor . webcamPosition as WebcamPosition ) . cy , 0 , 1 ) ,
226+ }
227+ : DEFAULT_WEBCAM_POSITION ;
188228
189229 const normalizedZoomRegions : ZoomRegion [ ] = Array . isArray ( editor . zoomRegions )
190230 ? editor . zoomRegions
@@ -396,13 +436,8 @@ export function normalizeProjectEditor(editor: Partial<ProjectEditorState>): Pro
396436 trimRegions : normalizedTrimRegions ,
397437 speedRegions : normalizedSpeedRegions ,
398438 annotationRegions : normalizedAnnotationRegions ,
399- aspectRatio :
400- editor . aspectRatio && validAspectRatios . has ( editor . aspectRatio ) ? editor . aspectRatio : "16:9" ,
401- webcamLayoutPreset :
402- editor . webcamLayoutPreset === "vertical-stack" ||
403- editor . webcamLayoutPreset === "picture-in-picture"
404- ? editor . webcamLayoutPreset
405- : DEFAULT_WEBCAM_LAYOUT_PRESET ,
439+ aspectRatio : normalizedAspectRatio ,
440+ webcamLayoutPreset : normalizedWebcamLayoutPreset ,
406441 webcamMaskShape :
407442 editor . webcamMaskShape === "rectangle" ||
408443 editor . webcamMaskShape === "circle" ||
@@ -414,16 +449,7 @@ export function normalizeProjectEditor(editor: Partial<ProjectEditorState>): Pro
414449 typeof editor . webcamSizePreset === "number" && isFiniteNumber ( editor . webcamSizePreset )
415450 ? Math . max ( 10 , Math . min ( 50 , editor . webcamSizePreset ) )
416451 : DEFAULT_WEBCAM_SIZE_PRESET ,
417- webcamPosition :
418- editor . webcamPosition &&
419- typeof editor . webcamPosition === "object" &&
420- isFiniteNumber ( ( editor . webcamPosition as WebcamPosition ) . cx ) &&
421- isFiniteNumber ( ( editor . webcamPosition as WebcamPosition ) . cy )
422- ? {
423- cx : clamp ( ( editor . webcamPosition as WebcamPosition ) . cx , 0 , 1 ) ,
424- cy : clamp ( ( editor . webcamPosition as WebcamPosition ) . cy , 0 , 1 ) ,
425- }
426- : DEFAULT_WEBCAM_POSITION ,
452+ webcamPosition : normalizedWebcamPosition ,
427453 exportQuality :
428454 editor . exportQuality === "medium" || editor . exportQuality === "source"
429455 ? editor . exportQuality
0 commit comments