diff --git a/src/components/video-editor/VideoEditor.tsx b/src/components/video-editor/VideoEditor.tsx index 2ccd6eb..d6b363d 100644 --- a/src/components/video-editor/VideoEditor.tsx +++ b/src/components/video-editor/VideoEditor.tsx @@ -1530,18 +1530,19 @@ export default function VideoEditor() { let bitrate: number; if (quality === "source") { - // Use source resolution exportWidth = sourceWidth; exportHeight = sourceHeight; + // Use the source's longer dimension as the long axis of the export so + // a landscape recording can still fill a portrait target (and vice versa). + const sourceLongDim = Math.max(sourceWidth, sourceHeight); + if (aspectRatioValue === 1) { - // Square (1:1): use smaller dimension to avoid codec limits const baseDimension = Math.floor(Math.min(sourceWidth, sourceHeight) / 2) * 2; exportWidth = baseDimension; exportHeight = baseDimension; } else if (aspectRatioValue > 1) { - // Landscape: find largest even dimensions that exactly match aspect ratio - const baseWidth = Math.floor(sourceWidth / 2) * 2; + const baseWidth = Math.floor(sourceLongDim / 2) * 2; let found = false; for (let w = baseWidth; w >= 100 && !found; w -= 2) { const h = Math.round(w / aspectRatioValue); @@ -1556,8 +1557,7 @@ export default function VideoEditor() { exportHeight = Math.floor(baseWidth / aspectRatioValue / 2) * 2; } } else { - // Portrait: find largest even dimensions that exactly match aspect ratio - const baseHeight = Math.floor(sourceHeight / 2) * 2; + const baseHeight = Math.floor(sourceLongDim / 2) * 2; let found = false; for (let h = baseHeight; h >= 100 && !found; h -= 2) { const w = Math.round(h * aspectRatioValue); @@ -1573,7 +1573,6 @@ export default function VideoEditor() { } } - // Calculate visually lossless bitrate matching screen recording optimization const totalPixels = exportWidth * exportHeight; bitrate = 30_000_000; if (totalPixels > 1920 * 1080 && totalPixels <= 2560 * 1440) { @@ -1582,14 +1581,18 @@ export default function VideoEditor() { bitrate = 80_000_000; } } else { - // Use quality-based target resolution - const targetHeight = quality === "medium" ? 720 : 1080; + // Quality presets target the SHORT side; the long side derives from the + // aspect ratio. This keeps 1080p portrait at 1080×1920 instead of 607×1080. + const targetShortDim = quality === "medium" ? 720 : 1080; - // Calculate dimensions maintaining aspect ratio - exportHeight = Math.floor(targetHeight / 2) * 2; - exportWidth = Math.floor((exportHeight * aspectRatioValue) / 2) * 2; + if (aspectRatioValue >= 1) { + exportHeight = Math.floor(targetShortDim / 2) * 2; + exportWidth = Math.floor((exportHeight * aspectRatioValue) / 2) * 2; + } else { + exportWidth = Math.floor(targetShortDim / 2) * 2; + exportHeight = Math.floor(exportWidth / aspectRatioValue / 2) * 2; + } - // Adjust bitrate for lower resolutions const totalPixels = exportWidth * exportHeight; if (totalPixels <= 1280 * 720) { bitrate = 10_000_000;