/** Shared track/clip types and helpers for Video / Audio editors. */ export type MediaAssetKind = 'image' | 'video' | 'audio' | 'text'; /** Spatial rect on the program frame (document px). */ export interface MediaClipRect { x: number; y: number; w: number; h: number; } export type MediaClipAlign = 'left' | 'center-h' | 'right' | 'top' | 'center-v' | 'bottom' | 'center' | 'full'; export interface MediaAsset { id: string; kind: MediaAssetKind; name: string; /** Object URL or remote URL */ src?: string; durationMs?: number; width?: number; height?: number; } export interface MediaClip { id: string; trackId: string; assetId?: string; name: string; kind: MediaAssetKind; src?: string; /** Timeline start */ startMs: number; /** Timeline end */ endMs: number; /** Source trim in */ trimInMs?: number; /** Source trim out (absolute in source) */ trimOutMs?: number; color?: string; /** Overlay / title text */ text?: string; /** Timeline clip block opacity (0–1). Does not affect program preview. */ opacity?: number; /** Program monitor / render opacity (0–1). */ previewOpacity?: number; volume?: number; fontSize?: number; fontWeight?: number | string; fontFamily?: string; textAlign?: 'left' | 'center' | 'right'; textColor?: string; /** Position on program monitor (document px). Overlays / positioned media. */ rect?: MediaClipRect; animationIn?: { type: string; durationMs: number; }; animationOut?: { type: string; durationMs: number; }; transitionOut?: { type: string; durationMs: number; }; } export type MediaTrackKind = 'video' | 'audio' | 'image'; export interface MediaTrack { id: string; name: string; kind: MediaTrackKind; muted?: boolean; solo?: boolean; locked?: boolean; armed?: boolean; color?: string; clips: MediaClip[]; } export declare function uid(prefix?: string): string; export declare function createMediaClip(partial: Omit & { id?: string; }): MediaClip; /** Default overlay rect for text / plates on a program frame. */ export declare function defaultOverlayRect(frame: { width: number; height: number; }, preset?: 'center' | 'lower-third' | 'top' | 'watermark' | 'full' | 'badge' | 'ticker' | 'side'): MediaClipRect; export declare function clipHasSpatialRect(clip: MediaClip): boolean; export declare function resolveClipRect(clip: MediaClip, frame: { width: number; height: number; }): MediaClipRect; export declare function alignClipRect(clip: MediaClip, frame: { width: number; height: number; }, align: MediaClipAlign): MediaClip; export declare function alignMediaRect(rect: MediaClipRect, bounds: { width: number; height: number; }, align: MediaClipAlign): MediaClipRect; export declare function createMediaTrack(partial: Omit & { id?: string; clips?: MediaClip[]; }): MediaTrack; export declare function clipDurationMs(clip: MediaClip): number; export declare function moveClip(clip: MediaClip, newStartMs: number, durationMs?: number): MediaClip; export declare function trimClipStart(clip: MediaClip, newStartMs: number, minDur?: number): MediaClip; export declare function trimClipEnd(clip: MediaClip, newEndMs: number, minDur?: number): MediaClip; export declare function isClipActiveAt(clip: MediaClip, timeMs: number): boolean; /** Active CapCut-style transition: straddles the cut of a clip with `transitionOut`. */ export interface MediaTransitionPlayback { from: MediaClip; to: MediaClip | null; trackId: string; type: string; /** 0 at transition start → 1 at end of transition */ progress: number; durationMs: number; windowStartMs: number; windowEndMs: number; } export declare function findTransitionAt(tracks: MediaTrack[], timeMs: number): MediaTransitionPlayback | null; /** Geometry for overflow-based wipes (reliable vs clip-path). */ export interface TransitionWipeBox { box: { left: string; top: string; width: string; height: string; }; content: { left: string; top: string; width: string; height: string; }; } export interface TransitionLayerStyle { opacity: number; transform: string; clipPath?: string; filter?: string; transformOrigin?: string; /** CSS mask-image (and -webkit-mask-image) */ maskImage?: string; /** Prefer this for hard directional wipes */ wipe?: TransitionWipeBox; } /** CSS bits for outgoing / incoming layers during a transition. */ export declare function transitionLayerStyle(role: 'from' | 'to', type: string, progress: number): TransitionLayerStyle; export declare function transitionDipOverlay(type: string, progress: number): { color: string; opacity: number; } | null; export declare function findClipAt(tracks: MediaTrack[], timeMs: number, kind?: MediaTrackKind): MediaClip | null; export declare function findClipById(tracks: MediaTrack[], clipId: string): MediaClip | null; export declare function updateClipInTracks(tracks: MediaTrack[], clipId: string, updater: (c: MediaClip) => MediaClip): MediaTrack[]; export declare function removeClipFromTracks(tracks: MediaTrack[], clipId: string): MediaTrack[]; export declare function removeClipsFromTracks(tracks: MediaTrack[], clipIds: string[]): MediaTrack[]; /** Split a clip at timeMs; returns updated tracks (no-op if playhead not inside clip). */ export declare function splitClipAt(tracks: MediaTrack[], clipId: string, timeMs: number, minDur?: number): MediaTrack[]; /** Split every selected clip that contains timeMs. */ export declare function splitClipsAt(tracks: MediaTrack[], clipIds: string[], timeMs: number, minDur?: number): MediaTrack[]; export declare function duplicateClipInTracks(tracks: MediaTrack[], clipId: string): MediaTrack[]; /** * Merge 2+ clips of the same kind into one spanning earliest start → latest end. * Clips may live on different tracks; the result is placed on the earliest clip's track. * Returns null if merge is not possible. */ export declare function canMergeMediaClips(tracks: MediaTrack[], clipIds: string[]): boolean; export declare function mergeClipsInTracks(tracks: MediaTrack[], clipIds: string[]): MediaTrack[] | null; /** Shift one or more clips in time by the same delta (clamped so none go before 0). */ export declare function moveClipsByDelta(tracks: MediaTrack[], clipIds: string[], deltaMs: number): MediaTrack[]; export declare function nextTrackName(tracks: MediaTrack[], kind: MediaTrackKind): string; /** Reorder tracks by id list (ids not listed keep relative order at the end). */ export declare function reorderTracks(tracks: MediaTrack[], orderedIds: string[]): MediaTrack[]; /** Move a track from one index to another. */ export declare function moveTrack(tracks: MediaTrack[], fromIndex: number, toIndex: number): MediaTrack[]; export declare function removeTrack(tracks: MediaTrack[], trackId: string): MediaTrack[]; export declare function removeTracks(tracks: MediaTrack[], trackIds: string[]): MediaTrack[]; /** Defaults for inspector reset (Unreal-style). */ export declare const MEDIA_CLIP_DEFAULTS: { opacity: number; previewOpacity: number; volume: number; fontSize: number; fontWeight: number | string; textAlign: "center"; textColor: string; color: string; trimInMs: number; trimOutMs: number | undefined; }; export type MediaClipRectAxis = 'x' | 'y' | 'w' | 'h'; export type MediaClipResettableField = keyof typeof MEDIA_CLIP_DEFAULTS | 'rect' | `rect.${MediaClipRectAxis}`; /** Default rect used by inspector reset (must stay in sync with `resetMediaClipField`). */ export declare function defaultMediaClipRect(clip: MediaClip, frame: { width: number; height: number; }): MediaClipRect; export declare function isMediaClipFieldModified(clip: MediaClip, field: MediaClipResettableField, frame?: { width: number; height: number; }): boolean; export declare function resetMediaClipField(clip: MediaClip, field: MediaClipResettableField, frame?: { width: number; height: number; }): MediaClip; /** Effective program-monitor opacity (ignores timeline clip opacity). */ export declare function resolvePreviewOpacity(clip: MediaClip): number; /** Effective timeline block opacity. */ export declare function resolveClipOpacity(clip: MediaClip): number; export declare function createMediaAsset(partial: Omit & { id?: string; }): MediaAsset; export declare function kindFromFile(file: File): MediaAssetKind; /** Probe width/height/duration from a local media URL. */ export declare function probeMediaSrc(src: string, kind: MediaAssetKind): Promise>;