textmode.export.js 1.8.0 → 1.9.0-beta.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.
- package/README.md +7 -2
- package/dist/textmode.export.esm.js +1 -1
- package/dist/textmode.export.umd.js +1 -1
- package/dist/types/exporters/base/FileHandler.d.ts +1 -14
- package/dist/types/exporters/base/FilenamePolicy.d.ts +6 -0
- package/dist/types/exporters/base/FramePreparation.d.ts +7 -0
- package/dist/types/exporters/base/frame-sequence/ExclusiveCaptureGate.d.ts +7 -0
- package/dist/types/exporters/base/frame-sequence/FrameSchedule.d.ts +8 -0
- package/dist/types/exporters/{video/VideoFrameDriver.d.ts → base/frame-sequence/FrameSequenceDriver.d.ts} +5 -11
- package/dist/types/exporters/base/frame-sequence/errors.d.ts +12 -0
- package/dist/types/exporters/base/frame-sequence/index.d.ts +5 -0
- package/dist/types/exporters/base/frame-sequence/types.d.ts +20 -0
- package/dist/types/exporters/base/frame-sequence/withAbortableTimeout.d.ts +1 -0
- package/dist/types/exporters/base/index.d.ts +3 -0
- package/dist/types/exporters/gif/GIFExporter.d.ts +1 -1
- package/dist/types/exporters/gif/index.d.ts +0 -1
- package/dist/types/exporters/gif/types.d.ts +6 -12
- package/dist/types/exporters/json/JSONExporter.d.ts +2 -2
- package/dist/types/exporters/video/VideoEncodingPolicy.d.ts +2 -19
- package/dist/types/exporters/video/VideoExporter.d.ts +4 -6
- package/dist/types/exporters/video/VideoRecorder.d.ts +2 -1
- package/dist/types/exporters/video/errors.d.ts +1 -0
- package/dist/types/exporters/video/index.d.ts +1 -1
- package/dist/types/exporters/video/types.d.ts +104 -107
- package/dist/types/exporters/zip/FrameSerializerRegistry.d.ts +4 -0
- package/dist/types/exporters/zip/ZIPArchiveWriter.d.ts +21 -0
- package/dist/types/exporters/zip/ZIPExporter.d.ts +32 -0
- package/dist/types/exporters/zip/ZIPManifest.d.ts +12 -0
- package/dist/types/exporters/zip/errors.d.ts +14 -0
- package/dist/types/exporters/zip/index.d.ts +3 -0
- package/dist/types/exporters/zip/types.d.ts +177 -0
- package/dist/types/index.d.ts +34 -6
- package/dist/types/overlay/blades/VideoBlade.d.ts +3 -6
- package/dist/types/overlay/types.d.ts +2 -4
- package/dist/types/runtime/TextmodeExportController.d.ts +3 -0
- package/dist/types/types.d.ts +72 -11
- package/package.json +6 -3
- package/dist/types/exporters/gif/GIFRecorder.d.ts +0 -23
|
@@ -1,45 +1,83 @@
|
|
|
1
|
-
import type { PrepareExportFrame } from '../base';
|
|
1
|
+
import type { FrameSequenceDriverLike, FrameSequenceRenderOptions, PrepareExportFrame } from '../base';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* High-level lifecycle state reported while a video export is captured, encoded, or completed.
|
|
4
4
|
*
|
|
5
|
-
* @category
|
|
5
|
+
* @category Video export
|
|
6
6
|
*
|
|
7
7
|
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/VideoRecordingState | VideoRecordingState API reference}
|
|
8
8
|
*/
|
|
9
9
|
export type VideoRecordingState = 'idle' | 'recording' | 'encoding' | 'completed' | 'error';
|
|
10
10
|
/**
|
|
11
|
-
*
|
|
11
|
+
* Detailed phase information for progress UIs that distinguish capability probing, frame capture, and output.
|
|
12
12
|
*
|
|
13
|
-
* `
|
|
13
|
+
* Current exports emit `probing`, `capturing`, and either `writing` for streamed file-system output or `finalizing`
|
|
14
|
+
* for buffered output. `rendering`, `encoding`, and `draining` remain available for compatibility with older progress
|
|
15
|
+
* producers.
|
|
14
16
|
*
|
|
15
|
-
* @category
|
|
17
|
+
* @category Video export
|
|
16
18
|
*
|
|
17
19
|
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/VideoExportPhase | VideoExportPhase API reference}
|
|
18
20
|
*/
|
|
19
21
|
export type VideoExportPhase = 'probing' | 'rendering' | 'capturing' | 'encoding' | 'draining' | 'writing' | 'finalizing';
|
|
20
22
|
export type VideoCodec = 'vp8' | 'vp9' | 'avc' | (string & {});
|
|
21
23
|
/**
|
|
22
|
-
*
|
|
24
|
+
* Qualitative video quality level matching Mediabunny's five native levels.
|
|
23
25
|
*
|
|
24
|
-
* Higher
|
|
25
|
-
*
|
|
26
|
-
* lossless. For exact bitrate control, pass a numeric `bitrate` value in bits per second instead.
|
|
26
|
+
* Higher levels generally preserve more detail and produce larger, content-dependent files. Mediabunny may use
|
|
27
|
+
* quantizer-based encoding or a codec-adjusted bitrate, depending on codec and browser support.
|
|
27
28
|
*
|
|
28
|
-
* @category
|
|
29
|
+
* @category Video export
|
|
29
30
|
*
|
|
30
|
-
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/
|
|
31
|
+
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/VideoQualityLevel | VideoQualityLevel API reference}
|
|
31
32
|
*/
|
|
32
|
-
export type
|
|
33
|
+
export type VideoQualityLevel = 'very-low' | 'low' | 'medium' | 'high' | 'very-high';
|
|
33
34
|
/**
|
|
34
|
-
*
|
|
35
|
+
* Video compression policy passed to Mediabunny.
|
|
35
36
|
*
|
|
36
|
-
*
|
|
37
|
+
* Use a named {@link VideoQualityLevel} for content-dependent qualitative encoding. Use the object form to request a
|
|
38
|
+
* positive target bitrate in bits per second and, optionally, constant or variable allocation. When `bitrateMode` is
|
|
39
|
+
* omitted, Mediabunny defaults bitrate-based encoding to `'variable'`. A target bitrate guides the encoder but does
|
|
40
|
+
* not guarantee an exact final file size.
|
|
41
|
+
*
|
|
42
|
+
* @example Named qualitative quality
|
|
43
|
+
* ```ts
|
|
44
|
+
* await t.saveVideo({ quality: 'very-high' });
|
|
45
|
+
* ```
|
|
46
|
+
*
|
|
47
|
+
* @example Target bitrate with constant allocation
|
|
48
|
+
* ```ts
|
|
49
|
+
* await t.saveVideo({ quality: { bitrate: 8_000_000, bitrateMode: 'constant' } });
|
|
50
|
+
* ```
|
|
51
|
+
*
|
|
52
|
+
* @category Video export
|
|
53
|
+
*
|
|
54
|
+
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/VideoQuality | VideoQuality API reference}
|
|
37
55
|
*/
|
|
38
|
-
export type
|
|
56
|
+
export type VideoQuality = VideoQualityLevel | {
|
|
57
|
+
bitrate: number;
|
|
58
|
+
bitrateMode?: VideoBitrateMode;
|
|
59
|
+
};
|
|
39
60
|
/**
|
|
40
|
-
*
|
|
61
|
+
* Destination policy used by `saveVideo()`.
|
|
62
|
+
*
|
|
63
|
+
* - `'download'` is the default. The complete video is buffered in memory before a browser download begins.
|
|
64
|
+
* - `'file-system'` opens the browser's save picker and streams encoded chunks directly to the selected file. It
|
|
65
|
+
* requires the File System Access API and rejects with `VIDEO_EXPORT_UNSUPPORTED` when that API is unavailable.
|
|
66
|
+
*
|
|
67
|
+
* This setting does not affect `toVideoBlob()`, which always returns an in-memory `Blob`.
|
|
41
68
|
*
|
|
42
|
-
* @category
|
|
69
|
+
* @category Video export
|
|
70
|
+
*
|
|
71
|
+
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/VideoSaveDestination | VideoSaveDestination API reference}
|
|
72
|
+
*/
|
|
73
|
+
export type VideoSaveDestination = 'download' | 'file-system';
|
|
74
|
+
/**
|
|
75
|
+
* Video container format produced by `saveVideo()` and `toVideoBlob()`.
|
|
76
|
+
*
|
|
77
|
+
* MP4 uses AVC/H.264 and requires even coded dimensions. WebM selects VP9 when available and falls back to VP8; it
|
|
78
|
+
* is the only format that can be requested with transparency.
|
|
79
|
+
*
|
|
80
|
+
* @category Video export
|
|
43
81
|
*
|
|
44
82
|
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/VideoExportFormat | VideoExportFormat API reference}
|
|
45
83
|
*/
|
|
@@ -52,23 +90,13 @@ export type VideoExportFormat = 'webm' | 'mp4';
|
|
|
52
90
|
* - `'constant'`: asks the encoder to keep the bitrate steadier throughout the export. This can make file size
|
|
53
91
|
* more predictable, but may waste bits on simple frames or reduce detail on complex frames.
|
|
54
92
|
*
|
|
55
|
-
*
|
|
93
|
+
* If omitted for an explicit target bitrate, Mediabunny uses `'variable'`.
|
|
94
|
+
*
|
|
95
|
+
* @category Video export
|
|
56
96
|
*
|
|
57
97
|
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/VideoBitrateMode | VideoBitrateMode API reference}
|
|
58
98
|
*/
|
|
59
99
|
export type VideoBitrateMode = 'variable' | 'constant';
|
|
60
|
-
/**
|
|
61
|
-
* Encoder scheduling mode.
|
|
62
|
-
*
|
|
63
|
-
* - `'quality'`: prioritizes complete, stable export output. Mediabunny notes that this mode prevents dropped frames.
|
|
64
|
-
* - `'realtime'`: prioritizes low-latency encoding. It is intended for live streams and may drop frames when overloaded,
|
|
65
|
-
* so it is usually not recommended for frame-perfect exports.
|
|
66
|
-
*
|
|
67
|
-
* @category Animation export
|
|
68
|
-
*
|
|
69
|
-
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/VideoLatencyMode | VideoLatencyMode API reference}
|
|
70
|
-
*/
|
|
71
|
-
export type VideoLatencyMode = 'quality' | 'realtime';
|
|
72
100
|
/**
|
|
73
101
|
* WebCodecs hardware acceleration preference.
|
|
74
102
|
*
|
|
@@ -78,34 +106,34 @@ export type VideoLatencyMode = 'quality' | 'realtime';
|
|
|
78
106
|
* availability and output characteristics vary by device.
|
|
79
107
|
* - `'prefer-software'`: prefer CPU encoding, often more consistent across machines, but usually slower.
|
|
80
108
|
*
|
|
81
|
-
* @category
|
|
109
|
+
* @category Video export
|
|
82
110
|
*
|
|
83
111
|
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/VideoHardwareAcceleration | VideoHardwareAcceleration API reference}
|
|
84
112
|
*/
|
|
85
113
|
export type VideoHardwareAcceleration = 'no-preference' | 'prefer-hardware' | 'prefer-software';
|
|
86
|
-
export type VideoExportErrorCode = 'VIDEO_EXPORT_UNSUPPORTED' | 'VIDEO_CODEC_UNSUPPORTED' | 'VIDEO_EXPORT_ABORTED' | 'VIDEO_EXPORT_TIMEOUT' | 'VIDEO_EXPORT_FAILED' | 'VIDEO_TRANSPARENCY_UNSUPPORTED' | 'VIDEO_DIMENSIONS_UNSUPPORTED'
|
|
114
|
+
export type VideoExportErrorCode = 'VIDEO_EXPORT_UNSUPPORTED' | 'VIDEO_CODEC_UNSUPPORTED' | 'VIDEO_EXPORT_ABORTED' | 'VIDEO_EXPORT_TIMEOUT' | 'VIDEO_EXPORT_FAILED' | 'VIDEO_TRANSPARENCY_UNSUPPORTED' | 'VIDEO_DIMENSIONS_UNSUPPORTED';
|
|
87
115
|
/**
|
|
88
|
-
* Progress information emitted
|
|
116
|
+
* Progress information emitted while a deterministic video is probed, captured, and written.
|
|
89
117
|
*
|
|
90
|
-
* @category
|
|
118
|
+
* @category Video export
|
|
91
119
|
*
|
|
92
120
|
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/VideoExportProgress | VideoExportProgress API reference}
|
|
93
121
|
*/
|
|
94
122
|
export type VideoExportProgress = {
|
|
95
123
|
/**
|
|
96
|
-
* Current
|
|
124
|
+
* Current high-level export state.
|
|
97
125
|
*
|
|
98
126
|
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/VideoExportProgress#state | VideoExportProgress.state API reference}
|
|
99
127
|
*/
|
|
100
128
|
state: VideoRecordingState;
|
|
101
129
|
/**
|
|
102
|
-
* Current
|
|
130
|
+
* Current detailed phase. See {@link VideoExportPhase} for current and compatibility-only values.
|
|
103
131
|
*
|
|
104
132
|
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/VideoExportProgress#phase | VideoExportProgress.phase API reference}
|
|
105
133
|
*/
|
|
106
134
|
phase?: VideoExportPhase;
|
|
107
135
|
/**
|
|
108
|
-
* Number of frames
|
|
136
|
+
* Number of frames captured so far.
|
|
109
137
|
*
|
|
110
138
|
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/VideoExportProgress#frameindex | VideoExportProgress.frameIndex API reference}
|
|
111
139
|
*/
|
|
@@ -123,7 +151,9 @@ export type VideoExportProgress = {
|
|
|
123
151
|
*/
|
|
124
152
|
totalFrames?: number;
|
|
125
153
|
/**
|
|
126
|
-
*
|
|
154
|
+
* Normalized frame-capture completion ratio between `0` and `1`.
|
|
155
|
+
*
|
|
156
|
+
* Final writing or muxing may still be in progress when this value reaches `1`.
|
|
127
157
|
*
|
|
128
158
|
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/VideoExportProgress#progress | VideoExportProgress.progress API reference}
|
|
129
159
|
*/
|
|
@@ -135,22 +165,34 @@ export type VideoExportProgress = {
|
|
|
135
165
|
*/
|
|
136
166
|
message?: string;
|
|
137
167
|
/**
|
|
138
|
-
*
|
|
168
|
+
* Effective codec family selected after capability probing (`avc`, `vp9`, or `vp8`).
|
|
169
|
+
*
|
|
170
|
+
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/VideoExportProgress#codec | VideoExportProgress.codec API reference}
|
|
171
|
+
*/
|
|
172
|
+
codec?: VideoCodec;
|
|
173
|
+
/**
|
|
174
|
+
* Effective coded width in pixels.
|
|
175
|
+
*
|
|
176
|
+
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/VideoExportProgress#codedwidth | VideoExportProgress.codedWidth API reference}
|
|
177
|
+
*/
|
|
178
|
+
codedWidth?: number;
|
|
179
|
+
/**
|
|
180
|
+
* Effective coded height in pixels.
|
|
139
181
|
*
|
|
140
|
-
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/VideoExportProgress#
|
|
182
|
+
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/VideoExportProgress#codedheight | VideoExportProgress.codedHeight API reference}
|
|
141
183
|
*/
|
|
142
|
-
|
|
184
|
+
codedHeight?: number;
|
|
143
185
|
/**
|
|
144
|
-
*
|
|
186
|
+
* Exact output frame rate passed to the muxer.
|
|
145
187
|
*
|
|
146
|
-
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/VideoExportProgress#
|
|
188
|
+
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/VideoExportProgress#framerate | VideoExportProgress.frameRate API reference}
|
|
147
189
|
*/
|
|
148
|
-
|
|
190
|
+
frameRate?: number;
|
|
149
191
|
};
|
|
150
192
|
/**
|
|
151
|
-
* Options for
|
|
193
|
+
* Options for capturing deterministic textmode frames as MP4 or WebM video.
|
|
152
194
|
*
|
|
153
|
-
* @category
|
|
195
|
+
* @category Video export
|
|
154
196
|
*
|
|
155
197
|
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/VideoExportOptions | VideoExportOptions API reference}
|
|
156
198
|
*/
|
|
@@ -180,39 +222,23 @@ export type VideoExportOptions = {
|
|
|
180
222
|
*/
|
|
181
223
|
frameRate?: number;
|
|
182
224
|
/**
|
|
183
|
-
*
|
|
225
|
+
* Video quality policy. Defaults to `'medium'`.
|
|
184
226
|
*
|
|
185
|
-
*
|
|
186
|
-
*
|
|
187
|
-
* large files. Numeric values remain exact bits-per-second targets and are wrapped in Mediabunny `Quality`.
|
|
227
|
+
* Named levels map one-to-one to Mediabunny's qualitative levels and produce content-dependent file sizes. Use the
|
|
228
|
+
* object form to request a positive target bitrate in bits per second and an optional bitrate mode.
|
|
188
229
|
*
|
|
189
|
-
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/VideoExportOptions#
|
|
230
|
+
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/VideoExportOptions#quality | VideoExportOptions.quality API reference}
|
|
190
231
|
*/
|
|
191
|
-
|
|
232
|
+
quality?: VideoQuality;
|
|
192
233
|
/**
|
|
193
|
-
*
|
|
194
|
-
*
|
|
195
|
-
* Use `'variable'` for most exports so simple frames can compress efficiently and complex frames can receive more
|
|
196
|
-
* bits. Use `'constant'` only when a steadier data rate is more important than compression efficiency.
|
|
234
|
+
* Save destination used by `saveVideo()`. Defaults to `'download'`.
|
|
197
235
|
*
|
|
198
|
-
*
|
|
199
|
-
|
|
200
|
-
bitrateMode?: VideoBitrateMode;
|
|
201
|
-
/**
|
|
202
|
-
* Content hint passed to the native video encoder. Defaults to `'text'`.
|
|
236
|
+
* `'file-system'` opens a save picker and streams directly to the selected file when the File System Access API is
|
|
237
|
+
* available. `toVideoBlob()` always returns an in-memory blob and does not use this setting.
|
|
203
238
|
*
|
|
204
|
-
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/VideoExportOptions#
|
|
239
|
+
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/VideoExportOptions#destination | VideoExportOptions.destination API reference}
|
|
205
240
|
*/
|
|
206
|
-
|
|
207
|
-
/**
|
|
208
|
-
* Encoder latency mode. Defaults to `'quality'`.
|
|
209
|
-
*
|
|
210
|
-
* Use `'quality'` for deterministic exports; it prioritizes completed output and avoids dropped frames. Use
|
|
211
|
-
* `'realtime'` only for low-latency use cases where dropped frames are acceptable.
|
|
212
|
-
*
|
|
213
|
-
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/VideoExportOptions#latencymode | VideoExportOptions.latencyMode API reference}
|
|
214
|
-
*/
|
|
215
|
-
latencyMode?: VideoLatencyMode;
|
|
241
|
+
destination?: VideoSaveDestination;
|
|
216
242
|
/**
|
|
217
243
|
* WebCodecs hardware acceleration hint. Defaults to `'no-preference'`.
|
|
218
244
|
*
|
|
@@ -251,7 +277,7 @@ export type VideoExportOptions = {
|
|
|
251
277
|
*/
|
|
252
278
|
prepareFrame?: PrepareExportFrame;
|
|
253
279
|
/**
|
|
254
|
-
* When true
|
|
280
|
+
* When `true`, attempts to preserve alpha data in WebM recordings. MP4 exports reject this option.
|
|
255
281
|
*
|
|
256
282
|
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/VideoExportOptions#transparent | VideoExportOptions.transparent API reference}
|
|
257
283
|
*/
|
|
@@ -268,22 +294,13 @@ export type VideoExportOptions = {
|
|
|
268
294
|
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/VideoExportOptions#debuglogging | VideoExportOptions.debugLogging API reference}
|
|
269
295
|
*/
|
|
270
296
|
debugLogging?: boolean;
|
|
271
|
-
/**
|
|
272
|
-
* Allows `toVideoBlob()` to retain its in-memory contract above the safe 100 MB default.
|
|
273
|
-
*
|
|
274
|
-
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/VideoExportOptions#allowlargeinmemory | VideoExportOptions.allowLargeInMemory API reference}
|
|
275
|
-
*/
|
|
276
|
-
allowLargeInMemory?: boolean;
|
|
277
297
|
};
|
|
278
298
|
export interface VideoGenerationOptions {
|
|
279
299
|
filename?: string;
|
|
280
300
|
format: VideoExportFormat;
|
|
281
301
|
frameRate: number;
|
|
282
302
|
frameCount: number;
|
|
283
|
-
|
|
284
|
-
bitrateMode: VideoBitrateMode;
|
|
285
|
-
contentHint?: VideoContentHint;
|
|
286
|
-
latencyMode: VideoLatencyMode;
|
|
303
|
+
quality: VideoQuality;
|
|
287
304
|
hardwareAcceleration: VideoHardwareAcceleration;
|
|
288
305
|
keyFrameInterval: number;
|
|
289
306
|
pixelDensity: number;
|
|
@@ -291,7 +308,6 @@ export interface VideoGenerationOptions {
|
|
|
291
308
|
height: number;
|
|
292
309
|
transparent: boolean;
|
|
293
310
|
debugLogging: boolean;
|
|
294
|
-
allowLargeInMemory?: boolean;
|
|
295
311
|
signal?: AbortSignal;
|
|
296
312
|
prepareFrame?: PrepareExportFrame;
|
|
297
313
|
}
|
|
@@ -300,14 +316,7 @@ export interface VideoEncodingPlan {
|
|
|
300
316
|
extension: '.webm' | '.mp4';
|
|
301
317
|
mimeType: string;
|
|
302
318
|
codec: VideoCodec;
|
|
303
|
-
|
|
304
|
-
bitrateMode: VideoBitrateMode;
|
|
305
|
-
qualityPreset: VideoBitratePreset | null;
|
|
306
|
-
rateControlIntent: 'bitrate' | 'constant-quality' | 'ultra';
|
|
307
|
-
qualityLevel?: 'medium' | 'high' | 'very-high';
|
|
308
|
-
contentHint: VideoContentHint;
|
|
309
|
-
estimatedBytes: number;
|
|
310
|
-
latencyMode: VideoLatencyMode;
|
|
319
|
+
quality: VideoQuality;
|
|
311
320
|
hardwareAcceleration: VideoHardwareAcceleration;
|
|
312
321
|
keyFrameInterval: number;
|
|
313
322
|
frameRate: number;
|
|
@@ -316,17 +325,5 @@ export interface VideoEncodingPlan {
|
|
|
316
325
|
height: number;
|
|
317
326
|
transparent: boolean;
|
|
318
327
|
}
|
|
319
|
-
export
|
|
320
|
-
|
|
321
|
-
frameRate: number;
|
|
322
|
-
signal?: AbortSignal;
|
|
323
|
-
prepareFrame?: PrepareExportFrame;
|
|
324
|
-
onFrame(frame: {
|
|
325
|
-
frameIndex: number;
|
|
326
|
-
canvas: HTMLCanvasElement;
|
|
327
|
-
}): Promise<void> | void;
|
|
328
|
-
}
|
|
329
|
-
export interface VideoFrameDriverLike {
|
|
330
|
-
readonly canvas: HTMLCanvasElement;
|
|
331
|
-
$render(options: VideoRenderFrameOptions): Promise<void>;
|
|
332
|
-
}
|
|
328
|
+
export type VideoRenderFrameOptions = FrameSequenceRenderOptions;
|
|
329
|
+
export type VideoFrameDriverLike = FrameSequenceDriverLike;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Textmodifier } from 'textmode.js';
|
|
2
|
+
import type { ZIPFrameFormat, ZIPFrameSerializer } from './types';
|
|
3
|
+
/** Resolves the thin adapter for one supported ZIP frame format. */
|
|
4
|
+
export declare function createZIPFrameSerializerRegistry(textmodifier: Textmodifier): Record<ZIPFrameFormat, ZIPFrameSerializer>;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ZIPEntryCompression } from './types';
|
|
2
|
+
/** Streaming ZIP wrapper that retains only compressed archive output chunks. */
|
|
3
|
+
export declare class ZIPArchiveWriter {
|
|
4
|
+
private readonly _archive;
|
|
5
|
+
private readonly _chunks;
|
|
6
|
+
private readonly _entryNames;
|
|
7
|
+
private readonly _modifiedAt;
|
|
8
|
+
private readonly _maxArchiveBytes;
|
|
9
|
+
private _state;
|
|
10
|
+
private _archiveBytes;
|
|
11
|
+
private _failure;
|
|
12
|
+
private _resolveFinal?;
|
|
13
|
+
private _rejectFinal?;
|
|
14
|
+
constructor(modifiedAt: Date, maxArchiveBytes?: number);
|
|
15
|
+
$addEntry(path: string, data: Uint8Array, compression: ZIPEntryCompression): Promise<void>;
|
|
16
|
+
$finalize(): Promise<Blob>;
|
|
17
|
+
$abort(reason?: unknown): void;
|
|
18
|
+
private _assertOpen;
|
|
19
|
+
private _validateEntryPath;
|
|
20
|
+
private _fail;
|
|
21
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { Textmodifier } from 'textmode.js';
|
|
2
|
+
import { type FrameSequenceDriverLike, type PostDrawSubscription } from '../base';
|
|
3
|
+
import type { ZIPExportOptions, ZIPFrameFormat, ZIPFrameSerializer } from './types';
|
|
4
|
+
interface ZIPExporterDependencies {
|
|
5
|
+
createDriver?: () => FrameSequenceDriverLike;
|
|
6
|
+
createWriter?: (createdAt: Date) => ZIPArchiveWriterLike;
|
|
7
|
+
resolveSerializer?: (format: ZIPFrameFormat) => ZIPFrameSerializer;
|
|
8
|
+
now?: () => Date;
|
|
9
|
+
}
|
|
10
|
+
interface ZIPArchiveWriterLike {
|
|
11
|
+
$addEntry(path: string, data: Uint8Array, compression: 'store' | 'deflate'): Promise<void>;
|
|
12
|
+
$finalize(): Promise<Blob>;
|
|
13
|
+
$abort(reason?: unknown): void;
|
|
14
|
+
}
|
|
15
|
+
/** Captures deterministic frames and archives them in capture order. */
|
|
16
|
+
export declare class ZIPExporter {
|
|
17
|
+
private readonly _textmodifier;
|
|
18
|
+
private readonly _registerPostDrawHook;
|
|
19
|
+
private readonly _dependencies;
|
|
20
|
+
constructor(_textmodifier: Textmodifier, _registerPostDrawHook: PostDrawSubscription, dependencies?: ZIPExporterDependencies);
|
|
21
|
+
$saveZIP(options: ZIPExportOptions): Promise<void>;
|
|
22
|
+
/** Generates a deterministic ZIP archive without initiating a download. */
|
|
23
|
+
$generateZIPBlob(options: ZIPExportOptions): Promise<Blob>;
|
|
24
|
+
private _export;
|
|
25
|
+
private _executeExport;
|
|
26
|
+
private _validateAndNormalize;
|
|
27
|
+
private _emitProgress;
|
|
28
|
+
private _progressFrameCount;
|
|
29
|
+
private _throwIfAborted;
|
|
30
|
+
private _yieldToBrowser;
|
|
31
|
+
}
|
|
32
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ZIPFrameFormat, ZIPFrameSequenceManifest } from './types';
|
|
2
|
+
export declare function createZIPFramePath(rootStem: string, frameIndex: number, extension: string): string;
|
|
3
|
+
export declare function createZIPManifest(options: {
|
|
4
|
+
createdAt: Date;
|
|
5
|
+
format: ZIPFrameFormat;
|
|
6
|
+
frameCount: number;
|
|
7
|
+
frameRate: number;
|
|
8
|
+
width: number;
|
|
9
|
+
height: number;
|
|
10
|
+
extension: string;
|
|
11
|
+
}): ZIPFrameSequenceManifest;
|
|
12
|
+
export declare function encodeZIPManifest(manifest: ZIPFrameSequenceManifest): Uint8Array;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ZIPExportErrorCode } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Error raised by ZIP frame-sequence validation, capture, or archive creation.
|
|
4
|
+
*
|
|
5
|
+
* @category ZIP frame-sequence export
|
|
6
|
+
* @see {@link https://code.textmode.art/api/textmode.export.js/classes/ZIPExportError | ZIPExportError API reference}
|
|
7
|
+
*/
|
|
8
|
+
export declare class ZIPExportError extends Error {
|
|
9
|
+
readonly code: ZIPExportErrorCode;
|
|
10
|
+
readonly cause?: unknown;
|
|
11
|
+
constructor(code: ZIPExportErrorCode, message: string, cause?: unknown);
|
|
12
|
+
}
|
|
13
|
+
export declare function createZIPAbortError(cause?: unknown): ZIPExportError;
|
|
14
|
+
export declare function normalizeZIPExportError(error: unknown): ZIPExportError;
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import type { PrepareExportFrame } from '../base';
|
|
2
|
+
import type { ImageExportOptions } from '../image';
|
|
3
|
+
import type { JSONExportOptions } from '../json';
|
|
4
|
+
import type { SVGExportOptions } from '../svg';
|
|
5
|
+
import type { TXTExportOptions } from '../txt';
|
|
6
|
+
/**
|
|
7
|
+
* File format used for every frame in a ZIP frame-sequence export.
|
|
8
|
+
*
|
|
9
|
+
* @category ZIP frame-sequence export
|
|
10
|
+
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/ZIPFrameFormat | ZIPFrameFormat API reference}
|
|
11
|
+
*/
|
|
12
|
+
export type ZIPFrameFormat = 'png' | 'jpg' | 'webp' | 'svg' | 'json' | 'txt';
|
|
13
|
+
/**
|
|
14
|
+
* Lifecycle state reported by a ZIP frame-sequence export.
|
|
15
|
+
*
|
|
16
|
+
* @category ZIP frame-sequence export
|
|
17
|
+
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/ZIPExportState | ZIPExportState API reference}
|
|
18
|
+
*/
|
|
19
|
+
export type ZIPExportState = 'capturing' | 'finalizing' | 'completed' | 'error';
|
|
20
|
+
/**
|
|
21
|
+
* Machine-readable ZIP export failure category.
|
|
22
|
+
*
|
|
23
|
+
* @category ZIP frame-sequence export
|
|
24
|
+
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/ZIPExportErrorCode | ZIPExportErrorCode API reference}
|
|
25
|
+
*/
|
|
26
|
+
export type ZIPExportErrorCode = 'ZIP_EXPORT_INVALID_OPTIONS' | 'ZIP_EXPORT_ENCODING_UNSUPPORTED' | 'ZIP_EXPORT_TOO_LARGE' | 'ZIP_EXPORT_ABORTED' | 'ZIP_EXPORT_TIMEOUT' | 'ZIP_EXPORT_BUSY' | 'ZIP_EXPORT_DISPOSED' | 'ZIP_EXPORT_FAILED';
|
|
27
|
+
/**
|
|
28
|
+
* Progress information emitted while ZIP frames are captured and archived.
|
|
29
|
+
*
|
|
30
|
+
* @category ZIP frame-sequence export
|
|
31
|
+
* @see {@link https://code.textmode.art/api/textmode.export.js/interfaces/ZIPExportProgress | ZIPExportProgress API reference}
|
|
32
|
+
*/
|
|
33
|
+
export interface ZIPExportProgress {
|
|
34
|
+
/**
|
|
35
|
+
* Current ZIP export state.
|
|
36
|
+
*
|
|
37
|
+
* @see {@link https://code.textmode.art/api/textmode.export.js/interfaces/ZIPExportProgress#state | ZIPExportProgress.state API reference}
|
|
38
|
+
*/
|
|
39
|
+
state: ZIPExportState;
|
|
40
|
+
/**
|
|
41
|
+
* Number of completed frame entries.
|
|
42
|
+
*
|
|
43
|
+
* @see {@link https://code.textmode.art/api/textmode.export.js/interfaces/ZIPExportProgress#frameindex | ZIPExportProgress.frameIndex API reference}
|
|
44
|
+
*/
|
|
45
|
+
frameIndex: number;
|
|
46
|
+
/**
|
|
47
|
+
* Total number of frame entries planned for the archive.
|
|
48
|
+
*
|
|
49
|
+
* @see {@link https://code.textmode.art/api/textmode.export.js/interfaces/ZIPExportProgress#totalframes | ZIPExportProgress.totalFrames API reference}
|
|
50
|
+
*/
|
|
51
|
+
totalFrames: number;
|
|
52
|
+
/**
|
|
53
|
+
* Normalized completed-frame ratio from `0` through `1`.
|
|
54
|
+
*
|
|
55
|
+
* @see {@link https://code.textmode.art/api/textmode.export.js/interfaces/ZIPExportProgress#progress | ZIPExportProgress.progress API reference}
|
|
56
|
+
*/
|
|
57
|
+
progress: number;
|
|
58
|
+
/**
|
|
59
|
+
* Optional failure message for an `error` event.
|
|
60
|
+
*
|
|
61
|
+
* @see {@link https://code.textmode.art/api/textmode.export.js/interfaces/ZIPExportProgress#message | ZIPExportProgress.message API reference}
|
|
62
|
+
*/
|
|
63
|
+
message?: string;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Options shared by all ZIP frame formats.
|
|
67
|
+
*
|
|
68
|
+
* @category ZIP frame-sequence export
|
|
69
|
+
* @see {@link https://code.textmode.art/api/textmode.export.js/interfaces/ZIPCaptureOptions | ZIPCaptureOptions API reference}
|
|
70
|
+
*/
|
|
71
|
+
export interface ZIPCaptureOptions {
|
|
72
|
+
/**
|
|
73
|
+
* Target archive filename, with or without `.zip`.
|
|
74
|
+
*
|
|
75
|
+
* @see {@link https://code.textmode.art/api/textmode.export.js/interfaces/ZIPCaptureOptions#filename | ZIPCaptureOptions.filename API reference}
|
|
76
|
+
*/
|
|
77
|
+
filename?: string;
|
|
78
|
+
/**
|
|
79
|
+
* Number of frames to capture. Defaults to `300`.
|
|
80
|
+
*
|
|
81
|
+
* @see {@link https://code.textmode.art/api/textmode.export.js/interfaces/ZIPCaptureOptions#framecount | ZIPCaptureOptions.frameCount API reference}
|
|
82
|
+
*/
|
|
83
|
+
frameCount?: number;
|
|
84
|
+
/**
|
|
85
|
+
* Deterministic sampling rate. Defaults to `60`.
|
|
86
|
+
*
|
|
87
|
+
* @see {@link https://code.textmode.art/api/textmode.export.js/interfaces/ZIPCaptureOptions#framerate | ZIPCaptureOptions.frameRate API reference}
|
|
88
|
+
*/
|
|
89
|
+
frameRate?: number;
|
|
90
|
+
/**
|
|
91
|
+
* Prepares external state before each deterministic redraw.
|
|
92
|
+
*
|
|
93
|
+
* @see {@link https://code.textmode.art/api/textmode.export.js/interfaces/ZIPCaptureOptions#prepareframe | ZIPCaptureOptions.prepareFrame API reference}
|
|
94
|
+
*/
|
|
95
|
+
prepareFrame?: PrepareExportFrame;
|
|
96
|
+
/**
|
|
97
|
+
* Cancels capture, serialization, or archive finalization.
|
|
98
|
+
*
|
|
99
|
+
* @see {@link https://code.textmode.art/api/textmode.export.js/interfaces/ZIPCaptureOptions#signal | ZIPCaptureOptions.signal API reference}
|
|
100
|
+
*/
|
|
101
|
+
signal?: AbortSignal;
|
|
102
|
+
/**
|
|
103
|
+
* Receives capture and archive lifecycle updates.
|
|
104
|
+
*
|
|
105
|
+
* @see {@link https://code.textmode.art/api/textmode.export.js/interfaces/ZIPCaptureOptions#onprogress | ZIPCaptureOptions.onProgress API reference}
|
|
106
|
+
*/
|
|
107
|
+
onProgress?: (progress: ZIPExportProgress) => void;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Format-specific options forwarded to each existing still exporter.
|
|
111
|
+
*
|
|
112
|
+
* @category ZIP frame-sequence export
|
|
113
|
+
* @see {@link https://code.textmode.art/api/textmode.export.js/interfaces/ZIPFrameOptionsMap | ZIPFrameOptionsMap API reference}
|
|
114
|
+
*/
|
|
115
|
+
export interface ZIPFrameOptionsMap {
|
|
116
|
+
png: Omit<ImageExportOptions, 'filename' | 'format'>;
|
|
117
|
+
jpg: Omit<ImageExportOptions, 'filename' | 'format'>;
|
|
118
|
+
webp: Omit<ImageExportOptions, 'filename' | 'format'>;
|
|
119
|
+
svg: Omit<SVGExportOptions, 'filename'>;
|
|
120
|
+
json: Omit<JSONExportOptions, 'filename'>;
|
|
121
|
+
txt: Omit<TXTExportOptions, 'filename'>;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Discriminated options for a deterministic ZIP frame-sequence export.
|
|
125
|
+
*
|
|
126
|
+
* @category ZIP frame-sequence export
|
|
127
|
+
* @see {@link https://code.textmode.art/api/textmode.export.js/type-aliases/ZIPExportOptions | ZIPExportOptions API reference}
|
|
128
|
+
*/
|
|
129
|
+
export type ZIPExportOptions = {
|
|
130
|
+
[F in ZIPFrameFormat]: ZIPCaptureOptions & {
|
|
131
|
+
format: F;
|
|
132
|
+
frameOptions?: ZIPFrameOptionsMap[F];
|
|
133
|
+
};
|
|
134
|
+
}[ZIPFrameFormat];
|
|
135
|
+
export interface ZIPGenerationOptions {
|
|
136
|
+
format: ZIPFrameFormat;
|
|
137
|
+
filename?: string;
|
|
138
|
+
frameCount: number;
|
|
139
|
+
frameRate: number;
|
|
140
|
+
frameOptions: unknown;
|
|
141
|
+
prepareFrame?: PrepareExportFrame;
|
|
142
|
+
signal?: AbortSignal;
|
|
143
|
+
onProgress?: (progress: ZIPExportProgress) => void;
|
|
144
|
+
}
|
|
145
|
+
export type ZIPEntryCompression = 'store' | 'deflate';
|
|
146
|
+
export interface ZIPFrameSerializer {
|
|
147
|
+
readonly extension: `.${ZIPFrameFormat}`;
|
|
148
|
+
readonly compression: ZIPEntryCompression;
|
|
149
|
+
getDimensions(context: {
|
|
150
|
+
canvas: HTMLCanvasElement;
|
|
151
|
+
frameOptions: unknown;
|
|
152
|
+
}): {
|
|
153
|
+
width: number;
|
|
154
|
+
height: number;
|
|
155
|
+
};
|
|
156
|
+
serialize(context: {
|
|
157
|
+
canvas: HTMLCanvasElement;
|
|
158
|
+
frameOptions: unknown;
|
|
159
|
+
createdAt: Date;
|
|
160
|
+
}): Promise<Uint8Array>;
|
|
161
|
+
}
|
|
162
|
+
export interface ZIPFrameSequenceManifest {
|
|
163
|
+
schema: 'textmode.frame-sequence';
|
|
164
|
+
schemaVersion: '1.0.0';
|
|
165
|
+
generator: {
|
|
166
|
+
name: 'textmode.export.js';
|
|
167
|
+
version: string;
|
|
168
|
+
};
|
|
169
|
+
createdAt: string;
|
|
170
|
+
format: ZIPFrameFormat;
|
|
171
|
+
frameCount: number;
|
|
172
|
+
frameRate: number;
|
|
173
|
+
width: number;
|
|
174
|
+
height: number;
|
|
175
|
+
indexBase: 1;
|
|
176
|
+
filePattern: string;
|
|
177
|
+
}
|