framewebworker 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.
- package/LICENSE +21 -0
- package/README.md +224 -0
- package/dist/index.cjs +572 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +144 -0
- package/dist/index.d.ts +144 -0
- package/dist/index.js +568 -0
- package/dist/index.js.map +1 -0
- package/dist/react/index.cjs +120 -0
- package/dist/react/index.cjs.map +1 -0
- package/dist/react/index.d.cts +119 -0
- package/dist/react/index.d.ts +119 -0
- package/dist/react/index.js +117 -0
- package/dist/react/index.js.map +1 -0
- package/package.json +83 -0
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
interface CaptionSegment {
|
|
2
|
+
text: string;
|
|
3
|
+
startTime: number;
|
|
4
|
+
endTime: number;
|
|
5
|
+
style?: Partial<CaptionStyle>;
|
|
6
|
+
}
|
|
7
|
+
type CaptionStylePreset = 'hormozi' | 'modern' | 'minimal' | 'bold';
|
|
8
|
+
interface CaptionStyle {
|
|
9
|
+
preset: CaptionStylePreset;
|
|
10
|
+
fontFamily: string;
|
|
11
|
+
fontSize: number;
|
|
12
|
+
fontWeight: string | number;
|
|
13
|
+
color: string;
|
|
14
|
+
strokeColor: string;
|
|
15
|
+
strokeWidth: number;
|
|
16
|
+
backgroundColor: string;
|
|
17
|
+
backgroundPadding: number;
|
|
18
|
+
backgroundRadius: number;
|
|
19
|
+
position: 'top' | 'center' | 'bottom';
|
|
20
|
+
textAlign: CanvasTextAlign;
|
|
21
|
+
lineHeight: number;
|
|
22
|
+
maxWidth: number;
|
|
23
|
+
shadow: boolean;
|
|
24
|
+
shadowColor: string;
|
|
25
|
+
shadowBlur: number;
|
|
26
|
+
shadowOffsetX: number;
|
|
27
|
+
shadowOffsetY: number;
|
|
28
|
+
uppercase: boolean;
|
|
29
|
+
wordHighlight: boolean;
|
|
30
|
+
wordHighlightColor: string;
|
|
31
|
+
wordHighlightTextColor: string;
|
|
32
|
+
}
|
|
33
|
+
type AspectRatio = '16:9' | '9:16' | '1:1' | '4:3' | '3:4' | 'original';
|
|
34
|
+
interface CropOptions {
|
|
35
|
+
x: number;
|
|
36
|
+
y: number;
|
|
37
|
+
width: number;
|
|
38
|
+
height: number;
|
|
39
|
+
}
|
|
40
|
+
interface CaptionOptions {
|
|
41
|
+
segments: CaptionSegment[];
|
|
42
|
+
style?: Partial<CaptionStyle>;
|
|
43
|
+
}
|
|
44
|
+
interface ClipInput {
|
|
45
|
+
/** Video source: URL string, File, Blob, or HTMLVideoElement */
|
|
46
|
+
source: string | File | Blob | HTMLVideoElement;
|
|
47
|
+
/** Trim start in seconds (default: 0) */
|
|
48
|
+
startTime?: number;
|
|
49
|
+
/** Trim end in seconds (default: video duration) */
|
|
50
|
+
endTime?: number;
|
|
51
|
+
/** Captions to overlay */
|
|
52
|
+
captions?: CaptionOptions;
|
|
53
|
+
/** Crop settings */
|
|
54
|
+
crop?: CropOptions;
|
|
55
|
+
/** Output aspect ratio */
|
|
56
|
+
aspectRatio?: AspectRatio;
|
|
57
|
+
/** Volume multiplier 0-2 (default: 1) */
|
|
58
|
+
volume?: number;
|
|
59
|
+
}
|
|
60
|
+
interface RenderOptions {
|
|
61
|
+
/** Output width in pixels (default: 1280) */
|
|
62
|
+
width?: number;
|
|
63
|
+
/** Output height in pixels (default: 720) */
|
|
64
|
+
height?: number;
|
|
65
|
+
/** Frames per second (default: 30) */
|
|
66
|
+
fps?: number;
|
|
67
|
+
/** Output MIME type (default: 'video/mp4') */
|
|
68
|
+
mimeType?: string;
|
|
69
|
+
/** Quality 0-1 for non-ffmpeg backends (default: 0.92) */
|
|
70
|
+
quality?: number;
|
|
71
|
+
/** Additional codec/format options passed to the backend */
|
|
72
|
+
encoderOptions?: Record<string, unknown>;
|
|
73
|
+
/** Progress callback (0-1) */
|
|
74
|
+
onProgress?: (progress: number) => void;
|
|
75
|
+
/** AbortSignal to cancel rendering */
|
|
76
|
+
signal?: AbortSignal;
|
|
77
|
+
}
|
|
78
|
+
interface EncodeOptions {
|
|
79
|
+
width: number;
|
|
80
|
+
height: number;
|
|
81
|
+
fps: number;
|
|
82
|
+
mimeType: string;
|
|
83
|
+
quality: number;
|
|
84
|
+
encoderOptions?: Record<string, unknown>;
|
|
85
|
+
onProgress?: (progress: number) => void;
|
|
86
|
+
signal?: AbortSignal;
|
|
87
|
+
}
|
|
88
|
+
interface FrameData {
|
|
89
|
+
imageData: ImageData;
|
|
90
|
+
timestamp: number;
|
|
91
|
+
width: number;
|
|
92
|
+
height: number;
|
|
93
|
+
}
|
|
94
|
+
/** Pluggable renderer backend interface */
|
|
95
|
+
interface RendererBackend {
|
|
96
|
+
/** Human-readable backend name */
|
|
97
|
+
name: string;
|
|
98
|
+
/** Initialize the backend (load WASM, etc.) */
|
|
99
|
+
init(): Promise<void>;
|
|
100
|
+
/** Encode an array of frames into a video Blob */
|
|
101
|
+
encode(frames: FrameData[], options: EncodeOptions): Promise<Blob>;
|
|
102
|
+
/** Concatenate multiple video Blobs */
|
|
103
|
+
concat(blobs: Blob[], options: EncodeOptions): Promise<Blob>;
|
|
104
|
+
/** Optional cleanup */
|
|
105
|
+
destroy?(): Promise<void>;
|
|
106
|
+
}
|
|
107
|
+
interface FrameWorkerConfig {
|
|
108
|
+
/** Renderer backend (default: ffmpeg.wasm) */
|
|
109
|
+
backend?: RendererBackend;
|
|
110
|
+
/** Default FPS (default: 30) */
|
|
111
|
+
fps?: number;
|
|
112
|
+
/** Default output width */
|
|
113
|
+
width?: number;
|
|
114
|
+
/** Default output height */
|
|
115
|
+
height?: number;
|
|
116
|
+
}
|
|
117
|
+
interface FrameWorker {
|
|
118
|
+
/** Render a single clip to a Blob */
|
|
119
|
+
render(clip: ClipInput, options?: RenderOptions): Promise<Blob>;
|
|
120
|
+
/** Render a single clip and return an object URL */
|
|
121
|
+
renderToUrl(clip: ClipInput, options?: RenderOptions): Promise<string>;
|
|
122
|
+
/** Stitch multiple clips into one Blob */
|
|
123
|
+
stitch(clips: ClipInput[], options?: RenderOptions): Promise<Blob>;
|
|
124
|
+
/** Stitch multiple clips and return an object URL */
|
|
125
|
+
stitchToUrl(clips: ClipInput[], options?: RenderOptions): Promise<string>;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
declare const STYLE_PRESETS: Record<CaptionStylePreset, CaptionStyle>;
|
|
129
|
+
|
|
130
|
+
declare class FFmpegBackend implements RendererBackend {
|
|
131
|
+
readonly name = "ffmpeg.wasm";
|
|
132
|
+
private ffmpeg;
|
|
133
|
+
private initialized;
|
|
134
|
+
private _fetchFile;
|
|
135
|
+
init(): Promise<void>;
|
|
136
|
+
encode(frames: FrameData[], options: EncodeOptions): Promise<Blob>;
|
|
137
|
+
concat(blobs: Blob[], options: EncodeOptions): Promise<Blob>;
|
|
138
|
+
destroy(): Promise<void>;
|
|
139
|
+
}
|
|
140
|
+
declare function createFFmpegBackend(): FFmpegBackend;
|
|
141
|
+
|
|
142
|
+
declare function createFrameWorker(config?: FrameWorkerConfig): FrameWorker;
|
|
143
|
+
|
|
144
|
+
export { type AspectRatio, type CaptionOptions, type CaptionSegment, type CaptionStyle, type CaptionStylePreset, type ClipInput, type CropOptions, type EncodeOptions, FFmpegBackend, type FrameData, type FrameWorker, type FrameWorkerConfig, type RenderOptions, type RendererBackend, STYLE_PRESETS, createFFmpegBackend, createFrameWorker };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
interface CaptionSegment {
|
|
2
|
+
text: string;
|
|
3
|
+
startTime: number;
|
|
4
|
+
endTime: number;
|
|
5
|
+
style?: Partial<CaptionStyle>;
|
|
6
|
+
}
|
|
7
|
+
type CaptionStylePreset = 'hormozi' | 'modern' | 'minimal' | 'bold';
|
|
8
|
+
interface CaptionStyle {
|
|
9
|
+
preset: CaptionStylePreset;
|
|
10
|
+
fontFamily: string;
|
|
11
|
+
fontSize: number;
|
|
12
|
+
fontWeight: string | number;
|
|
13
|
+
color: string;
|
|
14
|
+
strokeColor: string;
|
|
15
|
+
strokeWidth: number;
|
|
16
|
+
backgroundColor: string;
|
|
17
|
+
backgroundPadding: number;
|
|
18
|
+
backgroundRadius: number;
|
|
19
|
+
position: 'top' | 'center' | 'bottom';
|
|
20
|
+
textAlign: CanvasTextAlign;
|
|
21
|
+
lineHeight: number;
|
|
22
|
+
maxWidth: number;
|
|
23
|
+
shadow: boolean;
|
|
24
|
+
shadowColor: string;
|
|
25
|
+
shadowBlur: number;
|
|
26
|
+
shadowOffsetX: number;
|
|
27
|
+
shadowOffsetY: number;
|
|
28
|
+
uppercase: boolean;
|
|
29
|
+
wordHighlight: boolean;
|
|
30
|
+
wordHighlightColor: string;
|
|
31
|
+
wordHighlightTextColor: string;
|
|
32
|
+
}
|
|
33
|
+
type AspectRatio = '16:9' | '9:16' | '1:1' | '4:3' | '3:4' | 'original';
|
|
34
|
+
interface CropOptions {
|
|
35
|
+
x: number;
|
|
36
|
+
y: number;
|
|
37
|
+
width: number;
|
|
38
|
+
height: number;
|
|
39
|
+
}
|
|
40
|
+
interface CaptionOptions {
|
|
41
|
+
segments: CaptionSegment[];
|
|
42
|
+
style?: Partial<CaptionStyle>;
|
|
43
|
+
}
|
|
44
|
+
interface ClipInput {
|
|
45
|
+
/** Video source: URL string, File, Blob, or HTMLVideoElement */
|
|
46
|
+
source: string | File | Blob | HTMLVideoElement;
|
|
47
|
+
/** Trim start in seconds (default: 0) */
|
|
48
|
+
startTime?: number;
|
|
49
|
+
/** Trim end in seconds (default: video duration) */
|
|
50
|
+
endTime?: number;
|
|
51
|
+
/** Captions to overlay */
|
|
52
|
+
captions?: CaptionOptions;
|
|
53
|
+
/** Crop settings */
|
|
54
|
+
crop?: CropOptions;
|
|
55
|
+
/** Output aspect ratio */
|
|
56
|
+
aspectRatio?: AspectRatio;
|
|
57
|
+
/** Volume multiplier 0-2 (default: 1) */
|
|
58
|
+
volume?: number;
|
|
59
|
+
}
|
|
60
|
+
interface RenderOptions {
|
|
61
|
+
/** Output width in pixels (default: 1280) */
|
|
62
|
+
width?: number;
|
|
63
|
+
/** Output height in pixels (default: 720) */
|
|
64
|
+
height?: number;
|
|
65
|
+
/** Frames per second (default: 30) */
|
|
66
|
+
fps?: number;
|
|
67
|
+
/** Output MIME type (default: 'video/mp4') */
|
|
68
|
+
mimeType?: string;
|
|
69
|
+
/** Quality 0-1 for non-ffmpeg backends (default: 0.92) */
|
|
70
|
+
quality?: number;
|
|
71
|
+
/** Additional codec/format options passed to the backend */
|
|
72
|
+
encoderOptions?: Record<string, unknown>;
|
|
73
|
+
/** Progress callback (0-1) */
|
|
74
|
+
onProgress?: (progress: number) => void;
|
|
75
|
+
/** AbortSignal to cancel rendering */
|
|
76
|
+
signal?: AbortSignal;
|
|
77
|
+
}
|
|
78
|
+
interface EncodeOptions {
|
|
79
|
+
width: number;
|
|
80
|
+
height: number;
|
|
81
|
+
fps: number;
|
|
82
|
+
mimeType: string;
|
|
83
|
+
quality: number;
|
|
84
|
+
encoderOptions?: Record<string, unknown>;
|
|
85
|
+
onProgress?: (progress: number) => void;
|
|
86
|
+
signal?: AbortSignal;
|
|
87
|
+
}
|
|
88
|
+
interface FrameData {
|
|
89
|
+
imageData: ImageData;
|
|
90
|
+
timestamp: number;
|
|
91
|
+
width: number;
|
|
92
|
+
height: number;
|
|
93
|
+
}
|
|
94
|
+
/** Pluggable renderer backend interface */
|
|
95
|
+
interface RendererBackend {
|
|
96
|
+
/** Human-readable backend name */
|
|
97
|
+
name: string;
|
|
98
|
+
/** Initialize the backend (load WASM, etc.) */
|
|
99
|
+
init(): Promise<void>;
|
|
100
|
+
/** Encode an array of frames into a video Blob */
|
|
101
|
+
encode(frames: FrameData[], options: EncodeOptions): Promise<Blob>;
|
|
102
|
+
/** Concatenate multiple video Blobs */
|
|
103
|
+
concat(blobs: Blob[], options: EncodeOptions): Promise<Blob>;
|
|
104
|
+
/** Optional cleanup */
|
|
105
|
+
destroy?(): Promise<void>;
|
|
106
|
+
}
|
|
107
|
+
interface FrameWorkerConfig {
|
|
108
|
+
/** Renderer backend (default: ffmpeg.wasm) */
|
|
109
|
+
backend?: RendererBackend;
|
|
110
|
+
/** Default FPS (default: 30) */
|
|
111
|
+
fps?: number;
|
|
112
|
+
/** Default output width */
|
|
113
|
+
width?: number;
|
|
114
|
+
/** Default output height */
|
|
115
|
+
height?: number;
|
|
116
|
+
}
|
|
117
|
+
interface FrameWorker {
|
|
118
|
+
/** Render a single clip to a Blob */
|
|
119
|
+
render(clip: ClipInput, options?: RenderOptions): Promise<Blob>;
|
|
120
|
+
/** Render a single clip and return an object URL */
|
|
121
|
+
renderToUrl(clip: ClipInput, options?: RenderOptions): Promise<string>;
|
|
122
|
+
/** Stitch multiple clips into one Blob */
|
|
123
|
+
stitch(clips: ClipInput[], options?: RenderOptions): Promise<Blob>;
|
|
124
|
+
/** Stitch multiple clips and return an object URL */
|
|
125
|
+
stitchToUrl(clips: ClipInput[], options?: RenderOptions): Promise<string>;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
declare const STYLE_PRESETS: Record<CaptionStylePreset, CaptionStyle>;
|
|
129
|
+
|
|
130
|
+
declare class FFmpegBackend implements RendererBackend {
|
|
131
|
+
readonly name = "ffmpeg.wasm";
|
|
132
|
+
private ffmpeg;
|
|
133
|
+
private initialized;
|
|
134
|
+
private _fetchFile;
|
|
135
|
+
init(): Promise<void>;
|
|
136
|
+
encode(frames: FrameData[], options: EncodeOptions): Promise<Blob>;
|
|
137
|
+
concat(blobs: Blob[], options: EncodeOptions): Promise<Blob>;
|
|
138
|
+
destroy(): Promise<void>;
|
|
139
|
+
}
|
|
140
|
+
declare function createFFmpegBackend(): FFmpegBackend;
|
|
141
|
+
|
|
142
|
+
declare function createFrameWorker(config?: FrameWorkerConfig): FrameWorker;
|
|
143
|
+
|
|
144
|
+
export { type AspectRatio, type CaptionOptions, type CaptionSegment, type CaptionStyle, type CaptionStylePreset, type ClipInput, type CropOptions, type EncodeOptions, FFmpegBackend, type FrameData, type FrameWorker, type FrameWorkerConfig, type RenderOptions, type RendererBackend, STYLE_PRESETS, createFFmpegBackend, createFrameWorker };
|