diff --git a/src/components/video-editor/SettingsPanel.tsx b/src/components/video-editor/SettingsPanel.tsx index 1cbf39b7..c0498cdc 100644 --- a/src/components/video-editor/SettingsPanel.tsx +++ b/src/components/video-editor/SettingsPanel.tsx @@ -813,7 +813,7 @@ export function SettingsPanel({ {exportFormat === 'mp4' && ( -
+
+
)} diff --git a/src/components/video-editor/VideoEditor.tsx b/src/components/video-editor/VideoEditor.tsx index 97c3a3bf..e61af90d 100644 --- a/src/components/video-editor/VideoEditor.tsx +++ b/src/components/video-editor/VideoEditor.tsx @@ -1525,12 +1525,21 @@ export default function VideoEditor() { bitrate = 80_000_000; } } else { - // Use quality-based target resolution - const targetHeight = quality === 'medium' ? 720 : 1080; + // Use source-relative quality scaling. + // "source" is handled above; this branch maps the remaining tiers. + const qualityScale = + quality === 'medium' ? 0.6 : quality === 'good' ? 0.75 : 0.9; + const maxWidth = Math.max(2, Math.floor((sourceWidth * qualityScale) / 2) * 2); + const maxHeight = Math.max(2, Math.floor((sourceHeight * qualityScale) / 2) * 2); + const maxAspect = maxWidth / maxHeight; - // Calculate dimensions maintaining aspect ratio - exportHeight = Math.floor(targetHeight / 2) * 2; - exportWidth = Math.floor((exportHeight * aspectRatioValue) / 2) * 2; + if (aspectRatioValue >= maxAspect) { + exportWidth = maxWidth; + exportHeight = Math.max(2, Math.floor((exportWidth / aspectRatioValue) / 2) * 2); + } else { + exportHeight = maxHeight; + exportWidth = Math.max(2, Math.floor((exportHeight * aspectRatioValue) / 2) * 2); + } // Adjust bitrate for lower resolutions const totalPixels = exportWidth * exportHeight; diff --git a/src/components/video-editor/projectPersistence.ts b/src/components/video-editor/projectPersistence.ts index 0985fc72..af4e1aff 100644 --- a/src/components/video-editor/projectPersistence.ts +++ b/src/components/video-editor/projectPersistence.ts @@ -358,7 +358,13 @@ export function normalizeProjectEditor(editor: Partial): Pro (validAspectRatios.has(editor.aspectRatio as AspectRatio) || isCustomAspectRatio(editor.aspectRatio)) ? (editor.aspectRatio as AspectRatio) : "16:9", - exportQuality: editor.exportQuality === "medium" || editor.exportQuality === "source" ? editor.exportQuality : "good", + exportQuality: + editor.exportQuality === "medium" || + editor.exportQuality === "good" || + editor.exportQuality === "high" || + editor.exportQuality === "source" + ? editor.exportQuality + : "good", exportFormat: editor.exportFormat === "gif" ? "gif" : "mp4", gifFrameRate: editor.gifFrameRate === 15 || diff --git a/src/i18n/locales/en/settings.json b/src/i18n/locales/en/settings.json index 2405ce5f..2ffb67f0 100644 --- a/src/i18n/locales/en/settings.json +++ b/src/i18n/locales/en/settings.json @@ -47,7 +47,8 @@ "quality": { "low": "Low", "medium": "Medium", - "high": "High" + "high": "High", + "original": "Original" }, "loop": "Loop", "outputDimensions": "Output: {{dimensions}}px", diff --git a/src/i18n/locales/es/settings.json b/src/i18n/locales/es/settings.json index 7b3a1379..335bb00d 100644 --- a/src/i18n/locales/es/settings.json +++ b/src/i18n/locales/es/settings.json @@ -47,7 +47,8 @@ "quality": { "low": "Baja", "medium": "Media", - "high": "Alta" + "high": "Alta", + "original": "Original" }, "loop": "Bucle", "outputDimensions": "Salida: {{dimensions}}px", diff --git a/src/i18n/locales/zh-CN/settings.json b/src/i18n/locales/zh-CN/settings.json index 46106e60..5e2ef5bb 100644 --- a/src/i18n/locales/zh-CN/settings.json +++ b/src/i18n/locales/zh-CN/settings.json @@ -47,7 +47,8 @@ "quality": { "low": "低", "medium": "中", - "high": "高" + "high": "高", + "original": "原始" }, "loop": "循环", "outputDimensions": "输出:{{dimensions}}px", diff --git a/src/lib/exporter/types.ts b/src/lib/exporter/types.ts index fa0d4eaa..812d850d 100644 --- a/src/lib/exporter/types.ts +++ b/src/lib/exporter/types.ts @@ -27,7 +27,7 @@ export interface VideoFrameData { duration: number; // in microseconds } -export type ExportQuality = 'medium' | 'good' | 'source'; +export type ExportQuality = 'medium' | 'good' | 'high' | 'source'; // GIF Export Types export type ExportFormat = 'mp4' | 'gif';