mediabunny 1.0.2 → 1.0.4

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 (188) hide show
  1. package/README.md +4 -4
  2. package/dist/mediabunny.d.ts +4 -2
  3. package/dist/modules/codec-data.d.ts +95 -0
  4. package/dist/modules/codec-data.d.ts.map +1 -0
  5. package/dist/modules/codec-data.js +1103 -0
  6. package/dist/modules/codec.d.ts +250 -0
  7. package/dist/modules/codec.d.ts.map +1 -0
  8. package/dist/modules/codec.js +1100 -0
  9. package/dist/modules/conversion.d.ts +158 -0
  10. package/dist/modules/conversion.d.ts.map +1 -0
  11. package/dist/modules/conversion.js +866 -0
  12. package/dist/modules/custom-coder.d.ts +119 -0
  13. package/dist/modules/custom-coder.d.ts.map +1 -0
  14. package/dist/modules/custom-coder.js +91 -0
  15. package/dist/modules/demuxer.d.ts +17 -0
  16. package/dist/modules/demuxer.d.ts.map +1 -0
  17. package/dist/modules/demuxer.js +12 -0
  18. package/dist/modules/index.d.ts +25 -0
  19. package/dist/modules/index.d.ts.map +1 -0
  20. package/dist/modules/index.js +24 -0
  21. package/dist/modules/input-format.d.ts +121 -0
  22. package/dist/modules/input-format.d.ts.map +1 -0
  23. package/dist/modules/input-format.js +333 -0
  24. package/dist/modules/input-track.d.ts +138 -0
  25. package/dist/modules/input-track.d.ts.map +1 -0
  26. package/dist/modules/input-track.js +230 -0
  27. package/dist/modules/input.d.ts +55 -0
  28. package/dist/modules/input.d.ts.map +1 -0
  29. package/dist/modules/input.js +104 -0
  30. package/dist/modules/isobmff/isobmff-boxes.d.ts +202 -0
  31. package/dist/modules/isobmff/isobmff-boxes.d.ts.map +1 -0
  32. package/dist/modules/isobmff/isobmff-boxes.js +1111 -0
  33. package/dist/modules/isobmff/isobmff-demuxer.d.ts +163 -0
  34. package/dist/modules/isobmff/isobmff-demuxer.d.ts.map +1 -0
  35. package/dist/modules/isobmff/isobmff-demuxer.js +2080 -0
  36. package/dist/modules/isobmff/isobmff-misc.d.ts +14 -0
  37. package/dist/modules/isobmff/isobmff-misc.d.ts.map +1 -0
  38. package/dist/modules/isobmff/isobmff-misc.js +20 -0
  39. package/dist/modules/isobmff/isobmff-muxer.d.ts +142 -0
  40. package/dist/modules/isobmff/isobmff-muxer.d.ts.map +1 -0
  41. package/dist/modules/isobmff/isobmff-muxer.js +858 -0
  42. package/dist/modules/isobmff/isobmff-reader.d.ts +36 -0
  43. package/dist/modules/isobmff/isobmff-reader.d.ts.map +1 -0
  44. package/dist/modules/isobmff/isobmff-reader.js +105 -0
  45. package/dist/modules/matroska/ebml.d.ts +156 -0
  46. package/dist/modules/matroska/ebml.d.ts.map +1 -0
  47. package/dist/modules/matroska/ebml.js +529 -0
  48. package/dist/modules/matroska/matroska-demuxer.d.ts +119 -0
  49. package/dist/modules/matroska/matroska-demuxer.d.ts.map +1 -0
  50. package/dist/modules/matroska/matroska-demuxer.js +1330 -0
  51. package/dist/modules/matroska/matroska-misc.d.ts +14 -0
  52. package/dist/modules/matroska/matroska-misc.d.ts.map +1 -0
  53. package/dist/modules/matroska/matroska-misc.js +20 -0
  54. package/dist/modules/matroska/matroska-muxer.d.ts +71 -0
  55. package/dist/modules/matroska/matroska-muxer.d.ts.map +1 -0
  56. package/dist/modules/matroska/matroska-muxer.js +729 -0
  57. package/dist/modules/media-sink.d.ts +272 -0
  58. package/dist/modules/media-sink.d.ts.map +1 -0
  59. package/dist/modules/media-sink.js +1264 -0
  60. package/dist/modules/media-source.d.ts +230 -0
  61. package/dist/modules/media-source.d.ts.map +1 -0
  62. package/dist/modules/media-source.js +1095 -0
  63. package/dist/modules/misc.d.ts +127 -0
  64. package/dist/modules/misc.d.ts.map +1 -0
  65. package/dist/modules/misc.js +462 -0
  66. package/dist/modules/mp3/mp3-demuxer.d.ts +32 -0
  67. package/dist/modules/mp3/mp3-demuxer.d.ts.map +1 -0
  68. package/dist/modules/mp3/mp3-demuxer.js +160 -0
  69. package/dist/modules/mp3/mp3-misc.d.ts +37 -0
  70. package/dist/modules/mp3/mp3-misc.d.ts.map +1 -0
  71. package/dist/modules/mp3/mp3-misc.js +122 -0
  72. package/dist/modules/mp3/mp3-muxer.d.ts +27 -0
  73. package/dist/modules/mp3/mp3-muxer.d.ts.map +1 -0
  74. package/dist/modules/mp3/mp3-muxer.js +112 -0
  75. package/dist/modules/mp3/mp3-reader.d.ts +25 -0
  76. package/dist/modules/mp3/mp3-reader.d.ts.map +1 -0
  77. package/dist/modules/mp3/mp3-reader.js +73 -0
  78. package/dist/modules/mp3/mp3-writer.d.ts +30 -0
  79. package/dist/modules/mp3/mp3-writer.d.ts.map +1 -0
  80. package/dist/modules/mp3/mp3-writer.js +72 -0
  81. package/dist/modules/muxer.d.ts +32 -0
  82. package/dist/modules/muxer.d.ts.map +1 -0
  83. package/dist/modules/muxer.js +50 -0
  84. package/dist/modules/ogg/ogg-demuxer.d.ts +53 -0
  85. package/dist/modules/ogg/ogg-demuxer.d.ts.map +1 -0
  86. package/dist/modules/ogg/ogg-demuxer.js +701 -0
  87. package/dist/modules/ogg/ogg-misc.d.ts +27 -0
  88. package/dist/modules/ogg/ogg-misc.d.ts.map +1 -0
  89. package/dist/modules/ogg/ogg-misc.js +78 -0
  90. package/dist/modules/ogg/ogg-muxer.d.ts +58 -0
  91. package/dist/modules/ogg/ogg-muxer.d.ts.map +1 -0
  92. package/dist/modules/ogg/ogg-muxer.js +345 -0
  93. package/dist/modules/ogg/ogg-reader.d.ts +37 -0
  94. package/dist/modules/ogg/ogg-reader.d.ts.map +1 -0
  95. package/dist/modules/ogg/ogg-reader.js +104 -0
  96. package/dist/modules/output-format.d.ts +285 -0
  97. package/dist/modules/output-format.d.ts.map +1 -0
  98. package/dist/modules/output-format.js +385 -0
  99. package/dist/modules/output.d.ts +134 -0
  100. package/dist/modules/output.d.ts.map +1 -0
  101. package/dist/modules/output.js +269 -0
  102. package/dist/modules/packet.d.ts +86 -0
  103. package/dist/modules/packet.d.ts.map +1 -0
  104. package/dist/modules/packet.js +133 -0
  105. package/dist/modules/pcm.d.ts +12 -0
  106. package/dist/modules/pcm.d.ts.map +1 -0
  107. package/dist/modules/pcm.js +85 -0
  108. package/dist/modules/reader.d.ts +40 -0
  109. package/dist/modules/reader.d.ts.map +1 -0
  110. package/dist/modules/reader.js +153 -0
  111. package/dist/modules/sample.d.ts +186 -0
  112. package/dist/modules/sample.d.ts.map +1 -0
  113. package/dist/modules/sample.js +798 -0
  114. package/dist/modules/source.d.ts +76 -0
  115. package/dist/modules/source.d.ts.map +1 -0
  116. package/dist/modules/source.js +183 -0
  117. package/dist/modules/subtitles.d.ts +37 -0
  118. package/dist/modules/subtitles.d.ts.map +1 -0
  119. package/dist/modules/subtitles.js +89 -0
  120. package/dist/modules/target.d.ts +58 -0
  121. package/dist/modules/target.d.ts.map +1 -0
  122. package/dist/modules/target.js +63 -0
  123. package/dist/modules/wave/riff-reader.d.ts +19 -0
  124. package/dist/modules/wave/riff-reader.d.ts.map +1 -0
  125. package/dist/modules/wave/riff-reader.js +38 -0
  126. package/dist/modules/wave/riff-writer.d.ts +18 -0
  127. package/dist/modules/wave/riff-writer.d.ts.map +1 -0
  128. package/dist/modules/wave/riff-writer.js +25 -0
  129. package/dist/modules/wave/wave-demuxer.d.ts +42 -0
  130. package/dist/modules/wave/wave-demuxer.d.ts.map +1 -0
  131. package/dist/modules/wave/wave-demuxer.js +239 -0
  132. package/dist/modules/wave/wave-muxer.d.ts +27 -0
  133. package/dist/modules/wave/wave-muxer.d.ts.map +1 -0
  134. package/dist/modules/wave/wave-muxer.js +108 -0
  135. package/dist/modules/writer.d.ts +85 -0
  136. package/dist/modules/writer.d.ts.map +1 -0
  137. package/dist/modules/writer.js +347 -0
  138. package/package.json +14 -10
  139. package/src/codec-data.ts +1394 -0
  140. package/src/codec.ts +1392 -0
  141. package/src/conversion.ts +1199 -0
  142. package/src/custom-coder.ts +162 -0
  143. package/src/demuxer.ts +22 -0
  144. package/src/index.ts +148 -0
  145. package/src/input-format.ts +386 -0
  146. package/src/input-track.ts +341 -0
  147. package/src/input.ts +138 -0
  148. package/src/isobmff/isobmff-boxes.ts +1365 -0
  149. package/src/isobmff/isobmff-demuxer.ts +2646 -0
  150. package/src/isobmff/isobmff-misc.ts +29 -0
  151. package/src/isobmff/isobmff-muxer.ts +1210 -0
  152. package/src/isobmff/isobmff-reader.ts +137 -0
  153. package/src/matroska/ebml.ts +595 -0
  154. package/src/matroska/matroska-demuxer.ts +1677 -0
  155. package/src/matroska/matroska-misc.ts +29 -0
  156. package/src/matroska/matroska-muxer.ts +999 -0
  157. package/src/media-sink.ts +1577 -0
  158. package/src/media-source.ts +1406 -0
  159. package/src/misc.ts +584 -0
  160. package/src/mp3/mp3-demuxer.ts +228 -0
  161. package/src/mp3/mp3-misc.ts +154 -0
  162. package/src/mp3/mp3-muxer.ts +153 -0
  163. package/src/mp3/mp3-reader.ts +93 -0
  164. package/src/mp3/mp3-writer.ts +112 -0
  165. package/src/muxer.ts +88 -0
  166. package/src/ogg/ogg-demuxer.ts +985 -0
  167. package/src/ogg/ogg-misc.ts +116 -0
  168. package/src/ogg/ogg-muxer.ts +480 -0
  169. package/src/ogg/ogg-reader.ts +143 -0
  170. package/src/output-format.ts +689 -0
  171. package/src/output.ts +427 -0
  172. package/src/packet.ts +180 -0
  173. package/src/pcm.ts +112 -0
  174. package/src/reader.ts +205 -0
  175. package/src/sample.ts +1029 -0
  176. package/src/source.ts +279 -0
  177. package/src/subtitles.ts +131 -0
  178. package/src/target.ts +106 -0
  179. package/src/tsconfig.json +13 -0
  180. package/src/wave/riff-reader.ts +48 -0
  181. package/src/wave/riff-writer.ts +30 -0
  182. package/src/wave/wave-demuxer.ts +317 -0
  183. package/src/wave/wave-muxer.ts +145 -0
  184. package/src/writer.ts +461 -0
  185. /package/dist/{mediabunny.js → bundles/mediabunny.cjs} +0 -0
  186. /package/dist/{mediabunny.min.js → bundles/mediabunny.min.cjs} +0 -0
  187. /package/dist/{mediabunny.min.mjs → bundles/mediabunny.min.mjs} +0 -0
  188. /package/dist/{mediabunny.mjs → bundles/mediabunny.mjs} +0 -0
@@ -0,0 +1,285 @@
1
+ /*!
2
+ * Copyright (c) 2025-present, Vanilagy and contributors
3
+ *
4
+ * This Source Code Form is subject to the terms of the Mozilla Public
5
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
6
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7
+ */
8
+ import { AudioCodec, MediaCodec, SubtitleCodec, VideoCodec } from './codec';
9
+ import { MediaSource } from './media-source';
10
+ import { TrackType } from './output';
11
+ /**
12
+ * Specifies an inclusive range of integers.
13
+ * @public
14
+ */
15
+ export type InclusiveIntegerRange = {
16
+ /** The integer cannot be less than this. */
17
+ min: number;
18
+ /** The integer cannot be greater than this. */
19
+ max: number;
20
+ };
21
+ /**
22
+ * Specifies the number of tracks (for each track type and in total) that an output format supports.
23
+ * @public
24
+ */
25
+ export type TrackCountLimits = {
26
+ [K in TrackType]: InclusiveIntegerRange;
27
+ } & {
28
+ /** Specifies the overall allowed range of track counts for the output format. */
29
+ total: InclusiveIntegerRange;
30
+ };
31
+ /**
32
+ * Base class representing an output media file format.
33
+ * @public
34
+ */
35
+ export declare abstract class OutputFormat {
36
+ /** The file extension used by this output format, beginning with a dot. */
37
+ abstract get fileExtension(): string;
38
+ /** The base MIME type of the output format. */
39
+ abstract get mimeType(): string;
40
+ /** Returns a list of media codecs that this output format can contain. */
41
+ abstract getSupportedCodecs(): MediaCodec[];
42
+ /** Returns the number of tracks that this output format supports. */
43
+ abstract getSupportedTrackCounts(): TrackCountLimits;
44
+ /** Whether this output format supports video rotation metadata. */
45
+ abstract get supportsVideoRotationMetadata(): boolean;
46
+ /** Returns a list of video codecs that this output format can contain. */
47
+ getSupportedVideoCodecs(): VideoCodec[];
48
+ /** Returns a list of audio codecs that this output format can contain. */
49
+ getSupportedAudioCodecs(): AudioCodec[];
50
+ /** Returns a list of subtitle codecs that this output format can contain. */
51
+ getSupportedSubtitleCodecs(): SubtitleCodec[];
52
+ }
53
+ /**
54
+ * ISOBMFF-specific output options.
55
+ * @public
56
+ */
57
+ export type IsobmffOutputFormatOptions = {
58
+ /**
59
+ * Controls the placement of metadata in the file. Placing metadata at the start of the file is known as "Fast
60
+ * Start", which results in better playback at the cost of more required processing or memory.
61
+ *
62
+ * Use `false` to disable Fast Start, placing the metadata at the end of the file. Fastest and uses the least
63
+ * memory.
64
+ *
65
+ * Use `'in-memory'` to produce a file with Fast Start by keeping all media chunks in memory until the file is
66
+ * finalized. This produces a high-quality and compact output at the cost of a more expensive finalization step and
67
+ * higher memory requirements. Data will be written monotonically (in order) when this option is set.
68
+ *
69
+ * Use `'fragmented'` to place metadata at the start of the file by creating a fragmented file (fMP4). In a
70
+ * fragmented file, chunks of media and their metadata are written to the file in "fragments", eliminating the need
71
+ * to put all metadata in one place. Fragmented files are useful for streaming contexts, as each fragment can be
72
+ * played individually without requiring knowledge of the other fragments. Furthermore, they remain lightweight to
73
+ * create even for very large files, as they don't require all media to be kept in memory. However, fragmented files
74
+ * are not as widely and wholly supported as regular MP4/MOV files. Data will be written monotonically (in order)
75
+ * when this option is set.
76
+ *
77
+ * When this field is not defined, either `false` or `'in-memory'` will be used, automatically determined based on
78
+ * the type of output target used.
79
+ */
80
+ fastStart?: false | 'in-memory' | 'fragmented';
81
+ /**
82
+ * When using `fastStart: 'fragmented'`, this field controls the minimum duration of each fragment, in seconds.
83
+ * New fragments will only be created when the current fragment is longer than this value. Defaults to 1 second.
84
+ */
85
+ minimumFragmentDuration?: number;
86
+ /**
87
+ * Will be called once the ftyp (File Type) box of the output file has been written.
88
+ *
89
+ * @param data - The raw bytes.
90
+ * @param position - The byte offset of the data in the file.
91
+ */
92
+ onFtyp?: (data: Uint8Array, position: number) => unknown;
93
+ /**
94
+ * Will be called once the moov (Movie) box of the output file has been written.
95
+ *
96
+ * @param data - The raw bytes.
97
+ * @param position - The byte offset of the data in the file.
98
+ */
99
+ onMoov?: (data: Uint8Array, position: number) => unknown;
100
+ /**
101
+ * Will be called for each finalized mdat (Media Data) box of the output file. Usage of this callback is not
102
+ * recommended when not using `fastStart: 'fragmented'`, as there will be one monolithic mdat box which might
103
+ * require large amounts of memory.
104
+ *
105
+ * @param data - The raw bytes.
106
+ * @param position - The byte offset of the data in the file.
107
+ */
108
+ onMdat?: (data: Uint8Array, position: number) => unknown;
109
+ /**
110
+ * Will be called for each finalized moof (Movie Fragment) box of the output file.
111
+ *
112
+ * @param data - The raw bytes.
113
+ * @param position - The byte offset of the data in the file.
114
+ * @param timestamp - The start timestamp of the fragment in seconds.
115
+ */
116
+ onMoof?: (data: Uint8Array, position: number, timestamp: number) => unknown;
117
+ };
118
+ /**
119
+ * Format representing files compatible with the ISO base media file format (ISOBMFF), like MP4 or MOV files.
120
+ * @public
121
+ */
122
+ export declare abstract class IsobmffOutputFormat extends OutputFormat {
123
+ constructor(options?: IsobmffOutputFormatOptions);
124
+ getSupportedTrackCounts(): TrackCountLimits;
125
+ get supportsVideoRotationMetadata(): boolean;
126
+ }
127
+ /**
128
+ * MPEG-4 Part 14 (MP4) file format. Supports all codecs except PCM audio codecs.
129
+ * @public
130
+ */
131
+ export declare class Mp4OutputFormat extends IsobmffOutputFormat {
132
+ get fileExtension(): string;
133
+ get mimeType(): string;
134
+ getSupportedCodecs(): MediaCodec[];
135
+ }
136
+ /**
137
+ * QuickTime File Format (QTFF), often called MOV. Supports all video and audio codecs, but not subtitle codecs.
138
+ * @public
139
+ */
140
+ export declare class MovOutputFormat extends IsobmffOutputFormat {
141
+ get fileExtension(): string;
142
+ get mimeType(): string;
143
+ getSupportedCodecs(): MediaCodec[];
144
+ }
145
+ /**
146
+ * Matroska-specific output options.
147
+ * @public
148
+ */
149
+ export type MkvOutputFormatOptions = {
150
+ /**
151
+ * Configures the output to only append new data at the end, useful for live-streaming the file as it's being
152
+ * created. When enabled, some features such as storing duration and seeking will be disabled or impacted, so don't
153
+ * use this option when you want to write out a clean file for later use.
154
+ */
155
+ appendOnly?: boolean;
156
+ /**
157
+ * This field controls the minimum duration of each Matroska cluster, in seconds. New clusters will only be created
158
+ * when the current cluster is longer than this value. Defaults to 1 second.
159
+ */
160
+ minimumClusterDuration?: number;
161
+ /**
162
+ * Will be called once the EBML header of the output file has been written.
163
+ *
164
+ * @param data - The raw bytes.
165
+ * @param position - The byte offset of the data in the file.
166
+ */
167
+ onEbmlHeader?: (data: Uint8Array, position: number) => void;
168
+ /**
169
+ * Will be called once the header part of the Matroska Segment element has been written. The header data includes
170
+ * the Segment element and everything inside it, up to (but excluding) the first Matroska Cluster.
171
+ *
172
+ * @param data - The raw bytes.
173
+ * @param position - The byte offset of the data in the file.
174
+ */
175
+ onSegmentHeader?: (data: Uint8Array, position: number) => unknown;
176
+ /**
177
+ * Will be called for each finalized Matroska Cluster of the output file.
178
+ *
179
+ * @param data - The raw bytes.
180
+ * @param position - The byte offset of the data in the file.
181
+ * @param timestamp - The start timestamp of the cluster in seconds.
182
+ */
183
+ onCluster?: (data: Uint8Array, position: number, timestamp: number) => unknown;
184
+ };
185
+ /**
186
+ * Matroska file format.
187
+ * @public
188
+ */
189
+ export declare class MkvOutputFormat extends OutputFormat {
190
+ constructor(options?: MkvOutputFormatOptions);
191
+ getSupportedTrackCounts(): TrackCountLimits;
192
+ get fileExtension(): string;
193
+ get mimeType(): string;
194
+ getSupportedCodecs(): MediaCodec[];
195
+ get supportsVideoRotationMetadata(): boolean;
196
+ }
197
+ /**
198
+ * WebM-specific output options.
199
+ * @public
200
+ */
201
+ export type WebMOutputFormatOptions = MkvOutputFormatOptions;
202
+ /**
203
+ * WebM file format, based on Matroska.
204
+ * @public
205
+ */
206
+ export declare class WebMOutputFormat extends MkvOutputFormat {
207
+ getSupportedCodecs(): MediaCodec[];
208
+ get fileExtension(): string;
209
+ get mimeType(): string;
210
+ }
211
+ /**
212
+ * MP3-specific output options.
213
+ * @public
214
+ */
215
+ export type Mp3OutputFormatOptions = {
216
+ /**
217
+ * Will be called once the Xing metadata frame is finalized.
218
+ *
219
+ * @param data - The raw bytes.
220
+ * @param position - The byte offset of the data in the file.
221
+ */
222
+ onXingFrame?: (data: Uint8Array, position: number) => unknown;
223
+ };
224
+ /**
225
+ * MP3 file format.
226
+ * @public
227
+ */
228
+ export declare class Mp3OutputFormat extends OutputFormat {
229
+ constructor(options?: Mp3OutputFormatOptions);
230
+ getSupportedTrackCounts(): TrackCountLimits;
231
+ get fileExtension(): string;
232
+ get mimeType(): string;
233
+ getSupportedCodecs(): MediaCodec[];
234
+ get supportsVideoRotationMetadata(): boolean;
235
+ }
236
+ /**
237
+ * WAVE-specific output options.
238
+ * @public
239
+ */
240
+ export type WavOutputFormatOptions = {
241
+ /**
242
+ * Will be called once the file header is written. The header consists of the RIFF header, the format chunk, and the
243
+ * start of the data chunk (with a placeholder size of 0).
244
+ */
245
+ onHeader?: (data: Uint8Array, position: number) => unknown;
246
+ };
247
+ /**
248
+ * WAVE file format, based on RIFF.
249
+ * @public
250
+ */
251
+ export declare class WavOutputFormat extends OutputFormat {
252
+ constructor(options?: WavOutputFormatOptions);
253
+ getSupportedTrackCounts(): TrackCountLimits;
254
+ get fileExtension(): string;
255
+ get mimeType(): string;
256
+ getSupportedCodecs(): MediaCodec[];
257
+ get supportsVideoRotationMetadata(): boolean;
258
+ }
259
+ /**
260
+ * Ogg-specific output options.
261
+ * @public
262
+ */
263
+ export type OggOutputFormatOptions = {
264
+ /**
265
+ * Will be called for each Ogg page that is written.
266
+ *
267
+ * @param data - The raw bytes.
268
+ * @param position - The byte offset of the data in the file.
269
+ * @param source - The media source backing the page's logical bitstream (track).
270
+ */
271
+ onPage?: (data: Uint8Array, position: number, source: MediaSource) => unknown;
272
+ };
273
+ /**
274
+ * Ogg file format.
275
+ * @public
276
+ */
277
+ export declare class OggOutputFormat extends OutputFormat {
278
+ constructor(options?: OggOutputFormatOptions);
279
+ getSupportedTrackCounts(): TrackCountLimits;
280
+ get fileExtension(): string;
281
+ get mimeType(): string;
282
+ getSupportedCodecs(): MediaCodec[];
283
+ get supportsVideoRotationMetadata(): boolean;
284
+ }
285
+ //# sourceMappingURL=output-format.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output-format.d.ts","sourceRoot":"","sources":["../../src/output-format.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,385 @@
1
+ /*!
2
+ * Copyright (c) 2025-present, Vanilagy and contributors
3
+ *
4
+ * This Source Code Form is subject to the terms of the Mozilla Public
5
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
6
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7
+ */
8
+ import { AUDIO_CODECS, NON_PCM_AUDIO_CODECS, PCM_AUDIO_CODECS, SUBTITLE_CODECS, VIDEO_CODECS, } from './codec.js';
9
+ import { IsobmffMuxer } from './isobmff/isobmff-muxer.js';
10
+ import { MatroskaMuxer } from './matroska/matroska-muxer.js';
11
+ import { Mp3Muxer } from './mp3/mp3-muxer.js';
12
+ import { OggMuxer } from './ogg/ogg-muxer.js';
13
+ import { WaveMuxer } from './wave/wave-muxer.js';
14
+ /**
15
+ * Base class representing an output media file format.
16
+ * @public
17
+ */
18
+ export class OutputFormat {
19
+ /** Returns a list of video codecs that this output format can contain. */
20
+ getSupportedVideoCodecs() {
21
+ return this.getSupportedCodecs()
22
+ .filter(codec => VIDEO_CODECS.includes(codec));
23
+ }
24
+ /** Returns a list of audio codecs that this output format can contain. */
25
+ getSupportedAudioCodecs() {
26
+ return this.getSupportedCodecs()
27
+ .filter(codec => AUDIO_CODECS.includes(codec));
28
+ }
29
+ /** Returns a list of subtitle codecs that this output format can contain. */
30
+ getSupportedSubtitleCodecs() {
31
+ return this.getSupportedCodecs()
32
+ .filter(codec => SUBTITLE_CODECS.includes(codec));
33
+ }
34
+ /** @internal */
35
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
36
+ _codecUnsupportedHint(codec) {
37
+ return '';
38
+ }
39
+ }
40
+ /**
41
+ * Format representing files compatible with the ISO base media file format (ISOBMFF), like MP4 or MOV files.
42
+ * @public
43
+ */
44
+ export class IsobmffOutputFormat extends OutputFormat {
45
+ constructor(options = {}) {
46
+ if (!options || typeof options !== 'object') {
47
+ throw new TypeError('options must be an object.');
48
+ }
49
+ if (options.fastStart !== undefined && ![false, 'in-memory', 'fragmented'].includes(options.fastStart)) {
50
+ throw new TypeError('options.fastStart, when provided, must be false, "in-memory", or "fragmented".');
51
+ }
52
+ if (options.minimumFragmentDuration !== undefined
53
+ && (!Number.isFinite(options.minimumFragmentDuration) || options.minimumFragmentDuration < 0)) {
54
+ throw new TypeError('options.minimumFragmentDuration, when provided, must be a non-negative number.');
55
+ }
56
+ if (options.onFtyp !== undefined && typeof options.onFtyp !== 'function') {
57
+ throw new TypeError('options.onFtyp, when provided, must be a function.');
58
+ }
59
+ if (options.onMoov !== undefined && typeof options.onMoov !== 'function') {
60
+ throw new TypeError('options.onMoov, when provided, must be a function.');
61
+ }
62
+ if (options.onMdat !== undefined && typeof options.onMdat !== 'function') {
63
+ throw new TypeError('options.onMdat, when provided, must be a function.');
64
+ }
65
+ if (options.onMoof !== undefined && typeof options.onMoof !== 'function') {
66
+ throw new TypeError('options.onMoof, when provided, must be a function.');
67
+ }
68
+ super();
69
+ this._options = options;
70
+ }
71
+ getSupportedTrackCounts() {
72
+ return {
73
+ video: { min: 0, max: Infinity },
74
+ audio: { min: 0, max: Infinity },
75
+ subtitle: { min: 0, max: Infinity },
76
+ total: { min: 1, max: 2 ** 32 - 1 }, // Have fun reaching this one
77
+ };
78
+ }
79
+ get supportsVideoRotationMetadata() {
80
+ return true;
81
+ }
82
+ /** @internal */
83
+ _createMuxer(output) {
84
+ return new IsobmffMuxer(output, this);
85
+ }
86
+ }
87
+ /**
88
+ * MPEG-4 Part 14 (MP4) file format. Supports all codecs except PCM audio codecs.
89
+ * @public
90
+ */
91
+ export class Mp4OutputFormat extends IsobmffOutputFormat {
92
+ /** @internal */
93
+ get _name() {
94
+ return 'MP4';
95
+ }
96
+ get fileExtension() {
97
+ return '.mp4';
98
+ }
99
+ get mimeType() {
100
+ return 'video/mp4';
101
+ }
102
+ getSupportedCodecs() {
103
+ return [
104
+ ...VIDEO_CODECS,
105
+ ...NON_PCM_AUDIO_CODECS,
106
+ // These are supported via ISO/IEC 23003-5
107
+ 'pcm-s16',
108
+ 'pcm-s16be',
109
+ 'pcm-s24',
110
+ 'pcm-s24be',
111
+ 'pcm-s32',
112
+ 'pcm-s32be',
113
+ 'pcm-f32',
114
+ 'pcm-f32be',
115
+ 'pcm-f64',
116
+ 'pcm-f64be',
117
+ ...SUBTITLE_CODECS,
118
+ ];
119
+ }
120
+ /** @internal */
121
+ _codecUnsupportedHint(codec) {
122
+ if (new MovOutputFormat().getSupportedCodecs().includes(codec)) {
123
+ return ' Switching to MOV will grant support for this codec.';
124
+ }
125
+ return '';
126
+ }
127
+ }
128
+ /**
129
+ * QuickTime File Format (QTFF), often called MOV. Supports all video and audio codecs, but not subtitle codecs.
130
+ * @public
131
+ */
132
+ export class MovOutputFormat extends IsobmffOutputFormat {
133
+ /** @internal */
134
+ get _name() {
135
+ return 'MOV';
136
+ }
137
+ get fileExtension() {
138
+ return '.mov';
139
+ }
140
+ get mimeType() {
141
+ return 'video/quicktime';
142
+ }
143
+ getSupportedCodecs() {
144
+ return [
145
+ ...VIDEO_CODECS,
146
+ ...AUDIO_CODECS,
147
+ ];
148
+ }
149
+ /** @internal */
150
+ _codecUnsupportedHint(codec) {
151
+ if (new Mp4OutputFormat().getSupportedCodecs().includes(codec)) {
152
+ return ' Switching to MP4 will grant support for this codec.';
153
+ }
154
+ return '';
155
+ }
156
+ }
157
+ /**
158
+ * Matroska file format.
159
+ * @public
160
+ */
161
+ export class MkvOutputFormat extends OutputFormat {
162
+ constructor(options = {}) {
163
+ if (!options || typeof options !== 'object') {
164
+ throw new TypeError('options must be an object.');
165
+ }
166
+ if (options.appendOnly !== undefined && typeof options.appendOnly !== 'boolean') {
167
+ throw new TypeError('options.appendOnly, when provided, must be a boolean.');
168
+ }
169
+ if (options.minimumClusterDuration !== undefined
170
+ && (!Number.isFinite(options.minimumClusterDuration) || options.minimumClusterDuration < 0)) {
171
+ throw new TypeError('options.minimumClusterDuration, when provided, must be a non-negative number.');
172
+ }
173
+ if (options.onEbmlHeader !== undefined && typeof options.onEbmlHeader !== 'function') {
174
+ throw new TypeError('options.onEbmlHeader, when provided, must be a function.');
175
+ }
176
+ if (options.onSegmentHeader !== undefined && typeof options.onSegmentHeader !== 'function') {
177
+ throw new TypeError('options.onHeader, when provided, must be a function.');
178
+ }
179
+ if (options.onCluster !== undefined && typeof options.onCluster !== 'function') {
180
+ throw new TypeError('options.onCluster, when provided, must be a function.');
181
+ }
182
+ super();
183
+ this._options = options;
184
+ }
185
+ /** @internal */
186
+ _createMuxer(output) {
187
+ return new MatroskaMuxer(output, this);
188
+ }
189
+ /** @internal */
190
+ get _name() {
191
+ return 'Matroska';
192
+ }
193
+ getSupportedTrackCounts() {
194
+ return {
195
+ video: { min: 0, max: Infinity },
196
+ audio: { min: 0, max: Infinity },
197
+ subtitle: { min: 0, max: Infinity },
198
+ total: { min: 1, max: 127 },
199
+ };
200
+ }
201
+ get fileExtension() {
202
+ return '.mkv';
203
+ }
204
+ get mimeType() {
205
+ return 'video/x-matroska';
206
+ }
207
+ getSupportedCodecs() {
208
+ return [
209
+ ...VIDEO_CODECS,
210
+ ...NON_PCM_AUDIO_CODECS,
211
+ ...PCM_AUDIO_CODECS.filter(codec => !['pcm-s8', 'pcm-f32be', 'pcm-f64be', 'ulaw', 'alaw'].includes(codec)),
212
+ ...SUBTITLE_CODECS,
213
+ ];
214
+ }
215
+ get supportsVideoRotationMetadata() {
216
+ // While it technically does support it with ProjectionPoseRoll, many players appear to ignore this value
217
+ return false;
218
+ }
219
+ }
220
+ /**
221
+ * WebM file format, based on Matroska.
222
+ * @public
223
+ */
224
+ export class WebMOutputFormat extends MkvOutputFormat {
225
+ getSupportedCodecs() {
226
+ return [
227
+ ...VIDEO_CODECS.filter(codec => ['vp8', 'vp9', 'av1'].includes(codec)),
228
+ ...AUDIO_CODECS.filter(codec => ['opus', 'vorbis'].includes(codec)),
229
+ ...SUBTITLE_CODECS,
230
+ ];
231
+ }
232
+ /** @internal */
233
+ get _name() {
234
+ return 'WebM';
235
+ }
236
+ get fileExtension() {
237
+ return '.webm';
238
+ }
239
+ get mimeType() {
240
+ return 'video/webm';
241
+ }
242
+ /** @internal */
243
+ _codecUnsupportedHint(codec) {
244
+ if (new MkvOutputFormat().getSupportedCodecs().includes(codec)) {
245
+ return ' Switching to MKV will grant support for this codec.';
246
+ }
247
+ return '';
248
+ }
249
+ }
250
+ /**
251
+ * MP3 file format.
252
+ * @public
253
+ */
254
+ export class Mp3OutputFormat extends OutputFormat {
255
+ constructor(options = {}) {
256
+ if (!options || typeof options !== 'object') {
257
+ throw new TypeError('options must be an object.');
258
+ }
259
+ if (options.onXingFrame !== undefined && typeof options.onXingFrame !== 'function') {
260
+ throw new TypeError('options.onXingFrame, when provided, must be a function.');
261
+ }
262
+ super();
263
+ this._options = options;
264
+ }
265
+ /** @internal */
266
+ _createMuxer(output) {
267
+ return new Mp3Muxer(output, this);
268
+ }
269
+ /** @internal */
270
+ get _name() {
271
+ return 'MP3';
272
+ }
273
+ getSupportedTrackCounts() {
274
+ return {
275
+ video: { min: 0, max: 0 },
276
+ audio: { min: 1, max: 1 },
277
+ subtitle: { min: 0, max: 0 },
278
+ total: { min: 1, max: 1 },
279
+ };
280
+ }
281
+ get fileExtension() {
282
+ return '.mp3';
283
+ }
284
+ get mimeType() {
285
+ return 'audio/mpeg';
286
+ }
287
+ getSupportedCodecs() {
288
+ return ['mp3'];
289
+ }
290
+ get supportsVideoRotationMetadata() {
291
+ return false;
292
+ }
293
+ }
294
+ /**
295
+ * WAVE file format, based on RIFF.
296
+ * @public
297
+ */
298
+ export class WavOutputFormat extends OutputFormat {
299
+ constructor(options = {}) {
300
+ if (!options || typeof options !== 'object') {
301
+ throw new TypeError('options must be an object.');
302
+ }
303
+ if (options.onHeader !== undefined && typeof options.onHeader !== 'function') {
304
+ throw new TypeError('options.onHeader, when provided, must be a function.');
305
+ }
306
+ super();
307
+ this._options = options;
308
+ }
309
+ /** @internal */
310
+ _createMuxer(output) {
311
+ return new WaveMuxer(output, this);
312
+ }
313
+ /** @internal */
314
+ get _name() {
315
+ return 'WAVE';
316
+ }
317
+ getSupportedTrackCounts() {
318
+ return {
319
+ video: { min: 0, max: 0 },
320
+ audio: { min: 1, max: 1 },
321
+ subtitle: { min: 0, max: 0 },
322
+ total: { min: 1, max: 1 },
323
+ };
324
+ }
325
+ get fileExtension() {
326
+ return '.wav';
327
+ }
328
+ get mimeType() {
329
+ return 'audio/wav';
330
+ }
331
+ getSupportedCodecs() {
332
+ return [
333
+ ...PCM_AUDIO_CODECS.filter(codec => ['pcm-s16', 'pcm-s24', 'pcm-s32', 'pcm-f32', 'pcm-u8', 'ulaw', 'alaw'].includes(codec)),
334
+ ];
335
+ }
336
+ get supportsVideoRotationMetadata() {
337
+ return false;
338
+ }
339
+ }
340
+ /**
341
+ * Ogg file format.
342
+ * @public
343
+ */
344
+ export class OggOutputFormat extends OutputFormat {
345
+ constructor(options = {}) {
346
+ if (!options || typeof options !== 'object') {
347
+ throw new TypeError('options must be an object.');
348
+ }
349
+ if (options.onPage !== undefined && typeof options.onPage !== 'function') {
350
+ throw new TypeError('options.onPage, when provided, must be a function.');
351
+ }
352
+ super();
353
+ this._options = options;
354
+ }
355
+ /** @internal */
356
+ _createMuxer(output) {
357
+ return new OggMuxer(output, this);
358
+ }
359
+ /** @internal */
360
+ get _name() {
361
+ return 'Ogg';
362
+ }
363
+ getSupportedTrackCounts() {
364
+ return {
365
+ video: { min: 0, max: 0 },
366
+ audio: { min: 0, max: Infinity },
367
+ subtitle: { min: 0, max: 0 },
368
+ total: { min: 1, max: 2 ** 32 },
369
+ };
370
+ }
371
+ get fileExtension() {
372
+ return '.ogg';
373
+ }
374
+ get mimeType() {
375
+ return 'application/ogg';
376
+ }
377
+ getSupportedCodecs() {
378
+ return [
379
+ ...AUDIO_CODECS.filter(codec => ['vorbis', 'opus'].includes(codec)),
380
+ ];
381
+ }
382
+ get supportsVideoRotationMetadata() {
383
+ return false;
384
+ }
385
+ }