@remotion/media-parser 4.0.191 → 4.0.192

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 (40) hide show
  1. package/dist/boxes/iso-base-media/mdhd.d.ts +14 -0
  2. package/dist/boxes/iso-base-media/mdhd.js +33 -0
  3. package/dist/boxes/iso-base-media/process-box.js +13 -0
  4. package/dist/boxes/iso-base-media/stsd/samples.js +1 -0
  5. package/dist/boxes/webm/parse-webm-header.js +1 -1
  6. package/dist/boxes/webm/segments/track-entry.d.ts +10 -0
  7. package/dist/boxes/webm/segments/track-entry.js +23 -7
  8. package/dist/boxes/webm/segments.d.ts +2 -2
  9. package/dist/boxes/webm/segments.js +6 -0
  10. package/dist/buffer-iterator.js +2 -0
  11. package/dist/get-codec.d.ts +4 -0
  12. package/dist/get-codec.js +22 -0
  13. package/dist/get-fps.d.ts +7 -0
  14. package/dist/get-fps.js +84 -9
  15. package/dist/get-video-codec.d.ts +4 -0
  16. package/dist/get-video-codec.js +76 -0
  17. package/dist/has-all-info.d.ts +1 -1
  18. package/dist/has-all-info.js +4 -0
  19. package/dist/options.d.ts +7 -3
  20. package/dist/parse-media.js +4 -0
  21. package/dist/parse-result.d.ts +2 -1
  22. package/package.json +2 -2
  23. package/src/boxes/iso-base-media/mdhd.ts +56 -0
  24. package/src/boxes/iso-base-media/process-box.ts +15 -0
  25. package/src/boxes/iso-base-media/stsd/samples.ts +1 -0
  26. package/src/boxes/webm/parse-webm-header.ts +1 -1
  27. package/src/boxes/webm/segments/track-entry.ts +37 -10
  28. package/src/boxes/webm/segments.ts +15 -1
  29. package/src/buffer-iterator.ts +2 -0
  30. package/src/get-fps.ts +127 -9
  31. package/src/get-video-codec.ts +100 -0
  32. package/src/has-all-info.ts +7 -2
  33. package/src/options.ts +28 -3
  34. package/src/parse-media.ts +6 -1
  35. package/src/parse-result.ts +3 -1
  36. package/src/test/matroska.test.ts +5 -5
  37. package/src/test/parse-webm.test.ts +2 -0
  38. package/src/test/stream-local.test.ts +16 -5
  39. package/src/test/stream-remote.test.ts +41 -0
  40. package/tsconfig.tsbuildinfo +1 -1
@@ -77,6 +77,7 @@ const videoTags = [
77
77
  'v410',
78
78
  'v210',
79
79
  'hvc1',
80
+ 'ap4h',
80
81
  ];
81
82
 
82
83
  // https://developer.apple.com/documentation/quicktime-file-format/sound_sample_descriptions
@@ -5,7 +5,7 @@ import {expectSegment} from './segments';
5
5
  // Parsing according to https://darkcoding.net/software/reading-mediarecorders-webm-opus-output/
6
6
  export const parseWebm = (counter: BufferIterator): ParseResult => {
7
7
  counter.discard(4);
8
- const length = counter.getEBML();
8
+ const length = counter.getVint();
9
9
 
10
10
  if (length !== 31) {
11
11
  throw new Error(`Expected header length 31, got ${length}`);
@@ -51,10 +51,6 @@ export type TrackUIDSegment = {
51
51
 
52
52
  export const parseTrackUID = (iterator: BufferIterator): TrackUIDSegment => {
53
53
  const length = iterator.getVint();
54
- // Observation: AV1 has 8 bytes, WebM has 7
55
- if (length !== 8 && length !== 7) {
56
- throw new Error('Expected track number to be 8 byte');
57
- }
58
54
 
59
55
  const bytes = iterator.getSlice(length);
60
56
 
@@ -187,16 +183,11 @@ export type VideoSegment = {
187
183
  };
188
184
 
189
185
  export const parseVideoSegment = (iterator: BufferIterator): VideoSegment => {
190
- const offset = iterator.counter.getOffset();
191
-
192
186
  const length = iterator.getVint();
193
187
 
194
188
  return {
195
189
  type: 'video-segment',
196
- children: expectChildren(
197
- iterator,
198
- length - (iterator.counter.getOffset() - offset),
199
- ),
190
+ children: expectChildren(iterator, length),
200
191
  };
201
192
  };
202
193
 
@@ -293,3 +284,39 @@ export const parseColorSegment = (iterator: BufferIterator): ColorSegment => {
293
284
  type: 'color-segment',
294
285
  };
295
286
  };
287
+
288
+ export type TitleSegment = {
289
+ type: 'title-segment';
290
+ title: string;
291
+ };
292
+
293
+ export const parseTitleSegment = (iterator: BufferIterator): TitleSegment => {
294
+ const length = iterator.getVint();
295
+ const title = iterator.getByteString(length);
296
+
297
+ return {
298
+ type: 'title-segment',
299
+ title,
300
+ };
301
+ };
302
+
303
+ export type InterlacedSegment = {
304
+ type: 'interlaced-segment';
305
+ interlaced: boolean;
306
+ };
307
+
308
+ export const parseInterlacedSegment = (
309
+ iterator: BufferIterator,
310
+ ): InterlacedSegment => {
311
+ const length = iterator.getVint();
312
+ if (length !== 1) {
313
+ throw new Error('Expected interlaced segment to be 1 byte');
314
+ }
315
+
316
+ const interlaced = iterator.getUint8();
317
+
318
+ return {
319
+ type: 'interlaced-segment',
320
+ interlaced: Boolean(interlaced),
321
+ };
322
+ };
@@ -22,8 +22,10 @@ import type {
22
22
  DefaultDurationSegment,
23
23
  FlagLacingSegment,
24
24
  HeightSegment,
25
+ InterlacedSegment,
25
26
  LanguageSegment,
26
27
  MaxBlockAdditionId,
28
+ TitleSegment,
27
29
  TrackEntrySegment,
28
30
  TrackNumberSegment,
29
31
  TrackTypeSegment,
@@ -38,8 +40,10 @@ import {
38
40
  parseDefaultDurationSegment,
39
41
  parseFlagLacing,
40
42
  parseHeightSegment,
43
+ parseInterlacedSegment,
41
44
  parseLanguageSegment,
42
45
  parseMaxBlockAdditionId,
46
+ parseTitleSegment,
43
47
  parseTrackEntry,
44
48
  parseTrackNumber,
45
49
  parseTrackTypeSegment,
@@ -82,7 +86,9 @@ export type MatroskaSegment =
82
86
  | HeightSegment
83
87
  | AlphaModeSegment
84
88
  | MaxBlockAdditionId
85
- | ColorSegment;
89
+ | ColorSegment
90
+ | TitleSegment
91
+ | InterlacedSegment;
86
92
 
87
93
  export const expectSegment = (iterator: BufferIterator): MatroskaSegment => {
88
94
  const segmentId = iterator.getMatroskaSegmentId();
@@ -189,10 +195,18 @@ export const expectSegment = (iterator: BufferIterator): MatroskaSegment => {
189
195
  return parseHeightSegment(iterator);
190
196
  }
191
197
 
198
+ if (segmentId === '0x9a') {
199
+ return parseInterlacedSegment(iterator);
200
+ }
201
+
192
202
  if (segmentId === '0x53c0') {
193
203
  return parseAlphaModeSegment(iterator);
194
204
  }
195
205
 
206
+ if (segmentId === '0x7ba9') {
207
+ return parseTitleSegment(iterator);
208
+ }
209
+
196
210
  const length = iterator.getVint();
197
211
 
198
212
  const bytesRemaining = iterator.byteLength() - iterator.counter.getOffset();
@@ -154,6 +154,7 @@ export const getArrayBufferIterator = (initialData: Uint8Array) => {
154
154
  '0xe0',
155
155
  '0xb0',
156
156
  '0xba',
157
+ '0x9a',
157
158
  ];
158
159
  if (knownIdsWithOneLength.includes(firstOneString)) {
159
160
  return firstOneString;
@@ -172,6 +173,7 @@ export const getArrayBufferIterator = (initialData: Uint8Array) => {
172
173
  '0x4489',
173
174
  '0x55ee',
174
175
  '0x55b0',
176
+ '0x7ba9',
175
177
  ];
176
178
 
177
179
  const firstTwoString = `${firstOneString}${Array.from(
package/src/get-fps.ts CHANGED
@@ -1,18 +1,135 @@
1
1
  import type {SttsBox} from './boxes/iso-base-media/stts/stts';
2
2
  import type {AnySegment} from './parse-result';
3
3
 
4
- const calculateFps = (sttsBox: SttsBox, timeScale: number) => {
5
- let sum = 0;
4
+ const calculateFps = ({
5
+ sttsBox,
6
+ timeScale,
7
+ durationInSamples,
8
+ }: {
9
+ sttsBox: SttsBox;
10
+ timeScale: number;
11
+ durationInSamples: number;
12
+ }) => {
6
13
  let totalSamples = 0;
14
+
7
15
  for (const sample of sttsBox.sampleDistribution) {
8
- sum += sample.sampleCount * sample.sampleDelta;
9
16
  totalSamples += sample.sampleCount;
10
17
  }
11
18
 
12
- return timeScale / (sum / totalSamples);
19
+ const durationInSeconds = durationInSamples / timeScale;
20
+ const fps = totalSamples / durationInSeconds;
21
+
22
+ return fps;
23
+ };
24
+
25
+ type TimescaleAndDuration = {
26
+ timescale: number;
27
+ duration: number;
28
+ };
29
+
30
+ export const trakBoxContainsVideo = (trakBox: AnySegment): boolean => {
31
+ if (trakBox.type !== 'trak-box') {
32
+ return false;
33
+ }
34
+
35
+ const {children} = trakBox;
36
+ const mediaBoxes = children.filter(
37
+ (c) => c.type === 'regular-box' && c.boxType === 'mdia',
38
+ );
39
+ if (!mediaBoxes || mediaBoxes.length === 0) {
40
+ return false;
41
+ }
42
+
43
+ const firstMediaBox = mediaBoxes[0];
44
+ if (
45
+ firstMediaBox.type !== 'regular-box' ||
46
+ firstMediaBox.boxType !== 'mdia'
47
+ ) {
48
+ return false;
49
+ }
50
+
51
+ const minf = firstMediaBox.children.find(
52
+ (c) => c.type === 'regular-box' && c.boxType === 'minf',
53
+ );
54
+ if (!minf || minf.type !== 'regular-box' || minf.boxType !== 'minf') {
55
+ return false;
56
+ }
57
+
58
+ const stbl = minf.children.find(
59
+ (c) => c.type === 'regular-box' && c.boxType === 'stbl',
60
+ );
61
+ if (!stbl || stbl.type !== 'regular-box' || stbl.boxType !== 'stbl') {
62
+ return false;
63
+ }
64
+
65
+ const stsd = stbl.children.find((c) => c.type === 'stsd-box');
66
+ if (!stsd || stsd.type !== 'stsd-box') {
67
+ return false;
68
+ }
69
+
70
+ const videoSample = stsd.samples.find((s) => s.type === 'video');
71
+ if (!videoSample || videoSample.type !== 'video') {
72
+ return false;
73
+ }
74
+
75
+ return true;
76
+ };
77
+
78
+ export const getTimescaleAndDuration = (
79
+ boxes: AnySegment[],
80
+ ): TimescaleAndDuration | null => {
81
+ const moovBox = boxes.find((s) => s.type === 'moov-box');
82
+ if (!moovBox || moovBox.type !== 'moov-box') {
83
+ return null;
84
+ }
85
+
86
+ const {children} = moovBox;
87
+ const trackBoxes = children.filter((c) => c.type === 'trak-box');
88
+ if (!trackBoxes || trackBoxes.length === 0) {
89
+ return null;
90
+ }
91
+
92
+ const trackBox = trackBoxes.find(trakBoxContainsVideo);
93
+ if (!trackBox || trackBox.type !== 'trak-box') {
94
+ return null;
95
+ }
96
+
97
+ const trackBoxChildren = trackBox.children;
98
+ if (!trackBoxChildren || trackBoxChildren.length === 0) {
99
+ return null;
100
+ }
101
+
102
+ const mdiaBox = trackBoxChildren.find(
103
+ (c) => c.type === 'regular-box' && c.boxType === 'mdia',
104
+ );
105
+ if (
106
+ !mdiaBox ||
107
+ mdiaBox.type !== 'regular-box' ||
108
+ mdiaBox.boxType !== 'mdia'
109
+ ) {
110
+ return null;
111
+ }
112
+
113
+ const mdhdBox = mdiaBox?.children.find((c) => c.type === 'mdhd-box');
114
+ if (mdhdBox && mdhdBox.type === 'mdhd-box') {
115
+ return {timescale: mdhdBox.timescale, duration: mdhdBox.duration};
116
+ }
117
+
118
+ const mvhdBox = moovBox.children.find((c) => c.type === 'mvhd-box');
119
+ if (!mvhdBox || mvhdBox.type !== 'mvhd-box') {
120
+ return null;
121
+ }
122
+
123
+ const {timeScale, durationInUnits} = mvhdBox;
124
+ return {timescale: timeScale, duration: durationInUnits};
13
125
  };
14
126
 
15
127
  export const getFps = (segments: AnySegment[]) => {
128
+ const timescaleAndDuration = getTimescaleAndDuration(segments);
129
+ if (!timescaleAndDuration) {
130
+ return null;
131
+ }
132
+
16
133
  const moovBox = segments.find((s) => s.type === 'moov-box');
17
134
  if (!moovBox || moovBox.type !== 'moov-box') {
18
135
  return null;
@@ -23,16 +140,13 @@ export const getFps = (segments: AnySegment[]) => {
23
140
  return null;
24
141
  }
25
142
 
26
- const {timeScale} = mvhdBox;
27
-
28
143
  const {children} = moovBox;
29
144
  const trackBoxes = children.filter((c) => c.type === 'trak-box');
30
145
  if (!trackBoxes || trackBoxes.length === 0) {
31
146
  return null;
32
147
  }
33
148
 
34
- // TODO: What if the video track is not the first track?
35
- const trackBox = trackBoxes[0];
149
+ const trackBox = trackBoxes.find(trakBoxContainsVideo);
36
150
  if (!trackBox || trackBox.type !== 'trak-box') {
37
151
  return null;
38
152
  }
@@ -80,7 +194,11 @@ export const getFps = (segments: AnySegment[]) => {
80
194
  return null;
81
195
  }
82
196
 
83
- return calculateFps(sttsBox, timeScale);
197
+ return calculateFps({
198
+ sttsBox,
199
+ timeScale: timescaleAndDuration.timescale,
200
+ durationInSamples: timescaleAndDuration.duration,
201
+ });
84
202
  };
85
203
 
86
204
  export const hasFps = (boxes: AnySegment[]): boolean => {
@@ -0,0 +1,100 @@
1
+ /* eslint-disable max-depth */
2
+ import {trakBoxContainsVideo} from './get-fps';
3
+ import type {KnownVideoCodecs} from './options';
4
+ import type {AnySegment} from './parse-result';
5
+
6
+ export const hasVideoCodec = (boxes: AnySegment[]): boolean => {
7
+ try {
8
+ return getVideoCodec(boxes) !== null;
9
+ } catch (e) {
10
+ return false;
11
+ }
12
+ };
13
+
14
+ export const getVideoCodec = (boxes: AnySegment[]): KnownVideoCodecs | null => {
15
+ const moovBox = boxes.find((b) => b.type === 'moov-box');
16
+ if (moovBox && moovBox.type === 'moov-box') {
17
+ const trakBox = moovBox.children.find(
18
+ (b) => b.type === 'trak-box' && trakBoxContainsVideo(b),
19
+ );
20
+ if (trakBox && trakBox.type === 'trak-box') {
21
+ const mdiaBox = trakBox.children.find(
22
+ (b) => b.type === 'regular-box' && b.boxType === 'mdia',
23
+ );
24
+ if (
25
+ mdiaBox &&
26
+ mdiaBox.type === 'regular-box' &&
27
+ mdiaBox.boxType === 'mdia'
28
+ ) {
29
+ const minfBox = mdiaBox?.children.find(
30
+ (b) => b.type === 'regular-box' && b.boxType === 'minf',
31
+ );
32
+ if (
33
+ minfBox &&
34
+ minfBox.type === 'regular-box' &&
35
+ minfBox.boxType === 'minf'
36
+ ) {
37
+ const stblBox = minfBox?.children.find(
38
+ (b) => b.type === 'regular-box' && b.boxType === 'stbl',
39
+ );
40
+ if (stblBox && stblBox.type === 'regular-box') {
41
+ const stsdBox = stblBox?.children.find(
42
+ (b) => b.type === 'stsd-box',
43
+ );
44
+ if (stsdBox && stsdBox.type === 'stsd-box') {
45
+ const videoSample = stsdBox.samples.find(
46
+ (s) => s.type === 'video',
47
+ );
48
+ if (videoSample && videoSample.type === 'video') {
49
+ if (videoSample.format === 'hvc1') {
50
+ return 'h265';
51
+ }
52
+
53
+ if (videoSample.format === 'avc1') {
54
+ return 'h264';
55
+ }
56
+
57
+ if (videoSample.format === 'ap4h') {
58
+ return 'prores';
59
+ }
60
+ }
61
+ }
62
+ }
63
+ }
64
+ }
65
+ }
66
+ }
67
+
68
+ const mainSegment = boxes.find((b) => b.type === 'main-segment');
69
+ if (!mainSegment || mainSegment.type !== 'main-segment') {
70
+ return null;
71
+ }
72
+
73
+ const tracksSegment = mainSegment.children.find(
74
+ (b) => b.type === 'tracks-segment',
75
+ );
76
+ if (!tracksSegment || tracksSegment.type !== 'tracks-segment') {
77
+ return null;
78
+ }
79
+
80
+ for (const track of tracksSegment.children) {
81
+ if (track.type === 'track-entry-segment') {
82
+ const trackType = track.children.find((b) => b.type === 'codec-segment');
83
+ if (trackType && trackType.type === 'codec-segment') {
84
+ if (trackType.codec === 'V_VP8') {
85
+ return 'vp8';
86
+ }
87
+
88
+ if (trackType.codec === 'V_VP9') {
89
+ return 'vp9';
90
+ }
91
+
92
+ if (trackType.codec === 'V_AV1') {
93
+ return 'av1';
94
+ }
95
+ }
96
+ }
97
+ }
98
+
99
+ return null;
100
+ };
@@ -1,16 +1,17 @@
1
1
  import {hasDimensions} from './get-dimensions';
2
2
  import {hasDuration} from './get-duration';
3
3
  import {hasFps} from './get-fps';
4
+ import {hasVideoCodec} from './get-video-codec';
4
5
  import type {Options} from './options';
5
6
  import type {ParseResult} from './parse-result';
6
7
 
7
8
  export const hasAllInfo = (
8
- options: Options<boolean, boolean, boolean, boolean>,
9
+ options: Options<boolean, boolean, boolean, boolean, boolean>,
9
10
  parseResult: ParseResult,
10
11
  ) => {
11
12
  const keys = Object.entries(options)
12
13
  .filter(([, value]) => value)
13
- .map(([key]) => key) as (keyof Options<true, true, true, true>)[];
14
+ .map(([key]) => key) as (keyof Options<true, true, true, true, true>)[];
14
15
 
15
16
  return keys.every((key) => {
16
17
  if (key === 'boxes') {
@@ -29,6 +30,10 @@ export const hasAllInfo = (
29
30
  return hasFps(parseResult.segments) !== null;
30
31
  }
31
32
 
33
+ if (key === 'videoCodec') {
34
+ return hasVideoCodec(parseResult.segments) !== null;
35
+ }
36
+
32
37
  throw new Error(`Unknown key: ${key satisfies never}`);
33
38
  });
34
39
  };
package/src/options.ts CHANGED
@@ -2,16 +2,26 @@ import type {Dimensions} from './get-dimensions';
2
2
  import type {AnySegment} from './parse-result';
3
3
  import type {ReaderInterface} from './reader';
4
4
 
5
+ export type KnownVideoCodecs =
6
+ | 'h264'
7
+ | 'h265'
8
+ | 'vp8'
9
+ | 'vp9'
10
+ | 'av1'
11
+ | 'prores';
12
+
5
13
  export type Options<
6
14
  EnableDimensions extends boolean,
7
15
  EnableDuration extends boolean,
8
16
  EnableBoxes extends boolean,
9
17
  EnableFps extends boolean,
18
+ EnableVideoCodec extends boolean,
10
19
  > = {
11
20
  dimensions?: EnableDimensions;
12
21
  durationInSeconds?: EnableDuration;
13
22
  boxes?: EnableBoxes;
14
23
  fps?: EnableFps;
24
+ videoCodec?: EnableVideoCodec;
15
25
  };
16
26
 
17
27
  export type Metadata<
@@ -19,20 +29,35 @@ export type Metadata<
19
29
  EnableDuration extends boolean,
20
30
  EnableBoxes extends boolean,
21
31
  EnableFps extends boolean,
32
+ EnableVideoCodec extends boolean,
22
33
  > = (EnableDimensions extends true ? {dimensions: Dimensions} : {}) &
23
34
  (EnableDuration extends true ? {durationInSeconds: number | null} : {}) &
24
35
  (EnableBoxes extends true ? {boxes: AnySegment[]} : {}) &
25
- (EnableFps extends true ? {fps: number | null} : {});
36
+ (EnableFps extends true ? {fps: number | null} : {}) &
37
+ (EnableVideoCodec extends true ? {videoCodec: KnownVideoCodecs | null} : {});
26
38
 
27
39
  export type ParseMedia = <
28
40
  EnableDimensions extends boolean,
29
41
  EnableDuration extends boolean,
30
42
  EnableBoxes extends boolean,
31
43
  EnableFps extends boolean,
44
+ EnableVideoCodec extends boolean,
32
45
  >(
33
46
  src: string,
34
- options: Options<EnableDimensions, EnableDuration, EnableBoxes, EnableFps>,
47
+ options: Options<
48
+ EnableDimensions,
49
+ EnableDuration,
50
+ EnableBoxes,
51
+ EnableFps,
52
+ EnableVideoCodec
53
+ >,
35
54
  readerInterface?: ReaderInterface,
36
55
  ) => Promise<
37
- Metadata<EnableDimensions, EnableDuration, EnableBoxes, EnableFps>
56
+ Metadata<
57
+ EnableDimensions,
58
+ EnableDuration,
59
+ EnableBoxes,
60
+ EnableFps,
61
+ EnableVideoCodec
62
+ >
38
63
  >;
@@ -3,6 +3,7 @@ import {webReader} from './from-web';
3
3
  import {getDimensions} from './get-dimensions';
4
4
  import {getDuration} from './get-duration';
5
5
  import {getFps} from './get-fps';
6
+ import {getVideoCodec} from './get-video-codec';
6
7
  import {hasAllInfo} from './has-all-info';
7
8
  import type {Metadata, ParseMedia} from './options';
8
9
  import {parseVideo} from './parse-video';
@@ -14,7 +15,7 @@ export const parseMedia: ParseMedia = async (
14
15
  ) => {
15
16
  const reader = await readerInterface.read(src, null);
16
17
 
17
- const returnValue = {} as Metadata<true, true, true, true>;
18
+ const returnValue = {} as Metadata<true, true, true, true, true>;
18
19
 
19
20
  const iterator = getArrayBufferIterator(new Uint8Array([]));
20
21
  let parseResult = parseVideo(iterator);
@@ -49,6 +50,10 @@ export const parseMedia: ParseMedia = async (
49
50
  returnValue.fps = getFps(parseResult.segments);
50
51
  }
51
52
 
53
+ if (options.videoCodec) {
54
+ returnValue.videoCodec = getVideoCodec(parseResult.segments);
55
+ }
56
+
52
57
  if (options.boxes) {
53
58
  returnValue.boxes = parseResult.segments;
54
59
  }
@@ -1,5 +1,6 @@
1
1
  import type {BaseBox} from './boxes/iso-base-media/base-type';
2
2
  import type {FtypBox} from './boxes/iso-base-media/ftyp';
3
+ import type {MdhdBox} from './boxes/iso-base-media/mdhd';
3
4
  import type {MoovBox} from './boxes/iso-base-media/moov/moov';
4
5
  import type {MvhdBox} from './boxes/iso-base-media/mvhd';
5
6
  import type {KeysBox} from './boxes/iso-base-media/stsd/keys';
@@ -28,7 +29,8 @@ export type IsoBaseMediaBox =
28
29
  | KeysBox
29
30
  | MoovBox
30
31
  | TrakBox
31
- | SttsBox;
32
+ | SttsBox
33
+ | MdhdBox;
32
34
 
33
35
  export type AnySegment = MatroskaSegment | IsoBaseMediaBox;
34
36
 
@@ -137,18 +137,18 @@ test('Should get duration of AV1 video', async () => {
137
137
  {
138
138
  type: 'color-segment',
139
139
  },
140
+ {
141
+ id: '0x0163a294',
142
+ type: 'unknown-segment',
143
+ },
140
144
  ],
141
145
  },
142
146
  {
143
- id: '0x0163a294',
147
+ id: '0x0c000a0e',
144
148
  type: 'unknown-segment',
145
149
  },
146
150
  ],
147
151
  },
148
- {
149
- id: '0x0c000a0e',
150
- type: 'unknown-segment',
151
- },
152
152
  ],
153
153
  },
154
154
  {
@@ -8,8 +8,10 @@ test('should be able to parse a WebM', async () => {
8
8
  RenderInternals.exampleVideos.transparentWebm,
9
9
  {
10
10
  durationInSeconds: true,
11
+ videoCodec: true,
11
12
  },
12
13
  nodeReader,
13
14
  );
14
15
  expect(webm.durationInSeconds).toBe(5);
16
+ expect(webm.videoCodec).toBe('vp8');
15
17
  });