@agrhub/engine-pixi 0.0.0-stage → 1.4.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.
Files changed (93) hide show
  1. package/LICENSE +47 -0
  2. package/NOTICE.md +20 -0
  3. package/README.md +6 -2
  4. package/dist/animation/block-reveal-animation.d.ts +33 -0
  5. package/dist/animation/easings.d.ts +4 -0
  6. package/dist/animation/gsap-animation.d.ts +32 -0
  7. package/dist/animation/index.d.ts +9 -0
  8. package/dist/animation/keyframe-animation.d.ts +11 -0
  9. package/dist/animation/mask-animation.d.ts +170 -0
  10. package/dist/animation/pixi-animation-utils.d.ts +10 -0
  11. package/dist/animation/registry.d.ts +11 -0
  12. package/dist/animation/types.d.ts +211 -0
  13. package/dist/animation/wipe-animation.d.ts +53 -0
  14. package/dist/clips/audio-clip.d.ts +122 -0
  15. package/dist/clips/backdrop-clip.d.ts +56 -0
  16. package/dist/clips/base-clip.d.ts +150 -0
  17. package/dist/clips/base-text-clip.d.ts +228 -0
  18. package/dist/clips/caption-clip.d.ts +129 -0
  19. package/dist/clips/clip-registry.d.ts +56 -0
  20. package/dist/clips/effect-clip.d.ts +37 -0
  21. package/dist/clips/iclip.d.ts +235 -0
  22. package/dist/clips/image-clip.d.ts +116 -0
  23. package/dist/clips/index.d.ts +20 -0
  24. package/dist/clips/placeholder-clip.d.ts +22 -0
  25. package/dist/clips/shape-clip.d.ts +59 -0
  26. package/dist/clips/text-clip.d.ts +148 -0
  27. package/dist/clips/transition-clip.d.ts +45 -0
  28. package/dist/clips/video-clip.d.ts +216 -0
  29. package/dist/compositor/audio-mixer.d.ts +8 -0
  30. package/dist/compositor/av-encoder.d.ts +17 -0
  31. package/dist/compositor/clip-style-renderer.d.ts +23 -0
  32. package/dist/compositor/compositor-renderer.d.ts +29 -0
  33. package/dist/compositor/effect-manager.d.ts +30 -0
  34. package/dist/compositor/scheduler.d.ts +8 -0
  35. package/dist/compositor/transition-manager.d.ts +45 -0
  36. package/dist/compositor.d.ts +157 -0
  37. package/dist/effect/constant/index.d.ts +566 -0
  38. package/dist/effect/effect.d.ts +9 -0
  39. package/dist/effect/glsl/custom-glsl.d.ts +1043 -0
  40. package/dist/effect/glsl/gl-effect.d.ts +38 -0
  41. package/dist/effect/interface/index.d.ts +25 -0
  42. package/dist/effect/types.d.ts +26 -0
  43. package/dist/effect/vertex.d.ts +1 -0
  44. package/dist/event-emitter.d.ts +55 -0
  45. package/dist/filters/outline-filter.d.ts +28 -0
  46. package/dist/index.d.ts +27 -0
  47. package/dist/index.es.js +16144 -0
  48. package/dist/index.es.js.map +1 -0
  49. package/dist/index.umd.cjs +3335 -0
  50. package/dist/index.umd.cjs.map +1 -0
  51. package/dist/json-serialization.d.ts +312 -0
  52. package/dist/mp4-utils/index.d.ts +31 -0
  53. package/dist/mp4-utils/mp4box-utils.d.ts +44 -0
  54. package/dist/mp4-utils/sample-transform.d.ts +26 -0
  55. package/dist/sprite/base-sprite.d.ts +273 -0
  56. package/dist/sprite/pixi-sprite-renderer.d.ts +69 -0
  57. package/dist/standalone/index.es.js +94191 -0
  58. package/dist/standalone/index.es.js.map +1 -0
  59. package/dist/studio/history-manager.d.ts +46 -0
  60. package/dist/studio/resource-manager.d.ts +53 -0
  61. package/dist/studio/selection-manager.d.ts +66 -0
  62. package/dist/studio/timeline-model.d.ts +117 -0
  63. package/dist/studio/transport.d.ts +44 -0
  64. package/dist/studio-bridge.d.ts +50 -0
  65. package/dist/studio.d.ts +529 -0
  66. package/dist/transformer/handle.d.ts +17 -0
  67. package/dist/transformer/snapping.d.ts +45 -0
  68. package/dist/transformer/transformer.d.ts +38 -0
  69. package/dist/transformer/wireframe.d.ts +5 -0
  70. package/dist/transition/fragment.d.ts +1 -0
  71. package/dist/transition/glsl/custom-glsl.d.ts +231 -0
  72. package/dist/transition/glsl/gl-transition.d.ts +42 -0
  73. package/dist/transition/transition.d.ts +6 -0
  74. package/dist/transition/types.d.ts +31 -0
  75. package/dist/transition/uniforms.d.ts +35 -0
  76. package/dist/transition/vertex.d.ts +1 -0
  77. package/dist/utils/asset-manager.d.ts +15 -0
  78. package/dist/utils/audio-codec-detector.d.ts +39 -0
  79. package/dist/utils/audio.d.ts +81 -0
  80. package/dist/utils/chromakey.d.ts +24 -0
  81. package/dist/utils/color-adjustment.d.ts +53 -0
  82. package/dist/utils/color.d.ts +17 -0
  83. package/dist/utils/common.d.ts +7 -0
  84. package/dist/utils/dom.d.ts +48 -0
  85. package/dist/utils/effect.d.ts +1 -0
  86. package/dist/utils/fonts.d.ts +21 -0
  87. package/dist/utils/index.d.ts +6 -0
  88. package/dist/utils/log.d.ts +27 -0
  89. package/dist/utils/media-cache.d.ts +45 -0
  90. package/dist/utils/stream-utils.d.ts +4 -0
  91. package/dist/utils/video.d.ts +16 -0
  92. package/dist/utils/worker-timer.d.ts +1 -0
  93. package/package.json +63 -3
@@ -0,0 +1,45 @@
1
+ import { BaseClip } from './base-clip';
2
+ import { IClip } from './iclip';
3
+ import { TransitionKey } from '../transition/glsl/gl-transition';
4
+ export declare class Transition extends BaseClip {
5
+ readonly type = "Transition";
6
+ ready: IClip["ready"];
7
+ private _meta;
8
+ get meta(): {
9
+ duration: number;
10
+ width: number;
11
+ height: number;
12
+ };
13
+ /**
14
+ * Unique identifier for this clip instance
15
+ */
16
+ id: string;
17
+ /**
18
+ * The transition key
19
+ */
20
+ transitionKey: TransitionKey;
21
+ /**
22
+ * ID of the clip from which the transition starts
23
+ */
24
+ fromClipId: string | null;
25
+ /**
26
+ * ID of the clip to which the transition ends
27
+ */
28
+ toClipId: string | null;
29
+ /**
30
+ * Custom shader parameter values (uniform name -> value)
31
+ */
32
+ values: Record<string, any>;
33
+ constructor(transitionKey: TransitionKey);
34
+ clone(): Promise<this>;
35
+ tick(_time: number): Promise<{
36
+ video: ImageBitmap | undefined;
37
+ state: "success";
38
+ }>;
39
+ split(_time: number): Promise<[this, this]>;
40
+ toJSON(_main?: boolean): any;
41
+ /**
42
+ * Create a Transition instance from a JSON object
43
+ */
44
+ static fromObject(json: any): Promise<Transition>;
45
+ }
@@ -0,0 +1,216 @@
1
+ import { MP4Sample } from 'wrapbox';
2
+ import { file } from 'opfs-tools';
3
+ import { BaseClip } from './base-clip';
4
+ import { IClip, IPlaybackCapable } from './iclip';
5
+ import { VideoJSON } from '../json-serialization';
6
+ type OPFSToolFile = ReturnType<typeof file>;
7
+ type MPClipCloneArgs = Awaited<ReturnType<typeof mp4FileToSamples>> & {
8
+ localFile: OPFSToolFile;
9
+ };
10
+ interface MP4DecoderConf {
11
+ video: VideoDecoderConfig | null;
12
+ audio: AudioDecoderConfig | null;
13
+ }
14
+ export interface IMP4ClipOpts {
15
+ audio?: boolean | {
16
+ volume: number;
17
+ };
18
+ /**
19
+ * Unsafe, may be deprecated at any time
20
+ */
21
+ __unsafe_hardwareAcceleration__?: HardwarePreference;
22
+ }
23
+ type ExtMP4Sample = Omit<MP4Sample, "data"> & {
24
+ is_idr: boolean;
25
+ deleted?: boolean;
26
+ data: null | Uint8Array;
27
+ };
28
+ /**
29
+ * Video clip, parses MP4 files, uses {@link Video.tick} to decode image frames at specified time on demand
30
+ *
31
+ * Can be used to implement video frame extraction, thumbnail generation, video editing and other functions
32
+ *
33
+ * @example
34
+ * // Load video clip asynchronously
35
+ * const videoClip = await Video.fromUrl('clip.mp4', {
36
+ * x: 0,
37
+ * y: 0,
38
+ * width: 1920,
39
+ * height: 1080,
40
+ * });
41
+ *
42
+ * // Set timeline position
43
+ * videoClip.set({
44
+ * display: {
45
+ * from: 150, // frames
46
+ * to: 450, // frames (10 seconds at 30fps)
47
+ * },
48
+ * });
49
+ *
50
+ */
51
+ export declare class Video extends BaseClip implements IPlaybackCapable {
52
+ readonly type = "Video";
53
+ private insId;
54
+ private logger;
55
+ ready: IClip["ready"];
56
+ private _meta;
57
+ get meta(): {
58
+ duration: number;
59
+ width: number;
60
+ height: number;
61
+ audioSampleRate: number;
62
+ audioChanCount: number;
63
+ };
64
+ private localFile;
65
+ /** Store binary data of video header (box: ftyp, moov) */
66
+ private headerBoxPos;
67
+ /**
68
+ * Provide binary data of video header (box: ftyp, moov)
69
+ * Use any mp4 demuxer to parse and get detailed video information
70
+ * Unit tests include sample code using mp4box.js
71
+ */
72
+ getFileHeaderBinData(): Promise<ArrayBuffer>;
73
+ /** Store video transform and rotation info, currently only restores rotation */
74
+ private parsedMatrix;
75
+ private vfRotater;
76
+ private videoSamples;
77
+ private audioSamples;
78
+ private videoFrameFinder;
79
+ private audioFrameFinder;
80
+ protected onEffectiveVolumeChange(): void;
81
+ private decoderConf;
82
+ private opts;
83
+ /**
84
+ * Whether to include audio track (hybrid JSON structure)
85
+ */
86
+ audio: boolean;
87
+ /**
88
+ * Unique identifier for this clip instance
89
+ */
90
+ id: string;
91
+ /**
92
+ * Array of effects to be applied to this clip
93
+ * Each effect specifies key, startTime, duration, and optional targets
94
+ */
95
+ effects: Array<{
96
+ id: string;
97
+ key: string;
98
+ startTime: number;
99
+ duration: number;
100
+ }>;
101
+ getVisibleHandles(): Array<"tl" | "tr" | "bl" | "br" | "ml" | "mr" | "mt" | "mb" | "rot">;
102
+ /**
103
+ * Load a video clip from a URL
104
+ * @param url Video URL
105
+ * @param opts Position and size options
106
+ * @returns Promise that resolves to a video clip
107
+ *
108
+ * @example
109
+ * const videoClip = await Video.fromUrl('clip.mp4', {
110
+ * x: 0,
111
+ * y: 0,
112
+ * width: 1920,
113
+ * height: 1080,
114
+ * });
115
+ */
116
+ static fromUrl(url: string, opts?: {
117
+ x?: number;
118
+ y?: number;
119
+ width?: number;
120
+ height?: number;
121
+ }): Promise<Video>;
122
+ constructor(source: OPFSToolFile | ReadableStream<Uint8Array> | MPClipCloneArgs, opts?: IMP4ClipOpts, src?: string);
123
+ /**
124
+ * Intercept data returned by {@link Video.tick} method for secondary processing of image and audio data
125
+ * @param time Time when tick was called
126
+ * @param tickRet Data returned by tick
127
+ *
128
+ * */
129
+ tickInterceptor: <T extends Awaited<ReturnType<Video["tick"]>>>(time: number, tickRet: T) => Promise<T>;
130
+ /**
131
+ * Get image frame and audio data at specified time
132
+ * @param time Time in microseconds
133
+ */
134
+ tick(time: number): Promise<{
135
+ video?: VideoFrame;
136
+ audio: Float32Array[];
137
+ state: "success" | "done";
138
+ }>;
139
+ addEffect(effect: {
140
+ id: string;
141
+ key: string;
142
+ startTime: number;
143
+ duration: number;
144
+ }): void;
145
+ editEffect(effectId: string, newEffectData: Partial<{
146
+ key: string;
147
+ startTime: number;
148
+ duration: number;
149
+ }>): void;
150
+ removeEffect(effectId: string): void;
151
+ /**
152
+ * Split is handled by core state, not implemented here
153
+ */
154
+ split(_time: number): Promise<[this, this]>;
155
+ clone(): Promise<this>;
156
+ destroy(): void;
157
+ toJSON(main?: boolean): VideoJSON;
158
+ /**
159
+ * Create a Video instance from a JSON object (fabric.js pattern)
160
+ * @param json The JSON object representing the clip
161
+ * @returns Promise that resolves to a Video instance
162
+ */
163
+ static fromObject(json: VideoJSON): Promise<Video>;
164
+ /**
165
+ * Create HTMLVideoElement for playback
166
+ */
167
+ createPlaybackElement(): Promise<{
168
+ element: HTMLVideoElement;
169
+ objectUrl?: string;
170
+ }>;
171
+ play(element: HTMLVideoElement | HTMLAudioElement, timeSeconds: number): Promise<void>;
172
+ pause(element: HTMLVideoElement | HTMLAudioElement): void;
173
+ seek(element: HTMLVideoElement | HTMLAudioElement, timeSeconds: number): Promise<void>;
174
+ syncPlayback(element: HTMLVideoElement | HTMLAudioElement, isPlaying: boolean, timeSeconds: number): void;
175
+ cleanupPlayback(element: HTMLVideoElement | HTMLAudioElement, objectUrl?: string): void;
176
+ /**
177
+ * Scale clip to fit within the scene dimensions while maintaining aspect ratio
178
+ * Similar to fabric.js scaleToFit
179
+ * @param sceneWidth Scene width
180
+ * @param sceneHeight Scene height
181
+ */
182
+ scaleToFit(sceneWidth: number, sceneHeight: number): Promise<void>;
183
+ /**
184
+ * Scale clip to fill the scene dimensions while maintaining aspect ratio
185
+ * May crop parts of the clip. Similar to fabric.js scaleToFill
186
+ * @param sceneWidth Scene width
187
+ * @param sceneHeight Scene height
188
+ */
189
+ scaleToFill(sceneWidth: number, sceneHeight: number): Promise<void>;
190
+ /**
191
+ * Center the clip within the scene dimensions
192
+ * Similar to fabric.js center
193
+ * @param sceneWidth Scene width
194
+ * @param sceneHeight Scene height
195
+ */
196
+ centerInScene(sceneWidth: number, sceneHeight: number): void;
197
+ }
198
+ declare function mp4FileToSamples(otFile: OPFSToolFile, opts?: IMP4ClipOpts): Promise<{
199
+ videoSamples: ExtMP4Sample[];
200
+ audioSamples: ExtMP4Sample[];
201
+ decoderConf: MP4DecoderConf;
202
+ headerBoxPos: {
203
+ start: number;
204
+ size: number;
205
+ }[];
206
+ parsedMatrix: {
207
+ perspective: number;
208
+ rotationRad: number;
209
+ rotationDeg: number;
210
+ scaleX: number;
211
+ scaleY: number;
212
+ translateX: number;
213
+ translateY: number;
214
+ };
215
+ }>;
216
+ export {};
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Buffer input data and convert to AudioData with fixed frame count.
3
+ * Matches the WebCodecs audio configuration.
4
+ *
5
+ * @param framesPerChunk Number of audio frames per AudioData instance
6
+ * @param fps The video fps (used for calculating buffer limits)
7
+ */
8
+ export declare function createAudioTrackBuf(framesPerChunk: number, fps?: number): (timestamp: number, trackAudios: Float32Array[][]) => AudioData[];
@@ -0,0 +1,17 @@
1
+ import { recodemux } from 'wrapbox';
2
+ /**
3
+ * Resolve the WebGL/WebGL2 context already held by an OffscreenCanvas.
4
+ * Returns null if no WebGL context is attached (e.g. canvas not yet used).
5
+ */
6
+ export declare function getCanvasGl(canvas: OffscreenCanvas): WebGLRenderingContext | WebGL2RenderingContext | null;
7
+ /**
8
+ * Creates an AV encoder function that queues and encodes both mixed AudioData and VideoFrames.
9
+ */
10
+ export declare function createAVEncoder(opts: {
11
+ muxer: ReturnType<typeof recodemux>;
12
+ canvas: OffscreenCanvas;
13
+ outputAudio?: boolean;
14
+ hasVideoTrack: boolean;
15
+ timeSlice: number;
16
+ fps: number;
17
+ }): (timestamp: number, audios: Float32Array[][], hasVideo: boolean) => Promise<void>;
@@ -0,0 +1,23 @@
1
+ import { Container, Sprite, Texture, Graphics } from 'pixi.js';
2
+ import { IClip } from '../clips';
3
+ export interface IPooledClipObjects {
4
+ root: Container;
5
+ mainSprite: Sprite;
6
+ mirrors: Sprite[];
7
+ maskGfx: Graphics | null;
8
+ strokeGfx: Graphics | null;
9
+ shadowGfx: Graphics | null;
10
+ }
11
+ /**
12
+ * Applies layout transforms, mirrors, filters (blur, adjustments, chroma, hsl), and decoration styles
13
+ * (border radius, strokes, drop shadows) to a set of PixiJS containers and sprites representing a clip.
14
+ */
15
+ export declare function applyClipStylesAndFilters(opts: {
16
+ clip: IClip;
17
+ tex: Texture;
18
+ rootContainer: Container;
19
+ tempSprite: Sprite;
20
+ pooled: IPooledClipObjects;
21
+ scaleX: number;
22
+ scaleY: number;
23
+ }): void;
@@ -0,0 +1,29 @@
1
+ import { Application } from 'pixi.js';
2
+ import { IClip } from '../clips';
3
+ export interface ISpritesRenderOpts {
4
+ pixiApp: Application | null;
5
+ backgroundColor: string;
6
+ sprites: Array<IClip & {
7
+ main: boolean;
8
+ expired: boolean;
9
+ }>;
10
+ aborter: {
11
+ aborted: boolean;
12
+ };
13
+ scaleX: number;
14
+ scaleY: number;
15
+ }
16
+ export interface ISpritesRenderResult {
17
+ render: (timestamp: number) => Promise<{
18
+ audios: Float32Array[][];
19
+ mainSprDone: boolean;
20
+ hasVideo: boolean;
21
+ }>;
22
+ cleanup: () => void;
23
+ }
24
+ /**
25
+ * Creates the renderer pipeline for compositor frames.
26
+ * Delegates actual transition handling, asset transformations, styles/filters,
27
+ * and global effects pipeline execution to separate managers.
28
+ */
29
+ export declare function createSpritesRender(opts: ISpritesRenderOpts): ISpritesRenderResult;
@@ -0,0 +1,30 @@
1
+ import { Application, Container, Sprite } from 'pixi.js';
2
+ import { IClip } from '../clips';
3
+ import { PixiSpriteRenderer } from '../sprite/pixi-sprite-renderer';
4
+ export declare class EffectManager {
5
+ private pixiApp;
6
+ private effectCache;
7
+ private effectInputTexture;
8
+ private scaleX;
9
+ private scaleY;
10
+ constructor(pixiApp: Application, hasVideoTrack: boolean, scaleX?: number, scaleY?: number);
11
+ /**
12
+ * Processes all active global and adjustment layer effects at the given timestamp.
13
+ */
14
+ processEffects(opts: {
15
+ timestamp: number;
16
+ sprites: Array<IClip & {
17
+ expired?: boolean;
18
+ }>;
19
+ spriteById: Map<string, IClip>;
20
+ spriteIndexById: Map<string, number>;
21
+ spriteRenderers: Map<IClip & {
22
+ expired?: boolean;
23
+ }, PixiSpriteRenderer>;
24
+ transitionSprites: Map<string, Sprite>;
25
+ clipsEffectContainer: Container;
26
+ clipsNormalContainer: Container;
27
+ postProcessContainer: Container;
28
+ }): Promise<void>;
29
+ cleanup(): void;
30
+ }
@@ -0,0 +1,8 @@
1
+ export declare function yieldToScheduler(): Promise<void>;
2
+ /** Max frames allowed in the VideoEncoder queue before back-pressure kicks in. */
3
+ export declare const ENCODER_QUEUE_LIMIT = 20;
4
+ /**
5
+ * Wait until the encoder queue drains below the limit.
6
+ * Prevents OOM from too many queued VideoFrames.
7
+ */
8
+ export declare function waitEncoderQueue(getQueueSize: () => number): Promise<void>;
@@ -0,0 +1,45 @@
1
+ import { Application, Container, Sprite } from 'pixi.js';
2
+ import { IClip, Transition } from '../clips';
3
+ export declare class TransitionManager {
4
+ private pixiApp;
5
+ private scaleX;
6
+ private scaleY;
7
+ private transitionRenderers;
8
+ private transitionSprites;
9
+ private transFromTexture;
10
+ private transToTexture;
11
+ private transBgGraphics;
12
+ private transClipPool;
13
+ constructor(pixiApp: Application, scaleX: number, scaleY: number);
14
+ /**
15
+ * Reset the visibility of all transition sprites at the start of a frame.
16
+ */
17
+ resetFrame(): void;
18
+ /**
19
+ * Checks if a transition sprite has been created for a given ID.
20
+ */
21
+ getTransitionSprite(id: string): Sprite | undefined;
22
+ /**
23
+ * Retrieve pool container/sprite elements for a given clip to avoid allocations.
24
+ */
25
+ private getTransClipObjects;
26
+ private getClipFrameAtTimestamp;
27
+ private renderClipToTransitionTexture;
28
+ /**
29
+ * Render transition between two clips at a given timeline timestamp.
30
+ * Modifies target claimed set and updates internal transition sprite.
31
+ */
32
+ renderTransition(opts: {
33
+ sprite: Transition & {
34
+ expired?: boolean;
35
+ };
36
+ timestamp: number;
37
+ fromClip: IClip;
38
+ toClip: IClip;
39
+ getFrameCached: (clip: IClip, timestamp: number) => Promise<any>;
40
+ clipsNormalContainer: Container;
41
+ clipsClaimedByTransition: Set<string>;
42
+ onVideoState: () => void;
43
+ }): Promise<boolean>;
44
+ cleanup(): void;
45
+ }
@@ -0,0 +1,157 @@
1
+ import { IClip } from './clips';
2
+ import { default as EventEmitter } from './event-emitter';
3
+ import { ProjectJSON } from './json-serialization';
4
+ export interface ICompositorOpts {
5
+ width?: number;
6
+ height?: number;
7
+ bitrate?: number;
8
+ fps?: number;
9
+ backgroundColor?: string;
10
+ format?: string;
11
+ videoCodec?: string;
12
+ /**
13
+ * If false, exclude audio track from the output video
14
+ */
15
+ audio?: false;
16
+ audioCodec?: string;
17
+ audioSampleRate?: number;
18
+ /**
19
+ * Write metadata tags to the output video
20
+ */
21
+ metaDataTags?: Record<string, string>;
22
+ /**
23
+ * Unsafe, may be deprecated at any time
24
+ */
25
+ __unsafe_hardwareAcceleration__?: HardwarePreference;
26
+ }
27
+ /**
28
+ * Video compositor that can add multiple {@link OffscreenSprite} instances,
29
+ * @example
30
+ * const spr1 = new OffscreenSprite(
31
+ * new Video((await fetch('<mp4 url>')).body),
32
+ * );
33
+ * const spr2 = new OffscreenSprite(
34
+ * await Audio.fromUrl('<audio url>'),
35
+ * );
36
+ * const com = new Compositor({ width: 1280, height: 720, });
37
+
38
+ * await com.addSprite(spr1);
39
+ * await com.addSprite(spr2);
40
+
41
+ * com.output(); // => ReadableStream
42
+ *
43
+ */
44
+ export declare class Compositor extends EventEmitter<{
45
+ "export:progress": number;
46
+ error: Error;
47
+ }> {
48
+ /**
49
+ * Check compatibility with the current environment
50
+ * @param args.videoCodec Specify video codec, default avc1.42E032
51
+ * @param args.width Specify video width, default 1920
52
+ * @param args.height Specify video height, default 1080
53
+ * @param args.bitrate Specify video bitrate, default 5e6
54
+ */
55
+ static isSupported(args?: {
56
+ videoCodec?: string;
57
+ width?: number;
58
+ height?: number;
59
+ bitrate?: number;
60
+ }): Promise<boolean>;
61
+ private logger;
62
+ private destroyed;
63
+ private sprites;
64
+ private canvas;
65
+ private pixiApp;
66
+ private stopOutput;
67
+ private opts;
68
+ /** Encodable audio chosen for output (undefined = not resolved yet, null = audio must be skipped) */
69
+ private resolvedAudio;
70
+ private explicitOpts;
71
+ private hasVideoTrack;
72
+ private jsonDimensions;
73
+ /**
74
+ * Create a compositor instance based on configuration
75
+ * @param opts ICompositorOpts
76
+ */
77
+ constructor(opts?: ICompositorOpts);
78
+ initPixiApp(): Promise<void>;
79
+ /**
80
+ * Settles which audio codec/sample rate output() will use, falling back when the requested one
81
+ * isn't encodable here (e.g. no AAC encoder in headless Chromium). Called by initPixiApp and
82
+ * loadFromJSON, which callers await before output().
83
+ */
84
+ private resolveAudioEncoding;
85
+ /**
86
+ * Add a clip for video composition. Video duration defaults to the maximum duration value from all clips
87
+ * @param clip Clip (extends BaseSprite)
88
+ * @param opts.main If main is true, the video duration uses this clip's duration value
89
+ */
90
+ addSprite(clip: IClip, opts?: {
91
+ main?: boolean;
92
+ }): Promise<void>;
93
+ private initMuxer;
94
+ /**
95
+ * Output video file binary stream
96
+ * @param opts.maxTime Maximum duration allowed for output video, content exceeding this will be ignored
97
+ */
98
+ output(opts?: {
99
+ maxTime?: number;
100
+ }): ReadableStream<Uint8Array>;
101
+ /**
102
+ * Destroy instance and release resources
103
+ */
104
+ destroy(): void;
105
+ private runEncoding;
106
+ /**
107
+ * Export current compositor state to JSON
108
+ */
109
+ exportToJSON(): ProjectJSON;
110
+ /**
111
+ * Load clips from JSON
112
+ * @param json The JSON project data
113
+ */
114
+ loadFromJSON(json: ProjectJSON): Promise<void>;
115
+ /**
116
+ * Renders the frame at the given time and returns it as a base64-encoded PNG.
117
+ *
118
+ * Initialises the internal Pixi application on demand (if not already
119
+ * initialised), performs a single-frame render using the same sprite
120
+ * pipeline as {@link output}, and returns the result without modifying
121
+ * the compositor's encoding state.
122
+ *
123
+ * @param timeMs Time in milliseconds
124
+ * @param options.transparent If true, the renderer background is made
125
+ * transparent so the resulting PNG has a transparent background.
126
+ * @returns Base64 data-URL string (e.g. "data:image/png;base64,...")
127
+ *
128
+ * @example
129
+ * const compositor = new Compositor({ width: 1280, height: 720 });
130
+ * await compositor.addSprite(videoClip);
131
+ * const frame = await compositor.renderFrame(2000); // frame at 2 s
132
+ * const transparent = await compositor.renderFrame(2000, { transparent: true });
133
+ */
134
+ renderFrame(timeMs: number, options?: {
135
+ transparent?: boolean;
136
+ }): Promise<string>;
137
+ /**
138
+ * Alias for {@link renderFrame} with an optional timestamp.
139
+ * Captures a single frame as a base64-encoded PNG.
140
+ *
141
+ * @param timeMs Optional time in milliseconds, or an options object. If
142
+ * omitted, the first frame at time 0 is captured.
143
+ * @param options.transparent If true, the renderer background is made
144
+ * transparent so the resulting PNG has a transparent background.
145
+ * @returns Base64 data-URL string (e.g. "data:image/png;base64,...")
146
+ *
147
+ * @example
148
+ * const compositor = new Compositor({ width: 1280, height: 720 });
149
+ * await compositor.addSprite(videoClip);
150
+ * const firstFrame = await compositor.snapshot(); // time 0
151
+ * const frameAt2s = await compositor.snapshot(2000); // explicit timestamp
152
+ * const transparent = await compositor.snapshot({ transparent: true }); // time 0, transparent
153
+ */
154
+ snapshot(timeMs?: number | {
155
+ transparent?: boolean;
156
+ }): Promise<string>;
157
+ }