openvideo 0.0.1

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 (69) hide show
  1. package/LICENSE +63 -0
  2. package/dist/SharedSystems-pXK0PjzC.js +2691 -0
  3. package/dist/WebGLRenderer-B_y7ugdK.js +2639 -0
  4. package/dist/WebGPURenderer-ByeYcldK.js +1655 -0
  5. package/dist/browserAll-lTqv9nwW.js +1876 -0
  6. package/dist/clips/audio-clip.d.ts +128 -0
  7. package/dist/clips/base-clip.d.ts +116 -0
  8. package/dist/clips/caption-clip.d.ts +392 -0
  9. package/dist/clips/effect-clip.d.ts +37 -0
  10. package/dist/clips/iclip.d.ts +178 -0
  11. package/dist/clips/image-clip.d.ts +115 -0
  12. package/dist/clips/index.d.ts +14 -0
  13. package/dist/clips/placeholder-clip.d.ts +15 -0
  14. package/dist/clips/text-clip.d.ts +266 -0
  15. package/dist/clips/transition-clip.d.ts +45 -0
  16. package/dist/clips/video-clip.d.ts +238 -0
  17. package/dist/colorToUniform-C2jGzNe1.js +97 -0
  18. package/dist/compositor.d.ts +107 -0
  19. package/dist/effect/effect.d.ts +6 -0
  20. package/dist/effect/glsl/custom-glsl.d.ts +1017 -0
  21. package/dist/effect/glsl/gl-effect.d.ts +16 -0
  22. package/dist/effect/types.d.ts +24 -0
  23. package/dist/effect/vertex.d.ts +1 -0
  24. package/dist/event-emitter.d.ts +55 -0
  25. package/dist/index-CIRqJXOw.js +41882 -0
  26. package/dist/index.d.ts +20 -0
  27. package/dist/index.es.js +28 -0
  28. package/dist/index.umd.js +7741 -0
  29. package/dist/json-serialization.d.ts +222 -0
  30. package/dist/mp4-utils/index.d.ts +31 -0
  31. package/dist/mp4-utils/mp4box-utils.d.ts +44 -0
  32. package/dist/mp4-utils/sample-transform.d.ts +26 -0
  33. package/dist/sprite/base-sprite.d.ts +183 -0
  34. package/dist/sprite/pixi-sprite-renderer.d.ts +49 -0
  35. package/dist/studio/history-manager.d.ts +46 -0
  36. package/dist/studio/resource-manager.d.ts +53 -0
  37. package/dist/studio/resource-manager.spec.d.ts +1 -0
  38. package/dist/studio/selection-manager.d.ts +50 -0
  39. package/dist/studio/timeline-model.d.ts +110 -0
  40. package/dist/studio/transport.d.ts +44 -0
  41. package/dist/studio.d.ts +380 -0
  42. package/dist/studio.spec.d.ts +1 -0
  43. package/dist/transfomer/parts/handle.d.ts +17 -0
  44. package/dist/transfomer/parts/snapping.d.ts +41 -0
  45. package/dist/transfomer/parts/wireframe.d.ts +5 -0
  46. package/dist/transfomer/transformer.d.ts +31 -0
  47. package/dist/transition/fragment.d.ts +1 -0
  48. package/dist/transition/glsl/custom-glsl.d.ts +231 -0
  49. package/dist/transition/glsl/gl-transition.d.ts +18 -0
  50. package/dist/transition/transition.d.ts +6 -0
  51. package/dist/transition/types.d.ts +29 -0
  52. package/dist/transition/uniforms.d.ts +35 -0
  53. package/dist/transition/vertex.d.ts +1 -0
  54. package/dist/utils/asset-manager.d.ts +6 -0
  55. package/dist/utils/audio-codec-detector.d.ts +28 -0
  56. package/dist/utils/audio.d.ts +82 -0
  57. package/dist/utils/chromakey.d.ts +24 -0
  58. package/dist/utils/color.d.ts +9 -0
  59. package/dist/utils/common.d.ts +7 -0
  60. package/dist/utils/dom.d.ts +48 -0
  61. package/dist/utils/fonts.d.ts +16 -0
  62. package/dist/utils/index.d.ts +6 -0
  63. package/dist/utils/log.d.ts +27 -0
  64. package/dist/utils/srt-parser.d.ts +15 -0
  65. package/dist/utils/stream-utils.d.ts +9 -0
  66. package/dist/utils/video.d.ts +16 -0
  67. package/dist/utils/worker-timer.d.ts +1 -0
  68. package/dist/webworkerAll-BsrA7oC4.js +2670 -0
  69. package/package.json +63 -0
@@ -0,0 +1,238 @@
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
+ type ThumbnailOpts = {
29
+ start: number;
30
+ end: number;
31
+ step: number;
32
+ };
33
+ /**
34
+ * Video clip, parses MP4 files, uses {@link Video.tick} to decode image frames at specified time on demand
35
+ *
36
+ * Can be used to implement video frame extraction, thumbnail generation, video editing and other functions
37
+ *
38
+ * @example
39
+ * // Load video clip asynchronously
40
+ * const videoClip = await Video.fromUrl('clip.mp4', {
41
+ * x: 0,
42
+ * y: 0,
43
+ * width: 1920,
44
+ * height: 1080,
45
+ * });
46
+ *
47
+ * // Set timeline position
48
+ * videoClip.set({
49
+ * display: {
50
+ * from: 150, // frames
51
+ * to: 450, // frames (10 seconds at 30fps)
52
+ * },
53
+ * });
54
+ *
55
+ */
56
+ export declare class Video extends BaseClip implements IPlaybackCapable {
57
+ readonly type = "Video";
58
+ private insId;
59
+ private logger;
60
+ ready: IClip['ready'];
61
+ private _meta;
62
+ get meta(): {
63
+ duration: number;
64
+ width: number;
65
+ height: number;
66
+ audioSampleRate: number;
67
+ audioChanCount: number;
68
+ };
69
+ private localFile;
70
+ /** Store binary data of video header (box: ftyp, moov) */
71
+ private headerBoxPos;
72
+ /**
73
+ * Provide binary data of video header (box: ftyp, moov)
74
+ * Use any mp4 demuxer to parse and get detailed video information
75
+ * Unit tests include sample code using mp4box.js
76
+ */
77
+ getFileHeaderBinData(): Promise<ArrayBuffer>;
78
+ /** Store video transform and rotation info, currently only restores rotation */
79
+ private parsedMatrix;
80
+ private vfRotater;
81
+ private videoSamples;
82
+ private audioSamples;
83
+ private videoFrameFinder;
84
+ private audioFrameFinder;
85
+ private decoderConf;
86
+ private opts;
87
+ /**
88
+ * Whether to include audio track (hybrid JSON structure)
89
+ */
90
+ audio: boolean;
91
+ /**
92
+ * Unique identifier for this clip instance
93
+ */
94
+ id: string;
95
+ /**
96
+ * Array of effects to be applied to this clip
97
+ * Each effect specifies key, startTime, duration, and optional targets
98
+ */
99
+ effects: Array<{
100
+ id: string;
101
+ key: string;
102
+ startTime: number;
103
+ duration: number;
104
+ }>;
105
+ /**
106
+ * Load a video clip from a URL
107
+ * @param url Video URL
108
+ * @param opts Position and size options
109
+ * @returns Promise that resolves to a video clip
110
+ *
111
+ * @example
112
+ * const videoClip = await Video.fromUrl('clip.mp4', {
113
+ * x: 0,
114
+ * y: 0,
115
+ * width: 1920,
116
+ * height: 1080,
117
+ * });
118
+ */
119
+ static fromUrl(url: string, opts?: {
120
+ x?: number;
121
+ y?: number;
122
+ width?: number;
123
+ height?: number;
124
+ }): Promise<Video>;
125
+ constructor(source: OPFSToolFile | ReadableStream<Uint8Array> | MPClipCloneArgs, opts?: IMP4ClipOpts, src?: string);
126
+ /**
127
+ * Intercept data returned by {@link Video.tick} method for secondary processing of image and audio data
128
+ * @param time Time when tick was called
129
+ * @param tickRet Data returned by tick
130
+ *
131
+ * */
132
+ tickInterceptor: <T extends Awaited<ReturnType<Video['tick']>>>(time: number, tickRet: T) => Promise<T>;
133
+ /**
134
+ * Get image frame and audio data at specified time
135
+ * @param time Time in microseconds
136
+ */
137
+ tick(time: number): Promise<{
138
+ video?: VideoFrame;
139
+ audio: Float32Array[];
140
+ state: 'success' | 'done';
141
+ }>;
142
+ private thumbAborter;
143
+ private thumbFinder;
144
+ /**
145
+ * Generate thumbnails, default generates one 100px width thumbnail per keyframe.
146
+ *
147
+ * @param imgWidth Thumbnail width, default 100
148
+ * @param opts Partial<ThumbnailOpts>
149
+ * @returns Promise<Array<{ ts: number; img: Blob }>>
150
+ */
151
+ thumbnails(imgWidth?: number, opts?: Partial<ThumbnailOpts>): Promise<Array<{
152
+ ts: number;
153
+ img: Blob;
154
+ }>>;
155
+ split(time: number): Promise<[this, this]>;
156
+ addEffect(effect: {
157
+ id: string;
158
+ key: string;
159
+ startTime: number;
160
+ duration: number;
161
+ }): void;
162
+ editEffect(effectId: string, newEffectData: Partial<{
163
+ key: string;
164
+ startTime: number;
165
+ duration: number;
166
+ }>): void;
167
+ removeEffect(effectId: string): void;
168
+ clone(): Promise<this>;
169
+ /**
170
+ * Split Video into VideoClips containing only video track and audio track
171
+ * @returns VideoClip[]
172
+ */
173
+ splitTrack(): Promise<Video[]>;
174
+ /**
175
+ * Clean up thumbnail generation resources
176
+ */
177
+ cleanupThumbnails: () => Promise<void>;
178
+ destroy(): void;
179
+ toJSON(main?: boolean): VideoJSON;
180
+ /**
181
+ * Create a Video instance from a JSON object (fabric.js pattern)
182
+ * @param json The JSON object representing the clip
183
+ * @returns Promise that resolves to a Video instance
184
+ */
185
+ static fromObject(json: VideoJSON): Promise<Video>;
186
+ /**
187
+ * Create HTMLVideoElement for playback
188
+ */
189
+ createPlaybackElement(): Promise<{
190
+ element: HTMLVideoElement;
191
+ objectUrl?: string;
192
+ }>;
193
+ play(element: HTMLVideoElement | HTMLAudioElement, timeSeconds: number): Promise<void>;
194
+ pause(element: HTMLVideoElement | HTMLAudioElement): void;
195
+ seek(element: HTMLVideoElement | HTMLAudioElement, timeSeconds: number): Promise<void>;
196
+ syncPlayback(element: HTMLVideoElement | HTMLAudioElement, isPlaying: boolean, timeSeconds: number): void;
197
+ cleanupPlayback(element: HTMLVideoElement | HTMLAudioElement, objectUrl?: string): void;
198
+ /**
199
+ * Scale clip to fit within the scene dimensions while maintaining aspect ratio
200
+ * Similar to fabric.js scaleToFit
201
+ * @param sceneWidth Scene width
202
+ * @param sceneHeight Scene height
203
+ */
204
+ scaleToFit(sceneWidth: number, sceneHeight: number): Promise<void>;
205
+ /**
206
+ * Scale clip to fill the scene dimensions while maintaining aspect ratio
207
+ * May crop parts of the clip. Similar to fabric.js scaleToFill
208
+ * @param sceneWidth Scene width
209
+ * @param sceneHeight Scene height
210
+ */
211
+ scaleToFill(sceneWidth: number, sceneHeight: number): Promise<void>;
212
+ /**
213
+ * Center the clip within the scene dimensions
214
+ * Similar to fabric.js center
215
+ * @param sceneWidth Scene width
216
+ * @param sceneHeight Scene height
217
+ */
218
+ centerInScene(sceneWidth: number, sceneHeight: number): void;
219
+ }
220
+ declare function mp4FileToSamples(otFile: OPFSToolFile, opts?: IMP4ClipOpts): Promise<{
221
+ videoSamples: ExtMP4Sample[];
222
+ audioSamples: ExtMP4Sample[];
223
+ decoderConf: MP4DecoderConf;
224
+ headerBoxPos: {
225
+ start: number;
226
+ size: number;
227
+ }[];
228
+ parsedMatrix: {
229
+ perspective: number;
230
+ rotationRad: number;
231
+ rotationDeg: number;
232
+ scaleX: number;
233
+ scaleY: number;
234
+ translateX: number;
235
+ translateY: number;
236
+ };
237
+ }>;
238
+ export {};
@@ -0,0 +1,97 @@
1
+ const l = {
2
+ name: "local-uniform-bit",
3
+ vertex: {
4
+ header: (
5
+ /* wgsl */
6
+ `
7
+
8
+ struct LocalUniforms {
9
+ uTransformMatrix:mat3x3<f32>,
10
+ uColor:vec4<f32>,
11
+ uRound:f32,
12
+ }
13
+
14
+ @group(1) @binding(0) var<uniform> localUniforms : LocalUniforms;
15
+ `
16
+ ),
17
+ main: (
18
+ /* wgsl */
19
+ `
20
+ vColor *= localUniforms.uColor;
21
+ modelMatrix *= localUniforms.uTransformMatrix;
22
+ `
23
+ ),
24
+ end: (
25
+ /* wgsl */
26
+ `
27
+ if(localUniforms.uRound == 1)
28
+ {
29
+ vPosition = vec4(roundPixels(vPosition.xy, globalUniforms.uResolution), vPosition.zw);
30
+ }
31
+ `
32
+ )
33
+ }
34
+ }, e = {
35
+ ...l,
36
+ vertex: {
37
+ ...l.vertex,
38
+ // replace the group!
39
+ header: l.vertex.header.replace("group(1)", "group(2)")
40
+ }
41
+ }, n = {
42
+ name: "local-uniform-bit",
43
+ vertex: {
44
+ header: (
45
+ /* glsl */
46
+ `
47
+
48
+ uniform mat3 uTransformMatrix;
49
+ uniform vec4 uColor;
50
+ uniform float uRound;
51
+ `
52
+ ),
53
+ main: (
54
+ /* glsl */
55
+ `
56
+ vColor *= uColor;
57
+ modelMatrix = uTransformMatrix;
58
+ `
59
+ ),
60
+ end: (
61
+ /* glsl */
62
+ `
63
+ if(uRound == 1.)
64
+ {
65
+ gl_Position.xy = roundPixels(gl_Position.xy, uResolution);
66
+ }
67
+ `
68
+ )
69
+ }
70
+ };
71
+ class a {
72
+ constructor() {
73
+ this.batcherName = "default", this.topology = "triangle-list", this.attributeSize = 4, this.indexSize = 6, this.packAsQuad = !0, this.roundPixels = 0, this._attributeStart = 0, this._batcher = null, this._batch = null;
74
+ }
75
+ get blendMode() {
76
+ return this.renderable.groupBlendMode;
77
+ }
78
+ get color() {
79
+ return this.renderable.groupColorAlpha;
80
+ }
81
+ reset() {
82
+ this.renderable = null, this.texture = null, this._batcher = null, this._batch = null, this.bounds = null;
83
+ }
84
+ destroy() {
85
+ }
86
+ }
87
+ function s(o, r, i) {
88
+ const t = (o >> 24 & 255) / 255;
89
+ r[i++] = (o & 255) / 255 * t, r[i++] = (o >> 8 & 255) / 255 * t, r[i++] = (o >> 16 & 255) / 255 * t, r[i++] = t;
90
+ }
91
+ export {
92
+ a as B,
93
+ l as a,
94
+ n as b,
95
+ s as c,
96
+ e as l
97
+ };
@@ -0,0 +1,107 @@
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
+ bgColor?: string;
10
+ videoCodec?: string;
11
+ /**
12
+ * If false, exclude audio track from the output video
13
+ */
14
+ audio?: false;
15
+ /**
16
+ * Write metadata tags to the output video
17
+ */
18
+ metaDataTags?: Record<string, string>;
19
+ /**
20
+ * Unsafe, may be deprecated at any time
21
+ */
22
+ __unsafe_hardwareAcceleration__?: HardwarePreference;
23
+ }
24
+ /**
25
+ * Video compositor that can add multiple {@link OffscreenSprite} instances,
26
+ * @example
27
+ * const spr1 = new OffscreenSprite(
28
+ * new Video((await fetch('<mp4 url>')).body),
29
+ * );
30
+ * const spr2 = new OffscreenSprite(
31
+ * await Audio.fromUrl('<audio url>'),
32
+ * );
33
+ * const com = new Compositor({ width: 1280, height: 720, });
34
+
35
+ * await com.addSprite(spr1);
36
+ * await com.addSprite(spr2);
37
+
38
+ * com.output(); // => ReadableStream
39
+ *
40
+ */
41
+ export declare class Compositor extends EventEmitter<{
42
+ OutputProgress: number;
43
+ error: Error;
44
+ }> {
45
+ /**
46
+ * Check compatibility with the current environment
47
+ * @param args.videoCodec Specify video codec, default avc1.42E032
48
+ * @param args.width Specify video width, default 1920
49
+ * @param args.height Specify video height, default 1080
50
+ * @param args.bitrate Specify video bitrate, default 5e6
51
+ */
52
+ static isSupported(args?: {
53
+ videoCodec?: string;
54
+ width?: number;
55
+ height?: number;
56
+ bitrate?: number;
57
+ }): Promise<boolean>;
58
+ private logger;
59
+ private destroyed;
60
+ private sprites;
61
+ private canvas;
62
+ private pixiApp;
63
+ private stopOutput;
64
+ private opts;
65
+ private hasVideoTrack;
66
+ /**
67
+ * Create a compositor instance based on configuration
68
+ * @param opts ICompositorOpts
69
+ */
70
+ constructor(opts?: ICompositorOpts);
71
+ initPixiApp(): Promise<void>;
72
+ /**
73
+ * Add a clip for video composition. Video duration defaults to the maximum duration value from all clips
74
+ * @param clip Clip (extends BaseSprite)
75
+ * @param opts.main If main is true, the video duration uses this clip's duration value
76
+ */
77
+ addSprite(clip: IClip, opts?: {
78
+ main?: boolean;
79
+ }): Promise<void>;
80
+ private initMuxer;
81
+ /**
82
+ * Output video file binary stream
83
+ * @param opts.maxTime Maximum duration allowed for output video, content exceeding this will be ignored
84
+ */
85
+ output(opts?: {
86
+ maxTime?: number;
87
+ }): ReadableStream<Uint8Array>;
88
+ /**
89
+ * Destroy instance and release resources
90
+ */
91
+ destroy(): void;
92
+ private runEncoding;
93
+ /**
94
+ * Export current compositor state to JSON
95
+ */
96
+ exportToJSON(): ProjectJSON;
97
+ /**
98
+ * Load clips from JSON
99
+ * @param json The JSON project data
100
+ */
101
+ loadFromJSON(json: ProjectJSON): Promise<void>;
102
+ }
103
+ /**
104
+ * Buffer input data and convert to AudioData with fixed frame count
105
+ * @param framesPerChunk Number of audio frames per AudioData instance
106
+ */
107
+ export declare function createAudioTrackBuf(framesPerChunk: number): (timestamp: number, trackAudios: Float32Array[][]) => AudioData[];
@@ -0,0 +1,6 @@
1
+ import { Filter, RenderTexture } from 'pixi.js';
2
+ import { EffectOptions, EffectRendererOptions } from './types';
3
+ export declare function makeEffect({ name, renderer }: EffectOptions): {
4
+ filter: Filter;
5
+ render({ width, height, canvasTexture, progress }: EffectRendererOptions): RenderTexture;
6
+ };