diff --git a/src/components/video-editor/SettingsPanel.tsx b/src/components/video-editor/SettingsPanel.tsx index 5d016b238..aa7d2bfd0 100644 --- a/src/components/video-editor/SettingsPanel.tsx +++ b/src/components/video-editor/SettingsPanel.tsx @@ -12,6 +12,7 @@ import { } from "@/components/ui/select"; import { Switch } from "@/components/ui/switch"; import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"; +import { useTheme } from "@/contexts/ThemeContext"; import { getAssetPath, getRenderableAssetUrl, getWallpaperThumbnailUrl } from "@/lib/assetPath"; import type { ExtensionSettingField } from "@/lib/extensions"; import { extensionHost, type FrameInstance } from "@/lib/extensions"; @@ -27,7 +28,6 @@ import minimalCursorUrl from "../../../Minimal Cursor.svg"; import { useI18n, useScopedT } from "../../contexts/I18nContext"; import type { AppLocale } from "../../i18n/config"; import { SUPPORTED_LOCALES } from "../../i18n/config"; -import { useTheme } from "@/contexts/ThemeContext"; import { AnnotationSettingsPanel } from "./AnnotationSettingsPanel"; import { loadEditorPreferences, saveEditorPreferences } from "./editorPreferences"; import { SliderControl } from "./SliderControl"; @@ -50,9 +50,6 @@ import type { ZoomMode, ZoomTransitionEasing, } from "./types"; -import { - isZeroPadding, -} from "./videoPlayback/layoutUtils"; import { DEFAULT_AUTO_CAPTION_SETTINGS, DEFAULT_CROP_REGION, @@ -76,6 +73,7 @@ import { SPEED_OPTIONS, } from "./types"; import { fromCursorSwaySliderValue, toCursorSwaySliderValue } from "./videoPlayback/cursorSway"; +import { isZeroPadding } from "./videoPlayback/layoutUtils"; import { cursorSetAssets, getCursorStyleSizeMultiplier, @@ -348,6 +346,10 @@ interface SettingsPanelProps { onClipSpeedChange?: (speed: number) => void; onClipMutedChange?: (muted: boolean) => void; onClipDelete?: (id: string) => void; + selectedAudioId?: string | null; + selectedAudioVolume?: number | null; + onAudioVolumeChange?: (volume: number) => void; + onAudioDelete?: (id: string) => void; shadowIntensity?: number; onShadowChange?: (intensity: number) => void; backgroundBlur?: number; @@ -721,6 +723,10 @@ export function SettingsPanel({ onClipSpeedChange, onClipMutedChange, onClipDelete, + selectedAudioId, + selectedAudioVolume, + onAudioVolumeChange, + onAudioDelete, shadowIntensity = 0.67, onShadowChange, backgroundBlur = 0, @@ -3031,7 +3037,7 @@ export function SettingsPanel({
{selectedTrimId && ( @@ -3094,6 +3100,39 @@ export function SettingsPanel({
)} + + {selectedAudioId && ( +
+
+ + {tSettings("audio.volumeTitle", "Audio Volume")} + + + {Math.round((selectedAudioVolume ?? 1) * 100)}% + +
+ onAudioVolumeChange?.(v)} + formatValue={(v) => `${Math.round(v * 100)}%`} + parseInput={(text) => parseFloat(text.replace(/%$/, "")) / 100} + /> + +
+ )} ); diff --git a/src/components/video-editor/VideoEditor.tsx b/src/components/video-editor/VideoEditor.tsx index bc2c01ef0..580627ac4 100644 --- a/src/components/video-editor/VideoEditor.tsx +++ b/src/components/video-editor/VideoEditor.tsx @@ -3257,6 +3257,23 @@ export default function VideoEditor() { ); }, []); + const handleAudioVolumeChange = useCallback((volume: number) => { + if (!selectedAudioId) { + return; + } + + if (!Number.isFinite(volume)) { + return; + } + + const nextVolume = Math.max(0, Math.min(1, volume)); + setAudioRegions((prev) => + prev.map((region) => + region.id === selectedAudioId ? { ...region, volume: nextVolume } : region, + ), + ); + }, [selectedAudioId]); + const handleAudioDelete = useCallback( (id: string) => { setAudioRegions((prev) => prev.filter((region) => region.id !== id)); @@ -4396,6 +4413,8 @@ export default function VideoEditor() { effectiveSpeedRegions, frame, smokeExportConfig.encodingMode, + smokeExportConfig.fps, + smokeExportConfig.quality, ], ); @@ -5188,6 +5207,15 @@ export default function VideoEditor() { selectedClipId && handleClipMutedChange(muted) } onClipDelete={handleClipDelete} + selectedAudioId={selectedAudioId} + selectedAudioVolume={ + selectedAudioId + ? (audioRegions.find((r) => r.id === selectedAudioId) + ?.volume ?? null) + : null + } + onAudioVolumeChange={handleAudioVolumeChange} + onAudioDelete={handleAudioDelete} shadowIntensity={shadowIntensity} onShadowChange={setShadowIntensity} backgroundBlur={backgroundBlur} diff --git a/src/components/video-editor/timeline/Row.tsx b/src/components/video-editor/timeline/Row.tsx index f2aba7238..f54e5a9cb 100644 --- a/src/components/video-editor/timeline/Row.tsx +++ b/src/components/video-editor/timeline/Row.tsx @@ -30,7 +30,11 @@ export default function Row({ id, children, label, hint, isEmpty, labelColor = " {hint} )} -
+
{children}