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,76 @@
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
+ /**
9
+ * The source base class, representing a resource from which bytes can be read.
10
+ * @public
11
+ */
12
+ export declare abstract class Source {
13
+ /**
14
+ * Resolves with the total size of the file in bytes. This function is memoized, meaning only the first call
15
+ * will retrieve the size.
16
+ */
17
+ getSize(): Promise<number>;
18
+ /** Called each time data is requested from the source. */
19
+ onread: ((start: number, end: number) => unknown) | null;
20
+ }
21
+ /**
22
+ * A source backed by an ArrayBuffer or ArrayBufferView, with the entire file held in memory.
23
+ * @public
24
+ */
25
+ export declare class BufferSource extends Source {
26
+ constructor(buffer: ArrayBuffer | Uint8Array);
27
+ }
28
+ /**
29
+ * Options for defining a StreamSource.
30
+ * @public
31
+ */
32
+ export type StreamSourceOptions = {
33
+ /** Called when data is requested. Should return or resolve to the bytes from the specified byte range. */
34
+ read: (start: number, end: number) => Uint8Array | Promise<Uint8Array>;
35
+ /** Called when the size of the entire file is requested. Should return or resolve to the size in bytes. */
36
+ getSize: () => number | Promise<number>;
37
+ };
38
+ /**
39
+ * A general-purpose, callback-driven source that can get its data from anywhere.
40
+ * @public
41
+ */
42
+ export declare class StreamSource extends Source {
43
+ constructor(options: StreamSourceOptions);
44
+ }
45
+ /**
46
+ * A source backed by a Blob. Since Files are also Blobs, this is the source to use when reading files off the disk.
47
+ * @public
48
+ */
49
+ export declare class BlobSource extends Source {
50
+ constructor(blob: Blob);
51
+ }
52
+ /**
53
+ * Options for UrlSource.
54
+ * @public
55
+ */
56
+ export type UrlSourceOptions = {
57
+ /**
58
+ * The RequestInit used by the Fetch API. Can be used to further control the requests, such as setting
59
+ * custom headers.
60
+ */
61
+ requestInit?: RequestInit;
62
+ /**
63
+ * A function that returns the delay (in seconds) before retrying a failed request. The function is called
64
+ * with the number of previous, unsuccessful attempts. If the function returns `null`, no more retries will be made.
65
+ */
66
+ getRetryDelay?: (previousAttempts: number) => number | null;
67
+ };
68
+ /**
69
+ * A source backed by a URL. This is useful for reading data from the network. Be careful using this source however,
70
+ * as it typically comes with increased latency.
71
+ * @beta
72
+ */
73
+ export declare class UrlSource extends Source {
74
+ constructor(url: string | URL, options?: UrlSourceOptions);
75
+ }
76
+ //# sourceMappingURL=source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source.d.ts","sourceRoot":"","sources":["../../src/source.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH;;;GAGG;AACH,8BAAsB,MAAM;IAS3B;;;OAGG;IACH,OAAO;IAIP,0DAA0D;IAC1D,MAAM,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,IAAI,CAAQ;CAChE;AAED;;;GAGG;AACH,qBAAa,YAAa,SAAQ,MAAM;gBAI3B,MAAM,EAAE,WAAW,GAAG,UAAU;CAmB5C;AAED;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG;IACjC,0GAA0G;IAC1G,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACvE,2GAA2G;IAC3G,OAAO,EAAE,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACxC,CAAC;AAEF;;;GAGG;AACH,qBAAa,YAAa,SAAQ,MAAM;gBAI3B,OAAO,EAAE,mBAAmB;CAyBxC;AAED;;;GAGG;AACH,qBAAa,UAAW,SAAQ,MAAM;gBAIzB,IAAI,EAAE,IAAI;CAqBtB;AAED;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC9B;;;OAGG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;IAE1B;;;OAGG;IACH,aAAa,CAAC,EAAE,CAAC,gBAAgB,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;CAC5D,CAAC;AAEF;;;;GAIG;AACH,qBAAa,SAAU,SAAQ,MAAM;gBASnC,GAAG,EAAE,MAAM,GAAG,GAAG,EACjB,OAAO,GAAE,gBAAqB;CAwG/B"}
@@ -0,0 +1,183 @@
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 { mergeObjectsDeeply, retriedFetch } from './misc.js';
9
+ /**
10
+ * The source base class, representing a resource from which bytes can be read.
11
+ * @public
12
+ */
13
+ export class Source {
14
+ constructor() {
15
+ /** @internal */
16
+ this._sizePromise = null;
17
+ /** Called each time data is requested from the source. */
18
+ this.onread = null;
19
+ }
20
+ /**
21
+ * Resolves with the total size of the file in bytes. This function is memoized, meaning only the first call
22
+ * will retrieve the size.
23
+ */
24
+ getSize() {
25
+ return this._sizePromise ??= this._retrieveSize();
26
+ }
27
+ }
28
+ /**
29
+ * A source backed by an ArrayBuffer or ArrayBufferView, with the entire file held in memory.
30
+ * @public
31
+ */
32
+ export class BufferSource extends Source {
33
+ constructor(buffer) {
34
+ if (!(buffer instanceof ArrayBuffer) && !(buffer instanceof Uint8Array)) {
35
+ throw new TypeError('buffer must be an ArrayBuffer or Uint8Array.');
36
+ }
37
+ super();
38
+ this._bytes = buffer instanceof Uint8Array ? buffer : new Uint8Array(buffer);
39
+ }
40
+ /** @internal */
41
+ async _read(start, end) {
42
+ return this._bytes.subarray(start, end);
43
+ }
44
+ /** @internal */
45
+ async _retrieveSize() {
46
+ return this._bytes.byteLength;
47
+ }
48
+ }
49
+ /**
50
+ * A general-purpose, callback-driven source that can get its data from anywhere.
51
+ * @public
52
+ */
53
+ export class StreamSource extends Source {
54
+ constructor(options) {
55
+ if (!options || typeof options !== 'object') {
56
+ throw new TypeError('options must be an object.');
57
+ }
58
+ if (typeof options.read !== 'function') {
59
+ throw new TypeError('options.read must be a function.');
60
+ }
61
+ if (typeof options.getSize !== 'function') {
62
+ throw new TypeError('options.getSize must be a function.');
63
+ }
64
+ super();
65
+ this._options = options;
66
+ }
67
+ /** @internal */
68
+ async _read(start, end) {
69
+ return this._options.read(start, end);
70
+ }
71
+ /** @internal */
72
+ async _retrieveSize() {
73
+ return this._options.getSize();
74
+ }
75
+ }
76
+ /**
77
+ * A source backed by a Blob. Since Files are also Blobs, this is the source to use when reading files off the disk.
78
+ * @public
79
+ */
80
+ export class BlobSource extends Source {
81
+ constructor(blob) {
82
+ if (!(blob instanceof Blob)) {
83
+ throw new TypeError('blob must be a Blob.');
84
+ }
85
+ super();
86
+ this._blob = blob;
87
+ }
88
+ /** @internal */
89
+ async _read(start, end) {
90
+ const slice = this._blob.slice(start, end);
91
+ const buffer = await slice.arrayBuffer();
92
+ return new Uint8Array(buffer);
93
+ }
94
+ /** @internal */
95
+ async _retrieveSize() {
96
+ return this._blob.size;
97
+ }
98
+ }
99
+ /**
100
+ * A source backed by a URL. This is useful for reading data from the network. Be careful using this source however,
101
+ * as it typically comes with increased latency.
102
+ * @beta
103
+ */
104
+ export class UrlSource extends Source {
105
+ constructor(url, options = {}) {
106
+ if (typeof url !== 'string' && !(url instanceof URL)) {
107
+ throw new TypeError('url must be a string or URL.');
108
+ }
109
+ if (!options || typeof options !== 'object') {
110
+ throw new TypeError('options must be an object.');
111
+ }
112
+ if (options.requestInit !== undefined && (!options.requestInit || typeof options.requestInit !== 'object')) {
113
+ throw new TypeError('options.requestInit, when provided, must be an object.');
114
+ }
115
+ if (options.getRetryDelay !== undefined && typeof options.getRetryDelay !== 'function') {
116
+ throw new TypeError('options.getRetryDelay, when provided, must be a function.');
117
+ }
118
+ super();
119
+ /** @internal */
120
+ this._fullData = null;
121
+ this._url = url;
122
+ this._options = options;
123
+ }
124
+ /** @internal */
125
+ async _makeRequest(range) {
126
+ const headers = {};
127
+ if (range) {
128
+ headers['Range'] = `bytes=${range.start}-${range.end - 1}`;
129
+ }
130
+ const response = await retriedFetch(this._url, mergeObjectsDeeply(this._options.requestInit ?? {}, {
131
+ method: 'GET',
132
+ headers,
133
+ }), this._options.getRetryDelay ?? (() => null));
134
+ if (!response.ok) {
135
+ throw new Error(`Error fetching ${this._url}: ${response.status} ${response.statusText}`);
136
+ }
137
+ const buffer = await response.arrayBuffer();
138
+ if (!range) {
139
+ this._fullData = buffer;
140
+ }
141
+ return {
142
+ response: buffer,
143
+ statusCode: response.status,
144
+ };
145
+ }
146
+ /** @internal */
147
+ async _read(start, end) {
148
+ if (this._fullData) {
149
+ return new Uint8Array(this._fullData, start, end - start);
150
+ }
151
+ const { response, statusCode } = await this._makeRequest({ start, end });
152
+ // If server doesn't support range requests, it will return 200 instead of 206. In that case, let's manually
153
+ // slice the response.
154
+ if (statusCode === 200) {
155
+ const fullData = new Uint8Array(response);
156
+ return fullData.subarray(start, end);
157
+ }
158
+ return new Uint8Array(response);
159
+ }
160
+ /** @internal */
161
+ async _retrieveSize() {
162
+ if (this._fullData) {
163
+ return this._fullData.byteLength;
164
+ }
165
+ // Try a range request to get the Content-Range header
166
+ const rangeResponse = await retriedFetch(this._url, mergeObjectsDeeply(this._options.requestInit ?? {}, {
167
+ method: 'GET',
168
+ headers: { Range: 'bytes=0-0' },
169
+ }), this._options.getRetryDelay ?? (() => null));
170
+ if (rangeResponse.status === 206) {
171
+ const contentRange = rangeResponse.headers.get('Content-Range');
172
+ if (contentRange) {
173
+ const match = contentRange.match(/bytes \d+-\d+\/(\d+)/);
174
+ if (match && match[1]) {
175
+ return parseInt(match[1], 10);
176
+ }
177
+ }
178
+ }
179
+ // If the range request didn't provide the size, make a full GET request
180
+ const { response } = await this._makeRequest();
181
+ return response.byteLength;
182
+ }
183
+ }
@@ -0,0 +1,37 @@
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
+ export type SubtitleCue = {
9
+ timestamp: number;
10
+ duration: number;
11
+ text: string;
12
+ identifier?: string;
13
+ settings?: string;
14
+ notes?: string;
15
+ };
16
+ export type SubtitleConfig = {
17
+ description: string;
18
+ };
19
+ export type SubtitleMetadata = {
20
+ config?: SubtitleConfig;
21
+ };
22
+ type SubtitleParserOptions = {
23
+ codec: 'webvtt';
24
+ output: (cue: SubtitleCue, metadata: SubtitleMetadata) => unknown;
25
+ };
26
+ export declare const inlineTimestampRegex: RegExp;
27
+ export declare class SubtitleParser {
28
+ private options;
29
+ private preambleText;
30
+ private preambleEmitted;
31
+ constructor(options: SubtitleParserOptions);
32
+ parse(text: string): void;
33
+ }
34
+ export declare const parseSubtitleTimestamp: (string: string) => number;
35
+ export declare const formatSubtitleTimestamp: (timestamp: number) => string;
36
+ export {};
37
+ //# sourceMappingURL=subtitles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subtitles.d.ts","sourceRoot":"","sources":["../../src/subtitles.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,MAAM,WAAW,GAAG;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC5B,WAAW,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC9B,MAAM,CAAC,EAAE,cAAc,CAAC;CACxB,CAAC;AAEF,KAAK,qBAAqB,GAAG;IAC5B,KAAK,EAAE,QAAQ,CAAC;IAChB,MAAM,EAAE,CAAC,GAAG,EAAE,WAAW,EAAE,QAAQ,EAAE,gBAAgB,KAAK,OAAO,CAAC;CAClE,CAAC;AAIF,eAAO,MAAM,oBAAoB,QAA4C,CAAC;AAE9E,qBAAa,cAAc;IAC1B,OAAO,CAAC,OAAO,CAAwB;IACvC,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,eAAe,CAAS;gBAEpB,OAAO,EAAE,qBAAqB;IAI1C,KAAK,CAAC,IAAI,EAAE,MAAM;CAgElB;AAGD,eAAO,MAAM,sBAAsB,GAAI,QAAQ,MAAM,WAQpD,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAAI,WAAW,MAAM,WAUxD,CAAC"}
@@ -0,0 +1,89 @@
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
+ const cueBlockHeaderRegex = /(?:(.+?)\n)?((?:\d{2}:)?\d{2}:\d{2}.\d{3})\s+-->\s+((?:\d{2}:)?\d{2}:\d{2}.\d{3})/g;
9
+ const preambleStartRegex = /^WEBVTT(.|\n)*?\n{2}/;
10
+ export const inlineTimestampRegex = /<(?:(\d{2}):)?(\d{2}):(\d{2}).(\d{3})>/g;
11
+ export class SubtitleParser {
12
+ constructor(options) {
13
+ this.preambleText = null;
14
+ this.preambleEmitted = false;
15
+ this.options = options;
16
+ }
17
+ parse(text) {
18
+ text = text.replaceAll('\r\n', '\n').replaceAll('\r', '\n');
19
+ cueBlockHeaderRegex.lastIndex = 0;
20
+ let match;
21
+ if (!this.preambleText) {
22
+ if (!preambleStartRegex.test(text)) {
23
+ throw new Error('WebVTT preamble incorrect.');
24
+ }
25
+ match = cueBlockHeaderRegex.exec(text);
26
+ const preamble = text.slice(0, match?.index ?? text.length).trimEnd();
27
+ if (!preamble) {
28
+ throw new Error('No WebVTT preamble provided.');
29
+ }
30
+ this.preambleText = preamble;
31
+ if (match) {
32
+ text = text.slice(match.index);
33
+ cueBlockHeaderRegex.lastIndex = 0;
34
+ }
35
+ }
36
+ while ((match = cueBlockHeaderRegex.exec(text))) {
37
+ const notes = text.slice(0, match.index);
38
+ const cueIdentifier = match[1];
39
+ const matchEnd = match.index + match[0].length;
40
+ const bodyStart = text.indexOf('\n', matchEnd) + 1;
41
+ const cueSettings = text.slice(matchEnd, bodyStart).trim();
42
+ let bodyEnd = text.indexOf('\n\n', matchEnd);
43
+ if (bodyEnd === -1)
44
+ bodyEnd = text.length;
45
+ const startTime = parseSubtitleTimestamp(match[2]);
46
+ const endTime = parseSubtitleTimestamp(match[3]);
47
+ const duration = endTime - startTime;
48
+ const body = text.slice(bodyStart, bodyEnd).trim();
49
+ text = text.slice(bodyEnd).trimStart();
50
+ cueBlockHeaderRegex.lastIndex = 0;
51
+ const cue = {
52
+ timestamp: startTime / 1000,
53
+ duration: duration / 1000,
54
+ text: body,
55
+ identifier: cueIdentifier,
56
+ settings: cueSettings,
57
+ notes,
58
+ };
59
+ const meta = {};
60
+ if (!this.preambleEmitted) {
61
+ meta.config = {
62
+ description: this.preambleText,
63
+ };
64
+ this.preambleEmitted = true;
65
+ }
66
+ this.options.output(cue, meta);
67
+ }
68
+ }
69
+ }
70
+ const timestampRegex = /(?:(\d{2}):)?(\d{2}):(\d{2}).(\d{3})/;
71
+ export const parseSubtitleTimestamp = (string) => {
72
+ const match = timestampRegex.exec(string);
73
+ if (!match)
74
+ throw new Error('Expected match.');
75
+ return 60 * 60 * 1000 * Number(match[1] || '0')
76
+ + 60 * 1000 * Number(match[2])
77
+ + 1000 * Number(match[3])
78
+ + Number(match[4]);
79
+ };
80
+ export const formatSubtitleTimestamp = (timestamp) => {
81
+ const hours = Math.floor(timestamp / (60 * 60 * 1000));
82
+ const minutes = Math.floor((timestamp % (60 * 60 * 1000)) / (60 * 1000));
83
+ const seconds = Math.floor((timestamp % (60 * 1000)) / 1000);
84
+ const milliseconds = timestamp % 1000;
85
+ return hours.toString().padStart(2, '0') + ':'
86
+ + minutes.toString().padStart(2, '0') + ':'
87
+ + seconds.toString().padStart(2, '0') + '.'
88
+ + milliseconds.toString().padStart(3, '0');
89
+ };
@@ -0,0 +1,58 @@
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
+ /**
9
+ * Base class for targets, specifying where output files are written.
10
+ * @public
11
+ */
12
+ export declare abstract class Target {
13
+ }
14
+ /**
15
+ * A target that writes data directly into an ArrayBuffer in memory. Great for performance, but not suitable for very
16
+ * large files. The buffer will be available once the output has been finalized.
17
+ * @public
18
+ */
19
+ export declare class BufferTarget extends Target {
20
+ /** Stores the final output buffer. Until the output is finalized, this will be null. */
21
+ buffer: ArrayBuffer | null;
22
+ }
23
+ /**
24
+ * A data chunk for StreamTarget.
25
+ * @public
26
+ */
27
+ export type StreamTargetChunk = {
28
+ /** The operation type. */
29
+ type: 'write';
30
+ /** The data to write. */
31
+ data: Uint8Array;
32
+ /** The byte offset in the output file at which to write the data. */
33
+ position: number;
34
+ };
35
+ /**
36
+ * Options for StreamTarget.
37
+ * @public
38
+ */
39
+ export type StreamTargetOptions = {
40
+ /**
41
+ * When setting this to true, data created by the output will first be accumulated and only written out
42
+ * once it has reached sufficient size, using a default chunk size of 16 MiB. This is useful for reducing the total
43
+ * amount of writes, at the cost of latency.
44
+ */
45
+ chunked?: boolean;
46
+ /** When using `chunked: true`, this specifies the maximum size of each chunk. Defaults to 16 MiB. */
47
+ chunkSize?: number;
48
+ };
49
+ /**
50
+ * This target writes data to a WritableStream, making it a general-purpose target for writing data anywhere. It is
51
+ * also compatible with FileSystemWritableFileStream for use with the File System Access API. The WritableStream can
52
+ * also apply backpressure, which will propagate to the output and throttle the encoders.
53
+ * @public
54
+ */
55
+ export declare class StreamTarget extends Target {
56
+ constructor(writable: WritableStream<StreamTargetChunk>, options?: StreamTargetOptions);
57
+ }
58
+ //# sourceMappingURL=target.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"target.d.ts","sourceRoot":"","sources":["../../src/target.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH;;;GAGG;AACH,8BAAsB,MAAM;CAM3B;AAED;;;;GAIG;AACH,qBAAa,YAAa,SAAQ,MAAM;IACvC,wFAAwF;IACxF,MAAM,EAAE,WAAW,GAAG,IAAI,CAAQ;CAMlC;AAED;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC/B,0BAA0B;IAC1B,IAAI,EAAE,OAAO,CAAC;IACd,yBAAyB;IACzB,IAAI,EAAE,UAAU,CAAC;IACjB,qEAAqE;IACrE,QAAQ,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG;IACjC;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,qGAAqG;IACrG,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF;;;;;GAKG;AACH,qBAAa,YAAa,SAAQ,MAAM;gBAOtC,QAAQ,EAAE,cAAc,CAAC,iBAAiB,CAAC,EAC3C,OAAO,GAAE,mBAAwB;CAyBlC"}
@@ -0,0 +1,63 @@
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 { BufferTargetWriter, StreamTargetWriter } from './writer.js';
9
+ /**
10
+ * Base class for targets, specifying where output files are written.
11
+ * @public
12
+ */
13
+ export class Target {
14
+ constructor() {
15
+ /** @internal */
16
+ this._output = null;
17
+ }
18
+ }
19
+ /**
20
+ * A target that writes data directly into an ArrayBuffer in memory. Great for performance, but not suitable for very
21
+ * large files. The buffer will be available once the output has been finalized.
22
+ * @public
23
+ */
24
+ export class BufferTarget extends Target {
25
+ constructor() {
26
+ super(...arguments);
27
+ /** Stores the final output buffer. Until the output is finalized, this will be null. */
28
+ this.buffer = null;
29
+ }
30
+ /** @internal */
31
+ _createWriter() {
32
+ return new BufferTargetWriter(this);
33
+ }
34
+ }
35
+ /**
36
+ * This target writes data to a WritableStream, making it a general-purpose target for writing data anywhere. It is
37
+ * also compatible with FileSystemWritableFileStream for use with the File System Access API. The WritableStream can
38
+ * also apply backpressure, which will propagate to the output and throttle the encoders.
39
+ * @public
40
+ */
41
+ export class StreamTarget extends Target {
42
+ constructor(writable, options = {}) {
43
+ super();
44
+ if (!(writable instanceof WritableStream)) {
45
+ throw new TypeError('StreamTarget requires a WritableStream instance.');
46
+ }
47
+ if (options != null && typeof options !== 'object') {
48
+ throw new TypeError('StreamTarget options, when provided, must be an object.');
49
+ }
50
+ if (options.chunked !== undefined && typeof options.chunked !== 'boolean') {
51
+ throw new TypeError('options.chunked, when provided, must be a boolean.');
52
+ }
53
+ if (options.chunkSize !== undefined && (!Number.isInteger(options.chunkSize) || options.chunkSize < 1024)) {
54
+ throw new TypeError('options.chunkSize, when provided, must be an integer and not smaller than 1024.');
55
+ }
56
+ this._writable = writable;
57
+ this._options = options;
58
+ }
59
+ /** @internal */
60
+ _createWriter() {
61
+ return new StreamTargetWriter(this);
62
+ }
63
+ }
@@ -0,0 +1,19 @@
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 { Reader } from '../reader';
9
+ export declare class RiffReader {
10
+ reader: Reader;
11
+ pos: number;
12
+ littleEndian: boolean;
13
+ constructor(reader: Reader);
14
+ readBytes(length: number): Uint8Array<ArrayBufferLike>;
15
+ readU16(): number;
16
+ readU32(): number;
17
+ readAscii(length: number): string;
18
+ }
19
+ //# sourceMappingURL=riff-reader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"riff-reader.d.ts","sourceRoot":"","sources":["../../../src/wave/riff-reader.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAEnC,qBAAa,UAAU;IAIH,MAAM,EAAE,MAAM;IAHjC,GAAG,SAAK;IACR,YAAY,UAAQ;gBAED,MAAM,EAAE,MAAM;IAEjC,SAAS,CAAC,MAAM,EAAE,MAAM;IAOxB,OAAO;IAOP,OAAO;IAOP,SAAS,CAAC,MAAM,EAAE,MAAM;CAUxB"}
@@ -0,0 +1,38 @@
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
+ export class RiffReader {
9
+ constructor(reader) {
10
+ this.reader = reader;
11
+ this.pos = 0;
12
+ this.littleEndian = true;
13
+ }
14
+ readBytes(length) {
15
+ const { view, offset } = this.reader.getViewAndOffset(this.pos, this.pos + length);
16
+ this.pos += length;
17
+ return new Uint8Array(view.buffer, offset, length);
18
+ }
19
+ readU16() {
20
+ const { view, offset } = this.reader.getViewAndOffset(this.pos, this.pos + 2);
21
+ this.pos += 2;
22
+ return view.getUint16(offset, this.littleEndian);
23
+ }
24
+ readU32() {
25
+ const { view, offset } = this.reader.getViewAndOffset(this.pos, this.pos + 4);
26
+ this.pos += 4;
27
+ return view.getUint32(offset, this.littleEndian);
28
+ }
29
+ readAscii(length) {
30
+ const { view, offset } = this.reader.getViewAndOffset(this.pos, this.pos + length);
31
+ this.pos += length;
32
+ let str = '';
33
+ for (let i = 0; i < length; i++) {
34
+ str += String.fromCharCode(view.getUint8(offset + i));
35
+ }
36
+ return str;
37
+ }
38
+ }
@@ -0,0 +1,18 @@
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 { Writer } from '../writer';
9
+ export declare class RiffWriter {
10
+ private writer;
11
+ private helper;
12
+ private helperView;
13
+ constructor(writer: Writer);
14
+ writeU32(value: number): void;
15
+ writeU16(value: number): void;
16
+ writeAscii(text: string): void;
17
+ }
18
+ //# sourceMappingURL=riff-writer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"riff-writer.d.ts","sourceRoot":"","sources":["../../../src/wave/riff-writer.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAEnC,qBAAa,UAAU;IAIV,OAAO,CAAC,MAAM;IAH1B,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,UAAU,CAAoC;gBAElC,MAAM,EAAE,MAAM;IAElC,QAAQ,CAAC,KAAK,EAAE,MAAM;IAKtB,QAAQ,CAAC,KAAK,EAAE,MAAM;IAKtB,UAAU,CAAC,IAAI,EAAE,MAAM;CAGvB"}
@@ -0,0 +1,25 @@
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
+ export class RiffWriter {
9
+ constructor(writer) {
10
+ this.writer = writer;
11
+ this.helper = new Uint8Array(8);
12
+ this.helperView = new DataView(this.helper.buffer);
13
+ }
14
+ writeU32(value) {
15
+ this.helperView.setUint32(0, value, true);
16
+ this.writer.write(this.helper.subarray(0, 4));
17
+ }
18
+ writeU16(value) {
19
+ this.helperView.setUint16(0, value, true);
20
+ this.writer.write(this.helper.subarray(0, 2));
21
+ }
22
+ writeAscii(text) {
23
+ this.writer.write(new TextEncoder().encode(text));
24
+ }
25
+ }
@@ -0,0 +1,42 @@
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 } from '../codec';
9
+ import { Demuxer } from '../demuxer';
10
+ import { Input } from '../input';
11
+ import { InputAudioTrack } from '../input-track';
12
+ import { RiffReader } from './riff-reader';
13
+ export declare enum WaveFormat {
14
+ PCM = 1,
15
+ IEEE_FLOAT = 3,
16
+ ALAW = 6,
17
+ MULAW = 7,
18
+ EXTENSIBLE = 65534
19
+ }
20
+ export declare class WaveDemuxer extends Demuxer {
21
+ metadataReader: RiffReader;
22
+ chunkReader: RiffReader;
23
+ metadataPromise: Promise<void> | null;
24
+ dataStart: number;
25
+ dataSize: number;
26
+ audioInfo: {
27
+ format: number;
28
+ numberOfChannels: number;
29
+ sampleRate: number;
30
+ sampleSizeInBytes: number;
31
+ blockSizeInBytes: number;
32
+ } | null;
33
+ tracks: InputAudioTrack[];
34
+ constructor(input: Input);
35
+ readMetadata(): Promise<void>;
36
+ private parseFmtChunk;
37
+ getCodec(): AudioCodec | null;
38
+ getMimeType(): Promise<string>;
39
+ computeDuration(): Promise<number>;
40
+ getTracks(): Promise<InputAudioTrack[]>;
41
+ }
42
+ //# sourceMappingURL=wave-demuxer.d.ts.map