import { P as PlaybackEngine, a as PlaybackEngineOptions, b as PlaybackEngineFactory } from './types-B1786Fvo.js'; import { M as Ms, P as Project, T as Track, C as Clip, a as MediaSource, b as Theme, A as AspectRatio, K as KeyframeProp, E as EasingKind } from './types-BTUuytwo.js'; export { c as Keyframe, d as ProjectOutput } from './types-BTUuytwo.js'; import { L as Locale } from './i18n-DUwTFylQ.js'; export { f as formatLabel, l as localeEn, a as localeZh, m as mergeLocale } from './i18n-DUwTFylQ.js'; declare class HtmlVideoEngine implements PlaybackEngine { private host; private mount; private sources; private project; /** trackId → currently-active clipId on that track. PiP off keeps * only the first entry; PiP on holds one per video track. */ private activeByTrack; private playing; private timeMs; private rafHandle; private lastFrameTs; /** Permanent rAF that positions the active wrappers at the output * rect + pushes keyframe transforms onto the inner videos via CSS. */ private transformRaf; private pictureInPictureEnabled; /** Public event hooks — set by Editor. */ onTimeUpdate?: (ms: Ms) => void; onEnded?: () => void; onError?: (err: Error) => void; onReady?: () => void; onSourceMetadata?: (sourceId: string, durationMs: Ms) => void; constructor(opts: PlaybackEngineOptions); setProject(next: Project): void; setPictureInPictureEnabled(enabled: boolean): void; play(): void; pause(): void; isPlaying(): boolean; getTime(): Ms; seek(timeMs: Ms): void; /** * The OUTPUT frame — the fixed stage the rendered video is clipped * to. Independent of the keyframe transform. Used by the overlay to * draw the dashed border at a stable position. */ getOutputFrameRect(_clipId?: string): { x: number; y: number; w: number; h: number; } | null; /** * The CONTENT frame — where the transformed video pixels actually * land. Equal to the output frame when transform is identity; may * extend outside (zoom in) or fit inside (zoom out) when not. * * `clipId` (PiP): the overlay passes the selected clip so the * dashed border + corner handles latch onto a picture-in-picture * overlay instead of always tracking the primary. When omitted, * defaults to the primary (= bottom track) clip. */ getFrameRect(clipId?: string): { x: number; y: number; w: number; h: number; } | null; /** * Untransformed output-canvas rect. * * Source of truth: `Project.aspect` when the user picked a ratio * via the built-in picker. When it's null we fall back to a * STABLE reference — the first clip in the first video track, * regardless of playhead — so the canvas stays anchored as * playback crosses clip boundaries. Picks up the active primary * clip's dims as a last resort when the reference video hasn't * loaded metadata yet. * * Mirrors CapCut: "Original" means "lock to the first clip's * aspect", not "follow whatever's playing right now". Without * this, the canvas would visibly jump every time the playhead * crossed from track-0's clip 1 to clip 2. */ private baseFrameRect; /** * Dims of the canvas-anchor clip — the first clip (by start time) * on the first video track. Stable across playback so the canvas * doesn't resize at clip boundaries. Returns null when nothing's * decoded yet. */ getCanvasReferenceDims(): [number, number] | null; private canvasReferenceDims; /** * Permanent rAF that (a) sizes + positions every active wrapper to * the output frame, and (b) writes the keyframe transform onto each * inner video. Negligible cost — a handful of style writes per * frame even with PiP on. */ private startTransformLoop; private applyTransforms; destroy(): void; private syncSources; /** * Resolve the active clip per track for the current playhead and * reconcile wrapper visibility, audio policy, and per-source * playback state. Called on `seek` / `setProject` / `setPiP` and * whenever a tick advances past a clip boundary. */ private refreshActive; private computeActiveClips; /** First track-in-order with an active clip — the "primary" = * canvas reference + audio source. Track `0` wins when it has * content; otherwise the next video track with a clip. */ private primaryActiveClip; private playAllActive; private pauseAllActive; private seekVideoToClipOffset; private clipById; /** Earliest clip starting at-or-after `timeMs` across all video tracks. */ private nextClipAfterTime; /** Max clip end across all video tracks. */ private totalDuration; private startTickLoop; private stopTickLoop; private advance; } /** Factory shorthand for `Editor.create({ playbackEngine })`. */ declare const htmlVideoEngineFactory: PlaybackEngineFactory; interface CanvasCompositorEngineOptions extends PlaybackEngineOptions { /** * Show the corner HUD ("engine: canvas compositor • t=… • frames * painted: …"). Off by default — production hosts get a clean canvas * with no chrome painted on top. Turn on in development / demos to * see who's drawing and what the current state is. */ debug?: boolean; } /** * Reference second engine — demonstrates that the `PlaybackEngine` * surface really is engine-agnostic. Same `