@twick/browser-render 0.15.6 → 0.15.7

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/README.md CHANGED
@@ -112,15 +112,16 @@ const videoBlob = await renderTwickVideoInBrowser({
112
112
 
113
113
  **Note**: String paths only work in Node.js. In the browser, you must import and pass the Project object directly.
114
114
 
115
- ## WASM Setup
115
+ ## WASM and public assets
116
116
 
117
- Copy the WASM file to your public directory:
117
+ The package ships `public/` with `mp4-wasm.wasm` and `audio-worker.js`. Copy them into your app's public directory so they are served:
118
118
 
119
119
  ```bash
120
- cp node_modules/mp4-wasm/dist/mp4-wasm.wasm public/
120
+ cp node_modules/@twick/browser-render/public/mp4-wasm.wasm public/
121
+ cp node_modules/@twick/browser-render/public/audio-worker.js public/
121
122
  ```
122
123
 
123
- Or configure Vite to serve it:
124
+ Alternatively, configure your bundler (e.g. Vite) to serve WASM:
124
125
 
125
126
  ```typescript
126
127
  // vite.config.ts
@@ -134,18 +135,15 @@ export default defineConfig({
134
135
  - **Audio**: Audio processing is not yet implemented. Only video encoding is supported.
135
136
  - **Browser Support**: Requires WebCodecs API (Chrome 94+, Edge 94+)
136
137
 
137
- ## API Comparison
138
+ ## License
138
139
 
139
- This package follows the same API as the server renderer (`@twick/renderer`):
140
+ This package is licensed under the **Sustainable Use License (SUL) Version 1.0**.
140
141
 
141
- | Feature | Server | Browser |
142
- |---------|--------|---------|
143
- | Duration Calculation | `renderer.getNumberOfFrames()` | Same |
144
- | Playback State | `PlaybackState.Rendering` | ✅ Same |
145
- | Frame Progression | `playback.progress()` | ✅ Same |
146
- | Variables Assignment | `project.variables = {...}` | ✅ Same |
147
- | Audio Support | ✅ FFmpeg | ❌ Not yet |
142
+ - Free for use in commercial and non-commercial apps
143
+ - Can be modified and self-hosted
144
+ - Cannot be sold, rebranded, or distributed as a standalone SDK
148
145
 
149
- ## License
146
+ For commercial licensing inquiries, contact: contact@kifferai.com
147
+
148
+ For full license terms, see the main LICENSE.md file in the project root.
150
149
 
151
- MIT
@@ -0,0 +1,225 @@
1
+ import { Project } from '@twick/core';
2
+
3
+ /**
4
+ * Browser rendering configuration
5
+ */
6
+ interface BrowserRenderConfig {
7
+ /**
8
+ * Custom Project object
9
+ * If not provided, defaults to @twick/visualizer project
10
+ *
11
+ * Note: Must be an imported Project object, not a string path.
12
+ * String paths only work in Node.js environments (server renderer).
13
+ *
14
+ * Example:
15
+ * ```typescript
16
+ * import myProject from './my-custom-project';
17
+ *
18
+ * await renderTwickVideoInBrowser({
19
+ * projectFile: myProject,
20
+ * variables: { input: {...} }
21
+ * });
22
+ * ```
23
+ */
24
+ projectFile?: Project;
25
+ /** Input variables containing project configuration */
26
+ variables: {
27
+ input: any;
28
+ playerId?: string;
29
+ [key: string]: any;
30
+ };
31
+ /** Render settings */
32
+ settings?: {
33
+ width?: number;
34
+ height?: number;
35
+ fps?: number;
36
+ quality?: 'low' | 'medium' | 'high';
37
+ range?: [number, number];
38
+ includeAudio?: boolean;
39
+ downloadAudioSeparately?: boolean;
40
+ onAudioReady?: (audioBlob: Blob) => void;
41
+ onProgress?: (progress: number) => void;
42
+ onComplete?: (videoBlob: Blob) => void;
43
+ onError?: (error: Error) => void;
44
+ };
45
+ }
46
+ /**
47
+ * Renders a Twick video directly in the browser without requiring a server.
48
+ * Uses WebCodecs API for encoding video frames into MP4 format.
49
+ *
50
+ * This function uses the same signature as the server renderer for consistency.
51
+ *
52
+ * @param config - Configuration object containing variables and settings
53
+ * @param config.projectFile - Optional project file path or Project object (defaults to visualizer project)
54
+ * @param config.variables - Variables containing input configuration (tracks, elements, etc.)
55
+ * @param config.settings - Optional render settings (width, height, fps, etc.)
56
+ * @returns Promise resolving to a Blob containing the rendered video
57
+ *
58
+ * @example
59
+ * ```js
60
+ * import { renderTwickVideoInBrowser } from '@twick/browser-render';
61
+ *
62
+ * // Using default visualizer project
63
+ * const videoBlob = await renderTwickVideoInBrowser({
64
+ * variables: {
65
+ * input: {
66
+ * properties: { width: 1920, height: 1080, fps: 30 },
67
+ * tracks: [
68
+ * // Your tracks configuration
69
+ * ]
70
+ * }
71
+ * },
72
+ * settings: {
73
+ * width: 1920,
74
+ * height: 1080,
75
+ * fps: 30,
76
+ * quality: 'high',
77
+ * onProgress: (progress) => console.log(`Rendering: ${progress * 100}%`),
78
+ * }
79
+ * });
80
+ *
81
+ * // Using custom project
82
+ * import myProject from './my-custom-project';
83
+ * const videoBlob = await renderTwickVideoInBrowser({
84
+ * projectFile: myProject, // Must be an imported Project object
85
+ * variables: { input: {...} },
86
+ * settings: {...}
87
+ * });
88
+ *
89
+ * // Download the video
90
+ * const url = URL.createObjectURL(videoBlob);
91
+ * const a = document.createElement('a');
92
+ * a.href = url;
93
+ * a.download = 'video.mp4';
94
+ * a.click();
95
+ * URL.revokeObjectURL(url);
96
+ * ```
97
+ */
98
+ declare const renderTwickVideoInBrowser: (config: BrowserRenderConfig) => Promise<Blob>;
99
+ /**
100
+ * Helper function to download a video blob as a file
101
+ *
102
+ * @param videoBlob - The video blob to download
103
+ * @param filename - The desired filename (default: 'video.mp4')
104
+ *
105
+ * @example
106
+ * ```js
107
+ * const blob = await renderTwickVideoInBrowser(projectData);
108
+ * downloadVideoBlob(blob, 'my-video.mp4');
109
+ * ```
110
+ */
111
+ declare const downloadVideoBlob: (videoBlob: Blob, filename?: string) => void;
112
+
113
+ interface UseBrowserRendererOptions {
114
+ /**
115
+ * Custom Project object
116
+ * If not provided, defaults to @twick/visualizer project
117
+ *
118
+ * Note: Must be an imported Project object, not a string path.
119
+ * String paths only work in Node.js (server renderer).
120
+ *
121
+ * Example:
122
+ * ```typescript
123
+ * import myProject from './my-custom-project';
124
+ * useBrowserRenderer({ projectFile: myProject })
125
+ * ```
126
+ */
127
+ projectFile?: any;
128
+ /** Video width in pixels */
129
+ width?: number;
130
+ /** Video height in pixels */
131
+ height?: number;
132
+ /** Frames per second */
133
+ fps?: number;
134
+ /** Render quality */
135
+ quality?: 'low' | 'medium' | 'high';
136
+ /** Time range to render [start, end] in seconds */
137
+ range?: [number, number];
138
+ /** Include audio in rendered video (experimental) */
139
+ includeAudio?: boolean;
140
+ /** Download audio separately as WAV file */
141
+ downloadAudioSeparately?: boolean;
142
+ /** Callback when audio is ready */
143
+ onAudioReady?: (audioBlob: Blob) => void;
144
+ /** Automatically download the video when rendering completes */
145
+ autoDownload?: boolean;
146
+ /** Default filename for downloads */
147
+ downloadFilename?: string;
148
+ }
149
+ interface UseBrowserRendererReturn {
150
+ /** Start rendering the video */
151
+ render: (variables: BrowserRenderConfig['variables']) => Promise<Blob | null>;
152
+ /** Current rendering progress (0-1) */
153
+ progress: number;
154
+ /** Whether rendering is in progress */
155
+ isRendering: boolean;
156
+ /** Error if rendering failed */
157
+ error: Error | null;
158
+ /** The rendered video blob (available after rendering completes) */
159
+ videoBlob: Blob | null;
160
+ /** Download the rendered video */
161
+ download: (filename?: string) => void;
162
+ /** Reset the renderer state */
163
+ reset: () => void;
164
+ }
165
+ /**
166
+ * React hook for rendering Twick videos in the browser
167
+ *
168
+ * Uses the same pattern as the server renderer for consistency.
169
+ *
170
+ * @param options - Rendering options
171
+ * @returns Renderer state and control functions
172
+ *
173
+ * @example
174
+ * ```tsx
175
+ * import { useBrowserRenderer } from '@twick/browser-render';
176
+ *
177
+ * // Using default visualizer project
178
+ * function MyComponent() {
179
+ * const { render, progress, isRendering, videoBlob, download } = useBrowserRenderer({
180
+ * width: 1920,
181
+ * height: 1080,
182
+ * fps: 30,
183
+ * autoDownload: true,
184
+ * });
185
+ *
186
+ * const handleRender = async () => {
187
+ * await render({
188
+ * input: {
189
+ * properties: { width: 1920, height: 1080, fps: 30 },
190
+ * tracks: [
191
+ * // Your tracks configuration
192
+ * ]
193
+ * }
194
+ * });
195
+ * };
196
+ *
197
+ * return (
198
+ * <div>
199
+ * <button onClick={handleRender} disabled={isRendering}>
200
+ * {isRendering ? `Rendering... ${(progress * 100).toFixed(0)}%` : 'Render Video'}
201
+ * </button>
202
+ * {videoBlob && !autoDownload && (
203
+ * <button onClick={() => download('my-video.mp4')}>Download</button>
204
+ * )}
205
+ * </div>
206
+ * );
207
+ * }
208
+ *
209
+ * // Using custom project (must import it first)
210
+ * import myProject from './my-project';
211
+ *
212
+ * function CustomProjectComponent() {
213
+ * const { render } = useBrowserRenderer({
214
+ * projectFile: myProject, // Pass the imported project object
215
+ * width: 1920,
216
+ * height: 1080,
217
+ * });
218
+ *
219
+ * // ... rest of component
220
+ * }
221
+ * ```
222
+ */
223
+ declare const useBrowserRenderer: (options?: UseBrowserRendererOptions) => UseBrowserRendererReturn;
224
+
225
+ export { type BrowserRenderConfig, type UseBrowserRendererOptions, type UseBrowserRendererReturn, renderTwickVideoInBrowser as default, downloadVideoBlob, renderTwickVideoInBrowser, useBrowserRenderer };
@@ -0,0 +1,225 @@
1
+ import { Project } from '@twick/core';
2
+
3
+ /**
4
+ * Browser rendering configuration
5
+ */
6
+ interface BrowserRenderConfig {
7
+ /**
8
+ * Custom Project object
9
+ * If not provided, defaults to @twick/visualizer project
10
+ *
11
+ * Note: Must be an imported Project object, not a string path.
12
+ * String paths only work in Node.js environments (server renderer).
13
+ *
14
+ * Example:
15
+ * ```typescript
16
+ * import myProject from './my-custom-project';
17
+ *
18
+ * await renderTwickVideoInBrowser({
19
+ * projectFile: myProject,
20
+ * variables: { input: {...} }
21
+ * });
22
+ * ```
23
+ */
24
+ projectFile?: Project;
25
+ /** Input variables containing project configuration */
26
+ variables: {
27
+ input: any;
28
+ playerId?: string;
29
+ [key: string]: any;
30
+ };
31
+ /** Render settings */
32
+ settings?: {
33
+ width?: number;
34
+ height?: number;
35
+ fps?: number;
36
+ quality?: 'low' | 'medium' | 'high';
37
+ range?: [number, number];
38
+ includeAudio?: boolean;
39
+ downloadAudioSeparately?: boolean;
40
+ onAudioReady?: (audioBlob: Blob) => void;
41
+ onProgress?: (progress: number) => void;
42
+ onComplete?: (videoBlob: Blob) => void;
43
+ onError?: (error: Error) => void;
44
+ };
45
+ }
46
+ /**
47
+ * Renders a Twick video directly in the browser without requiring a server.
48
+ * Uses WebCodecs API for encoding video frames into MP4 format.
49
+ *
50
+ * This function uses the same signature as the server renderer for consistency.
51
+ *
52
+ * @param config - Configuration object containing variables and settings
53
+ * @param config.projectFile - Optional project file path or Project object (defaults to visualizer project)
54
+ * @param config.variables - Variables containing input configuration (tracks, elements, etc.)
55
+ * @param config.settings - Optional render settings (width, height, fps, etc.)
56
+ * @returns Promise resolving to a Blob containing the rendered video
57
+ *
58
+ * @example
59
+ * ```js
60
+ * import { renderTwickVideoInBrowser } from '@twick/browser-render';
61
+ *
62
+ * // Using default visualizer project
63
+ * const videoBlob = await renderTwickVideoInBrowser({
64
+ * variables: {
65
+ * input: {
66
+ * properties: { width: 1920, height: 1080, fps: 30 },
67
+ * tracks: [
68
+ * // Your tracks configuration
69
+ * ]
70
+ * }
71
+ * },
72
+ * settings: {
73
+ * width: 1920,
74
+ * height: 1080,
75
+ * fps: 30,
76
+ * quality: 'high',
77
+ * onProgress: (progress) => console.log(`Rendering: ${progress * 100}%`),
78
+ * }
79
+ * });
80
+ *
81
+ * // Using custom project
82
+ * import myProject from './my-custom-project';
83
+ * const videoBlob = await renderTwickVideoInBrowser({
84
+ * projectFile: myProject, // Must be an imported Project object
85
+ * variables: { input: {...} },
86
+ * settings: {...}
87
+ * });
88
+ *
89
+ * // Download the video
90
+ * const url = URL.createObjectURL(videoBlob);
91
+ * const a = document.createElement('a');
92
+ * a.href = url;
93
+ * a.download = 'video.mp4';
94
+ * a.click();
95
+ * URL.revokeObjectURL(url);
96
+ * ```
97
+ */
98
+ declare const renderTwickVideoInBrowser: (config: BrowserRenderConfig) => Promise<Blob>;
99
+ /**
100
+ * Helper function to download a video blob as a file
101
+ *
102
+ * @param videoBlob - The video blob to download
103
+ * @param filename - The desired filename (default: 'video.mp4')
104
+ *
105
+ * @example
106
+ * ```js
107
+ * const blob = await renderTwickVideoInBrowser(projectData);
108
+ * downloadVideoBlob(blob, 'my-video.mp4');
109
+ * ```
110
+ */
111
+ declare const downloadVideoBlob: (videoBlob: Blob, filename?: string) => void;
112
+
113
+ interface UseBrowserRendererOptions {
114
+ /**
115
+ * Custom Project object
116
+ * If not provided, defaults to @twick/visualizer project
117
+ *
118
+ * Note: Must be an imported Project object, not a string path.
119
+ * String paths only work in Node.js (server renderer).
120
+ *
121
+ * Example:
122
+ * ```typescript
123
+ * import myProject from './my-custom-project';
124
+ * useBrowserRenderer({ projectFile: myProject })
125
+ * ```
126
+ */
127
+ projectFile?: any;
128
+ /** Video width in pixels */
129
+ width?: number;
130
+ /** Video height in pixels */
131
+ height?: number;
132
+ /** Frames per second */
133
+ fps?: number;
134
+ /** Render quality */
135
+ quality?: 'low' | 'medium' | 'high';
136
+ /** Time range to render [start, end] in seconds */
137
+ range?: [number, number];
138
+ /** Include audio in rendered video (experimental) */
139
+ includeAudio?: boolean;
140
+ /** Download audio separately as WAV file */
141
+ downloadAudioSeparately?: boolean;
142
+ /** Callback when audio is ready */
143
+ onAudioReady?: (audioBlob: Blob) => void;
144
+ /** Automatically download the video when rendering completes */
145
+ autoDownload?: boolean;
146
+ /** Default filename for downloads */
147
+ downloadFilename?: string;
148
+ }
149
+ interface UseBrowserRendererReturn {
150
+ /** Start rendering the video */
151
+ render: (variables: BrowserRenderConfig['variables']) => Promise<Blob | null>;
152
+ /** Current rendering progress (0-1) */
153
+ progress: number;
154
+ /** Whether rendering is in progress */
155
+ isRendering: boolean;
156
+ /** Error if rendering failed */
157
+ error: Error | null;
158
+ /** The rendered video blob (available after rendering completes) */
159
+ videoBlob: Blob | null;
160
+ /** Download the rendered video */
161
+ download: (filename?: string) => void;
162
+ /** Reset the renderer state */
163
+ reset: () => void;
164
+ }
165
+ /**
166
+ * React hook for rendering Twick videos in the browser
167
+ *
168
+ * Uses the same pattern as the server renderer for consistency.
169
+ *
170
+ * @param options - Rendering options
171
+ * @returns Renderer state and control functions
172
+ *
173
+ * @example
174
+ * ```tsx
175
+ * import { useBrowserRenderer } from '@twick/browser-render';
176
+ *
177
+ * // Using default visualizer project
178
+ * function MyComponent() {
179
+ * const { render, progress, isRendering, videoBlob, download } = useBrowserRenderer({
180
+ * width: 1920,
181
+ * height: 1080,
182
+ * fps: 30,
183
+ * autoDownload: true,
184
+ * });
185
+ *
186
+ * const handleRender = async () => {
187
+ * await render({
188
+ * input: {
189
+ * properties: { width: 1920, height: 1080, fps: 30 },
190
+ * tracks: [
191
+ * // Your tracks configuration
192
+ * ]
193
+ * }
194
+ * });
195
+ * };
196
+ *
197
+ * return (
198
+ * <div>
199
+ * <button onClick={handleRender} disabled={isRendering}>
200
+ * {isRendering ? `Rendering... ${(progress * 100).toFixed(0)}%` : 'Render Video'}
201
+ * </button>
202
+ * {videoBlob && !autoDownload && (
203
+ * <button onClick={() => download('my-video.mp4')}>Download</button>
204
+ * )}
205
+ * </div>
206
+ * );
207
+ * }
208
+ *
209
+ * // Using custom project (must import it first)
210
+ * import myProject from './my-project';
211
+ *
212
+ * function CustomProjectComponent() {
213
+ * const { render } = useBrowserRenderer({
214
+ * projectFile: myProject, // Pass the imported project object
215
+ * width: 1920,
216
+ * height: 1080,
217
+ * });
218
+ *
219
+ * // ... rest of component
220
+ * }
221
+ * ```
222
+ */
223
+ declare const useBrowserRenderer: (options?: UseBrowserRendererOptions) => UseBrowserRendererReturn;
224
+
225
+ export { type BrowserRenderConfig, type UseBrowserRendererOptions, type UseBrowserRendererReturn, renderTwickVideoInBrowser as default, downloadVideoBlob, renderTwickVideoInBrowser, useBrowserRenderer };