@remotion/media-parser 4.0.206 → 4.0.208

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 (143) hide show
  1. package/dist/av1-codec-string.d.ts +3 -0
  2. package/dist/av1-codec-string.js +91 -0
  3. package/dist/boxes/iso-base-media/ftype.d.ts +9 -0
  4. package/dist/boxes/iso-base-media/ftype.js +31 -0
  5. package/dist/boxes/iso-base-media/stsd/avcc-hvcc.d.ts +20 -0
  6. package/dist/boxes/iso-base-media/stsd/avcc-hvcc.js +73 -0
  7. package/dist/boxes/iso-base-media/stsd/ctts.js +8 -1
  8. package/dist/boxes/iso-base-media/stsd/samples.d.ts +6 -3
  9. package/dist/boxes/iso-base-media/stsd/samples.js +6 -6
  10. package/dist/boxes/iso-base-media/stts/stts.d.ts +15 -0
  11. package/dist/boxes/iso-base-media/stts/stts.js +35 -0
  12. package/dist/boxes/webm/bitstream/av1/bitstream-frame-header.d.ts +14 -0
  13. package/dist/boxes/webm/bitstream/av1/bitstream-frame-header.js +67 -0
  14. package/dist/boxes/webm/bitstream/av1/bitstream-frame.d.ts +11 -0
  15. package/dist/boxes/webm/bitstream/av1/bitstream-frame.js +14 -0
  16. package/dist/boxes/webm/bitstream/av1/chroma-sample-position.d.ts +6 -0
  17. package/dist/boxes/webm/bitstream/av1/chroma-sample-position.js +9 -0
  18. package/dist/boxes/webm/bitstream/av1/color-config.d.ts +16 -0
  19. package/dist/boxes/webm/bitstream/av1/color-config.js +103 -0
  20. package/dist/boxes/webm/bitstream/av1/color-primaries.d.ts +14 -0
  21. package/dist/boxes/webm/bitstream/av1/color-primaries.js +17 -0
  22. package/dist/boxes/webm/bitstream/av1/decoder-model-info.d.ts +9 -0
  23. package/dist/boxes/webm/bitstream/av1/decoder-model-info.js +17 -0
  24. package/dist/boxes/webm/bitstream/av1/frame.d.ts +0 -0
  25. package/dist/boxes/webm/bitstream/av1/frame.js +1 -0
  26. package/dist/boxes/webm/bitstream/av1/header-segment.d.ts +51 -0
  27. package/dist/boxes/webm/bitstream/av1/header-segment.js +183 -0
  28. package/dist/boxes/webm/bitstream/av1/matrix-coefficients.d.ts +17 -0
  29. package/dist/boxes/webm/bitstream/av1/matrix-coefficients.js +20 -0
  30. package/dist/boxes/webm/bitstream/av1/operating-parameters-info.d.ts +10 -0
  31. package/dist/boxes/webm/bitstream/av1/operating-parameters-info.js +15 -0
  32. package/dist/boxes/webm/bitstream/av1/temporal-point-info.d.ts +5 -0
  33. package/dist/boxes/webm/bitstream/av1/temporal-point-info.js +8 -0
  34. package/dist/boxes/webm/bitstream/av1/timing-info.d.ts +8 -0
  35. package/dist/boxes/webm/bitstream/av1/timing-info.js +20 -0
  36. package/dist/boxes/webm/bitstream/av1/transfer-characteristics.d.ts +21 -0
  37. package/dist/boxes/webm/bitstream/av1/transfer-characteristics.js +24 -0
  38. package/dist/boxes/webm/bitstream/av1/uvlc.d.ts +2 -0
  39. package/dist/boxes/webm/bitstream/av1/uvlc.js +20 -0
  40. package/dist/boxes/webm/bitstream/av1.d.ts +20 -0
  41. package/dist/boxes/webm/bitstream/av1.js +118 -0
  42. package/dist/boxes/webm/bitstream/h264/get-h264-descriptor.d.ts +0 -0
  43. package/dist/boxes/webm/bitstream/h264/get-h264-descriptor.js +1 -0
  44. package/dist/boxes/webm/make-header.d.ts +6 -2
  45. package/dist/boxes/webm/make-header.js +102 -18
  46. package/dist/boxes/webm/parse-ebml.js +3 -1
  47. package/dist/boxes/webm/segments/all-segments.d.ts +70 -12
  48. package/dist/boxes/webm/segments/all-segments.js +43 -5
  49. package/dist/boxes/webm/segments/duration.d.ts +6 -0
  50. package/dist/boxes/webm/segments/duration.js +19 -0
  51. package/dist/boxes/webm/segments/info.d.ts +9 -0
  52. package/dist/boxes/webm/segments/info.js +22 -0
  53. package/dist/boxes/webm/segments/main.d.ts +5 -0
  54. package/dist/boxes/webm/segments/main.js +2 -0
  55. package/dist/boxes/webm/segments/muxing.d.ts +6 -0
  56. package/dist/boxes/webm/segments/muxing.js +11 -0
  57. package/dist/boxes/webm/segments/seek-head.d.ts +9 -0
  58. package/dist/boxes/webm/segments/seek-head.js +22 -0
  59. package/dist/boxes/webm/segments/seek-position.d.ts +6 -0
  60. package/dist/boxes/webm/segments/seek-position.js +11 -0
  61. package/dist/boxes/webm/segments/seek.d.ts +13 -0
  62. package/dist/boxes/webm/segments/seek.js +35 -0
  63. package/dist/boxes/webm/segments/timestamp-scale.d.ts +6 -0
  64. package/dist/boxes/webm/segments/timestamp-scale.js +11 -0
  65. package/dist/boxes/webm/segments/tracks.d.ts +8 -0
  66. package/dist/boxes/webm/segments/tracks.js +21 -0
  67. package/dist/boxes/webm/segments/unknown.d.ts +6 -0
  68. package/dist/boxes/webm/segments/unknown.js +11 -0
  69. package/dist/boxes/webm/segments/void.d.ts +6 -0
  70. package/dist/boxes/webm/segments/void.js +11 -0
  71. package/dist/boxes/webm/segments/writing.d.ts +6 -0
  72. package/dist/boxes/webm/segments/writing.js +11 -0
  73. package/dist/boxes/webm/tracks.d.ts +8 -0
  74. package/dist/boxes/webm/tracks.js +21 -0
  75. package/dist/combine-uint8array.d.ts +1 -0
  76. package/dist/combine-uint8array.js +13 -0
  77. package/dist/create/cluster-segment.d.ts +10 -0
  78. package/dist/create/cluster-segment.js +41 -0
  79. package/dist/create/create-media.d.ts +13 -0
  80. package/dist/create/create-media.js +108 -0
  81. package/dist/create/matroska-header.d.ts +1 -0
  82. package/dist/create/matroska-header.js +66 -0
  83. package/dist/create/matroska-info.d.ts +4 -0
  84. package/dist/create/matroska-info.js +41 -0
  85. package/dist/create/matroska-segment.d.ts +2 -0
  86. package/dist/create/matroska-segment.js +12 -0
  87. package/dist/create/matroska-trackentry.d.ts +32 -0
  88. package/dist/create/matroska-trackentry.js +266 -0
  89. package/dist/from-web.d.ts +2 -0
  90. package/dist/from-web.js +45 -0
  91. package/dist/get-video-metadata.d.ts +2 -0
  92. package/dist/get-video-metadata.js +44 -0
  93. package/dist/index.d.ts +5 -0
  94. package/dist/index.js +5 -1
  95. package/dist/options.d.ts +1 -1
  96. package/dist/parse-media.js +1 -1
  97. package/dist/read-and-increment-offset.d.ts +28 -0
  98. package/dist/read-and-increment-offset.js +177 -0
  99. package/dist/readers/from-fetch.d.ts +2 -0
  100. package/dist/readers/from-fetch.js +64 -0
  101. package/dist/readers/from-node.d.ts +2 -0
  102. package/dist/readers/from-node.js +40 -0
  103. package/dist/readers/from-web-file.d.ts +2 -0
  104. package/dist/readers/from-web-file.js +39 -0
  105. package/dist/readers/reader.d.ts +11 -0
  106. package/dist/readers/reader.js +2 -0
  107. package/dist/traversal.d.ts +1 -1
  108. package/dist/understand-vorbis.d.ts +1 -0
  109. package/dist/understand-vorbis.js +12 -0
  110. package/dist/writers/web-fs.d.ts +2 -0
  111. package/dist/writers/web-fs.js +44 -0
  112. package/dist/writers/writer.d.ts +11 -0
  113. package/dist/writers/writer.js +2 -0
  114. package/package.json +13 -8
  115. package/src/boxes/iso-base-media/stsd/ctts.ts +10 -1
  116. package/src/boxes/iso-base-media/stsd/samples.ts +12 -9
  117. package/src/boxes/webm/make-header.ts +132 -24
  118. package/src/boxes/webm/parse-ebml.ts +4 -1
  119. package/src/boxes/webm/segments/all-segments.ts +67 -7
  120. package/src/create/cluster-segment.ts +62 -0
  121. package/src/create/create-media.ts +172 -0
  122. package/src/create/matroska-header.ts +63 -0
  123. package/src/create/matroska-info.ts +46 -0
  124. package/src/create/matroska-segment.ts +10 -0
  125. package/src/create/matroska-trackentry.ts +325 -0
  126. package/src/index.ts +9 -0
  127. package/src/options.ts +1 -1
  128. package/src/parse-media.ts +1 -1
  129. package/src/test/av1.test.ts +1 -1
  130. package/src/test/create-matroska.test.ts +31 -6
  131. package/src/test/duration.test.ts +1 -1
  132. package/src/test/matroska.test.ts +35 -5
  133. package/src/test/parse-video.test.ts +1 -1
  134. package/src/test/parse-webm.test.ts +1 -1
  135. package/src/test/stream-local.test.ts +1 -1
  136. package/src/test/stream-samples.test.ts +1 -1
  137. package/src/writers/web-fs.ts +50 -0
  138. package/src/writers/writer.ts +12 -0
  139. package/tsconfig.tsbuildinfo +1 -1
  140. /package/src/{from-fetch.ts → readers/from-fetch.ts} +0 -0
  141. /package/src/{from-node.ts → readers/from-node.ts} +0 -0
  142. /package/src/{from-web-file.ts → readers/from-web-file.ts} +0 -0
  143. /package/src/{reader.ts → readers/reader.ts} +0 -0
@@ -0,0 +1,325 @@
1
+ import {makeMatroskaBytes, padMatroskaBytes} from '../boxes/webm/make-header';
2
+ import type {BytesAndOffset} from '../boxes/webm/segments/all-segments';
3
+
4
+ export type MatroskaColorParams = {
5
+ transferChracteristics: 'bt709' | 'smpte170m' | 'iec61966-2-1' | null;
6
+ matrixCoefficients: 'bt709' | 'bt470bg' | 'rgb' | 'smpte170m' | null;
7
+ primaries: 'bt709' | 'smpte170m' | 'bt470bg' | null;
8
+ fullRange: boolean | null;
9
+ };
10
+
11
+ export const makeMatroskaColorBytes = ({
12
+ transferChracteristics,
13
+ matrixCoefficients,
14
+ primaries,
15
+ fullRange,
16
+ }: MatroskaColorParams) => {
17
+ const rangeValue =
18
+ transferChracteristics && matrixCoefficients
19
+ ? 3
20
+ : fullRange === true
21
+ ? 2
22
+ : fullRange === false
23
+ ? 1
24
+ : 0;
25
+
26
+ // https://datatracker.ietf.org/doc/draft-ietf-cellar-matroska/
27
+ // 5.1.4.1.28.27
28
+ const primariesValue =
29
+ primaries === 'bt709'
30
+ ? 1
31
+ : primaries === 'smpte170m'
32
+ ? 6
33
+ : primaries === 'bt470bg'
34
+ ? 5
35
+ : 2;
36
+
37
+ const transferChracteristicsValue =
38
+ transferChracteristics === 'bt709'
39
+ ? 1
40
+ : transferChracteristics === 'smpte170m'
41
+ ? 6
42
+ : transferChracteristics === 'iec61966-2-1'
43
+ ? 13
44
+ : 2;
45
+
46
+ if (matrixCoefficients === 'rgb') {
47
+ throw new Error('Cannot encode Matroska in RGB');
48
+ }
49
+
50
+ const matrixCoefficientsValue =
51
+ matrixCoefficients === 'bt709'
52
+ ? 1
53
+ : matrixCoefficients === 'bt470bg'
54
+ ? 5
55
+ : matrixCoefficients === 'smpte170m'
56
+ ? 6
57
+ : 2;
58
+
59
+ return makeMatroskaBytes({
60
+ type: 'Colour',
61
+ minVintWidth: null,
62
+ value: [
63
+ {
64
+ type: 'TransferCharacteristics',
65
+ value: {
66
+ value: transferChracteristicsValue,
67
+ byteLength: null,
68
+ },
69
+ minVintWidth: null,
70
+ },
71
+ {
72
+ type: 'MatrixCoefficients',
73
+ value: {
74
+ value: matrixCoefficientsValue,
75
+ byteLength: null,
76
+ },
77
+ minVintWidth: null,
78
+ },
79
+ {
80
+ type: 'Primaries',
81
+ value: {
82
+ value: primariesValue,
83
+ byteLength: null,
84
+ },
85
+ minVintWidth: null,
86
+ },
87
+ {
88
+ type: 'Range',
89
+ value: {
90
+ value: rangeValue,
91
+ byteLength: null,
92
+ },
93
+ minVintWidth: null,
94
+ },
95
+ ],
96
+ });
97
+ };
98
+
99
+ export const makeMatroskaVideoBytes = ({
100
+ color,
101
+ width,
102
+ height,
103
+ }: {
104
+ color: MatroskaColorParams;
105
+ width: number;
106
+ height: number;
107
+ }) => {
108
+ return makeMatroskaBytes({
109
+ type: 'Video',
110
+ value: [
111
+ {
112
+ type: 'PixelWidth',
113
+ value: {
114
+ value: width,
115
+ byteLength: null,
116
+ },
117
+ minVintWidth: null,
118
+ },
119
+ {
120
+ type: 'PixelHeight',
121
+ value: {
122
+ value: height,
123
+ byteLength: null,
124
+ },
125
+ minVintWidth: null,
126
+ },
127
+ {
128
+ type: 'FlagInterlaced',
129
+ value: {
130
+ // https://datatracker.ietf.org/doc/draft-ietf-cellar-matroska/
131
+ // 5.1.4.1.28.1.
132
+ value: 2, // 2 - progressive, no interlaced
133
+ byteLength: null,
134
+ },
135
+ minVintWidth: null,
136
+ },
137
+ makeMatroskaColorBytes(color),
138
+ ],
139
+ minVintWidth: null,
140
+ });
141
+ };
142
+
143
+ export type MakeTrackAudio = {
144
+ trackNumber: number;
145
+ codecId: string;
146
+ numberOfChannels: number;
147
+ sampleRate: number;
148
+ type: 'audio';
149
+ };
150
+
151
+ export type MakeTrackVideo = {
152
+ color: MatroskaColorParams;
153
+ width: number;
154
+ height: number;
155
+ defaultDuration: number;
156
+ trackNumber: number;
157
+ codecId: string;
158
+ type: 'video';
159
+ };
160
+
161
+ export const makeMatroskaAudioTrackEntryBytes = ({
162
+ trackNumber,
163
+ codecId,
164
+ numberOfChannels: audioChannels,
165
+ sampleRate,
166
+ }: MakeTrackAudio) => {
167
+ return makeMatroskaBytes({
168
+ type: 'TrackEntry',
169
+ minVintWidth: null,
170
+ value: [
171
+ {
172
+ type: 'TrackNumber',
173
+ value: {
174
+ value: trackNumber,
175
+ byteLength: null,
176
+ },
177
+ minVintWidth: null,
178
+ },
179
+ {
180
+ type: 'TrackUID',
181
+ value: '0x188FEB95C8EFABA',
182
+ minVintWidth: null,
183
+ },
184
+ {
185
+ type: 'TrackType',
186
+ value: {
187
+ value: 2,
188
+ byteLength: null,
189
+ },
190
+ minVintWidth: null,
191
+ },
192
+ {
193
+ type: 'TrackTimestampScale',
194
+ value: {
195
+ value: 1,
196
+ size: '64',
197
+ },
198
+ minVintWidth: null,
199
+ },
200
+ {
201
+ type: 'CodecID',
202
+ value: codecId,
203
+ minVintWidth: null,
204
+ },
205
+ {
206
+ type: 'Audio',
207
+ value: [
208
+ {
209
+ type: 'Channels',
210
+ minVintWidth: null,
211
+ value: {
212
+ value: audioChannels,
213
+ byteLength: null,
214
+ },
215
+ },
216
+ {
217
+ type: 'SamplingFrequency',
218
+ minVintWidth: null,
219
+ value: {
220
+ value: sampleRate,
221
+ size: '64',
222
+ },
223
+ },
224
+ {
225
+ type: 'BitDepth',
226
+ minVintWidth: null,
227
+ value: {
228
+ value: 32,
229
+ byteLength: null,
230
+ },
231
+ },
232
+ ],
233
+ minVintWidth: null,
234
+ },
235
+ ],
236
+ });
237
+ };
238
+
239
+ export const makeMatroskaVideoTrackEntryBytes = ({
240
+ color,
241
+ width,
242
+ height,
243
+ defaultDuration,
244
+ trackNumber,
245
+ codecId,
246
+ }: MakeTrackVideo) => {
247
+ return makeMatroskaBytes({
248
+ type: 'TrackEntry',
249
+ minVintWidth: null,
250
+ value: [
251
+ {
252
+ type: 'TrackNumber',
253
+ value: {
254
+ value: trackNumber,
255
+ byteLength: null,
256
+ },
257
+ minVintWidth: null,
258
+ },
259
+ {
260
+ type: 'TrackUID',
261
+ value: '0xab2171012bb9020a',
262
+ minVintWidth: null,
263
+ },
264
+ {
265
+ type: 'FlagLacing',
266
+ value: {
267
+ value: 0,
268
+ byteLength: null,
269
+ },
270
+ minVintWidth: null,
271
+ },
272
+ {
273
+ type: 'Language',
274
+ value: 'und',
275
+ minVintWidth: null,
276
+ },
277
+ {
278
+ type: 'FlagDefault',
279
+ value: {
280
+ value: 0,
281
+ byteLength: null,
282
+ },
283
+ minVintWidth: null,
284
+ },
285
+ {
286
+ type: 'CodecID',
287
+ value: codecId,
288
+ minVintWidth: null,
289
+ },
290
+ {
291
+ type: 'TrackType',
292
+ value: {
293
+ value: 1, // 'video'
294
+ byteLength: null,
295
+ },
296
+ minVintWidth: null,
297
+ },
298
+ {
299
+ type: 'DefaultDuration',
300
+ value: {
301
+ value: defaultDuration,
302
+ byteLength: null,
303
+ },
304
+ minVintWidth: null,
305
+ },
306
+ makeMatroskaVideoBytes({
307
+ color,
308
+ width,
309
+ height,
310
+ }),
311
+ ],
312
+ });
313
+ };
314
+
315
+ export const makeMatroskaTracks = (tracks: BytesAndOffset[]) => {
316
+ return padMatroskaBytes(
317
+ makeMatroskaBytes({
318
+ type: 'Tracks',
319
+ value: tracks,
320
+ minVintWidth: null,
321
+ }),
322
+ // TODO: That's too much padding
323
+ 1000,
324
+ );
325
+ };
package/src/index.ts CHANGED
@@ -1,3 +1,6 @@
1
+ import {createMedia} from './create/create-media';
2
+
3
+ export {AudioTrack, OtherTrack, Track, VideoTrack} from './get-tracks';
1
4
  export {parseMedia} from './parse-media';
2
5
  export {
3
6
  AudioSample,
@@ -7,3 +10,9 @@ export {
7
10
  OnVideoTrack,
8
11
  VideoSample,
9
12
  } from './webcodec-sample-types';
13
+
14
+ export type {MediaFn} from './create/create-media';
15
+
16
+ export const MediaParserInternals = {
17
+ createMedia,
18
+ };
package/src/options.ts CHANGED
@@ -3,7 +3,7 @@ import type {Dimensions} from './get-dimensions';
3
3
  import type {AudioTrack, VideoTrack} from './get-tracks';
4
4
  import type {AnySegment} from './parse-result';
5
5
  import type {InternalStats} from './parser-state';
6
- import type {ReaderInterface} from './reader';
6
+ import type {ReaderInterface} from './readers/reader';
7
7
  import type {OnAudioTrack, OnVideoTrack} from './webcodec-sample-types';
8
8
 
9
9
  export type KnownVideoCodecs =
@@ -1,7 +1,6 @@
1
1
  /* eslint-disable max-depth */
2
2
  import type {BufferIterator} from './buffer-iterator';
3
3
  import {getArrayBufferIterator} from './buffer-iterator';
4
- import {fetchReader} from './from-fetch';
5
4
  import {getAudioCodec} from './get-audio-codec';
6
5
  import {getDimensions} from './get-dimensions';
7
6
  import {getDuration} from './get-duration';
@@ -14,6 +13,7 @@ import type {ParseResult} from './parse-result';
14
13
  import {parseVideo} from './parse-video';
15
14
  import type {ParserContext} from './parser-context';
16
15
  import {makeParserState} from './parser-state';
16
+ import {fetchReader} from './readers/from-fetch';
17
17
 
18
18
  export const parseMedia: ParseMedia = async ({
19
19
  src,
@@ -1,9 +1,9 @@
1
1
  import {RenderInternals} from '@remotion/renderer';
2
2
  import {expect, test} from 'bun:test';
3
- import {nodeReader} from '../from-node';
4
3
  import {trakBoxContainsVideo} from '../get-fps';
5
4
  import {getAv1CBox} from '../get-sample-aspect-ratio';
6
5
  import {parseMedia} from '../parse-media';
6
+ import {nodeReader} from '../readers/from-node';
7
7
  import {getMoovBox, getTraks} from '../traversal';
8
8
 
9
9
  test('AV1 in MP4', async () => {
@@ -9,11 +9,11 @@ import type {
9
9
  TrackEntry,
10
10
  } from '../boxes/webm/segments/all-segments';
11
11
  import {getArrayBufferIterator} from '../buffer-iterator';
12
- import {nodeReader} from '../from-node';
13
12
  import {parseMedia} from '../parse-media';
14
13
  import type {AnySegment} from '../parse-result';
15
14
  import type {ParserContext} from '../parser-context';
16
15
  import {makeParserState} from '../parser-state';
16
+ import {nodeReader} from '../readers/from-node';
17
17
 
18
18
  const state = makeParserState({
19
19
  hasAudioCallbacks: false,
@@ -72,7 +72,10 @@ test('Should make Matroska header that is same as input', async () => {
72
72
  ],
73
73
  });
74
74
 
75
- const iterator = getArrayBufferIterator(headerOutput, headerOutput.length);
75
+ const iterator = getArrayBufferIterator(
76
+ headerOutput.bytes,
77
+ headerOutput.bytes.length,
78
+ );
76
79
  const parsed = await parseEbml(iterator, options);
77
80
 
78
81
  expect(parsed).toEqual({
@@ -128,7 +131,7 @@ test('Should be able to create SeekIdBox', async () => {
128
131
  value: '0x1549a966',
129
132
  minVintWidth: 1,
130
133
  });
131
- expect(custom).toEqual(file);
134
+ expect(custom.bytes).toEqual(file);
132
135
  });
133
136
 
134
137
  test('Should be able to create Seek', async () => {
@@ -154,7 +157,7 @@ test('Should be able to create Seek', async () => {
154
157
  });
155
158
 
156
159
  const custom = makeMatroskaBytes(parsed);
157
- expect(custom).toEqual(file);
160
+ expect(custom.bytes).toEqual(file);
158
161
  });
159
162
 
160
163
  test('Should parse seekHead', async () => {
@@ -186,7 +189,29 @@ test('Should parse seekHead', async () => {
186
189
  ],
187
190
  minVintWidth: 1,
188
191
  });
189
- expect(custom).toEqual(file);
192
+ expect(custom.offsets).toEqual({
193
+ offset: 0,
194
+ children: [
195
+ {
196
+ offset: 5,
197
+ children: [
198
+ {
199
+ offset: 8,
200
+ children: [],
201
+ field: 'SeekID',
202
+ },
203
+ {
204
+ offset: 15,
205
+ children: [],
206
+ field: 'SeekPosition',
207
+ },
208
+ ],
209
+ field: 'Seek',
210
+ },
211
+ ],
212
+ field: 'SeekHead',
213
+ });
214
+ expect(custom.bytes).toEqual(file);
190
215
 
191
216
  const iterator = getArrayBufferIterator(file, file.length);
192
217
  const parsed = await parseEbml(iterator, options);
@@ -225,7 +250,7 @@ const parseWebm = async (str: string) => {
225
250
  const stringifyWebm = (boxes: AnySegment[]) => {
226
251
  const buffers: Uint8Array[] = [];
227
252
  for (const box of boxes) {
228
- const bytes = makeMatroskaBytes(box as MatroskaSegment);
253
+ const {bytes} = makeMatroskaBytes(box as MatroskaSegment);
229
254
  buffers.push(bytes);
230
255
  }
231
256
 
@@ -1,7 +1,7 @@
1
1
  import {RenderInternals} from '@remotion/renderer';
2
2
  import {expect, test} from 'bun:test';
3
- import {nodeReader} from '../from-node';
4
3
  import {parseMedia} from '../parse-media';
4
+ import {nodeReader} from '../readers/from-node';
5
5
 
6
6
  test('Should get duration of video', async () => {
7
7
  const parsed = await parseMedia({
@@ -1,7 +1,7 @@
1
1
  import {RenderInternals} from '@remotion/renderer';
2
2
  import {expect, test} from 'bun:test';
3
- import {nodeReader} from '../from-node';
4
3
  import {parseMedia} from '../parse-media';
4
+ import {nodeReader} from '../readers/from-node';
5
5
 
6
6
  test('Should get duration of AV1 video', async () => {
7
7
  const parsed = await parseMedia({
@@ -233,10 +233,40 @@ test('Should get duration of AV1 video', async () => {
233
233
  },
234
234
  {
235
235
  type: 'Colour',
236
- value: new Uint8Array([
237
- 85, 186, 129, 1, 85, 177, 129, 1, 85, 187, 129, 1, 85,
238
- 185, 129, 1,
239
- ]),
236
+ value: [
237
+ {
238
+ minVintWidth: 1,
239
+ type: 'TransferCharacteristics',
240
+ value: {
241
+ byteLength: 1,
242
+ value: 1,
243
+ },
244
+ },
245
+ {
246
+ minVintWidth: 1,
247
+ type: 'MatrixCoefficients',
248
+ value: {
249
+ byteLength: 1,
250
+ value: 1,
251
+ },
252
+ },
253
+ {
254
+ minVintWidth: 1,
255
+ type: 'Primaries',
256
+ value: {
257
+ byteLength: 1,
258
+ value: 1,
259
+ },
260
+ },
261
+ {
262
+ minVintWidth: 1,
263
+ type: 'Range',
264
+ value: {
265
+ byteLength: 1,
266
+ value: 1,
267
+ },
268
+ },
269
+ ],
240
270
  minVintWidth: 1,
241
271
  },
242
272
  ],
@@ -1,7 +1,7 @@
1
1
  import {RenderInternals} from '@remotion/renderer';
2
2
  import {expect, test} from 'bun:test';
3
- import {nodeReader} from '../from-node';
4
3
  import {parseMedia} from '../parse-media';
4
+ import {nodeReader} from '../readers/from-node';
5
5
 
6
6
  test('Parse Big Buck bunny', async () => {
7
7
  const data = await parseMedia({
@@ -1,7 +1,7 @@
1
1
  import {RenderInternals} from '@remotion/renderer';
2
2
  import {expect, test} from 'bun:test';
3
- import {nodeReader} from '../from-node';
4
3
  import {parseMedia} from '../parse-media';
4
+ import {nodeReader} from '../readers/from-node';
5
5
 
6
6
  test('should be able to parse a WebM', async () => {
7
7
  const webm = await parseMedia({
@@ -1,7 +1,7 @@
1
1
  import {RenderInternals} from '@remotion/renderer';
2
2
  import {expect, test} from 'bun:test';
3
- import {nodeReader} from '../from-node';
4
3
  import {parseMedia} from '../parse-media';
4
+ import {nodeReader} from '../readers/from-node';
5
5
 
6
6
  test('Should stream ISO base media', async () => {
7
7
  let videoTracks = 0;
@@ -2,8 +2,8 @@ import {RenderInternals} from '@remotion/renderer';
2
2
  import {expect, test} from 'bun:test';
3
3
  import {getSamplePositionsFromTrack} from '../boxes/iso-base-media/get-sample-positions-from-track';
4
4
  import type {TrakBox} from '../boxes/iso-base-media/trak/trak';
5
- import {nodeReader} from '../from-node';
6
5
  import {parseMedia} from '../parse-media';
6
+ import {nodeReader} from '../readers/from-node';
7
7
 
8
8
  test('Stream samples', async () => {
9
9
  const {videoTracks, audioTracks} = await parseMedia({
@@ -0,0 +1,50 @@
1
+ import type {Writer, WriterInterface} from './writer';
2
+
3
+ const createContent = async () => {
4
+ const directoryHandle = await navigator.storage.getDirectory();
5
+ const filename = `media-parser-${Math.random().toString().replace('0.', '')}.webm`;
6
+
7
+ const fileHandle = await directoryHandle.getFileHandle(filename, {
8
+ create: true,
9
+ });
10
+ const writable = await fileHandle.createWritable();
11
+
12
+ let written = 0;
13
+
14
+ const writer: Writer = {
15
+ write: async (arr: Uint8Array) => {
16
+ await writable.write(arr);
17
+ written += arr.byteLength;
18
+ },
19
+ save: async () => {
20
+ await writable.close();
21
+ const picker = await window.showSaveFilePicker({
22
+ suggestedName: `${Math.random().toString().replace('.', '')}.webm`,
23
+ });
24
+
25
+ const newHandle = await directoryHandle.getFileHandle(filename, {
26
+ create: true,
27
+ });
28
+ const newFile = await newHandle.getFile();
29
+ const pickerWriteable = await picker.createWritable();
30
+ const stream = newFile.stream();
31
+ await stream.pipeTo(pickerWriteable);
32
+
33
+ await directoryHandle.removeEntry(filename, {
34
+ recursive: true,
35
+ });
36
+ },
37
+ getWrittenByteCount: () => written,
38
+ updateDataAt: async (position: number, vint: Uint8Array) => {
39
+ await writable.seek(position);
40
+ await writable.write(vint);
41
+ await writable.seek(written);
42
+ },
43
+ };
44
+
45
+ return writer;
46
+ };
47
+
48
+ export const webFsWriter: WriterInterface = {
49
+ createContent,
50
+ };
@@ -0,0 +1,12 @@
1
+ export type Writer = {
2
+ write: (arr: Uint8Array) => Promise<void>;
3
+ save: () => Promise<void>;
4
+ getWrittenByteCount: () => number;
5
+ updateDataAt: (position: number, vint: Uint8Array) => Promise<void>;
6
+ };
7
+
8
+ type CreateContent = () => Promise<Writer>;
9
+
10
+ export type WriterInterface = {
11
+ createContent: CreateContent;
12
+ };