@remotion/media-parser 4.0.200 → 4.0.202
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/av1-codec-string.d.ts +5 -0
- package/dist/av1-codec-string.js +18 -1
- package/dist/bitstream/av1.d.ts +2 -0
- package/dist/bitstream/av1.js +12 -0
- package/dist/boxes/iso-base-media/avcc-hvcc.d.ts +20 -0
- package/dist/boxes/iso-base-media/avcc-hvcc.js +73 -0
- package/dist/boxes/iso-base-media/avcc.d.ts +18 -0
- package/dist/boxes/iso-base-media/avcc.js +27 -0
- package/dist/boxes/iso-base-media/esds-descriptors.d.ts +21 -0
- package/dist/boxes/iso-base-media/esds-descriptors.js +62 -0
- package/dist/boxes/iso-base-media/esds.d.ts +15 -0
- package/dist/boxes/iso-base-media/esds.js +27 -0
- package/dist/boxes/iso-base-media/mdat/mdat.js +2 -1
- package/dist/boxes/iso-base-media/moov/moov.js +1 -0
- package/dist/boxes/iso-base-media/mvhd.js +2 -2
- package/dist/boxes/iso-base-media/process-box.d.ts +4 -2
- package/dist/boxes/iso-base-media/process-box.js +56 -40
- package/dist/boxes/iso-base-media/stsd/keys.js +1 -1
- package/dist/boxes/iso-base-media/stsd/mebx.d.ts +2 -1
- package/dist/boxes/iso-base-media/stsd/mebx.js +2 -1
- package/dist/boxes/iso-base-media/stsd/samples.js +3 -0
- package/dist/boxes/iso-base-media/stsd/stco.d.ts +3 -2
- package/dist/boxes/iso-base-media/stsd/stco.js +2 -2
- package/dist/boxes/iso-base-media/trak/trak.js +1 -0
- package/dist/boxes/webm/av1-codec-private.js +1 -1
- package/dist/boxes/webm/bitstream/av1.js +10 -1
- package/dist/boxes/webm/description.d.ts +2 -2
- package/dist/boxes/webm/description.js +2 -2
- package/dist/boxes/webm/ebml.d.ts +2 -2
- package/dist/boxes/webm/ebml.js +23 -1
- package/dist/boxes/webm/get-ready-tracks.d.ts +1 -1
- package/dist/boxes/webm/get-ready-tracks.js +3 -3
- package/dist/boxes/webm/get-sample-from-block.d.ts +17 -0
- package/dist/boxes/webm/get-sample-from-block.js +78 -0
- package/dist/boxes/webm/get-track.d.ts +2 -2
- package/dist/boxes/webm/get-track.js +26 -25
- package/dist/boxes/webm/make-header.d.ts +3 -1
- package/dist/boxes/webm/make-header.js +90 -32
- package/dist/boxes/webm/parse-ebml.d.ts +12 -0
- package/dist/boxes/webm/parse-ebml.js +175 -0
- package/dist/boxes/webm/parse-webm-header.js +8 -9
- package/dist/boxes/webm/segments/all-segments.d.ts +572 -1
- package/dist/boxes/webm/segments/all-segments.js +353 -2
- package/dist/boxes/webm/segments/track-entry.d.ts +5 -189
- package/dist/boxes/webm/segments/track-entry.js +2 -457
- package/dist/boxes/webm/segments.d.ts +3 -16
- package/dist/boxes/webm/segments.js +40 -219
- package/dist/boxes/webm/traversal.d.ts +5 -5
- package/dist/boxes/webm/traversal.js +17 -6
- package/dist/buffer-iterator.d.ts +10 -7
- package/dist/buffer-iterator.js +83 -7
- package/dist/create/create-media.d.ts +2 -0
- package/dist/create/create-media.js +36 -0
- package/dist/create/matroska-header.d.ts +1 -0
- package/dist/create/matroska-header.js +66 -0
- package/dist/create/matroska-info.d.ts +4 -0
- package/dist/create/matroska-info.js +39 -0
- package/dist/create/matroska-segment.d.ts +1 -0
- package/dist/create/matroska-segment.js +12 -0
- package/dist/create/matroska-trackentry.d.ts +21 -0
- package/dist/create/matroska-trackentry.js +191 -0
- package/dist/create-media.d.ts +1 -0
- package/dist/create-media.js +78 -0
- package/dist/from-fetch.js +13 -3
- package/dist/from-input-type-file.d.ts +2 -0
- package/dist/from-input-type-file.js +37 -0
- package/dist/from-node.js +9 -2
- package/dist/from-web-file.js +6 -1
- package/dist/from-web.js +15 -6
- package/dist/get-audio-codec.d.ts +2 -2
- package/dist/get-audio-codec.js +13 -13
- package/dist/get-codec.d.ts +4 -0
- package/dist/get-codec.js +22 -0
- package/dist/get-duration.js +12 -14
- package/dist/get-sample-positions.js +1 -1
- package/dist/get-tracks.js +2 -2
- package/dist/get-video-codec.js +13 -13
- package/dist/has-all-info.js +1 -1
- package/dist/options.d.ts +3 -2
- package/dist/parse-media.js +17 -10
- package/dist/parse-video.js +16 -0
- package/dist/parser-context.d.ts +1 -0
- package/dist/parser-state.d.ts +4 -3
- package/dist/parser-state.js +16 -3
- package/dist/reader.d.ts +1 -1
- package/dist/readers/from-fetch.d.ts +2 -0
- package/dist/readers/from-fetch.js +64 -0
- package/dist/readers/from-node.d.ts +2 -0
- package/dist/readers/from-node.js +40 -0
- package/dist/readers/from-web-file.d.ts +2 -0
- package/dist/readers/from-web-file.js +39 -0
- package/dist/readers/reader.d.ts +11 -0
- package/dist/readers/reader.js +2 -0
- package/dist/traversal.d.ts +19 -17
- package/dist/traversal.js +38 -39
- package/dist/web-file.d.ts +2 -0
- package/dist/web-file.js +37 -0
- package/dist/writers/web-fs.d.ts +2 -0
- package/dist/writers/web-fs.js +28 -0
- package/dist/writers/writer.d.ts +9 -0
- package/dist/writers/writer.js +2 -0
- package/input.webm +0 -0
- package/package.json +2 -2
- package/src/boxes/iso-base-media/mdat/mdat.ts +2 -1
- package/src/boxes/iso-base-media/moov/moov.ts +1 -0
- package/src/boxes/iso-base-media/mvhd.ts +2 -2
- package/src/boxes/iso-base-media/process-box.ts +70 -40
- package/src/boxes/iso-base-media/stsd/keys.ts +1 -1
- package/src/boxes/iso-base-media/stsd/mebx.ts +3 -0
- package/src/boxes/iso-base-media/stsd/samples.ts +3 -0
- package/src/boxes/iso-base-media/stsd/stco.ts +5 -3
- package/src/boxes/iso-base-media/trak/trak.ts +1 -0
- package/src/boxes/webm/av1-codec-private.ts +1 -1
- package/src/boxes/webm/description.ts +7 -4
- package/src/boxes/webm/ebml.ts +24 -4
- package/src/boxes/webm/get-ready-tracks.ts +4 -4
- package/src/boxes/webm/get-sample-from-block.ts +125 -0
- package/src/boxes/webm/get-track.ts +38 -31
- package/src/boxes/webm/make-header.ts +129 -32
- package/src/boxes/webm/parse-ebml.ts +247 -0
- package/src/boxes/webm/parse-webm-header.ts +8 -12
- package/src/boxes/webm/segments/all-segments.ts +539 -1
- package/src/boxes/webm/segments/track-entry.ts +5 -843
- package/src/boxes/webm/segments.ts +48 -435
- package/src/boxes/webm/traversal.ts +28 -15
- package/src/buffer-iterator.ts +104 -10
- package/src/from-fetch.ts +22 -3
- package/src/from-node.ts +18 -4
- package/src/from-web-file.ts +11 -1
- package/src/get-audio-codec.ts +14 -16
- package/src/get-duration.ts +15 -16
- package/src/get-sample-positions.ts +1 -1
- package/src/get-tracks.ts +2 -2
- package/src/get-video-codec.ts +13 -15
- package/src/has-all-info.ts +1 -1
- package/src/options.ts +3 -2
- package/src/parse-media.ts +20 -9
- package/src/parse-video.ts +17 -0
- package/src/parser-context.ts +1 -0
- package/src/parser-state.ts +22 -5
- package/src/reader.ts +1 -0
- package/src/test/create-matroska.test.ts +255 -7
- package/src/test/matroska.test.ts +311 -334
- package/src/test/mvhd.test.ts +1 -1
- package/src/test/parse-esds.test.ts +2 -2
- package/src/test/parse-stco.test.ts +4 -2
- package/src/test/parse-stsc.test.ts +2 -2
- package/src/test/parse-stsz.test.ts +2 -2
- package/src/test/parse-stts.test.ts +1 -1
- package/src/test/stream-local.test.ts +23 -9
- package/src/test/stream-remote.test.ts +23 -19
- package/src/test/stsd.test.ts +6 -2
- package/src/test/tkhd.test.ts +1 -1
- package/src/traversal.ts +62 -85
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/boxes/iso-base-media/ftype.d.ts +0 -9
- package/dist/boxes/iso-base-media/ftype.js +0 -31
- package/dist/get-video-metadata.d.ts +0 -2
- package/dist/get-video-metadata.js +0 -44
- package/dist/read-and-increment-offset.d.ts +0 -28
- package/dist/read-and-increment-offset.js +0 -177
- package/dist/understand-vorbis.d.ts +0 -1
- package/dist/understand-vorbis.js +0 -12
- package/src/boxes/webm/segments/duration.ts +0 -29
- package/src/boxes/webm/segments/info.ts +0 -34
- package/src/boxes/webm/segments/main.ts +0 -6
- package/src/boxes/webm/segments/muxing.ts +0 -18
- package/src/boxes/webm/segments/seek-head.ts +0 -34
- package/src/boxes/webm/segments/seek-position.ts +0 -18
- package/src/boxes/webm/segments/seek.ts +0 -45
- package/src/boxes/webm/segments/timestamp-scale.ts +0 -17
- package/src/boxes/webm/segments/tracks.ts +0 -32
- package/src/boxes/webm/segments/unknown.ts +0 -19
- package/src/boxes/webm/segments/void.ts +0 -18
- package/src/boxes/webm/segments/writing.ts +0 -18
- package/src/combine-uint8array.ts +0 -13
- /package/dist/{boxes/webm/bitstream/av1/frame.d.ts → get-samples.d.ts} +0 -0
- /package/dist/{boxes/webm/bitstream/av1/frame.js → get-samples.js} +0 -0
- /package/dist/{boxes/webm/bitstream/h264/get-h264-descriptor.d.ts → sample-aspect-ratio.d.ts} +0 -0
- /package/dist/{boxes/webm/bitstream/h264/get-h264-descriptor.js → sample-aspect-ratio.js} +0 -0
|
@@ -1,126 +1,8 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {ParserContext} from '../../../parser-context';
|
|
3
|
-
import type {VideoSample} from '../../../webcodec-sample-types';
|
|
4
|
-
import type {MatroskaSegment} from '../segments';
|
|
5
|
-
import type {matroskaElements} from './all-segments';
|
|
6
|
-
import {parseBlockFlags} from './block-simple-block-flags';
|
|
7
|
-
import {expectChildren} from './parse-children';
|
|
1
|
+
import type {TrackEntry} from './all-segments';
|
|
8
2
|
|
|
9
|
-
export type
|
|
10
|
-
type: 'track-entry-segment';
|
|
11
|
-
children: MatroskaSegment[];
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
export const parseTrackEntry = async (
|
|
15
|
-
iterator: BufferIterator,
|
|
16
|
-
length: number,
|
|
17
|
-
parserContext: ParserContext,
|
|
18
|
-
): Promise<TrackEntrySegment> => {
|
|
19
|
-
const children = await expectChildren({
|
|
20
|
-
iterator,
|
|
21
|
-
length,
|
|
22
|
-
initialChildren: [],
|
|
23
|
-
wrap: null,
|
|
24
|
-
parserContext,
|
|
25
|
-
});
|
|
26
|
-
if (children.status === 'incomplete') {
|
|
27
|
-
throw new Error('Incomplete children ' + length);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
return {
|
|
31
|
-
type: 'track-entry-segment',
|
|
32
|
-
children: children.segments as MatroskaSegment[],
|
|
33
|
-
};
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
export type TrackNumberSegment = {
|
|
37
|
-
type: 'track-number-segment';
|
|
38
|
-
trackNumber: number;
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
export type TrackUIDSegment = {
|
|
42
|
-
type: 'track-uid-segment';
|
|
43
|
-
trackUid: string;
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
export const parseTrackUID = (
|
|
47
|
-
iterator: BufferIterator,
|
|
48
|
-
length: number,
|
|
49
|
-
): TrackUIDSegment => {
|
|
50
|
-
const bytes = iterator.getSlice(length);
|
|
51
|
-
|
|
52
|
-
const asString = [...bytes]
|
|
53
|
-
.map((b) => b.toString(16).padStart(2, '0'))
|
|
54
|
-
.join('');
|
|
55
|
-
return {
|
|
56
|
-
type: 'track-uid-segment',
|
|
57
|
-
trackUid: asString,
|
|
58
|
-
};
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
export type FlagLacingSegment = {
|
|
62
|
-
type: 'flag-lacing-segment';
|
|
63
|
-
lacing: boolean;
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
export const parseFlagLacing = (
|
|
67
|
-
iterator: BufferIterator,
|
|
68
|
-
length: number,
|
|
69
|
-
): FlagLacingSegment => {
|
|
70
|
-
if (length !== 1) {
|
|
71
|
-
throw new Error('Expected flag lacing to be 1 byte');
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
const bytes = iterator.getSlice(length);
|
|
75
|
-
|
|
76
|
-
if (bytes[0] !== 1 && bytes[0] !== 0) {
|
|
77
|
-
throw new Error('Expected lacing to be 1 or 0');
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
return {
|
|
81
|
-
type: 'flag-lacing-segment',
|
|
82
|
-
lacing: Boolean(bytes[0]),
|
|
83
|
-
};
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
export type LanguageSegment = {
|
|
87
|
-
type: 'language-segment';
|
|
88
|
-
language: string;
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
export const parseLanguageSegment = (
|
|
92
|
-
iterator: BufferIterator,
|
|
93
|
-
length: number,
|
|
94
|
-
): LanguageSegment => {
|
|
95
|
-
if (length !== 3) {
|
|
96
|
-
throw new Error('Expected language segment to be 3 bytes');
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
const language = iterator.getByteString(length);
|
|
100
|
-
|
|
101
|
-
return {
|
|
102
|
-
type: 'language-segment',
|
|
103
|
-
language,
|
|
104
|
-
};
|
|
105
|
-
};
|
|
106
|
-
|
|
107
|
-
export type CodecSegment = {
|
|
108
|
-
type: 'codec-segment';
|
|
3
|
+
export type TrackInfo = {
|
|
109
4
|
codec: string;
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
export const parseCodecSegment = (
|
|
113
|
-
iterator: BufferIterator,
|
|
114
|
-
length: number,
|
|
115
|
-
): CodecSegment => {
|
|
116
|
-
// Could make a TypeScript enum with it
|
|
117
|
-
// https://www.matroska.org/technical/codec_specs.html
|
|
118
|
-
const codec = iterator.getByteString(length);
|
|
119
|
-
|
|
120
|
-
return {
|
|
121
|
-
type: 'codec-segment',
|
|
122
|
-
codec,
|
|
123
|
-
};
|
|
5
|
+
trackTimescale: number | null;
|
|
124
6
|
};
|
|
125
7
|
|
|
126
8
|
type TrackType =
|
|
@@ -132,12 +14,7 @@ type TrackType =
|
|
|
132
14
|
| 'control'
|
|
133
15
|
| 'metadata';
|
|
134
16
|
|
|
135
|
-
export
|
|
136
|
-
type: 'track-type-segment';
|
|
137
|
-
trackType: TrackType;
|
|
138
|
-
};
|
|
139
|
-
|
|
140
|
-
const trackTypeToString = (trackType: number): TrackType => {
|
|
17
|
+
export const trackTypeToString = (trackType: number): TrackType => {
|
|
141
18
|
switch (trackType) {
|
|
142
19
|
case 1:
|
|
143
20
|
return 'video';
|
|
@@ -158,719 +35,4 @@ const trackTypeToString = (trackType: number): TrackType => {
|
|
|
158
35
|
}
|
|
159
36
|
};
|
|
160
37
|
|
|
161
|
-
export
|
|
162
|
-
iterator: BufferIterator,
|
|
163
|
-
length: number,
|
|
164
|
-
): TrackTypeSegment => {
|
|
165
|
-
if (length !== 1) {
|
|
166
|
-
throw new Error('Expected track type segment to be 1 byte');
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
const trackType = iterator.getUint8();
|
|
170
|
-
|
|
171
|
-
const trackTypeString = trackTypeToString(trackType);
|
|
172
|
-
|
|
173
|
-
// Could make the return type nicer
|
|
174
|
-
/* 1 - video,
|
|
175
|
-
2 - audio,
|
|
176
|
-
3 - complex,
|
|
177
|
-
16 - logo,
|
|
178
|
-
17 - subtitle,
|
|
179
|
-
18 - buttons,
|
|
180
|
-
32 - control,
|
|
181
|
-
33 - metadata;
|
|
182
|
-
*/
|
|
183
|
-
return {
|
|
184
|
-
type: 'track-type-segment',
|
|
185
|
-
trackType: trackTypeString,
|
|
186
|
-
};
|
|
187
|
-
};
|
|
188
|
-
|
|
189
|
-
export type DefaultDurationSegment = {
|
|
190
|
-
type: 'default-duration-segment';
|
|
191
|
-
defaultDuration: number;
|
|
192
|
-
};
|
|
193
|
-
|
|
194
|
-
export const parseDefaultDurationSegment = (
|
|
195
|
-
iterator: BufferIterator,
|
|
196
|
-
length: number,
|
|
197
|
-
): DefaultDurationSegment => {
|
|
198
|
-
const defaultDuration = iterator.getDecimalBytes(length);
|
|
199
|
-
|
|
200
|
-
return {
|
|
201
|
-
type: 'default-duration-segment',
|
|
202
|
-
defaultDuration,
|
|
203
|
-
};
|
|
204
|
-
};
|
|
205
|
-
|
|
206
|
-
export type VideoSegment = {
|
|
207
|
-
type: 'video-segment';
|
|
208
|
-
children: MatroskaSegment[];
|
|
209
|
-
};
|
|
210
|
-
|
|
211
|
-
export const parseVideoSegment = async (
|
|
212
|
-
iterator: BufferIterator,
|
|
213
|
-
length: number,
|
|
214
|
-
parserContext: ParserContext,
|
|
215
|
-
): Promise<VideoSegment> => {
|
|
216
|
-
const children = await expectChildren({
|
|
217
|
-
iterator,
|
|
218
|
-
length,
|
|
219
|
-
initialChildren: [],
|
|
220
|
-
wrap: null,
|
|
221
|
-
parserContext,
|
|
222
|
-
});
|
|
223
|
-
|
|
224
|
-
if (children.status === 'incomplete') {
|
|
225
|
-
throw new Error('Incomplete children');
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
return {
|
|
229
|
-
type: 'video-segment',
|
|
230
|
-
children: children.segments as MatroskaSegment[],
|
|
231
|
-
};
|
|
232
|
-
};
|
|
233
|
-
|
|
234
|
-
export type AudioSegment = {
|
|
235
|
-
type: 'audio-segment';
|
|
236
|
-
children: MatroskaSegment[];
|
|
237
|
-
};
|
|
238
|
-
|
|
239
|
-
export const parseAudioSegment = async (
|
|
240
|
-
iterator: BufferIterator,
|
|
241
|
-
length: number,
|
|
242
|
-
parserContext: ParserContext,
|
|
243
|
-
): Promise<AudioSegment> => {
|
|
244
|
-
const children = await expectChildren({
|
|
245
|
-
iterator,
|
|
246
|
-
length,
|
|
247
|
-
initialChildren: [],
|
|
248
|
-
wrap: null,
|
|
249
|
-
parserContext,
|
|
250
|
-
});
|
|
251
|
-
|
|
252
|
-
if (children.status === 'incomplete') {
|
|
253
|
-
throw new Error('Incomplete children');
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
return {
|
|
257
|
-
type: 'audio-segment',
|
|
258
|
-
children: children.segments as MatroskaSegment[],
|
|
259
|
-
};
|
|
260
|
-
};
|
|
261
|
-
|
|
262
|
-
export type WidthSegment = {
|
|
263
|
-
type: 'width-segment';
|
|
264
|
-
width: number;
|
|
265
|
-
};
|
|
266
|
-
|
|
267
|
-
export const parseWidthSegment = (
|
|
268
|
-
iterator: BufferIterator,
|
|
269
|
-
length: number,
|
|
270
|
-
): WidthSegment => {
|
|
271
|
-
if (length !== 2) {
|
|
272
|
-
throw new Error('Expected width segment to be 2 bytes');
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
const width = iterator.getUint16();
|
|
276
|
-
|
|
277
|
-
return {
|
|
278
|
-
type: 'width-segment',
|
|
279
|
-
width,
|
|
280
|
-
};
|
|
281
|
-
};
|
|
282
|
-
|
|
283
|
-
export type HeightSegment = {
|
|
284
|
-
type: 'height-segment';
|
|
285
|
-
height: number;
|
|
286
|
-
};
|
|
287
|
-
|
|
288
|
-
export const parseHeightSegment = (
|
|
289
|
-
iterator: BufferIterator,
|
|
290
|
-
length: number,
|
|
291
|
-
): HeightSegment => {
|
|
292
|
-
if (length !== 2) {
|
|
293
|
-
throw new Error('Expected height segment to be 2 bytes');
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
const height = iterator.getUint16();
|
|
297
|
-
|
|
298
|
-
return {
|
|
299
|
-
type: 'height-segment',
|
|
300
|
-
height,
|
|
301
|
-
};
|
|
302
|
-
};
|
|
303
|
-
|
|
304
|
-
export type DisplayWidthSegment = {
|
|
305
|
-
type: 'display-width-segment';
|
|
306
|
-
displayWidth: number;
|
|
307
|
-
};
|
|
308
|
-
|
|
309
|
-
export const parseDisplayWidthSegment = (
|
|
310
|
-
iterator: BufferIterator,
|
|
311
|
-
length: number,
|
|
312
|
-
): DisplayWidthSegment => {
|
|
313
|
-
if (length !== 2) {
|
|
314
|
-
throw new Error(
|
|
315
|
-
`Expected display width segment to be 2 bytes, got ${length}`,
|
|
316
|
-
);
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
const displayWidth = iterator.getUint16();
|
|
320
|
-
|
|
321
|
-
return {
|
|
322
|
-
type: 'display-width-segment',
|
|
323
|
-
displayWidth,
|
|
324
|
-
};
|
|
325
|
-
};
|
|
326
|
-
|
|
327
|
-
export type DisplayHeightSegment = {
|
|
328
|
-
type: 'display-height-segment';
|
|
329
|
-
displayHeight: number;
|
|
330
|
-
};
|
|
331
|
-
|
|
332
|
-
export const parseDisplayHeightSegment = (
|
|
333
|
-
iterator: BufferIterator,
|
|
334
|
-
length: number,
|
|
335
|
-
): DisplayHeightSegment => {
|
|
336
|
-
if (length !== 2) {
|
|
337
|
-
throw new Error(
|
|
338
|
-
`Expected display height segment to be 2 bytes, got ${length}`,
|
|
339
|
-
);
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
const displayHeight = iterator.getUint16();
|
|
343
|
-
|
|
344
|
-
return {
|
|
345
|
-
type: 'display-height-segment',
|
|
346
|
-
displayHeight,
|
|
347
|
-
};
|
|
348
|
-
};
|
|
349
|
-
|
|
350
|
-
export type AlphaModeSegment = {
|
|
351
|
-
type: 'alpha-mode-segment';
|
|
352
|
-
alphaMode: number;
|
|
353
|
-
};
|
|
354
|
-
|
|
355
|
-
export const parseAlphaModeSegment = (
|
|
356
|
-
iterator: BufferIterator,
|
|
357
|
-
length: number,
|
|
358
|
-
): AlphaModeSegment => {
|
|
359
|
-
if (length !== 1) {
|
|
360
|
-
throw new Error('Expected alpha mode segment to be 1 byte');
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
const alphaMode = iterator.getUint8();
|
|
364
|
-
|
|
365
|
-
return {
|
|
366
|
-
type: 'alpha-mode-segment',
|
|
367
|
-
alphaMode,
|
|
368
|
-
};
|
|
369
|
-
};
|
|
370
|
-
|
|
371
|
-
export type MaxBlockAdditionId = {
|
|
372
|
-
type: 'max-block-addition-id-segment';
|
|
373
|
-
maxBlockAdditionId: number;
|
|
374
|
-
};
|
|
375
|
-
|
|
376
|
-
export const parseMaxBlockAdditionId = (
|
|
377
|
-
iterator: BufferIterator,
|
|
378
|
-
length: number,
|
|
379
|
-
): MaxBlockAdditionId => {
|
|
380
|
-
if (length !== 1) {
|
|
381
|
-
throw new Error('Expected alpha mode segment to be 1 byte');
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
const maxBlockAdditionId = iterator.getUint8();
|
|
385
|
-
|
|
386
|
-
return {
|
|
387
|
-
type: 'max-block-addition-id-segment',
|
|
388
|
-
maxBlockAdditionId,
|
|
389
|
-
};
|
|
390
|
-
};
|
|
391
|
-
|
|
392
|
-
export type ColorSegment = {
|
|
393
|
-
type: 'color-segment';
|
|
394
|
-
length: number;
|
|
395
|
-
};
|
|
396
|
-
|
|
397
|
-
export const parseColorSegment = (
|
|
398
|
-
iterator: BufferIterator,
|
|
399
|
-
length: number,
|
|
400
|
-
): ColorSegment => {
|
|
401
|
-
iterator.discard(length);
|
|
402
|
-
|
|
403
|
-
return {
|
|
404
|
-
type: 'color-segment',
|
|
405
|
-
length,
|
|
406
|
-
};
|
|
407
|
-
};
|
|
408
|
-
|
|
409
|
-
export type TitleSegment = {
|
|
410
|
-
type: 'title-segment';
|
|
411
|
-
title: string;
|
|
412
|
-
};
|
|
413
|
-
|
|
414
|
-
export const parseTitleSegment = (
|
|
415
|
-
iterator: BufferIterator,
|
|
416
|
-
length: number,
|
|
417
|
-
): TitleSegment => {
|
|
418
|
-
const title = iterator.getByteString(length);
|
|
419
|
-
|
|
420
|
-
return {
|
|
421
|
-
type: 'title-segment',
|
|
422
|
-
title,
|
|
423
|
-
};
|
|
424
|
-
};
|
|
425
|
-
|
|
426
|
-
export type InterlacedSegment = {
|
|
427
|
-
type: 'interlaced-segment';
|
|
428
|
-
interlaced: boolean;
|
|
429
|
-
};
|
|
430
|
-
|
|
431
|
-
export const parseInterlacedSegment = (
|
|
432
|
-
iterator: BufferIterator,
|
|
433
|
-
length: number,
|
|
434
|
-
): InterlacedSegment => {
|
|
435
|
-
if (length !== 1) {
|
|
436
|
-
throw new Error(
|
|
437
|
-
'Expected interlaced segment to be 1 byte, but is ' + length,
|
|
438
|
-
);
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
const interlaced = iterator.getUint8();
|
|
442
|
-
|
|
443
|
-
return {
|
|
444
|
-
type: 'interlaced-segment',
|
|
445
|
-
interlaced: Boolean(interlaced),
|
|
446
|
-
};
|
|
447
|
-
};
|
|
448
|
-
|
|
449
|
-
export type CodecPrivateSegment = {
|
|
450
|
-
type: 'codec-private-segment';
|
|
451
|
-
codecPrivateData: Uint8Array;
|
|
452
|
-
};
|
|
453
|
-
|
|
454
|
-
export const parseCodecPrivateSegment = (
|
|
455
|
-
iterator: BufferIterator,
|
|
456
|
-
length: number,
|
|
457
|
-
): CodecPrivateSegment => {
|
|
458
|
-
return {
|
|
459
|
-
type: 'codec-private-segment',
|
|
460
|
-
codecPrivateData: iterator.getSlice(length),
|
|
461
|
-
};
|
|
462
|
-
};
|
|
463
|
-
|
|
464
|
-
export type Crc32Segment = {
|
|
465
|
-
type: 'crc32-segment';
|
|
466
|
-
crc32: number[];
|
|
467
|
-
};
|
|
468
|
-
|
|
469
|
-
export const parseCrc32Segment = (
|
|
470
|
-
iterator: BufferIterator,
|
|
471
|
-
length: number,
|
|
472
|
-
): Crc32Segment => {
|
|
473
|
-
return {
|
|
474
|
-
type: 'crc32-segment',
|
|
475
|
-
crc32: [...iterator.getSlice(length)],
|
|
476
|
-
};
|
|
477
|
-
};
|
|
478
|
-
|
|
479
|
-
export type SegmentUUIDSegment = {
|
|
480
|
-
type: 'segment-uuid-segment';
|
|
481
|
-
segmentUUID: string;
|
|
482
|
-
};
|
|
483
|
-
|
|
484
|
-
export const parseSegmentUUIDSegment = (
|
|
485
|
-
iterator: BufferIterator,
|
|
486
|
-
length: number,
|
|
487
|
-
): SegmentUUIDSegment => {
|
|
488
|
-
return {
|
|
489
|
-
type: 'segment-uuid-segment',
|
|
490
|
-
segmentUUID: iterator.getSlice(length).toString(),
|
|
491
|
-
};
|
|
492
|
-
};
|
|
493
|
-
|
|
494
|
-
export type DefaultFlagSegment = {
|
|
495
|
-
type: 'default-flag-segment';
|
|
496
|
-
defaultFlag: boolean;
|
|
497
|
-
};
|
|
498
|
-
|
|
499
|
-
export const parseDefaultFlagSegment = (
|
|
500
|
-
iterator: BufferIterator,
|
|
501
|
-
length: number,
|
|
502
|
-
): DefaultFlagSegment => {
|
|
503
|
-
if (length !== 1) {
|
|
504
|
-
throw new Error('Expected default flag segment to be 1 byte');
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
return {
|
|
508
|
-
type: 'default-flag-segment',
|
|
509
|
-
defaultFlag: Boolean(iterator.getUint8()),
|
|
510
|
-
};
|
|
511
|
-
};
|
|
512
|
-
|
|
513
|
-
export type TagsSegment = {
|
|
514
|
-
type: 'tags-segment';
|
|
515
|
-
children: MatroskaSegment[];
|
|
516
|
-
};
|
|
517
|
-
|
|
518
|
-
export const parseTagsSegment = async (
|
|
519
|
-
iterator: BufferIterator,
|
|
520
|
-
length: number,
|
|
521
|
-
parserContext: ParserContext,
|
|
522
|
-
): Promise<TagsSegment> => {
|
|
523
|
-
const children = await expectChildren({
|
|
524
|
-
iterator,
|
|
525
|
-
length,
|
|
526
|
-
initialChildren: [],
|
|
527
|
-
wrap: null,
|
|
528
|
-
parserContext,
|
|
529
|
-
});
|
|
530
|
-
|
|
531
|
-
if (children.status === 'incomplete') {
|
|
532
|
-
throw new Error('Incomplete children');
|
|
533
|
-
}
|
|
534
|
-
|
|
535
|
-
return {
|
|
536
|
-
type: 'tags-segment',
|
|
537
|
-
children: children.segments as MatroskaSegment[],
|
|
538
|
-
};
|
|
539
|
-
};
|
|
540
|
-
|
|
541
|
-
export type TagSegment = {
|
|
542
|
-
type: 'tag-segment';
|
|
543
|
-
length: number;
|
|
544
|
-
};
|
|
545
|
-
|
|
546
|
-
export const parseTagSegment = (
|
|
547
|
-
iterator: BufferIterator,
|
|
548
|
-
length: number,
|
|
549
|
-
): TagSegment => {
|
|
550
|
-
iterator.discard(length);
|
|
551
|
-
|
|
552
|
-
return {
|
|
553
|
-
type: 'tag-segment',
|
|
554
|
-
length,
|
|
555
|
-
};
|
|
556
|
-
};
|
|
557
|
-
|
|
558
|
-
export type ClusterSegment = {
|
|
559
|
-
type: 'cluster-segment';
|
|
560
|
-
children: MatroskaSegment[];
|
|
561
|
-
};
|
|
562
|
-
|
|
563
|
-
export type TimestampSegment = {
|
|
564
|
-
type: 'timestamp-segment';
|
|
565
|
-
timestamp: number;
|
|
566
|
-
};
|
|
567
|
-
|
|
568
|
-
export const parseTimestampSegment = (
|
|
569
|
-
iterator: BufferIterator,
|
|
570
|
-
length: number,
|
|
571
|
-
): TimestampSegment => {
|
|
572
|
-
if (length > 3) {
|
|
573
|
-
throw new Error(
|
|
574
|
-
'Expected timestamp segment to be 1 byte or 2 bytes, but is ' + length,
|
|
575
|
-
);
|
|
576
|
-
}
|
|
577
|
-
|
|
578
|
-
if (length === 3) {
|
|
579
|
-
const val = iterator.getUint24();
|
|
580
|
-
return {
|
|
581
|
-
type: 'timestamp-segment',
|
|
582
|
-
timestamp: val,
|
|
583
|
-
};
|
|
584
|
-
}
|
|
585
|
-
|
|
586
|
-
const value = length === 2 ? iterator.getUint16() : iterator.getUint8();
|
|
587
|
-
|
|
588
|
-
return {
|
|
589
|
-
type: 'timestamp-segment',
|
|
590
|
-
timestamp: value,
|
|
591
|
-
};
|
|
592
|
-
};
|
|
593
|
-
|
|
594
|
-
export type SimpleBlockOrBlockSegment = {
|
|
595
|
-
type: 'simple-block-or-block-segment';
|
|
596
|
-
length: number;
|
|
597
|
-
trackNumber: number;
|
|
598
|
-
timecode: number;
|
|
599
|
-
keyframe: boolean | null;
|
|
600
|
-
lacing: number;
|
|
601
|
-
invisible: boolean;
|
|
602
|
-
videoSample: Omit<VideoSample, 'type'> | null;
|
|
603
|
-
};
|
|
604
|
-
|
|
605
|
-
export type GetTracks = () => TrackEntrySegment[];
|
|
606
|
-
|
|
607
|
-
export const parseSimpleBlockOrBlockSegment = async ({
|
|
608
|
-
iterator,
|
|
609
|
-
length,
|
|
610
|
-
parserContext,
|
|
611
|
-
type,
|
|
612
|
-
}: {
|
|
613
|
-
iterator: BufferIterator;
|
|
614
|
-
length: number;
|
|
615
|
-
parserContext: ParserContext;
|
|
616
|
-
type:
|
|
617
|
-
| (typeof matroskaElements)['Block']
|
|
618
|
-
| (typeof matroskaElements)['SimpleBlock'];
|
|
619
|
-
}): Promise<SimpleBlockOrBlockSegment> => {
|
|
620
|
-
const start = iterator.counter.getOffset();
|
|
621
|
-
const trackNumber = iterator.getVint();
|
|
622
|
-
const timecodeRelativeToCluster = iterator.getUint16();
|
|
623
|
-
|
|
624
|
-
const {invisible, lacing, keyframe} = parseBlockFlags(iterator, type);
|
|
625
|
-
|
|
626
|
-
const codec = parserContext.parserState.getTrackInfoByNumber(trackNumber);
|
|
627
|
-
const clusterOffset =
|
|
628
|
-
parserContext.parserState.getTimestampOffsetForByteOffset(
|
|
629
|
-
iterator.counter.getOffset(),
|
|
630
|
-
);
|
|
631
|
-
|
|
632
|
-
if (clusterOffset === undefined) {
|
|
633
|
-
throw new Error(
|
|
634
|
-
'Could not find offset for byte offset ' + iterator.counter.getOffset(),
|
|
635
|
-
);
|
|
636
|
-
}
|
|
637
|
-
|
|
638
|
-
const timecode = timecodeRelativeToCluster + clusterOffset;
|
|
639
|
-
|
|
640
|
-
if (!codec) {
|
|
641
|
-
throw new Error('Could not find codec for track ' + trackNumber);
|
|
642
|
-
}
|
|
643
|
-
|
|
644
|
-
const remainingNow = length - (iterator.counter.getOffset() - start);
|
|
645
|
-
|
|
646
|
-
let videoSample: Omit<VideoSample, 'type'> | null = null;
|
|
647
|
-
|
|
648
|
-
if (codec.codec.startsWith('V_')) {
|
|
649
|
-
const partialVideoSample: Omit<VideoSample, 'type'> = {
|
|
650
|
-
data: iterator.getSlice(remainingNow),
|
|
651
|
-
cts: null,
|
|
652
|
-
dts: null,
|
|
653
|
-
duration: undefined,
|
|
654
|
-
trackId: trackNumber,
|
|
655
|
-
timestamp: timecode,
|
|
656
|
-
};
|
|
657
|
-
|
|
658
|
-
if (keyframe === null) {
|
|
659
|
-
// If we don't know if this is a keyframe, we know after we emit the BlockGroup
|
|
660
|
-
videoSample = partialVideoSample;
|
|
661
|
-
} else {
|
|
662
|
-
const sample: VideoSample = {
|
|
663
|
-
...partialVideoSample,
|
|
664
|
-
type: keyframe ? 'key' : 'delta',
|
|
665
|
-
};
|
|
666
|
-
|
|
667
|
-
await parserContext.parserState.onVideoSample(trackNumber, sample);
|
|
668
|
-
}
|
|
669
|
-
}
|
|
670
|
-
|
|
671
|
-
if (codec.codec.startsWith('A_')) {
|
|
672
|
-
await parserContext.parserState.onAudioSample(trackNumber, {
|
|
673
|
-
data: iterator.getSlice(remainingNow),
|
|
674
|
-
trackId: trackNumber,
|
|
675
|
-
timestamp: timecode,
|
|
676
|
-
type: 'key',
|
|
677
|
-
});
|
|
678
|
-
}
|
|
679
|
-
|
|
680
|
-
const remainingNowAfter = length - (iterator.counter.getOffset() - start);
|
|
681
|
-
if (remainingNowAfter > 0) {
|
|
682
|
-
iterator.discard(remainingNowAfter);
|
|
683
|
-
}
|
|
684
|
-
|
|
685
|
-
return {
|
|
686
|
-
type: 'simple-block-or-block-segment',
|
|
687
|
-
length,
|
|
688
|
-
trackNumber,
|
|
689
|
-
timecode,
|
|
690
|
-
keyframe,
|
|
691
|
-
lacing,
|
|
692
|
-
invisible,
|
|
693
|
-
videoSample,
|
|
694
|
-
};
|
|
695
|
-
};
|
|
696
|
-
|
|
697
|
-
export const parseTrackNumber = (
|
|
698
|
-
iterator: BufferIterator,
|
|
699
|
-
length: number,
|
|
700
|
-
): TrackNumberSegment => {
|
|
701
|
-
if (length !== 1) {
|
|
702
|
-
throw new Error('Expected track number to be 1 byte');
|
|
703
|
-
}
|
|
704
|
-
|
|
705
|
-
const trackNumber = iterator.getUint8();
|
|
706
|
-
|
|
707
|
-
return {
|
|
708
|
-
type: 'track-number-segment',
|
|
709
|
-
trackNumber,
|
|
710
|
-
};
|
|
711
|
-
};
|
|
712
|
-
|
|
713
|
-
export type BlockGroupSegment = {
|
|
714
|
-
type: 'block-group-segment';
|
|
715
|
-
children: MatroskaSegment[];
|
|
716
|
-
};
|
|
717
|
-
|
|
718
|
-
export const parseBlockGroupSegment = async (
|
|
719
|
-
iterator: BufferIterator,
|
|
720
|
-
length: number,
|
|
721
|
-
parserContext: ParserContext,
|
|
722
|
-
): Promise<BlockGroupSegment> => {
|
|
723
|
-
const children = await expectChildren({
|
|
724
|
-
iterator,
|
|
725
|
-
length,
|
|
726
|
-
initialChildren: [],
|
|
727
|
-
wrap: null,
|
|
728
|
-
parserContext,
|
|
729
|
-
});
|
|
730
|
-
if (children.status === 'incomplete') {
|
|
731
|
-
throw new Error('Incomplete boxes are not allowed');
|
|
732
|
-
}
|
|
733
|
-
|
|
734
|
-
return {
|
|
735
|
-
type: 'block-group-segment',
|
|
736
|
-
children: children.segments as MatroskaSegment[],
|
|
737
|
-
};
|
|
738
|
-
};
|
|
739
|
-
|
|
740
|
-
export type ReferenceBlockSegment = {
|
|
741
|
-
type: 'reference-block-segment';
|
|
742
|
-
referenceBlock: number;
|
|
743
|
-
};
|
|
744
|
-
|
|
745
|
-
export const parseReferenceBlockSegment = (
|
|
746
|
-
iterator: BufferIterator,
|
|
747
|
-
length: number,
|
|
748
|
-
): ReferenceBlockSegment => {
|
|
749
|
-
if (length > 4) {
|
|
750
|
-
throw new Error(
|
|
751
|
-
`Expected reference block segment to be 4 bytes, but got ${length}`,
|
|
752
|
-
);
|
|
753
|
-
}
|
|
754
|
-
|
|
755
|
-
const referenceBlock =
|
|
756
|
-
length === 4
|
|
757
|
-
? iterator.getUint32()
|
|
758
|
-
: length === 3
|
|
759
|
-
? iterator.getUint24()
|
|
760
|
-
: length === 2
|
|
761
|
-
? iterator.getUint16()
|
|
762
|
-
: iterator.getUint8();
|
|
763
|
-
|
|
764
|
-
return {
|
|
765
|
-
type: 'reference-block-segment',
|
|
766
|
-
referenceBlock,
|
|
767
|
-
};
|
|
768
|
-
};
|
|
769
|
-
|
|
770
|
-
export type BlockAdditionsSegment = {
|
|
771
|
-
type: 'block-additions-segment';
|
|
772
|
-
blockAdditions: Uint8Array;
|
|
773
|
-
};
|
|
774
|
-
|
|
775
|
-
export const parseBlockAdditionsSegment = (
|
|
776
|
-
iterator: BufferIterator,
|
|
777
|
-
length: number,
|
|
778
|
-
): BlockAdditionsSegment => {
|
|
779
|
-
const blockAdditions = iterator.getSlice(length);
|
|
780
|
-
|
|
781
|
-
return {
|
|
782
|
-
type: 'block-additions-segment',
|
|
783
|
-
blockAdditions,
|
|
784
|
-
};
|
|
785
|
-
};
|
|
786
|
-
|
|
787
|
-
export type BlockElement = {
|
|
788
|
-
type: 'block-element-segment';
|
|
789
|
-
length: number;
|
|
790
|
-
};
|
|
791
|
-
|
|
792
|
-
export const parseBlockElementSegment = (
|
|
793
|
-
iterator: BufferIterator,
|
|
794
|
-
length: number,
|
|
795
|
-
): BlockElement => {
|
|
796
|
-
iterator.discard(length);
|
|
797
|
-
|
|
798
|
-
return {
|
|
799
|
-
type: 'block-element-segment',
|
|
800
|
-
length,
|
|
801
|
-
};
|
|
802
|
-
};
|
|
803
|
-
|
|
804
|
-
export type SamplingFrequencySegment = {
|
|
805
|
-
type: 'sampling-frequency-segment';
|
|
806
|
-
samplingFrequency: number;
|
|
807
|
-
};
|
|
808
|
-
|
|
809
|
-
export const parseSamplingFrequencySegment = (
|
|
810
|
-
iterator: BufferIterator,
|
|
811
|
-
length: number,
|
|
812
|
-
): SamplingFrequencySegment => {
|
|
813
|
-
if (length === 4) {
|
|
814
|
-
return {
|
|
815
|
-
type: 'sampling-frequency-segment',
|
|
816
|
-
samplingFrequency: iterator.getFloat32(),
|
|
817
|
-
};
|
|
818
|
-
}
|
|
819
|
-
|
|
820
|
-
if (length === 8) {
|
|
821
|
-
return {
|
|
822
|
-
type: 'sampling-frequency-segment',
|
|
823
|
-
samplingFrequency: iterator.getFloat64(),
|
|
824
|
-
};
|
|
825
|
-
}
|
|
826
|
-
|
|
827
|
-
throw new Error(
|
|
828
|
-
`Expected length of sampling frequency segment to be 4 or 8, got ${length}`,
|
|
829
|
-
);
|
|
830
|
-
};
|
|
831
|
-
|
|
832
|
-
export type ChannelsSegment = {
|
|
833
|
-
type: 'channels-segment';
|
|
834
|
-
channels: number;
|
|
835
|
-
};
|
|
836
|
-
|
|
837
|
-
export const parseChannelsSegment = (
|
|
838
|
-
iterator: BufferIterator,
|
|
839
|
-
length: number,
|
|
840
|
-
): ChannelsSegment => {
|
|
841
|
-
if (length !== 1) {
|
|
842
|
-
throw new Error(
|
|
843
|
-
`Expected length of channels segment to be 1, got ${length}`,
|
|
844
|
-
);
|
|
845
|
-
}
|
|
846
|
-
|
|
847
|
-
const channels = iterator.getUint8();
|
|
848
|
-
|
|
849
|
-
return {
|
|
850
|
-
type: 'channels-segment',
|
|
851
|
-
channels,
|
|
852
|
-
};
|
|
853
|
-
};
|
|
854
|
-
|
|
855
|
-
export type BitDepthSegment = {
|
|
856
|
-
type: 'bit-depth-segment';
|
|
857
|
-
bitDepth: number;
|
|
858
|
-
};
|
|
859
|
-
|
|
860
|
-
export const parseBitDepthSegment = (
|
|
861
|
-
iterator: BufferIterator,
|
|
862
|
-
length: number,
|
|
863
|
-
): BitDepthSegment => {
|
|
864
|
-
if (length !== 1) {
|
|
865
|
-
throw new Error(
|
|
866
|
-
`Expected length of bit depth segment to be 1, got ${length}`,
|
|
867
|
-
);
|
|
868
|
-
}
|
|
869
|
-
|
|
870
|
-
const bitDepth = iterator.getUint8();
|
|
871
|
-
|
|
872
|
-
return {
|
|
873
|
-
type: 'bit-depth-segment',
|
|
874
|
-
bitDepth,
|
|
875
|
-
};
|
|
876
|
-
};
|
|
38
|
+
export type GetTracks = () => TrackEntry[];
|