fix: audioRegions are now allowed (reloading a project with a user audio would not work.

This commit is contained in:
Alan Trebugeais
2026-05-09 19:24:07 +02:00
parent 4d5a7ceb6d
commit ef993a09d0
13 changed files with 64 additions and 36 deletions
+8
View File
@@ -428,6 +428,7 @@ export async function loadProjectFromPath(projectPath: string) {
const projectObj = project as Record<string, unknown>;
const editorObj = projectObj?.editor as Record<string, unknown> | undefined;
const audioTracks = editorObj?.audioTracks as { sourcePath?: unknown }[] | undefined;
const audioRegions = editorObj?.audioRegions as { audioPath?: unknown }[] | undefined;
const approvedProjectPaths: Array<string | null | undefined> = [
mediaSources.videoPath,
mediaSources.webcamPath,
@@ -439,6 +440,13 @@ export async function loadProjectFromPath(projectPath: string) {
}
}
}
if (Array.isArray(audioRegions)) {
for (const region of audioRegions) {
if (typeof region?.audioPath === "string") {
approvedProjectPaths.push(region.audioPath);
}
}
}
await replaceApprovedSessionLocalReadPaths(approvedProjectPaths);
await rememberRecentProject(normalizedPath);
+1 -1
View File
@@ -149,6 +149,7 @@ import {
} from "./TutorialHelp";
import TimelineEditor, { type TimelineEditorHandle } from "./timeline/TimelineEditor";
import { normalizeCursorTelemetry } from "./timeline/zoomSuggestionUtils";
import type { SourceAudioTrackSettings } from "@/components/video-editor/audio/audioTypes";
import {
type AnnotationRegion,
type AudioRegion,
@@ -197,7 +198,6 @@ import {
type ZoomMotionBlurTuning,
type ZoomRegion,
type ZoomTransitionEasing,
type SourceAudioTrackSettings,
} from "./types";
import VideoPlayback, { VideoPlaybackRef } from "./VideoPlayback";
import {
@@ -0,0 +1,25 @@
import type { AudioPeaksData } from "../timeline/core/timelineTypes";
export type SourceAudioTrackId = "mixed" | "system" | "mic" | (string & {});
export interface SourceAudioTrackSetting {
volume: number;
normalize: boolean;
}
export type SourceAudioTrackSettings = Record<string, SourceAudioTrackSetting>;
export interface SourceAudioTrackMetaItem {
id: SourceAudioTrackId;
label: string;
}
export type SourceAudioTrackMeta = SourceAudioTrackMetaItem[];
export interface SourceAudioTrackWithPeaks extends SourceAudioTrackMetaItem {
peaks: AudioPeaksData;
}
export const SOURCE_AUDIO_FALLBACK_TOAST_ID = "source-audio-fallback-error";
export const SOURCE_AUDIO_NORMALIZE_GAIN = 1.35;
@@ -1,5 +0,0 @@
import { getSourceTrackIdFromPath } from "@/lib/exporter/sourceTrackRoutingPolicy";
export const SOURCE_AUDIO_FALLBACK_TOAST_ID = "source-audio-fallback-error";
export const SOURCE_AUDIO_NORMALIZE_GAIN = 1.35;
export { getSourceTrackIdFromPath };
@@ -1,10 +1,10 @@
import React, { useCallback, useMemo } from "react";
import {
SOURCE_AUDIO_NORMALIZE_GAIN,
getSourceTrackIdFromPath,
} from "./sourceAudioTracks";
type SourceAudioTrackSettings,
} from "@/components/video-editor/audio/audioTypes";
import { useSourceAudioTrackSettings } from "./useSourceAudioTrackSettings";
import { SourceAudioTrackSettings } from "../types";
import { getSourceTrackIdFromPath } from "@/lib/exporter/audioRoutingEngine";
interface UseClipAudioSettingsControllerParams {
selectedClipId: string | null;
@@ -1,6 +1,6 @@
import { useEffect, useState } from "react";
import { toast } from "sonner";
import { SOURCE_AUDIO_FALLBACK_TOAST_ID } from "./sourceAudioTracks";
import { SOURCE_AUDIO_FALLBACK_TOAST_ID } from "@/components/video-editor/audio/audioTypes";
interface UseSourceAudioFallbackParams {
currentSourcePath: string | null;
@@ -1,7 +1,8 @@
import React, { useCallback, useMemo, useState } from "react";
import type { SourceAudioTrackSettings } from "../types";
export type SourceAudioTrackMeta = Array<{ id: string; label: string }>;
import type {
SourceAudioTrackMeta,
SourceAudioTrackSettings,
} from "@/components/video-editor/audio/audioTypes";
interface UseSourceAudioTrackSettingsParams {
selectedClipId: string | null;
@@ -3,9 +3,9 @@ import { resolveSourceTrackRoutingPolicy } from "@/lib/exporter/sourceTrackRouti
import type {
AudioRegion,
ClipRegion,
SourceAudioTrackSettings,
SpeedRegion,
} from "../types";
import type { SourceAudioTrackSettings } from "@/components/video-editor/audio/audioTypes";
import { getActiveClipIdAtSourceTime, isClipMutedById } from "./clipAudio";
import { useAudioPreviewSync } from "./useAudioPreviewSync";
import { useClipAudioSettingsController } from "./useClipAudioSettingsController";
@@ -20,6 +20,7 @@ import {
import { DEFAULT_WALLPAPER_PATH } from "@/lib/wallpapers";
import { ASPECT_RATIOS, type AspectRatio, isCustomAspectRatio } from "@/utils/aspectRatioUtils";
import { CURSOR_MOTION_PRESETS, resolveCursorMotionPresetId } from "./cursorMotionPresets";
import type { SourceAudioTrackSettings } from "@/components/video-editor/audio/audioTypes";
import {
type AnnotationRegion,
type AudioRegion,
@@ -62,7 +63,6 @@ import {
DEFAULT_ZOOM_SMOOTHNESS,
getDefaultCaptionFontFamily,
type Padding,
SourceAudioTrackSettings,
type SpeedRegion,
type TrimRegion,
type WebcamOverlaySettings,
@@ -18,6 +18,11 @@ import {
import { formatShortcut } from "@/utils/platformUtils";
import { loadEditorPreferences, saveEditorPreferences } from "../editorPreferences";
import { fromFileUrl } from "../projectPersistence";
import type {
SourceAudioTrackMeta,
SourceAudioTrackSettings,
SourceAudioTrackWithPeaks,
} from "@/components/video-editor/audio/audioTypes";
import type {
AnnotationRegion,
AudioRegion,
@@ -36,7 +41,6 @@ import { useTimelineEditorRuntime } from "./hooks/useTimelineEditorRuntime";
import { useTimelineRange } from "./hooks/useTimelineRange";
import TimelineCanvas from "./components/viewport/TimelineCanvas";
import TimelineToolbar from "./components/toolbar/TimelineToolbar";
import type { AudioPeaksData } from "./core/timelineTypes";
export interface TimelineEditorProps {
videoDuration: number;
@@ -84,11 +88,11 @@ export interface TimelineEditorProps {
hideToolbar?: boolean;
showSourceAudioTrack?: boolean;
onSourceAudioAvailabilityChange?: (available: boolean) => void;
sourceAudioTrackSettings?: Record<string, { volume: number; normalize: boolean }>;
sourceAudioTrackSettings?: SourceAudioTrackSettings;
getSourceAudioTrackSettingsForClip?: (
clipId: string | null,
) => Record<string, { volume: number; normalize: boolean }>;
onSourceAudioTracksMetaChange?: (tracks: Array<{ id: string; label: string }>) => void;
) => SourceAudioTrackSettings;
onSourceAudioTracksMetaChange?: (tracks: SourceAudioTrackMeta) => void;
}
function extractLocalPathFromMediaServerUrl(input: string | null | undefined): string | null {
@@ -288,9 +292,9 @@ const TimelineEditor = forwardRef<TimelineEditorHandle, TimelineEditorProps>(
);
const micSidecarPeaks = useTimelineAudioPeaks(micSidecarPath);
const systemSidecarPeaks = useTimelineAudioPeaks(systemSidecarPath);
const sourceAudioTracks = useMemo<Array<{ id: string; label: string; peaks: AudioPeaksData }>>(() => {
const sourceAudioTracks = useMemo<SourceAudioTrackWithPeaks[]>(() => {
if (systemSidecarPeaks || micSidecarPeaks) {
const tracks: Array<{ id: string; label: string; peaks: AudioPeaksData }> = [];
const tracks: SourceAudioTrackWithPeaks[] = [];
if (systemSidecarPeaks)
tracks.push({
id: "system",
@@ -11,6 +11,10 @@ import {
type MouseEventHandler,
} from "react";
import { cn } from "@/lib/utils";
import type {
SourceAudioTrackSettings,
SourceAudioTrackWithPeaks,
} from "@/components/video-editor/audio/audioTypes";
import {
getTimelineContentMinHeightPx,
getTimelineRowsMinHeightPx,
@@ -21,7 +25,7 @@ import glassStyles from "../../ItemGlass.module.css";
import Item from "../../Item";
import Row from "../../Row";
import { CLIP_ROW_ID, SOURCE_AUDIO_ROW_ID, ZOOM_ROW_ID } from "../../core/constants";
import type { AudioPeaksData, TimelineRenderItem } from "../../core/timelineTypes";
import type { TimelineRenderItem } from "../../core/timelineTypes";
import {
getAnnotationTrackIndex,
getAnnotationTrackRowId,
@@ -57,10 +61,10 @@ interface TimelineCanvasProps {
selectAllBlocksActive?: boolean;
onClearBlockSelection?: () => void;
keyframes?: { id: string; time: number }[];
sourceAudioTracks?: Array<{ id: string; label: string; peaks: AudioPeaksData }>;
sourceAudioTracks?: SourceAudioTrackWithPeaks[];
getSourceAudioTrackSettingsForClip?: (
clipId: string | null,
) => Record<string, { volume: number; normalize: boolean }>;
) => SourceAudioTrackSettings;
showSourceAudioTrack?: boolean;
liveSpanPreviewById?: Record<string, { start: number; end: number }>;
liveHiddenItemIds?: string[];
@@ -224,10 +228,10 @@ interface TimelineCanvasRowsProps {
onSelectClip?: (id: string | null) => void;
onSelectAnnotation?: (id: string | null) => void;
onSelectAudio?: (id: string | null) => void;
sourceAudioTracks?: Array<{ id: string; label: string; peaks: AudioPeaksData }>;
sourceAudioTracks?: SourceAudioTrackWithPeaks[];
getSourceAudioTrackSettingsForClip?: (
clipId: string | null,
) => Record<string, { volume: number; normalize: boolean }>;
) => SourceAudioTrackSettings;
showSourceAudioTrack?: boolean;
liveSpanPreviewById?: Record<string, { start: number; end: number }>;
liveHiddenItemIds?: string[];
+1 -7
View File
@@ -466,13 +466,7 @@ export const DEFAULT_PADDING: Padding = {
right: 20,
linked: true,
};
export interface SourceAudioTrackSetting {
volume: number;
normalize: boolean;
}
export type SourceAudioTrackSettings = Record<string, SourceAudioTrackSetting>;
export type { SourceAudioTrackSetting, SourceAudioTrackSettings } from "@/components/video-editor/audio/audioTypes";
export interface AudioRegion {
id: string;
@@ -1,11 +1,8 @@
import {
buildResolvedAudioPlan,
getSourceTrackIdFromPath,
type SourceTrackId,
} from "./audioRoutingEngine";
export { getSourceTrackIdFromPath, type SourceTrackId };
export interface SourceTrackRoutingPolicy {
hasEmbeddedSourceAudio: boolean;
pathsByTrack: Partial<Record<SourceTrackId, string>>;