From f1d5932c54178c4f8eac61d3d3e0e4a30101780f Mon Sep 17 00:00:00 2001 From: Maze Winther Date: Tue, 31 Mar 2026 23:23:36 +0200 Subject: feat: separate audio from elements --- .../editor/panels/timeline/timeline-element.tsx | 35 ++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'apps/web/src/components/editor/panels/timeline/timeline-element.tsx') diff --git a/apps/web/src/components/editor/panels/timeline/timeline-element.tsx b/apps/web/src/components/editor/panels/timeline/timeline-element.tsx index f196da44..bb30b0b0 100644 --- a/apps/web/src/components/editor/panels/timeline/timeline-element.tsx +++ b/apps/web/src/components/editor/panels/timeline/timeline-element.tsx @@ -39,6 +39,11 @@ import type { } from "@/lib/timeline"; import type { MediaAsset } from "@/lib/media/types"; import { mediaSupportsAudio } from "@/lib/media/media-utils"; +import { + canToggleSourceAudio, + getSourceAudioActionLabel, + isSourceAudioSeparated, +} from "@/lib/timeline/audio-separation"; import { getActionDefinition, type TAction, @@ -61,7 +66,9 @@ import { Search01Icon, Exchange01Icon, KeyframeIcon, + Link02Icon, MagicWand05Icon, + Unlink02Icon, } from "@hugeicons/core-free-icons"; import { HugeiconsIcon } from "@hugeicons/react"; import { uppercase } from "@/utils/string"; @@ -280,6 +287,19 @@ export function TimelineElement({ }; const isMuted = canElementHaveAudio(element) && element.muted === true; + const canToggleCurrentSourceAudio = + selectedElements.length === 1 && + isCurrentElementSelected && + canToggleSourceAudio({ + element, + mediaAsset, + }); + const sourceAudioLabel = + element.type === "video" + ? getSourceAudioActionLabel({ element }) + : "Extract audio"; + const isElementSourceAudioSeparated = + element.type === "video" && isSourceAudioSeparated({ element }); return ( @@ -334,6 +354,21 @@ export function TimelineElement({ isMuted={isMuted} /> )} + {canToggleCurrentSourceAudio && ( + + } + onClick={(event: React.MouseEvent) => { + event.stopPropagation(); + invokeAction("toggle-source-audio"); + }} + > + {sourceAudioLabel} + + )} {canElementBeHidden(element) && (