textmode.export.js 1.4.0 → 1.5.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 (28) hide show
  1. package/dist/textmode.export.esm.js +5080 -1612
  2. package/dist/textmode.export.umd.js +68 -2
  3. package/dist/types/exporters/video/VideoExporter.d.ts +12 -16
  4. package/dist/types/exporters/video/VideoExporter.d.ts.map +1 -1
  5. package/dist/types/exporters/video/VideoExporter.test.d.ts +2 -0
  6. package/dist/types/exporters/video/VideoExporter.test.d.ts.map +1 -0
  7. package/dist/types/exporters/video/VideoFrameDriver.d.ts +32 -0
  8. package/dist/types/exporters/video/VideoFrameDriver.d.ts.map +1 -0
  9. package/dist/types/exporters/video/VideoFrameDriver.test.d.ts +2 -0
  10. package/dist/types/exporters/video/VideoFrameDriver.test.d.ts.map +1 -0
  11. package/dist/types/exporters/video/VideoRecorder.d.ts +10 -23
  12. package/dist/types/exporters/video/VideoRecorder.d.ts.map +1 -1
  13. package/dist/types/exporters/video/VideoRecorder.test.d.ts +2 -0
  14. package/dist/types/exporters/video/VideoRecorder.test.d.ts.map +1 -0
  15. package/dist/types/exporters/video/errors.d.ts +9 -0
  16. package/dist/types/exporters/video/errors.d.ts.map +1 -0
  17. package/dist/types/exporters/video/index.d.ts +3 -1
  18. package/dist/types/exporters/video/index.d.ts.map +1 -1
  19. package/dist/types/exporters/video/types.d.ts +147 -5
  20. package/dist/types/exporters/video/types.d.ts.map +1 -1
  21. package/dist/types/index.d.ts +3 -27
  22. package/dist/types/index.d.ts.map +1 -1
  23. package/dist/types/overlay/blades/VideoBlade.d.ts +10 -1
  24. package/dist/types/overlay/blades/VideoBlade.d.ts.map +1 -1
  25. package/dist/types/overlay/formatRegistry.d.ts.map +1 -1
  26. package/dist/types/types.d.ts +15 -3
  27. package/dist/types/types.d.ts.map +1 -1
  28. package/package.json +3 -3
@@ -3,32 +3,28 @@ import type { TextmodePluginContext } from 'textmode.js';
3
3
  import type { VideoExportOptions } from './types';
4
4
  /**
5
5
  * Main video exporter for the textmode.js library.
6
- * Orchestrates the video export process by coordinating canvas capture,
7
- * frame processing, and file handling.
8
6
  */
9
7
  export declare class VideoExporter {
10
8
  private readonly _recorder;
11
9
  private readonly _textmodifier;
12
10
  private readonly _registerPostDrawHook;
13
- /**
14
- * Creates an instance of VideoExporter.
15
- *
16
- * @param textmodifier The Textmodifier instance to extract data from
17
- * @param registerPostDrawHook The function to register post-draw hooks
18
- */
19
11
  constructor(textmodifier: Textmodifier, registerPostDrawHook: TextmodePluginContext['registerPostDrawHook']);
20
12
  /**
21
- * Captures frames and saves them as a WEBM file
13
+ * Captures deterministic frames and saves them as a video file.
22
14
  *
23
15
  * @param options Export options
24
16
  */
25
- $saveWEBM(options?: VideoExportOptions): Promise<void>;
26
- /**
27
- * Applies default values to video export options
28
- *
29
- * @param options User-provided options
30
- * @returns Complete options with defaults applied
31
- */
17
+ $saveVideo(options?: VideoExportOptions): Promise<void>;
18
+ private _saveVideo;
32
19
  private _applyDefaultOptions;
20
+ private _positiveInteger;
21
+ private _positiveNumber;
22
+ private _bitrate;
23
+ private _bitrateMode;
24
+ private _latencyMode;
25
+ private _hardwareAcceleration;
26
+ private _keyFrameInterval;
27
+ private _currentPixelDensity;
28
+ private _withExtension;
33
29
  }
34
30
  //# sourceMappingURL=VideoExporter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"VideoExporter.d.ts","sourceRoot":"","sources":["../../../../src/exporters/video/VideoExporter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAEzD,OAAO,KAAK,EAAE,kBAAkB,EAA0B,MAAM,SAAS,CAAC;AAG1E;;;;GAIG;AACH,qBAAa,aAAa;IACzB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAgB;IAC1C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAe;IAC7C,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAgD;IAEtF;;;;;OAKG;gBACS,YAAY,EAAE,YAAY,EAAE,oBAAoB,EAAE,qBAAqB,CAAC,sBAAsB,CAAC;IAM3G;;;;OAIG;IACU,SAAS,CAAC,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBvE;;;;;OAKG;IACH,OAAO,CAAC,oBAAoB;CAU5B"}
1
+ {"version":3,"file":"VideoExporter.d.ts","sourceRoot":"","sources":["../../../../src/exporters/video/VideoExporter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAIzD,OAAO,KAAK,EAIX,kBAAkB,EAIlB,MAAM,SAAS,CAAC;AAWjB;;GAEG;AACH,qBAAa,aAAa;IACzB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAgB;IAC1C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAe;IAC7C,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAgD;gBAE1E,YAAY,EAAE,YAAY,EAAE,oBAAoB,EAAE,qBAAqB,CAAC,sBAAsB,CAAC;IAM3G;;;;OAIG;IACU,UAAU,CAAC,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC;YAI1D,UAAU;IAqBxB,OAAO,CAAC,oBAAoB;IA2B5B,OAAO,CAAC,gBAAgB;IAOxB,OAAO,CAAC,eAAe;IAOvB,OAAO,CAAC,QAAQ;IAUhB,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,qBAAqB;IAO7B,OAAO,CAAC,iBAAiB;IAOzB,OAAO,CAAC,oBAAoB;IAM5B,OAAO,CAAC,cAAc;CAUtB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=VideoExporter.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VideoExporter.test.d.ts","sourceRoot":"","sources":["../../../../src/exporters/video/VideoExporter.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,32 @@
1
+ import type { Textmodifier, TextmodePluginContext } from 'textmode.js';
2
+ import type { VideoRenderFrameOptions } from './types';
3
+ /**
4
+ * Drives deterministic video export frames through public textmode APIs.
5
+ *
6
+ * The visible textmode canvas remains untouched. Each presented frame is copied
7
+ * into a staging canvas sized for the requested video output.
8
+ */
9
+ export declare class VideoFrameDriver {
10
+ readonly canvas: HTMLCanvasElement;
11
+ private readonly _textmodifier;
12
+ private readonly _registerPostDrawHook;
13
+ private readonly _context;
14
+ private readonly _sourceCanvas;
15
+ private _pendingFrame;
16
+ private _syntheticFrameCount;
17
+ private _syntheticMillis;
18
+ constructor(textmodifier: Textmodifier, registerPostDrawHook: TextmodePluginContext['registerPostDrawHook'], width: number, height: number);
19
+ $render(options: VideoRenderFrameOptions): Promise<void>;
20
+ private _renderOneFrame;
21
+ private _capturePendingFrame;
22
+ private _createStagingCanvas;
23
+ private _captureMethodSnapshots;
24
+ private _capturePropertySnapshots;
25
+ private _shadowTimingProperties;
26
+ private _shadowTimingMethods;
27
+ private _shadowResizeCanvas;
28
+ private _restoreMethods;
29
+ private _restoreProperties;
30
+ private _throwIfAborted;
31
+ }
32
+ //# sourceMappingURL=VideoFrameDriver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VideoFrameDriver.d.ts","sourceRoot":"","sources":["../../../../src/exporters/video/VideoFrameDriver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAEvE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAC;AAoCvD;;;;;GAKG;AACH,qBAAa,gBAAgB;IAC5B,SAAgB,MAAM,EAAE,iBAAiB,CAAC;IAE1C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAoB;IAClD,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAgD;IACtF,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA2B;IACpD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAoB;IAClD,OAAO,CAAC,aAAa,CAAmC;IACxD,OAAO,CAAC,oBAAoB,CAAa;IACzC,OAAO,CAAC,gBAAgB,CAAa;gBAGpC,YAAY,EAAE,YAAY,EAC1B,oBAAoB,EAAE,qBAAqB,CAAC,sBAAsB,CAAC,EACnE,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM;IAeF,OAAO,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC;IAqDrE,OAAO,CAAC,eAAe;IAiBvB,OAAO,CAAC,oBAAoB;IA2B5B,OAAO,CAAC,oBAAoB;IAO5B,OAAO,CAAC,uBAAuB;IAQ/B,OAAO,CAAC,yBAAyB;IAQjC,OAAO,CAAC,uBAAuB;IA6B/B,OAAO,CAAC,oBAAoB;IAa5B,OAAO,CAAC,mBAAmB;IAM3B,OAAO,CAAC,eAAe;IAWvB,OAAO,CAAC,kBAAkB;IAU1B,OAAO,CAAC,eAAe;CAKvB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=VideoFrameDriver.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VideoFrameDriver.test.d.ts","sourceRoot":"","sources":["../../../../src/exporters/video/VideoFrameDriver.test.ts"],"names":[],"mappings":""}
@@ -1,28 +1,15 @@
1
- import type { TextmodePluginContext } from 'textmode.js';
2
- import type { VideoExportProgress, VideoGenerationOptions } from './types';
1
+ import type { VideoExportProgress, VideoFrameDriverLike, VideoGenerationOptions } from './types';
3
2
  /**
4
- * Records frames from a canvas to create WEBM video files.
5
- * Captures frames at specified intervals using textmode.js post-draw hooks
6
- * and encodes them into a WEBM video format.
3
+ * Records deterministic textmode frames through WebCodecs and muxes them with Mediabunny.
7
4
  */
8
5
  export declare class VideoRecorder {
9
- /**
10
- * Records a sequence of frames from the provided canvas and encodes them as a WEBM video.
11
- *
12
- * @param canvas - Source canvas to capture frames from
13
- * @param options - Video generation options
14
- * @param registerPostDrawHook - Hook registration function from textmode.js API
15
- * @param onProgress - Optional callback for recording progress updates
16
- * @returns Promise resolving to a Blob containing the encoded WEBM video
17
- * @throws {Error} If frame capture or encoding fails
18
- */
19
- $record(canvas: HTMLCanvasElement, options: VideoGenerationOptions, registerPostDrawHook: TextmodePluginContext['registerPostDrawHook'], onProgress?: (progress: VideoExportProgress) => void): Promise<Blob>;
20
- /**
21
- * Creates a reusable snapshot function for capturing canvas frames.
22
- * Uses a cached canvas and context to avoid repeated allocations.
23
- *
24
- * @returns Function that takes a canvas and returns a snapshot canvas
25
- */
26
- private _createSnapshotSurface;
6
+ $record(options: VideoGenerationOptions, frameDriver: VideoFrameDriverLike, onProgress?: (progress: VideoExportProgress) => void): Promise<Blob>;
7
+ private _createEncodingPlan;
8
+ private _assertWebCodecsAvailable;
9
+ private _resolveBitrate;
10
+ private _throwIfAborted;
11
+ private _emitProgress;
12
+ private _normalizeError;
13
+ private _log;
27
14
  }
28
15
  //# sourceMappingURL=VideoRecorder.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"VideoRecorder.d.ts","sourceRoot":"","sources":["../../../../src/exporters/video/VideoRecorder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,KAAK,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAG3E;;;;GAIG;AACH,qBAAa,aAAa;IACzB;;;;;;;;;OASG;IACU,OAAO,CACnB,MAAM,EAAE,iBAAiB,EACzB,OAAO,EAAE,sBAAsB,EAC/B,oBAAoB,EAAE,qBAAqB,CAAC,sBAAsB,CAAC,EACnE,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,mBAAmB,KAAK,IAAI,GAClD,OAAO,CAAC,IAAI,CAAC;IAyIhB;;;;;OAKG;IACH,OAAO,CAAC,sBAAsB;CAsD9B"}
1
+ {"version":3,"file":"VideoRecorder.d.ts","sourceRoot":"","sources":["../../../../src/exporters/video/VideoRecorder.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAIX,mBAAmB,EACnB,oBAAoB,EACpB,sBAAsB,EACtB,MAAM,SAAS,CAAC;AAKjB;;GAEG;AACH,qBAAa,aAAa;IACZ,OAAO,CACnB,OAAO,EAAE,sBAAsB,EAC/B,WAAW,EAAE,oBAAoB,EACjC,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,mBAAmB,KAAK,IAAI,GAClD,OAAO,CAAC,IAAI,CAAC;YAsDF,mBAAmB;IAgDjC,OAAO,CAAC,yBAAyB;IAcjC,OAAO,CAAC,eAAe;IAkBvB,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,aAAa;IAiBrB,OAAO,CAAC,eAAe;IAWvB,OAAO,CAAC,IAAI;CAKZ"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=VideoRecorder.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VideoRecorder.test.d.ts","sourceRoot":"","sources":["../../../../src/exporters/video/VideoRecorder.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,9 @@
1
+ import type { VideoExportErrorCode } from './types';
2
+ export declare class VideoExportError extends Error {
3
+ readonly code: VideoExportErrorCode;
4
+ readonly cause?: unknown;
5
+ constructor(code: VideoExportErrorCode, message: string, cause?: unknown);
6
+ }
7
+ export declare function createAbortError(): VideoExportError;
8
+ export declare function isAbortError(error: unknown): boolean;
9
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../../src/exporters/video/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAEpD,qBAAa,gBAAiB,SAAQ,KAAK;IAC1C,SAAgB,IAAI,EAAE,oBAAoB,CAAC;IAC3C,SAAgB,KAAK,CAAC,EAAE,OAAO,CAAC;gBAEpB,IAAI,EAAE,oBAAoB,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAMxE;AAED,wBAAgB,gBAAgB,IAAI,gBAAgB,CAEnD;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAKpD"}
@@ -1,4 +1,6 @@
1
1
  export { VideoExporter } from './VideoExporter';
2
+ export { VideoFrameDriver } from './VideoFrameDriver';
2
3
  export { VideoRecorder } from './VideoRecorder';
3
- export type { VideoExportOptions, VideoExportProgress, VideoGenerationOptions, VideoRecordingState } from './types';
4
+ export { VideoExportError } from './errors';
5
+ export type { VideoBitrateMode, VideoBitratePreset, VideoEncodingPlan, VideoExportErrorCode, VideoExportFormat, VideoExportOptions, VideoExportPhase, VideoFrameDriverLike, VideoHardwareAcceleration, VideoLatencyMode, VideoExportProgress, VideoGenerationOptions, VideoRecordingState, VideoRenderFrameOptions, } from './types';
4
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/exporters/video/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,YAAY,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/exporters/video/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5C,YAAY,EACX,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,EACjB,oBAAoB,EACpB,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,oBAAoB,EACpB,yBAAyB,EACzB,gBAAgB,EAChB,mBAAmB,EACnB,sBAAsB,EACtB,mBAAmB,EACnB,uBAAuB,GACvB,MAAM,SAAS,CAAC"}
@@ -1,4 +1,51 @@
1
+ /**
2
+ * Lifecycle state reported while a video export is being prepared, recorded, encoded, or completed.
3
+ */
1
4
  export type VideoRecordingState = 'idle' | 'recording' | 'encoding' | 'completed' | 'error';
5
+ /**
6
+ * More granular phase information for progress UIs that need to distinguish setup, rendering, and finalization.
7
+ */
8
+ export type VideoExportPhase = 'probing' | 'rendering' | 'encoding' | 'finalizing';
9
+ export type VideoCodec = 'vp8' | 'vp9' | 'avc' | (string & {});
10
+ /**
11
+ * Subjective bitrate preset used when an exact bits-per-second value is not supplied.
12
+ *
13
+ * Higher presets produce larger files with more detail. For exact control, pass a numeric
14
+ * `bitrate` value in bits per second instead.
15
+ */
16
+ export type VideoBitratePreset = 'low' | 'medium' | 'high';
17
+ /**
18
+ * Video container format written by `saveVideo`.
19
+ */
20
+ export type VideoExportFormat = 'webm' | 'mp4';
21
+ /**
22
+ * Bitrate allocation strategy for the native encoder.
23
+ *
24
+ * - `'variable'`: lets the encoder spend more bits on visually complex frames and fewer bits on simple frames.
25
+ * This is usually the best default for generative animations.
26
+ * - `'constant'`: asks the encoder to keep the bitrate steadier throughout the export. This can make file size
27
+ * more predictable, but may waste bits on simple frames or reduce detail on complex frames.
28
+ */
29
+ export type VideoBitrateMode = 'variable' | 'constant';
30
+ /**
31
+ * Encoder scheduling mode.
32
+ *
33
+ * - `'quality'`: prioritizes complete, stable export output. Mediabunny notes that this mode prevents dropped frames.
34
+ * - `'realtime'`: prioritizes low-latency encoding. It is intended for live streams and may drop frames when overloaded,
35
+ * so it is usually not recommended for frame-perfect exports.
36
+ */
37
+ export type VideoLatencyMode = 'quality' | 'realtime';
38
+ /**
39
+ * WebCodecs hardware acceleration preference.
40
+ *
41
+ * This is a browser hint rather than a guarantee:
42
+ * - `'no-preference'`: let the browser choose the best available encoder.
43
+ * - `'prefer-hardware'`: prefer GPU/ASIC encoding when available, often faster and more power-efficient, but codec
44
+ * availability and output characteristics vary by device.
45
+ * - `'prefer-software'`: prefer CPU encoding, often more consistent across machines, but usually slower.
46
+ */
47
+ export type VideoHardwareAcceleration = 'no-preference' | 'prefer-hardware' | 'prefer-software';
48
+ export type VideoExportErrorCode = 'VIDEO_EXPORT_UNSUPPORTED' | 'VIDEO_CODEC_UNSUPPORTED' | 'VIDEO_EXPORT_ABORTED' | 'VIDEO_EXPORT_FAILED' | 'VIDEO_TRANSPARENCY_UNSUPPORTED';
2
49
  /**
3
50
  * Progress information emitted during the video export process.
4
51
  */
@@ -6,15 +53,27 @@ export type VideoExportProgress = {
6
53
  /**
7
54
  * Current state of the recording process.
8
55
  */
9
- state: 'idle' | 'recording' | 'encoding' | 'completed' | 'error';
56
+ state: VideoRecordingState;
57
+ /**
58
+ * Current export phase for newer progress UIs.
59
+ */
60
+ phase?: VideoExportPhase;
10
61
  /**
11
62
  * Number of frames that have been recorded so far.
12
63
  */
13
64
  frameIndex?: number;
65
+ /**
66
+ * Alias for {@link frameIndex}. Prefer this field in new code.
67
+ */
68
+ frame?: number;
14
69
  /**
15
70
  * Total number of frames planned for the recording.
16
71
  */
17
72
  totalFrames?: number;
73
+ /**
74
+ * Export completion ratio between `0` and `1`.
75
+ */
76
+ progress?: number;
18
77
  /**
19
78
  * Optional status message for UI consumption.
20
79
  */
@@ -28,6 +87,10 @@ export type VideoExportOptions = {
28
87
  * Target filename without extension. Defaults to an auto-generated value.
29
88
  */
30
89
  filename?: string;
90
+ /**
91
+ * Video container format. Defaults to `'mp4'`.
92
+ */
93
+ format?: VideoExportFormat;
31
94
  /**
32
95
  * Desired total number of frames to capture. Defaults to `300`.
33
96
  */
@@ -37,11 +100,52 @@ export type VideoExportOptions = {
37
100
  */
38
101
  frameRate?: number;
39
102
  /**
40
- * Encoder quality between 0.0 and 1.0. Higher values request higher fidelity. Defaults to `1.0` *(lossless)*.
103
+ * Target bitrate in bits per second or a bitrate preset. Defaults to `'medium'`.
104
+ *
105
+ * Bitrate controls how much encoded data is available per second of video. Higher values can preserve more detail
106
+ * in noisy or fast-changing sketches, but create larger files. Presets are resolved from the export dimensions and
107
+ * frame rate; numeric values are passed directly to the encoder.
108
+ */
109
+ bitrate?: number | VideoBitratePreset;
110
+ /**
111
+ * Encoder bitrate allocation mode. Defaults to `'variable'`.
112
+ *
113
+ * Use `'variable'` for most exports so simple frames can compress efficiently and complex frames can receive more
114
+ * bits. Use `'constant'` only when a steadier data rate is more important than compression efficiency.
115
+ */
116
+ bitrateMode?: VideoBitrateMode;
117
+ /**
118
+ * Encoder latency mode. Defaults to `'quality'`.
119
+ *
120
+ * Use `'quality'` for deterministic exports; it prioritizes completed output and avoids dropped frames. Use
121
+ * `'realtime'` only for low-latency use cases where dropped frames are acceptable.
122
+ */
123
+ latencyMode?: VideoLatencyMode;
124
+ /**
125
+ * WebCodecs hardware acceleration hint. Defaults to `'no-preference'`.
126
+ *
127
+ * Browsers may ignore this hint. `'prefer-hardware'` can be faster on supported devices; `'prefer-software'` can be
128
+ * more predictable but slower. `'no-preference'` lets the browser choose.
129
+ */
130
+ hardwareAcceleration?: VideoHardwareAcceleration;
131
+ /**
132
+ * Key frame interval in seconds. Defaults to `2`.
133
+ *
134
+ * Key frames are independently decodable frames used for seeking and recovery. Shorter intervals improve seeking
135
+ * responsiveness but increase file size. Longer intervals can shrink files but make seeking less precise.
136
+ * Use `0` to request every frame as a key frame.
137
+ */
138
+ keyFrameInterval?: number;
139
+ /**
140
+ * Pixel density used during export. Defaults to `1` so video dimensions match the live canvas.
41
141
  */
42
- quality?: number;
142
+ pixelDensity?: number;
43
143
  /**
44
- * When true, attempts to preserve alpha data in the recording *(experimental)*. Defaults to `false`.
144
+ * Abort signal for cancelling an in-progress export.
145
+ */
146
+ signal?: AbortSignal;
147
+ /**
148
+ * When true, attempts to preserve alpha data in WebM recordings. MP4 exports reject this option.
45
149
  */
46
150
  transparent?: boolean;
47
151
  /**
@@ -55,10 +159,48 @@ export type VideoExportOptions = {
55
159
  };
56
160
  export interface VideoGenerationOptions {
57
161
  filename?: string;
162
+ format: VideoExportFormat;
58
163
  frameRate: number;
59
164
  frameCount: number;
60
- quality: number;
165
+ bitrate: number | VideoBitratePreset;
166
+ bitrateMode: VideoBitrateMode;
167
+ latencyMode: VideoLatencyMode;
168
+ hardwareAcceleration: VideoHardwareAcceleration;
169
+ keyFrameInterval: number;
170
+ pixelDensity: number;
171
+ width: number;
172
+ height: number;
61
173
  transparent: boolean;
62
174
  debugLogging: boolean;
175
+ signal?: AbortSignal;
176
+ }
177
+ export interface VideoEncodingPlan {
178
+ format: VideoExportFormat;
179
+ extension: '.webm' | '.mp4';
180
+ mimeType: string;
181
+ codec: VideoCodec;
182
+ bitrate: number;
183
+ bitrateMode: VideoBitrateMode;
184
+ latencyMode: VideoLatencyMode;
185
+ hardwareAcceleration: VideoHardwareAcceleration;
186
+ keyFrameInterval: number;
187
+ frameRate: number;
188
+ frameCount: number;
189
+ width: number;
190
+ height: number;
191
+ transparent: boolean;
192
+ }
193
+ export interface VideoRenderFrameOptions {
194
+ frameCount: number;
195
+ frameRate: number;
196
+ signal?: AbortSignal;
197
+ onFrame(frame: {
198
+ frameIndex: number;
199
+ canvas: HTMLCanvasElement;
200
+ }): Promise<void> | void;
201
+ }
202
+ export interface VideoFrameDriverLike {
203
+ readonly canvas: HTMLCanvasElement;
204
+ $render(options: VideoRenderFrameOptions): Promise<void>;
63
205
  }
64
206
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/exporters/video/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,WAAW,GAAG,UAAU,GAAG,WAAW,GAAG,OAAO,CAAC;AAE5F;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG;IACjC;;OAEG;IACH,KAAK,EAAE,MAAM,GAAG,WAAW,GAAG,UAAU,GAAG,WAAW,GAAG,OAAO,CAAC;IACjE;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAChC;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;OAEG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;OAEG;IACH,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,mBAAmB,KAAK,IAAI,CAAC;IACrD;;OAEG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF,MAAM,WAAW,sBAAsB;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,OAAO,CAAC;IACrB,YAAY,EAAE,OAAO,CAAC;CACtB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/exporters/video/types.ts"],"names":[],"mappings":"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"}
@@ -21,7 +21,7 @@
21
21
  *
22
22
  * ### Animation formats
23
23
  * - {@link GIFExportOptions | GIF} - Save as animated GIF
24
- * - {@link VideoExportOptions | WEBM} - Save as video file
24
+ * - {@link VideoExportOptions | Video} - Save as WebM or MP4 video
25
25
  *
26
26
  * @module textmode.export.js
27
27
  */
@@ -33,7 +33,7 @@ export type { SVGExportOptions } from './exporters/svg';
33
33
  export type { TXTExportOptions } from './exporters/txt';
34
34
  export type { JSONCellCollection, JSONCellTransform, JSONColorValue, JSONDocumentFormat, JSONDocumentVersion, JSONExportColorMode, JSONExportMetadata, JSONExportOptions, JSONExportTarget, JSONLayerGrid, JSONObjectRowCell, JSONObjectRowsCellCollection, JSONRGBAColor, TextmodeAllDocumentJSON, TextmodeDocumentJSON, TextmodeDocumentLayer, TextmodeSelectedDocumentJSON, TextmodeSelectedDocumentLayer, } from './exporters/json';
35
35
  export type { GIFExportOptions, GIFExportProgress } from './exporters/gif';
36
- export type { VideoExportOptions, VideoExportProgress } from './exporters/video';
36
+ export type { VideoBitrateMode, VideoBitratePreset, VideoExportErrorCode, VideoExportFormat, VideoExportOptions, VideoExportPhase, VideoExportProgress, VideoHardwareAcceleration, VideoLatencyMode, VideoRecordingState, } from './exporters/video';
37
37
  export type { LayerExportOptions } from './exporters/base';
38
38
  /**
39
39
  * Export plugin for textmode.js.
@@ -43,31 +43,7 @@ export type { LayerExportOptions } from './exporters/base';
43
43
  * access to all export options, which can be controlled at runtime.
44
44
  *
45
45
  * @example
46
- * ```js
47
- * import { textmode } from 'textmode.js';
48
- * import { ExportPlugin } from 'textmode.export.js';
49
- *
50
- * const t = textmode.create({
51
- * plugins: [ExportPlugin]
52
- * });
53
- *
54
- * t.draw(() => {
55
- * t.background(0);
56
- * t.char('A');
57
- * t.rotateZ(t.frameCount);
58
- * t.rect(16, 16);
59
- * });
60
- *
61
- * // Export methods are now available
62
- * t.saveCanvas({ format: 'png', scale: 2.0 });
63
- * t.saveSVG({ filename: 'my-artwork' });
64
- * t.saveGIF({ duration: 3, fps: 30 });
65
- *
66
- * // Control overlay visibility at runtime
67
- * t.exportOverlay.hide(); // Hide the overlay
68
- * t.exportOverlay.show(); // Show the overlay
69
- * t.exportOverlay.toggle(); // Toggle visibility
70
- * ```
46
+ * {@includeCode ../examples/ExportPlugin/init/sketch.js}
71
47
  */
72
48
  export declare const ExportPlugin: TextmodePlugin;
73
49
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAyB,MAAM,aAAa,CAAC;AASzE,OAAO,KAAK,EAAqB,2BAA2B,EAA2B,MAAM,SAAS,CAAC;AAIvG,YAAY,EAAE,iBAAiB,EAAE,2BAA2B,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAC;AACvG,YAAY,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,YAAY,EACX,kBAAkB,EAClB,iBAAiB,EACjB,cAAc,EACd,kBAAkB,EAClB,mBAAmB,EACnB,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,aAAa,EACb,iBAAiB,EACjB,4BAA4B,EAC5B,aAAa,EACb,uBAAuB,EACvB,oBAAoB,EACpB,qBAAqB,EACrB,4BAA4B,EAC5B,6BAA6B,GAC7B,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAC3E,YAAY,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACjF,YAAY,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAO3D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,eAAO,MAAM,YAAY,EAAE,cAqL1B,CAAC;AAEF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,0BAA0B,GAAI,UAAS,2BAAgC,KAAG,cAkBtF,CAAC;AAEF,OAAO,CAAC,MAAM,CAAC;IACd,UAAU,MAAM;QACf,YAAY,CAAC,EAAE,cAAc,CAAC;QAC9B,0BAA0B,CAAC,EAAE,OAAO,0BAA0B,CAAC;KAC/D;CACD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAyB,MAAM,aAAa,CAAC;AASzE,OAAO,KAAK,EAAqB,2BAA2B,EAA2B,MAAM,SAAS,CAAC;AAIvG,YAAY,EAAE,iBAAiB,EAAE,2BAA2B,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAC;AACvG,YAAY,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,YAAY,EACX,kBAAkB,EAClB,iBAAiB,EACjB,cAAc,EACd,kBAAkB,EAClB,mBAAmB,EACnB,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,aAAa,EACb,iBAAiB,EACjB,4BAA4B,EAC5B,aAAa,EACb,uBAAuB,EACvB,oBAAoB,EACpB,qBAAqB,EACrB,4BAA4B,EAC5B,6BAA6B,GAC7B,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAC3E,YAAY,EACX,gBAAgB,EAChB,kBAAkB,EAClB,oBAAoB,EACpB,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,EACnB,yBAAyB,EACzB,gBAAgB,EAChB,mBAAmB,GACnB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAO3D;;;;;;;;;GASG;AACH,eAAO,MAAM,YAAY,EAAE,cAqL1B,CAAC;AAEF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,0BAA0B,GAAI,UAAS,2BAAgC,KAAG,cAkBtF,CAAC;AAEF,OAAO,CAAC,MAAM,CAAC;IACd,UAAU,MAAM;QACf,YAAY,CAAC,EAAE,cAAc,CAAC;QAC9B,0BAA0B,CAAC,EAAE,OAAO,0BAA0B,CAAC;KAC/D;CACD"}
@@ -2,9 +2,15 @@ import type { VideoExportOptions, VideoExportProgress, VideoRecordingState } fro
2
2
  import type { BladeConfig } from './Blade';
3
3
  import { Blade } from './Blade';
4
4
  export declare class VideoBlade extends Blade<VideoExportOptions> {
5
+ private formatSelect;
6
+ private bitrateSelect;
5
7
  private frameRateInput;
6
8
  private frameCountInput;
7
- private qualityInput;
9
+ private bitrateModeSelect;
10
+ private latencyModeSelect;
11
+ private hardwareAccelerationSelect;
12
+ private keyFrameIntervalInput;
13
+ private transparencyInput;
8
14
  private status;
9
15
  private recordingState;
10
16
  constructor(config: BladeConfig<VideoExportOptions>);
@@ -18,5 +24,8 @@ export declare class VideoBlade extends Blade<VideoExportOptions> {
18
24
  private syncStatus;
19
25
  private resolvePlannedFrameCount;
20
26
  private applyDefaults;
27
+ private resolveBitratePreset;
28
+ private readonly handleFormatChange;
29
+ private syncTransparencyAvailability;
21
30
  }
22
31
  //# sourceMappingURL=VideoBlade.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"VideoBlade.d.ts","sourceRoot":"","sources":["../../../../src/overlay/blades/VideoBlade.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAO1G,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AA+ChC,qBAAa,UAAW,SAAQ,KAAK,CAAC,kBAAkB,CAAC;IACxD,OAAO,CAAC,cAAc,CAMpB;IAEF,OAAO,CAAC,eAAe,CAKrB;IAEF,OAAO,CAAC,YAAY,CAMlB;IAEF,OAAO,CAAC,MAAM,CAOZ;IAEF,OAAO,CAAC,cAAc,CAA+B;gBAEzC,MAAM,EAAE,WAAW,CAAC,kBAAkB,CAAC;IAInD,MAAM,IAAI,WAAW;IAuCrB,UAAU,IAAI,kBAAkB;IAahC,KAAK,IAAI,IAAI;IAMb,QAAQ,IAAI,OAAO;IAWnB,WAAW,IAAI,OAAO;IAItB,iBAAiB,CAAC,KAAK,EAAE,mBAAmB,EAAE,QAAQ,CAAC,EAAE,mBAAmB,GAAG,IAAI;IAUnF,cAAc,CAAC,QAAQ,EAAE,mBAAmB,GAAG,IAAI;IAInD,OAAO,CAAC,UAAU;IA+BlB,OAAO,CAAC,wBAAwB;IAKhC,OAAO,CAAC,aAAa;CAarB"}
1
+ {"version":3,"file":"VideoBlade.d.ts","sourceRoot":"","sources":["../../../../src/overlay/blades/VideoBlade.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAIX,kBAAkB,EAClB,mBAAmB,EAGnB,mBAAmB,EACnB,MAAM,uBAAuB,CAAC;AAQ/B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAehC,qBAAa,UAAW,SAAQ,KAAK,CAAC,kBAAkB,CAAC;IACxD,OAAO,CAAC,YAAY,CASlB;IAEF,OAAO,CAAC,aAAa,CAUnB;IAEF,OAAO,CAAC,cAAc,CAMpB;IAEF,OAAO,CAAC,eAAe,CAKrB;IAEF,OAAO,CAAC,iBAAiB,CASvB;IAEF,OAAO,CAAC,iBAAiB,CASvB;IAEF,OAAO,CAAC,0BAA0B,CAUhC;IAEF,OAAO,CAAC,qBAAqB,CAM3B;IAEF,OAAO,CAAC,iBAAiB,CAMvB;IAEF,OAAO,CAAC,MAAM,CAOZ;IAEF,OAAO,CAAC,cAAc,CAA+B;gBAEzC,MAAM,EAAE,WAAW,CAAC,kBAAkB,CAAC;IAInD,MAAM,IAAI,WAAW;IA4FrB,UAAU,IAAI,kBAAkB;IA2BhC,KAAK,IAAI,IAAI;IAMb,QAAQ,IAAI,OAAO;IAcnB,WAAW,IAAI,OAAO;IAItB,iBAAiB,CAAC,KAAK,EAAE,mBAAmB,EAAE,QAAQ,CAAC,EAAE,mBAAmB,GAAG,IAAI;IAgBnF,cAAc,CAAC,QAAQ,EAAE,mBAAmB,GAAG,IAAI;IAInD,OAAO,CAAC,UAAU;IAmClB,OAAO,CAAC,wBAAwB;IAKhC,OAAO,CAAC,aAAa;IAuBrB,OAAO,CAAC,oBAAoB;IAI5B,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAEjC;IAEF,OAAO,CAAC,4BAA4B;CAYpC"}
@@ -1 +1 @@
1
- {"version":3,"file":"formatRegistry.d.ts","sourceRoot":"","sources":["../../../src/overlay/formatRegistry.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAE7D,wBAAgB,0BAA0B,CACzC,mBAAmB,CAAC,EAAE,mBAAmB,GACvC,aAAa,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC,CAgG/C"}
1
+ {"version":3,"file":"formatRegistry.d.ts","sourceRoot":"","sources":["../../../src/overlay/formatRegistry.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAE7D,wBAAgB,0BAA0B,CACzC,mBAAmB,CAAC,EAAE,mBAAmB,GACvC,aAAa,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC,CAsG/C"}
@@ -47,6 +47,9 @@ export interface ExportOverlayController {
47
47
  }
48
48
  /**
49
49
  * Runtime export helpers that `createExportPlugin` attaches to the `Textmodifier` instance.
50
+ *
51
+ * @example
52
+ * {@includeCode ../examples/ExportPlugin/layerTargets/sketch.js}
50
53
  */
51
54
  export interface TextmodeExportAPI {
52
55
  /**
@@ -171,16 +174,25 @@ export interface TextmodeExportAPI {
171
174
  */
172
175
  saveGIF(options?: GIFExportOptions): Promise<void>;
173
176
  /**
174
- * Captures a WEBM video and saves it to disk.
177
+ * Captures a video and saves it to disk *(`'mp4'` by default)*.
175
178
  *
176
179
  * @param options Export options.
177
180
  *
178
181
  * @example
179
182
  * ```ts
180
- * await t.saveWEBM({ frameCount: 240, frameRate: 60, filename: 'capture' });
183
+ * await t.saveVideo({ frameCount: 240, frameRate: 60, filename: 'capture' });
184
+ * await t.saveVideo({
185
+ * format: 'webm',
186
+ * bitrate: 'high',
187
+ * bitrateMode: 'variable',
188
+ * latencyMode: 'quality',
189
+ * keyFrameInterval: 2,
190
+ * frameCount: 240,
191
+ * filename: 'capture',
192
+ * });
181
193
  * ```
182
194
  */
183
- saveWEBM(options?: VideoExportOptions): Promise<void>;
195
+ saveVideo(options?: VideoExportOptions): Promise<void>;
184
196
  }
185
197
  /**
186
198
  * Options for configuring the export plugin.
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAEhF;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACvC;;;;;;;OAOG;IACH,IAAI,IAAI,IAAI,CAAC;IAEb;;;;;;;OAOG;IACH,IAAI,IAAI,IAAI,CAAC;IAEb;;;;;;;OAOG;IACH,MAAM,IAAI,IAAI,CAAC;IAEf;;;;;;;OAOG;IACH,SAAS,IAAI,OAAO,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IACjC;;OAEG;IACH,aAAa,EAAE,uBAAuB,CAAC;IAEvC;;;;;;;;;OASG;IACH,UAAU,CAAC,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAExD;;;;;;;;;OASG;IACH,UAAU,CAAC,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAExD;;;;;;;;;OASG;IACH,OAAO,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAE1C;;;;;;;;;OASG;IACH,WAAW,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAE9C;;;;;;;;;;OAUG;IACH,KAAK,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,MAAM,CAAC;IAE1C;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,MAAM,CAAC;IAE7C;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,oBAAoB,CAAC;IAE1D;;;;;;;;;;;OAWG;IACH,YAAY,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,MAAM,CAAC;IAElD;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAE5C;;;;;;;;;OASG;IACH,OAAO,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnD;;;;;;;;;OASG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACtD;AAED;;;;;;GAMG;AACH,MAAM,WAAW,2BAA2B;IAC3C;;;;;OAKG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CAClB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAEhF;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACvC;;;;;;;OAOG;IACH,IAAI,IAAI,IAAI,CAAC;IAEb;;;;;;;OAOG;IACH,IAAI,IAAI,IAAI,CAAC;IAEb;;;;;;;OAOG;IACH,MAAM,IAAI,IAAI,CAAC;IAEf;;;;;;;OAOG;IACH,SAAS,IAAI,OAAO,CAAC;CACrB;AAED;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IACjC;;OAEG;IACH,aAAa,EAAE,uBAAuB,CAAC;IAEvC;;;;;;;;;OASG;IACH,UAAU,CAAC,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAExD;;;;;;;;;OASG;IACH,UAAU,CAAC,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAExD;;;;;;;;;OASG;IACH,OAAO,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAE1C;;;;;;;;;OASG;IACH,WAAW,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAE9C;;;;;;;;;;OAUG;IACH,KAAK,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,MAAM,CAAC;IAE1C;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,MAAM,CAAC;IAE7C;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,oBAAoB,CAAC;IAE1D;;;;;;;;;;;OAWG;IACH,YAAY,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,MAAM,CAAC;IAElD;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAE5C;;;;;;;;;OASG;IACH,OAAO,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnD;;;;;;;;;;;;;;;;;;OAkBG;IACH,SAAS,CAAC,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACvD;AAED;;;;;;GAMG;AACH,MAAM,WAAW,2BAA2B;IAC3C;;;;;OAKG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CAClB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "textmode.export.js",
3
- "version": "1.4.0",
3
+ "version": "1.5.0",
4
4
  "description": "Export plugin for textmode.js - Save your creations as images, GIFs, videos, SVG, JSON, and plain text.",
5
5
  "type": "module",
6
6
  "main": "./dist/textmode.export.umd.js",
@@ -47,7 +47,7 @@
47
47
  },
48
48
  "dependencies": {
49
49
  "gifenc": "^1.0.1",
50
- "webm-writer": "^1.0.0"
50
+ "mediabunny": "^1.45.4"
51
51
  },
52
52
  "devDependencies": {
53
53
  "@commitlint/cli": "^20.5.0",
@@ -73,7 +73,7 @@
73
73
  "prettier": "^3.8.3",
74
74
  "semantic-release": "^25.0.3",
75
75
  "terser": "^5.44.0",
76
- "textmode.js": "^0.13.0",
76
+ "textmode.js": "^0.16.0",
77
77
  "typedoc": "^0.28.19",
78
78
  "typedoc-plugin-frontmatter": "^1.3.1",
79
79
  "typedoc-plugin-markdown": "^4.11.0",