@designcombo/video 0.0.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 (47) hide show
  1. package/LICENSE +63 -0
  2. package/dist/SharedSystems-BSw9neqH.js +2691 -0
  3. package/dist/WebGLRenderer-BrabW-VK.js +2639 -0
  4. package/dist/WebGPURenderer-BKwBKkzk.js +1655 -0
  5. package/dist/browserAll-C7HVZtqZ.js +1876 -0
  6. package/dist/clips/audio-clip.d.ts +132 -0
  7. package/dist/clips/base-clip.d.ts +86 -0
  8. package/dist/clips/caption-clip.d.ts +257 -0
  9. package/dist/clips/iclip.d.ts +120 -0
  10. package/dist/clips/image-clip.d.ts +110 -0
  11. package/dist/clips/index.d.ts +8 -0
  12. package/dist/clips/text-clip.d.ts +192 -0
  13. package/dist/clips/video-clip.d.ts +200 -0
  14. package/dist/colorToUniform-Du0ROyNd.js +274 -0
  15. package/dist/compositor.d.ts +111 -0
  16. package/dist/index-CjzowIhV.js +28270 -0
  17. package/dist/index.d.ts +14 -0
  18. package/dist/index.es.js +20 -0
  19. package/dist/index.umd.js +1295 -0
  20. package/dist/internal-utils/event-tool.d.ts +50 -0
  21. package/dist/internal-utils/index.d.ts +14 -0
  22. package/dist/internal-utils/log.d.ts +34 -0
  23. package/dist/internal-utils/meta-box.d.ts +1 -0
  24. package/dist/internal-utils/recodemux.d.ts +65 -0
  25. package/dist/internal-utils/stream-utils.d.ts +43 -0
  26. package/dist/internal-utils/worker-timer.d.ts +8 -0
  27. package/dist/json-serialization.d.ts +142 -0
  28. package/dist/mp4-utils/index.d.ts +31 -0
  29. package/dist/mp4-utils/mp4box-utils.d.ts +36 -0
  30. package/dist/mp4-utils/sample-transform.d.ts +23 -0
  31. package/dist/sprite/base-sprite.d.ts +147 -0
  32. package/dist/sprite/pixi-sprite-renderer.d.ts +48 -0
  33. package/dist/studio.d.ts +142 -0
  34. package/dist/transfomer/parts/handle.d.ts +17 -0
  35. package/dist/transfomer/parts/wireframe.d.ts +5 -0
  36. package/dist/transfomer/transformer.d.ts +21 -0
  37. package/dist/utils/audio.d.ts +82 -0
  38. package/dist/utils/chromakey.d.ts +24 -0
  39. package/dist/utils/color.d.ts +4 -0
  40. package/dist/utils/common.d.ts +7 -0
  41. package/dist/utils/dom.d.ts +48 -0
  42. package/dist/utils/fonts.d.ts +16 -0
  43. package/dist/utils/index.d.ts +5 -0
  44. package/dist/utils/srt-parser.d.ts +15 -0
  45. package/dist/utils/video.d.ts +18 -0
  46. package/dist/webworkerAll-DsE6HIYE.js +2497 -0
  47. package/package.json +53 -0
@@ -0,0 +1,50 @@
1
+ type EventKey = string | symbol;
2
+ type EventToolType = Record<EventKey, (...args: any[]) => any>;
3
+ /**
4
+ * Event utility class
5
+ *
6
+ * @example
7
+ * const evtTool = new EventTool<{
8
+ * timeupdate: (time: number) => void;
9
+ * paused: () => void;
10
+ * playing: () => void;
11
+ * }>()
12
+ * evtTool.on('paused', () => {})
13
+ * evtTool.emit('paused')
14
+ */
15
+ export declare class EventTool<T extends EventToolType> {
16
+ /**
17
+ * Forward messages between two EventTool instances
18
+ * @param from
19
+ * @param to
20
+ * @param evtTypes Message types that need to be forwarded
21
+ *
22
+ * @example
23
+ * EventTool.forwardEvent(from, to, ['evtName']),
24
+ */
25
+ static forwardEvent<T1 extends EventToolType, T2 extends EventToolType, EvtType extends (keyof T1 | [keyof T1, keyof T2])[]>(from: {
26
+ on: EventTool<T1>['on'];
27
+ }, to: {
28
+ emit: EventTool<T2>['emit'];
29
+ }, evtTypes: EvtType): () => void;
30
+ private listeners;
31
+ /**
32
+ * Listen to events defined in EventType
33
+ */
34
+ on: <Type extends keyof T>(type: Type, listener: T[Type]) => (() => void);
35
+ /**
36
+ * Listen to event, automatically remove listener after first trigger
37
+ *
38
+ * For events that expect to callback once, use once; for events that expect multiple callbacks use on
39
+ */
40
+ once: <Type extends keyof T>(type: Type, listener: T[Type]) => (() => void);
41
+ /**
42
+ * Emit event
43
+ * @param type
44
+ * @param args
45
+ * @returns
46
+ */
47
+ emit: <Type extends keyof T>(type: Type, ...args: Type extends string ? T[Type] extends (...args: any[]) => any ? Parameters<T[Type]> : never : never) => void;
48
+ destroy(): void;
49
+ }
50
+ export {};
@@ -0,0 +1,14 @@
1
+ export { EventTool } from './event-tool';
2
+ export { Log } from './log';
3
+ export { recodemux } from './recodemux';
4
+ export { autoReadStream, file2stream } from './stream-utils';
5
+ export { workerTimer } from './worker-timer';
6
+ /**
7
+ * 函数节流
8
+ */
9
+ export declare function throttle<F extends (...args: any[]) => any>(func: F, wait: number): (...rest: Parameters<F>) => undefined | ReturnType<F>;
10
+ /**
11
+ * 函数防抖
12
+ * 在指定时间内多次调用,只执行最后一次
13
+ */
14
+ export declare function debounce<F extends (...args: any[]) => any>(func: F, wait: number): (...rest: Parameters<F>) => void;
@@ -0,0 +1,34 @@
1
+ /**
2
+ * 全局日志对象,将日志内容写入 OPFS 临时文件
3
+ */
4
+ export declare const Log: {
5
+ /**
6
+ * 生成一个 log 实例,所有输出前都会附加 tag
7
+ *
8
+ * @example
9
+ * const log = Log.create('<prefix>')
10
+ * log.info('xxx') // '<prefix> xxx'
11
+ */
12
+ create: (tag: string) => {
13
+ [k: string]: (...args: any[]) => void;
14
+ };
15
+ /**
16
+ * 将所有日志导出为一个字符串
17
+ *
18
+ * @example
19
+ * Log.dump() // => [level][time] 内容...
20
+ *
21
+ */
22
+ dump(): Promise<string>;
23
+ debug: (...data: any[]) => void;
24
+ info: (...data: any[]) => void;
25
+ warn: (...data: any[]) => void;
26
+ error: (...data: any[]) => void;
27
+ /**
28
+ * 设置记录日志的级别
29
+ *
30
+ * @example
31
+ * Log.setLogLevel(Log.warn) // 记录 warn,error 日志
32
+ */
33
+ setLogLevel: <T extends Function>(logfn: T) => void;
34
+ };
@@ -0,0 +1 @@
1
+ export declare const createMetaBox: (data: Record<string, string>) => Uint8Array;
@@ -0,0 +1,65 @@
1
+ import { MP4File } from '@webav/mp4box.js';
2
+ type CleanFn = () => void;
3
+ /**
4
+ * Configuration options for recodemux function
5
+ */
6
+ interface RecodeMuxOpts {
7
+ /**
8
+ * Video configuration options, if null then video is not processed
9
+ */
10
+ video: {
11
+ width: number;
12
+ height: number;
13
+ expectFPS: number;
14
+ codec: string;
15
+ bitrate: number;
16
+ /**
17
+ * Unsafe, may be deprecated at any time
18
+ */
19
+ __unsafe_hardwareAcceleration__?: HardwareAcceleration;
20
+ } | null;
21
+ /**
22
+ * Audio configuration options, if null then audio is not processed
23
+ */
24
+ audio: {
25
+ codec: 'opus' | 'aac';
26
+ sampleRate: number;
27
+ channelCount: number;
28
+ } | null;
29
+ /**
30
+ * Preset duration, does not represent actual track duration
31
+ */
32
+ duration?: number;
33
+ metaDataTags?: Record<string, string>;
34
+ }
35
+ /**
36
+ * Handle audio and video encoding and decoding
37
+ * @param opts - Configuration for encoding audio and video data
38
+ */
39
+ export declare function recodemux(opts: RecodeMuxOpts): {
40
+ /**
41
+ * Encode video frame
42
+ */
43
+ encodeVideo: (frame: VideoFrame, options: VideoEncoderEncodeOptions, gopId?: number) => void;
44
+ /**
45
+ * Encode audio data
46
+ */
47
+ encodeAudio: (data: AudioData) => void;
48
+ /**
49
+ * Close encoder, stop task
50
+ */
51
+ close: CleanFn;
52
+ /**
53
+ * Flush encoder queue
54
+ */
55
+ flush: () => Promise<void>;
56
+ /**
57
+ * mp4box instance
58
+ */
59
+ mp4file: MP4File;
60
+ /**
61
+ * Returns queue length (backpressure), used to control video production progress, excessive queue will占用大量显存
62
+ */
63
+ getEncodeQueueSize: () => number;
64
+ };
65
+ export {};
@@ -0,0 +1,43 @@
1
+ import { MP4File } from '@webav/mp4box.js';
2
+ /**
3
+ * 自动读取流并处理每个数据块。
4
+ *
5
+ * @template ST - 可读流的类型。
6
+ * @param stream - 要读取的流。
7
+ * @param cbs - 回调函数对象。
8
+ * @param cbs.onChunk - 当读取到新的数据块时调用的函数。该函数接收一个参数,即数据块,并返回一个 Promise。
9
+ * @param cbs.onDone - 当读取完所有数据块时调用的函数。
10
+ * @returns - 返回一个函数,调用该函数可以停止读取流。
11
+ *
12
+ * @example
13
+ * const stream = getSomeReadableStream();
14
+ * const onChunk = async (chunk) => {
15
+ * console.log('New chunk:', chunk);
16
+ * };
17
+ * const onDone = () => {
18
+ * console.log('Done reading stream');
19
+ * };
20
+ * const stopReading = autoReadStream(stream, { onChunk, onDone });
21
+ * // Later...
22
+ * stopReading();
23
+ */
24
+ export declare function autoReadStream<ST extends ReadableStream>(stream: ST, cbs: {
25
+ onChunk: ST extends ReadableStream<infer DT> ? (chunk: DT) => Promise<void> : never;
26
+ onDone: () => void;
27
+ }): () => void;
28
+ /**
29
+ * 将 mp4box file 转换为文件流,用于上传服务器或存储到本地
30
+ * @param file - MP4 文件实例 {@link MP4File}。
31
+ * @param timeSlice - 时间片,用于控制流的发送速度。
32
+ * @param onCancel - 当返回的流被取消时触发该回调函数
33
+ */
34
+ export declare function file2stream(file: MP4File, timeSlice: number, onCancel?: () => void): {
35
+ /**
36
+ * 可读流,流的数据是 `Uint8Array`
37
+ */
38
+ stream: ReadableStream<Uint8Array>;
39
+ /**
40
+ * 流的生产者主动停止向流中输出数据,可向消费者传递错误信息
41
+ */
42
+ stop: (err?: Error) => void;
43
+ };
@@ -0,0 +1,8 @@
1
+ /**
2
+ * 专门解决页面长时间处于后台时,定时器不(或延迟)执行的问题
3
+ *
4
+ * 跟 `setInterval` 很相似,⚠️ 但 time 会有一定偏差,请优先使用 `setInterval`
5
+ *
6
+ * @see [JS 定时器时长控制细节](https://hughfenghen.github.io/posts/2023/06/15/timer-delay/)
7
+ */
8
+ export declare const workerTimer: (handler: () => void, time: number) => (() => void);
@@ -0,0 +1,142 @@
1
+ import { IClip } from './clips';
2
+ interface BaseClipJSON {
3
+ src: string;
4
+ display: {
5
+ from: number;
6
+ to: number;
7
+ };
8
+ playbackRate: number;
9
+ duration: number;
10
+ left: number;
11
+ top: number;
12
+ width: number;
13
+ height: number;
14
+ angle: number;
15
+ zIndex: number;
16
+ opacity: number;
17
+ flip: 'horizontal' | 'vertical' | null;
18
+ animation?: {
19
+ keyFrames: Record<string, Partial<{
20
+ x: number;
21
+ y: number;
22
+ w: number;
23
+ h: number;
24
+ angle: number;
25
+ opacity: number;
26
+ }>>;
27
+ opts: {
28
+ duration: number;
29
+ delay?: number;
30
+ iterCount?: number;
31
+ };
32
+ };
33
+ main?: boolean;
34
+ }
35
+ export interface VideoClipJSON extends BaseClipJSON {
36
+ type: 'Video';
37
+ audio?: boolean;
38
+ }
39
+ export interface AudioClipJSON extends BaseClipJSON {
40
+ type: 'Audio';
41
+ loop?: boolean;
42
+ volume?: number;
43
+ }
44
+ export interface ImageClipJSON extends BaseClipJSON {
45
+ type: 'Image';
46
+ }
47
+ export interface TextStyleJSON {
48
+ fontSize?: number;
49
+ fontFamily?: string;
50
+ fontWeight?: number;
51
+ fontStyle?: string;
52
+ color?: string;
53
+ align?: 'left' | 'center' | 'right';
54
+ fontUrl?: string;
55
+ stroke?: {
56
+ color: string;
57
+ width: number;
58
+ };
59
+ shadow?: {
60
+ color: string;
61
+ alpha: number;
62
+ blur: number;
63
+ offsetX: number;
64
+ offsetY: number;
65
+ };
66
+ }
67
+ export interface TextClipJSON extends BaseClipJSON {
68
+ type: 'Text';
69
+ text: string;
70
+ style?: TextStyleJSON;
71
+ }
72
+ export interface CaptionColorsJSON {
73
+ appeared?: string;
74
+ active?: string;
75
+ activeFill?: string;
76
+ background?: string;
77
+ keyword?: string;
78
+ }
79
+ export interface CaptionPositioningJSON {
80
+ bottomOffset?: number;
81
+ videoWidth?: number;
82
+ videoHeight?: number;
83
+ }
84
+ export interface CaptionDataJSON {
85
+ words?: Array<{
86
+ text: string;
87
+ from: number;
88
+ to: number;
89
+ isKeyWord: boolean;
90
+ }>;
91
+ colors?: CaptionColorsJSON;
92
+ preserveKeywordColor?: boolean;
93
+ positioning?: CaptionPositioningJSON;
94
+ }
95
+ export interface CaptionClipJSON extends BaseClipJSON {
96
+ type: 'Caption';
97
+ text: string;
98
+ style?: TextStyleJSON;
99
+ caption?: CaptionDataJSON;
100
+ bottomOffset?: number;
101
+ words?: Array<{
102
+ text: string;
103
+ from: number;
104
+ to: number;
105
+ isKeyWord: boolean;
106
+ }>;
107
+ appearedColor?: string;
108
+ activeColor?: string;
109
+ activeFillColor?: string;
110
+ backgroundColor?: string;
111
+ isKeyWordColor?: string;
112
+ preservedColorKeyWord?: boolean;
113
+ videoWidth?: number;
114
+ videoHeight?: number;
115
+ fontUrl?: string;
116
+ }
117
+ export type ClipJSON = VideoClipJSON | AudioClipJSON | ImageClipJSON | TextClipJSON | CaptionClipJSON;
118
+ export interface ProjectJSON {
119
+ clips: ClipJSON[];
120
+ settings?: {
121
+ width?: number;
122
+ height?: number;
123
+ fps?: number;
124
+ bgColor?: string;
125
+ videoCodec?: string;
126
+ bitrate?: number;
127
+ audio?: boolean;
128
+ metaDataTags?: Record<string, string>;
129
+ };
130
+ }
131
+ /**
132
+ * Serialize a clip to JSON format
133
+ * @param clip The clip to serialize
134
+ * @param main Whether this is the main clip (for Compositor)
135
+ */
136
+ export declare function clipToJSON(clip: IClip, main?: boolean): ClipJSON;
137
+ /**
138
+ * Deserialize JSON to a clip instance
139
+ * Uses fromObject static method if available (fabric.js pattern), otherwise falls back to manual construction
140
+ */
141
+ export declare function jsonToClip(json: ClipJSON): Promise<IClip>;
142
+ export {};
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Quick concatenate multiple MP4 file streams, requires all MP4s to have consistent properties,
3
+ * properties include (but not limited to): audio/video codec format, resolution, sample rate
4
+ *
5
+ * @param streams An array of readable streams containing Uint8Array.
6
+ * @returns Returns a Promise that resolves to a readable stream containing merged MP4 data.
7
+ * @throws Will throw error if unable to generate file from streams.
8
+ *
9
+ * @example
10
+ * const streams = [stream1, stream2, stream3];
11
+ * const resultStream = await fastConcatMP4(streams);
12
+ */
13
+ export declare function fastConcatMP4(streams: ReadableStream<Uint8Array>[]): Promise<ReadableStream<Uint8Array>>;
14
+ /**
15
+ * Set correct duration value for fMP4 files generated by WebAV
16
+ */
17
+ export declare function fixFMP4Duration(stream: ReadableStream<Uint8Array>): Promise<ReadableStream<Uint8Array>>;
18
+ /**
19
+ * Video dubbing; mix MP4 with audio file, only re-encode audio, video track unchanged
20
+ * @param mp4Stream - MP4 stream
21
+ * @param audio - Audio information
22
+ * @param audio.stream - Audio data stream
23
+ * @param audio.volume - Audio volume
24
+ * @param audio.loop - When audio duration is less than video, whether to loop audio stream
25
+ * @returns Output mixed audio stream
26
+ */
27
+ export declare function mixinMP4AndAudio(mp4Stream: ReadableStream<Uint8Array>, audio: {
28
+ stream: ReadableStream<Uint8Array>;
29
+ volume: number;
30
+ loop: boolean;
31
+ }): ReadableStream<Uint8Array<ArrayBufferLike>>;
@@ -0,0 +1,36 @@
1
+ import { AudioTrackOpts, MP4File, MP4Info, MP4Sample, VideoTrackOpts } from '@webav/mp4box.js';
2
+ import { file } from 'opfs-tools';
3
+ export declare function extractFileConfig(file: MP4File, info: MP4Info): {
4
+ videoTrackConf?: VideoTrackOpts;
5
+ videoDecoderConf?: Parameters<VideoDecoder["configure"]>[0];
6
+ audioTrackConf?: AudioTrackOpts;
7
+ audioDecoderConf?: Parameters<AudioDecoder["configure"]>[0];
8
+ };
9
+ /**
10
+ * Quick parse mp4 file, if not fMP4 format, will prioritize parsing moov box (skip mdat) to avoid excessive memory usage
11
+ */
12
+ export declare function quickParseMP4File(reader: Awaited<ReturnType<ReturnType<typeof file>['createReader']>>, onReady: (data: {
13
+ mp4boxFile: MP4File;
14
+ info: MP4Info;
15
+ }) => void, onSamples: (id: number, sampleType: 'video' | 'audio', samples: MP4Sample[]) => void): Promise<void>;
16
+ export declare function parseMatrix(matrix?: Int32Array): {
17
+ scaleX?: undefined;
18
+ scaleY?: undefined;
19
+ rotationRad?: undefined;
20
+ rotationDeg?: undefined;
21
+ translateX?: undefined;
22
+ translateY?: undefined;
23
+ perspective?: undefined;
24
+ } | {
25
+ scaleX: number;
26
+ scaleY: number;
27
+ rotationRad: number;
28
+ rotationDeg: number;
29
+ translateX: number;
30
+ translateY: number;
31
+ perspective: number;
32
+ };
33
+ /**
34
+ * Rotate VideoFrame
35
+ */
36
+ export declare function createVFRotater(width: number, height: number, rotationDeg: number): (vf: VideoFrame | null) => VideoFrame | null;
@@ -0,0 +1,23 @@
1
+ import { MP4File, MP4Info, MP4Sample } from '@webav/mp4box.js';
2
+ /**
3
+ * Transform raw byte stream into MP4Sample stream
4
+ */
5
+ export declare class SampleTransform {
6
+ readable: ReadableStream<{
7
+ chunkType: 'ready';
8
+ data: {
9
+ info: MP4Info;
10
+ file: MP4File;
11
+ };
12
+ } | {
13
+ chunkType: 'samples';
14
+ data: {
15
+ id: number;
16
+ type: 'video' | 'audio';
17
+ samples: MP4Sample[];
18
+ };
19
+ }>;
20
+ writable: WritableStream<Uint8Array>;
21
+ private inputBufOffset;
22
+ constructor();
23
+ }
@@ -0,0 +1,147 @@
1
+ type IRectBaseProps = any;
2
+ interface IAnimationOpts {
3
+ duration: number;
4
+ delay?: number;
5
+ iterCount?: number;
6
+ }
7
+ type TAnimateProps = IRectBaseProps & {
8
+ opacity: number;
9
+ };
10
+ export type TAnimationKeyFrame = Array<[number, Partial<TAnimateProps>]>;
11
+ type TKeyFrameOpts = Partial<Record<`${number}%` | 'from' | 'to', Partial<TAnimateProps>>>;
12
+ /**
13
+ * Sprite base class
14
+ *
15
+ * @see {@link OffscreenSprite}
16
+ */
17
+ export declare abstract class BaseSprite {
18
+ /**
19
+ * Control display time range of clips, commonly used in editing scenario timeline (track) module
20
+ * from: start time offset in microseconds
21
+ * to: end time (from + duration) in microseconds
22
+ */
23
+ display: {
24
+ from: number;
25
+ to: number;
26
+ };
27
+ /**
28
+ * Duration of the clip in microseconds
29
+ * Cannot exceed the duration of the referenced {@link IClip}
30
+ */
31
+ duration: number;
32
+ /**
33
+ * Playback rate of current clip, 1 means normal playback
34
+ * **Note**
35
+ * 1. When setting playbackRate, duration must be actively corrected
36
+ * 2. Audio uses the simplest interpolation algorithm to change rate, so changing rate will cause pitch variation, for custom algorithm please use {@link VideoClip.tickInterceptor} to implement
37
+ */
38
+ playbackRate: number;
39
+ private evtTool;
40
+ /**
41
+ * Listen to property change events
42
+ * @example
43
+ * sprite.on('propsChange', (changedProps) => {})
44
+ */
45
+ on: <Type extends "propsChange">(type: Type, listener: {
46
+ propsChange: (value: Partial<{
47
+ left: number;
48
+ top: number;
49
+ width: number;
50
+ height: number;
51
+ angle: number;
52
+ zIndex: number;
53
+ }>) => void;
54
+ }[Type]) => (() => void);
55
+ private _left;
56
+ /**
57
+ * Left position (x coordinate)
58
+ */
59
+ get left(): number;
60
+ set left(v: number);
61
+ private _top;
62
+ /**
63
+ * Top position (y coordinate)
64
+ */
65
+ get top(): number;
66
+ set top(v: number);
67
+ private _width;
68
+ /**
69
+ * Width
70
+ */
71
+ get width(): number;
72
+ set width(v: number);
73
+ private _height;
74
+ /**
75
+ * Height
76
+ */
77
+ get height(): number;
78
+ set height(v: number);
79
+ private _angle;
80
+ /**
81
+ * Rotation angle
82
+ * @see [MDN Canvas rotate](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/rotate)
83
+ */
84
+ get angle(): number;
85
+ set angle(v: number);
86
+ /**
87
+ * Center point calculated from position and dimensions
88
+ */
89
+ get center(): {
90
+ x: number;
91
+ y: number;
92
+ };
93
+ private _zIndex;
94
+ get zIndex(): number;
95
+ /**
96
+ * Control layering relationship between clips, clips with smaller zIndex will be occluded
97
+ */
98
+ set zIndex(v: number);
99
+ /**
100
+ * Opacity
101
+ */
102
+ opacity: number;
103
+ /**
104
+ * Flip clip horizontally or vertically
105
+ */
106
+ flip: 'horizontal' | 'vertical' | null;
107
+ private animatKeyFrame;
108
+ private animatOpts;
109
+ /**
110
+ * @see {@link IClip.ready}
111
+ * For clips, this should be Promise<IClipMeta>, but for BaseSprite it's just Promise<void>
112
+ */
113
+ ready: Promise<any>;
114
+ constructor();
115
+ protected _render(ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D): void;
116
+ /**
117
+ * Add animation to clip, usage reference CSS animation
118
+ *
119
+ * @example
120
+ * sprite.setAnimation(
121
+ * {
122
+ * '0%': { x: 0, y: 0 },
123
+ * '25%': { x: 1200, y: 680 },
124
+ * '50%': { x: 1200, y: 0 },
125
+ * '75%': { x: 0, y: 680 },
126
+ * '100%': { x: 0, y: 0 },
127
+ * },
128
+ * { duration: 4e6, iterCount: 1 },
129
+ * );
130
+ *
131
+ * @see [Video watermark animation](https://webav-tech.github.io/WebAV/demo/2_1-concat-video)
132
+ */
133
+ setAnimation(keyFrame: TKeyFrameOpts, opts: IAnimationOpts): void;
134
+ /**
135
+ * If current sprite has animation set, set sprite's animation properties to state at specified time
136
+ */
137
+ animate(time: number): void;
138
+ /**
139
+ * Copy current sprite's properties to target
140
+ *
141
+ * Used for cloning or copying state between {@link OffscreenSprite} instances
142
+ */
143
+ copyStateTo<T extends BaseSprite>(target: T): void;
144
+ protected destroy(): void;
145
+ }
146
+ export declare function linearTimeFn(time: number, keyFrame: TAnimationKeyFrame, opts: Required<IAnimationOpts>): Partial<TAnimateProps>;
147
+ export {};
@@ -0,0 +1,48 @@
1
+ import { Application, Sprite, Texture } from 'pixi.js';
2
+ import { IClip } from '../clips/iclip';
3
+ /**
4
+ * Update sprite transform based on clip properties
5
+ * Utility function for updating standalone sprites (e.g., video sprites from HTMLVideoElement)
6
+ * For sprites managed by PixiSpriteRenderer, use renderer.updateTransforms() instead
7
+ */
8
+ export declare function updateSpriteTransform(clip: IClip, sprite: Sprite): void;
9
+ /**
10
+ * Renders video frames using Pixi.js
11
+ * Uses a canvas-based approach: draws frames to a canvas and creates texture from it
12
+ * This matches the pattern used in other video rendering libraries
13
+ */
14
+ export declare class PixiSpriteRenderer {
15
+ private pixiApp;
16
+ private sprite;
17
+ private pixiSprite;
18
+ private texture;
19
+ private canvas;
20
+ private context;
21
+ private destroyed;
22
+ constructor(pixiApp: Application, sprite: IClip);
23
+ /**
24
+ * Update the sprite with a new video frame or Texture
25
+ * @param frame ImageBitmap, Texture, or null to render
26
+ * (VideoFrames are converted to ImageBitmap in getFrame)
27
+ */
28
+ updateFrame(frame: ImageBitmap | Texture | null): Promise<void>;
29
+ /**
30
+ * Apply sprite transformations to the Pixi Sprite
31
+ * This reads the current sprite properties (which may have been updated by animations)
32
+ * and applies them to the Pixi sprite
33
+ */
34
+ private applySpriteTransforms;
35
+ /**
36
+ * Update sprite properties without changing the frame
37
+ * Useful when sprite properties change but frame stays the same
38
+ */
39
+ updateTransforms(): void;
40
+ /**
41
+ * Get the Pixi Sprite instance
42
+ */
43
+ getSprite(): Sprite | null;
44
+ /**
45
+ * Destroy the renderer and clean up resources
46
+ */
47
+ destroy(): void;
48
+ }