import { RationalTime, TimecodeFrameRate } from "@techsquidtv/canvas-timeline-utils"; import { ActiveLayerResult, ActiveLayerSelector, MaybePromise, PlaybackOptions, TimelineCommandResult, TimelineContentPlaybackStatus, TimelineLayerSyncDetails } from "@techsquidtv/canvas-timeline-core"; //#region src/hooks/playback/internal/externalMediaPlaybackTransport.d.ts /** * Options for coordinating timeline playback with an external media clock. * * @remarks * * Use this hook when your preview surface owns the media clock. The hook tells * {@link https://canvastimeline.com/packages/core/api/timeline-engine | TimelineEngine} * to play with an external clock, reads timeline seconds from `getClockTime`, * and calls `syncLayers` with an {@link ActiveLayerResult} whenever active * clips need to be rendered, sought, or paused. * * Higher-level adapters such as `useHTMLTimelineMedia` and * `useMediabunnyTimelineMedia` wrap this contract for common media stacks. * * @template LayerName - Named media layer keys inferred from `layers`, such as * `"visuals" | "audio"`. * * @see {@link TimelineLayerSyncDetails} * @see {@link useTimelineMediaSync} * @see {@link https://canvastimeline.com/demos/media-preview-sync | Mediabunny media sync demo} */ interface UseTimelineMediaPlaybackOptions { /** Returns current timeline seconds from the external media clock. */ getClockTime: () => number; /** Optional sequence frame rate used to quantize playback updates to project frames. */ frameRate?: TimecodeFrameRate; /** Core playback range policy applied to the external clock; looping is configured by `loop`. */ playbackOptions?: Omit; /** Stops the external media clock when timeline playback pauses or leaves active content. */ stopClock?: () => void; /** Applies a validated playback-rate change to the external media clock. */ setClockRate?: (playbackRate: number) => void; /** Named active layer selectors used by the external media surface. */ layers: Record; /** Synchronizes external rendering, audio, text, or effects for the active layers. */ syncLayers?: (details: TimelineLayerSyncDetails) => MaybePromise; /** * Enables looping and realigns the external clock after Core returns to the range start. * The callback is invoked once per loop transition until the clock re-enters range. * Its presence and implementation are captured when each playback run begins. */ loop?: (timelineTime: RationalTime, activeLayers: ActiveLayerResult) => MaybePromise; /** Receives high-level playback status changes. */ onStatus?: (status: TimelineContentPlaybackStatus) => void; /** Receives external rendering or scheduling failures before playback is paused. */ onError?: (error: Error) => void; } interface TimelineMediaPlaybackSynchronizationRunner { run: (operation: () => Promise, superseded: () => Result) => Promise; } /** * Result returned by `useTimelineMediaPlayback`. * * @remarks * * These commands operate on the timeline engine and resolve * {@link TimelineCommandResult} values so toolbar code can show disabled, * content-gap, invalid-input, or synchronization feedback without reading * private engine state. Playback and rate changes await serialized adapter * synchronization before resolving. */ interface UseTimelineMediaPlaybackResult { /** Whether the timeline engine is currently playing against the external clock. */ playing: boolean; /** Current timeline playback speed multiplier. */ playbackRate: number; /** Starts playback after active external layers finish synchronizing. */ play: () => Promise; /** Stops timeline playback and synchronizes external media into a paused state. */ pause: () => TimelineCommandResult; /** Updates both clocks and resolves after active layers resynchronize. */ setPlaybackRate: (rate: number) => Promise; } /** * Coordinates timeline playback with an external media clock. * * @remarks * * The hook is media-library agnostic. Apps provide a clock and a single layer * sync callback while the hook advances the TimelineEngine playhead and decides * when active layer clips need to be resynchronized. * * @param options - External media clock, active layer selectors, sync callback, and status callback. * @template LayerName - Named media layer keys inferred from `options.layers`, * such as `"visuals" | "audio"`. * @returns Timeline playback state and commands backed by the external media clock. * * @example * ```tsx * import { useMemo, useRef } from 'react'; * import { useTimelineMediaPlayback } from '@techsquidtv/canvas-timeline-react/hooks'; * * const previewLayers = { * visuals: { trackKind: 'visual' }, * audio: { trackKind: 'audio' }, * } as const; * * export function CustomClockTransport() { * const clockSecondsRef = useRef(0); * const layers = useMemo(() => previewLayers, []); * const playback = useTimelineMediaPlayback({ * layers, * getClockTime: () => clockSecondsRef.current, * stopClock: () => { * clockSecondsRef.current = 0; * }, * syncLayers: ({ activeLayers, reason }) => { * const visualClip = activeLayers.primary.visuals?.clip; * console.info(reason, visualClip?.id ?? 'blank frame'); * }, * }); * * return ( * * ); * } * ``` * * @see {@link ActiveLayerSelector} * @see {@link ActiveLayerResult} * @see {@link useTimelineMediaSync} * @see {@link https://canvastimeline.com/docs/react-hooks | React editor hooks} */ declare function useTimelineMediaPlayback(options: UseTimelineMediaPlaybackOptions): UseTimelineMediaPlaybackResult; declare function useTimelineMediaPlaybackInternal(options: UseTimelineMediaPlaybackOptions, delegatedSynchronization?: TimelineMediaPlaybackSynchronizationRunner): UseTimelineMediaPlaybackResult; //#endregion export { UseTimelineMediaPlaybackOptions, UseTimelineMediaPlaybackResult, useTimelineMediaPlayback, useTimelineMediaPlaybackInternal }; //# sourceMappingURL=externalMediaPlaybackTransport.d.mts.map