@cutcraft/player 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,298 @@
1
+ import { $ as postEffects, A as ImageFrameSource, At as FRAME_EPS, B as buildGainEnvelope, Bt as QUEUE_MAX, C as ClipDecoder, Ct as devWarn, D as ErrorFrame, Dt as DUCK_ATTACK_S, E as AssetSources, Et as AUDIO_PRIME_S, F as ManualClock, Ft as MAX_RATE, G as MaskSpec, Gt as SEEK_MODE_SPEED, H as BackgroundGradient, Ht as REVERSE_WINDOW_FRAMES, I as PerformanceClock, It as MIN_RATE, J as buildFramePlan, K as ResolveNested, Kt as SETTLE_MS, L as AudioOccurrence, Lt as MOUNT_AHEAD_S, M as defaultCreateCanvas, Mt as INPUT_IDLE_CLOSE_S, N as fromMap, Nt as LOOKAHEAD_S, O as ErrorFrameSource, Ot as DUCK_RELEASE_S, P as toResolver, Pt as MAX_OPEN_INPUTS, Q as filterString, R as GainPoint, Rt as PICK_EPS, S as DecoderPool, St as captureWarnings, T as AssetSourceDeps, Tt as AUDIO_CHUNK_S, U as DrawOp, Ut as REVERSE_WINDOW_S, V as duckIntervals, Vt as QUEUE_TARGET, W as FramePlan, Wt as SCHEDULER_MS, X as FilterResult, Y as compositionBackground, Z as PostEffect, _ as FrameSourceHooks, _t as MediaHandle, a as TickOptions, at as AudioOutput, b as mediabunnyFrameSourceFactory, bt as PlayerEvents, c as backgroundCss, ct as AudioSourceInfo, d as paintBackground, dt as Ctx2D, et as EASING_FN, f as setMatrix, ft as EnvelopePoint, g as mediabunnyAudioSourceFactory, gt as FrameSourceInfo, h as MediabunnyAudioSource, ht as FrameSourceFactory, i as FrameIntercept, it as AnyCanvas, j as copyFrame, jt as FRAME_WAIT_MS, k as ImageFrame, kt as ENVELOPE_STEP_S, l as backgroundFill, lt as Clock, m as traceMask, mt as FrameSource, n as Compositor, nt as hasKeyframes, o as CanvasPainter, ot as AudioSource, p as roundedRect, pt as Frame, q as blendOf, qt as UNMOUNT_BEHIND_S, r as CompositorDeps, rt as keyframedValue, s as PaintInputs, st as AudioSourceFactory, t as makeNestedResolver, tt as ease, u as coversCanvas, ut as CreateCanvas, v as MediabunnyFrameSource, vt as MediaResolver, w as DecodeMode, wt as AUDIO_CACHE_S, x as MediabunnyInputs, xt as ScheduledSource, y as SampleFrame, yt as PlayerErrorEvent, z as buildAudioPlan, zt as PLAY_PRIME_TIMEOUT_MS } from "./nested-Bd4Y7qrF.mjs";
2
+ import { A as visiblePlacements, C as scaleM, D as VisibleItem, E as TransitionRole, F as nestedSourceTime, I as placementSourceTime, L as timecode, M as frameTime, N as layerClock, O as isVisibleAt, P as localT, S as rotate, T as translate, _ as cssTransform, a as Motion, b as matrixToCss, c as effect, d as DrawRect, f as IDENTITY, g as boundsOf, h as animatedTransform, i as GraphicAnimation, j as frameIndex, k as trackItems, l as motionAt, m as Matrix2D, n as backdropTracks, o as STILL, p as Layout, r as ClipRect, s as combine, t as OVERLAY_KINDS, u as Box, v as fitRect, w as transformMatrix, x as multiply, y as layoutRect } from "./backdrop-BqrzCzTB.mjs";
3
+ import { t as indexLayerInteriors } from "./layer-interiors-r4SeMbp2.mjs";
4
+ import { LayerClock, ResolvedState } from "@cutcraft/kit";
5
+ import { CSSProperties, ReactNode } from "react";
6
+ /**
7
+ * `AudioContext.currentTime` while the context runs, the performance clock
8
+ * otherwise, with an offset captured at every state change so `now()` never
9
+ * jumps. Audio scheduling converts back with `toContextTime`.
10
+ */
11
+ export declare class AudioContextClock implements Clock {
12
+ private readonly ctx;
13
+ private offset;
14
+ private wasRunning;
15
+ private lastNow;
16
+ constructor(ctx: BaseAudioContext);
17
+ get running(): boolean;
18
+ now(): number;
19
+ /** Audio context seconds for a clock time; exact while the context runs. */
20
+ toContextTime(clockTime: number): number;
21
+ }
22
+ /**
23
+ * Composition time as an anchor on the clock: `anchorTime + (now − anchorClock) × rate`.
24
+ * Every play, pause, seek and rate change re-anchors, so time is always derived from
25
+ * the clock and never accumulates drift.
26
+ */
27
+ export declare class Transport {
28
+ private readonly clock;
29
+ duration: number;
30
+ private anchorTime;
31
+ private anchorClock;
32
+ private _rate;
33
+ private _playing;
34
+ loop: boolean;
35
+ constructor(clock: Clock, duration: number);
36
+ get playing(): boolean;
37
+ get rate(): number;
38
+ time(): number;
39
+ timeAt(clockTime: number): number;
40
+ /** Clock time at which composition time `t` plays; the inverse of `timeAt` while playing. */
41
+ clockTimeFor(t: number): number;
42
+ play(): void;
43
+ pause(): void;
44
+ seek(t: number): void;
45
+ setRate(rate: number): void;
46
+ /** Advance bookkeeping at the end: loops wrap, otherwise playback stops on the last time. */
47
+ check(): "ended" | "looped" | null;
48
+ private clamp;
49
+ }
50
+ export interface AudioEngineDeps {
51
+ readonly output: AudioOutput;
52
+ readonly transport: Transport;
53
+ /** Clock seconds (the transport's clock) → audio context seconds. */
54
+ readonly toContextTime: (clockTime: number) => number;
55
+ readonly audioSource: (assetId: string) => Promise<AudioSource>;
56
+ readonly state: () => ResolvedState;
57
+ readonly resolveNested?: ResolveNested | undefined;
58
+ readonly setInterval: (fn: () => void, ms: number) => unknown;
59
+ readonly clearInterval: (id: unknown) => void;
60
+ readonly onError?: ((e: PlayerErrorEvent) => void) | undefined;
61
+ }
62
+ /**
63
+ * Schedules audio chunks on the output ahead of the transport. Every play
64
+ * starts a session; a scheduler tick plans the window since the last tick
65
+ * up to the lookahead and schedules each new chunk once, with offset,
66
+ * duration and playback rate derived from the transport. Pause cancels
67
+ * everything; seek and rate changes restart the session.
68
+ */
69
+ export declare class AudioEngine {
70
+ private readonly deps;
71
+ private session;
72
+ private timer;
73
+ private scheduled;
74
+ private scheduledUpTo;
75
+ private running;
76
+ private cache;
77
+ private cacheSeconds;
78
+ private _muted;
79
+ private _volume;
80
+ constructor(deps: AudioEngineDeps);
81
+ get muted(): boolean;
82
+ get volume(): number;
83
+ get active(): boolean;
84
+ setMaster(volume: number, muted: boolean): void;
85
+ /** Decode what plays in the first moments after `t`, bounded by a timeout, so play starts on time. */
86
+ prime(t: number): Promise<void>;
87
+ start(): void;
88
+ stop(): void;
89
+ /** After a seek, a rate change or a loop: reschedule from the new position. */
90
+ reseek(): void;
91
+ tick(): void;
92
+ dispose(): void;
93
+ private schedule;
94
+ private buffer;
95
+ }
96
+ /** Web Audio graph: per scheduled chunk `source → gain(envelope) → [pan] → master → destination`. */
97
+ export declare class WebAudioOutput implements AudioOutput {
98
+ private readonly ctx;
99
+ private readonly master;
100
+ private readonly live;
101
+ constructor(ctx: AudioContext);
102
+ get contextTime(): number;
103
+ get running(): boolean;
104
+ schedule(src: ScheduledSource): void;
105
+ cancel(keyPrefix: string): void;
106
+ cancelAll(): void;
107
+ setMaster(gain: number): void;
108
+ resume(): Promise<void>;
109
+ private drop;
110
+ private stop;
111
+ private disconnect;
112
+ }
113
+ export interface CaptureSheetOptions {
114
+ /** Cells per row; default 4, never more than the number of times. */
115
+ readonly columns?: number;
116
+ /** Cell width in pixels; default the composition width capped at 320. Height follows the aspect ratio. */
117
+ readonly cellWidth?: number;
118
+ /** Draw a `mm:ss:ff` label in each cell; default true. */
119
+ readonly labels?: boolean;
120
+ }
121
+ export interface PlayerOptions {
122
+ readonly state: ResolvedState;
123
+ readonly media: MediaResolver | Readonly<Record<string, Blob | string>>;
124
+ readonly audioContext?: AudioContext | undefined;
125
+ readonly loop?: boolean | undefined;
126
+ readonly initiallyMuted?: boolean | undefined;
127
+ readonly playbackRate?: number | undefined;
128
+ readonly resolveNested?: ResolveNested | undefined;
129
+ /** Test seams; the browser defaults are the audio-context clock, Web Audio and mediabunny. */
130
+ readonly clock?: Clock | undefined;
131
+ readonly audioOutput?: AudioOutput | undefined;
132
+ readonly toContextTime?: ((clockTime: number) => number) | undefined;
133
+ readonly frameSourceFactory?: FrameSourceFactory | undefined;
134
+ readonly audioSourceFactory?: AudioSourceFactory | undefined;
135
+ readonly createCanvas?: CreateCanvas | undefined;
136
+ readonly raf?: ((cb: () => void) => number) | undefined;
137
+ readonly cancelRaf?: ((id: number) => void) | undefined;
138
+ readonly setInterval?: ((fn: () => void, ms: number) => unknown) | undefined;
139
+ readonly clearInterval?: ((id: unknown) => void) | undefined;
140
+ readonly setTimeout?: ((fn: () => void, ms: number) => unknown) | undefined;
141
+ readonly clearTimeout?: ((id: unknown) => void) | undefined;
142
+ }
143
+ export interface TimeSnapshot {
144
+ readonly time: number;
145
+ readonly frame: number;
146
+ }
147
+ type Listener<K extends keyof PlayerEvents> = (e: PlayerEvents[K]) => void;
148
+ /**
149
+ * The framework-free player: owns the transport, the compositor (canvas),
150
+ * the audio engine and the media sources. React's `<Player>` is a thin
151
+ * wrapper over it; a headless exporter can drive `renderFrame` directly.
152
+ */
153
+ export declare class PlayerCore {
154
+ private _state;
155
+ private readonly media;
156
+ private readonly clock;
157
+ private readonly transport;
158
+ readonly compositor: Compositor;
159
+ private readonly engine;
160
+ private readonly sources;
161
+ private readonly inputs;
162
+ private readonly audioContext;
163
+ private readonly audioSources;
164
+ private readonly listeners;
165
+ private readonly timeListeners;
166
+ private readonly createCanvas;
167
+ private readonly raf;
168
+ private readonly cancelRaf;
169
+ private rafId;
170
+ private readonly setTimeoutFn;
171
+ private readonly clearTimeoutFn;
172
+ private settleTimer;
173
+ private seekGeneration;
174
+ private snapshot;
175
+ private _muted;
176
+ private _volume;
177
+ private disposed;
178
+ constructor(options: PlayerOptions);
179
+ get state(): ResolvedState;
180
+ get duration(): number;
181
+ get playbackRate(): number;
182
+ set playbackRate(rate: number);
183
+ get loop(): boolean;
184
+ set loop(v: boolean);
185
+ get muted(): boolean;
186
+ set muted(v: boolean);
187
+ get volume(): number;
188
+ set volume(v: number);
189
+ /** The media handle for an asset id, for DOM elements that show images. */
190
+ resolveMedia(assetId: string): Promise<MediaHandle>;
191
+ getCurrentTime(): number;
192
+ getCurrentFrame(): number;
193
+ isPlaying(): boolean;
194
+ getTime(): TimeSnapshot;
195
+ play(): Promise<void>;
196
+ pause(): void;
197
+ toggle(): Promise<void>;
198
+ /** Jump to `time` and draw its exact frame before resolving, playing or not. */
199
+ seekTo(time: number): Promise<void>;
200
+ seekToFrame(frame: number): Promise<void>;
201
+ /** Draw `time` without moving the transport; decoders return to the play head afterwards. */
202
+ renderFrame(time: number): Promise<void>;
203
+ /**
204
+ * A contact sheet of the canvas plane at `times`: each cell is `renderFrame`
205
+ * of that time with a timecode label, laid out `columns` wide. The way an
206
+ * agent or a test looks at the result without exporting. DOM overlays
207
+ * (titles, shapes, Layer interiors) are not on the canvas and do not appear.
208
+ */
209
+ captureSheet(times: readonly number[], options?: CaptureSheetOptions): Promise<AnyCanvas>;
210
+ /**
211
+ * The editor pushes a new resolve on every drag step. Decoders of the same
212
+ * asset keep their frames and take the new trim; a paused preview paints at
213
+ * once with what is decoded and fetches the exact frame after the gesture
214
+ * has been quiet for `SETTLE_MS`.
215
+ */
216
+ setState(state: ResolvedState): void;
217
+ attachCanvas(canvas: HTMLCanvasElement | OffscreenCanvas | null): void;
218
+ addEventListener<K extends keyof PlayerEvents>(type: K, fn: Listener<K>): () => void;
219
+ removeEventListener<K extends keyof PlayerEvents>(type: K, fn: Listener<K>): void;
220
+ /** For `useSyncExternalStore`: notified once per painted frame and on every seek. */
221
+ subscribeTime(fn: () => void): () => void;
222
+ dispose(): void;
223
+ private startLoop;
224
+ private stopLoop;
225
+ private publish;
226
+ private emit;
227
+ private audioSource;
228
+ }
229
+ export declare const PlayerContext: import("react").Context<PlayerCore | null>;
230
+ /** The layer's clock inside a `<Layer>`; null outside one. */
231
+ export declare const LayerContext: import("react").Context<LayerClock | null>;
232
+ export declare function usePlayer(): PlayerCore;
233
+ export declare function useCompositionTime(): number;
234
+ export declare function useCompositionFrame(): number;
235
+ /** What the kit's `useLayer()` and `useT()` delegate to while a Player is mounted. */
236
+ export declare function useLayerClock(): LayerClock;
237
+ /** 0..1 progress through the enclosing Layer. */
238
+ export declare function useLayerT(): number;
239
+ /** Installs the kit's layer hooks for the first mounted Player and removes them after the last unmounts. */
240
+ export declare function retainUseT(): () => void;
241
+ export interface DomLayerProps {
242
+ readonly state: ResolvedState;
243
+ readonly interiors: ReadonlyMap<string, ReactNode>;
244
+ /** Which overlays: those beneath the footage (`backdropTracks`), or the rest and the captions (default). */
245
+ readonly layer?: "backdrop" | "front";
246
+ }
247
+ /** Overlay elements as DOM, one absolutely positioned group per track in compositing order, above the canvas (or, for the backdrop, below it). */
248
+ export declare function DomLayer({ state, interiors, layer }: DomLayerProps): import("react").JSX.Element;
249
+ export interface ElementCellProps {
250
+ item: VisibleItem;
251
+ state: ResolvedState;
252
+ time: number;
253
+ interior: ReactNode;
254
+ }
255
+ /**
256
+ * Whether two renders of an overlay would produce the same DOM. Placements
257
+ * are new objects on every resolve, so compare what matters: timing, the
258
+ * parsed props (referentially stable while untouched), children, the
259
+ * element-relative frame, the transition progress, the text and the
260
+ * composition box.
261
+ */
262
+ export declare function sameElement(a: ElementCellProps, b: ElementCellProps): boolean;
263
+ /** Play/pause, scrubber, time readout, mute and rate. */
264
+ export declare function Controls(): import("react").JSX.Element;
265
+ export interface PlayerProps {
266
+ readonly state: ResolvedState;
267
+ readonly media: MediaResolver | Readonly<Record<string, Blob | string>>;
268
+ /** The evaluated file element (`mod.default(props)`); needed only to render `<Layer>` interiors. */
269
+ readonly element?: ReactNode;
270
+ readonly controls?: boolean;
271
+ readonly loop?: boolean;
272
+ readonly autoPlay?: boolean;
273
+ readonly initiallyMuted?: boolean;
274
+ readonly playbackRate?: number;
275
+ /** `contain` scales the composition into the box; `none` renders at composition pixels. */
276
+ readonly fit?: "contain" | "none";
277
+ readonly style?: CSSProperties;
278
+ readonly className?: string;
279
+ readonly audioContext?: AudioContext;
280
+ readonly onError?: (e: PlayerEvents["error"]) => void;
281
+ readonly onFrame?: (e: PlayerEvents["frameupdate"]) => void;
282
+ /** Test seams forwarded to PlayerCore. */
283
+ readonly coreOptions?: Partial<PlayerOptions>;
284
+ }
285
+ export type PlayerRef = Pick<PlayerCore, "play" | "pause" | "toggle" | "seekTo" | "seekToFrame" | "getCurrentTime" | "getCurrentFrame" | "isPlaying" | "addEventListener" | "removeEventListener" | "renderFrame" | "captureSheet" | "duration" | "state"> & {
286
+ playbackRate: number;
287
+ loop: boolean;
288
+ muted: boolean;
289
+ volume: number;
290
+ readonly core: PlayerCore;
291
+ readonly canvas: HTMLCanvasElement | null;
292
+ };
293
+ /**
294
+ * Canvas for media, DOM for overlays, controls below. The root carries
295
+ * `data-time` and `data-frame`; every element carries `data-el`/`data-kind`.
296
+ */
297
+ export declare const Player: import("react").ForwardRefExoticComponent<PlayerProps & import("react").RefAttributes<PlayerRef>>;
298
+ export { AUDIO_CACHE_S, AUDIO_CHUNK_S, AUDIO_PRIME_S, AnyCanvas, AssetSourceDeps, AssetSources, AudioOccurrence, AudioOutput, AudioSource, AudioSourceFactory, AudioSourceInfo, BackgroundGradient, Box, CanvasPainter, ClipDecoder, ClipRect, Clock, Compositor, CompositorDeps, CreateCanvas, Ctx2D, DUCK_ATTACK_S, DUCK_RELEASE_S, DecodeMode, DecoderPool, DrawOp, DrawRect, EASING_FN, ENVELOPE_STEP_S, EnvelopePoint, ErrorFrame, ErrorFrameSource, FRAME_EPS, FRAME_WAIT_MS, FilterResult, Frame, FrameIntercept, FramePlan, FrameSource, FrameSourceFactory, FrameSourceHooks, FrameSourceInfo, GainPoint, GraphicAnimation, IDENTITY, INPUT_IDLE_CLOSE_S, ImageFrame, ImageFrameSource, LOOKAHEAD_S, Layout, MAX_OPEN_INPUTS, MAX_RATE, MIN_RATE, MOUNT_AHEAD_S, ManualClock, MaskSpec, Matrix2D, MediaHandle, MediaResolver, MediabunnyAudioSource, MediabunnyFrameSource, MediabunnyInputs, Motion, OVERLAY_KINDS, PICK_EPS, PLAY_PRIME_TIMEOUT_MS, PaintInputs, PerformanceClock, PlayerErrorEvent, PlayerEvents, PostEffect, QUEUE_MAX, QUEUE_TARGET, REVERSE_WINDOW_FRAMES, REVERSE_WINDOW_S, ResolveNested, SCHEDULER_MS, SEEK_MODE_SPEED, SETTLE_MS, STILL, SampleFrame, ScheduledSource, TickOptions, TransitionRole, UNMOUNT_BEHIND_S, VisibleItem, animatedTransform, backdropTracks, backgroundCss, backgroundFill, blendOf, boundsOf, buildAudioPlan, buildFramePlan, buildGainEnvelope, captureWarnings, combine, compositionBackground, copyFrame, coversCanvas, cssTransform, defaultCreateCanvas, devWarn, duckIntervals, ease, effect, filterString, fitRect, frameIndex, frameTime, fromMap, hasKeyframes, indexLayerInteriors, isVisibleAt, keyframedValue, layerClock, layoutRect, localT, makeNestedResolver, matrixToCss, mediabunnyAudioSourceFactory, mediabunnyFrameSourceFactory, motionAt, multiply, nestedSourceTime, paintBackground, placementSourceTime, postEffects, rotate, roundedRect, scaleM, setMatrix, timecode, toResolver, traceMask, trackItems, transformMatrix, translate, visiblePlacements };