@remotion/media-parser 4.0.332 → 4.0.334

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 (29) hide show
  1. package/dist/containers/iso-base-media/base-media-box.d.ts +2 -1
  2. package/dist/containers/iso-base-media/get-video-codec-from-iso-track.d.ts +1 -1
  3. package/dist/containers/iso-base-media/get-video-codec-from-iso-track.js +3 -0
  4. package/dist/containers/iso-base-media/mdat/calculate-jump-marks.js +19 -26
  5. package/dist/containers/iso-base-media/mdat/mdat.js +39 -47
  6. package/dist/containers/iso-base-media/process-box.js +21 -14
  7. package/dist/containers/iso-base-media/stsd/samples.js +2 -0
  8. package/dist/containers/iso-base-media/stsd/vpcc.d.ts +19 -0
  9. package/dist/containers/iso-base-media/stsd/vpcc.js +42 -0
  10. package/dist/containers/mp3/parse-packet-header.js +1 -4
  11. package/dist/containers/wav/parse-wav.js +1 -1
  12. package/dist/esm/index.mjs +221 -212
  13. package/dist/esm/worker-server-entry.mjs +220 -211
  14. package/dist/esm/worker-web-entry.mjs +220 -211
  15. package/dist/get-sample-aspect-ratio.d.ts +2 -0
  16. package/dist/get-sample-aspect-ratio.js +13 -1
  17. package/dist/get-video-codec.js +6 -2
  18. package/dist/index.d.ts +11 -4
  19. package/dist/parse-loop.js +1 -0
  20. package/dist/perform-seek.d.ts +3 -1
  21. package/dist/perform-seek.js +4 -1
  22. package/dist/state/iso-base-media/cached-sample-positions.d.ts +17 -25
  23. package/dist/state/iso-base-media/cached-sample-positions.js +83 -24
  24. package/dist/state/iso-base-media/iso-state.d.ts +11 -4
  25. package/dist/state/parser-state.d.ts +11 -4
  26. package/dist/version.d.ts +1 -1
  27. package/dist/version.js +1 -1
  28. package/dist/work-on-seek-request.js +2 -0
  29. package/package.json +3 -3
@@ -23,6 +23,7 @@ import type { StsdBox } from './stsd/stsd';
23
23
  import type { StssBox } from './stsd/stss';
24
24
  import type { StszBox } from './stsd/stsz';
25
25
  import type { SttsBox } from './stsd/stts';
26
+ import type { VpccBox } from './stsd/vpcc';
26
27
  import type { TfdtBox } from './tfdt';
27
28
  import type { TfhdBox } from './tfhd';
28
29
  import type { TkhdBox } from './tkhd';
@@ -36,4 +37,4 @@ export interface RegularBox extends BaseBox {
36
37
  offset: number;
37
38
  type: 'regular-box';
38
39
  }
39
- export type IsoBaseMediaBox = RegularBox | FtypBox | MvhdBox | TkhdBox | StsdBox | ElstBox | MebxBox | KeysBox | MoovBox | TrakBox | SttsBox | MdhdBox | IlstBox | EsdsBox | StszBox | StcoBox | StscBox | AvccBox | HvccBox | VoidBox | StssBox | PaspBox | CttsBox | Av1CBox | TrunBox | HdlrBox | ColorParameterBox | TfdtBox | TfhdBox | TfraBox | TrexBox;
40
+ export type IsoBaseMediaBox = RegularBox | FtypBox | MvhdBox | TkhdBox | StsdBox | ElstBox | MebxBox | KeysBox | MoovBox | TrakBox | SttsBox | MdhdBox | IlstBox | EsdsBox | StszBox | StcoBox | StscBox | AvccBox | HvccBox | VpccBox | VoidBox | StssBox | PaspBox | CttsBox | Av1CBox | TrunBox | HdlrBox | ColorParameterBox | TfdtBox | TfhdBox | TfraBox | TrexBox;
@@ -1,2 +1,2 @@
1
1
  import type { TrakBox } from './trak/trak';
2
- export declare const getVideoCodecFromIsoTrak: (trakBox: TrakBox) => "h264" | "av1" | "h265" | "prores";
2
+ export declare const getVideoCodecFromIsoTrak: (trakBox: TrakBox) => "h264" | "vp9" | "av1" | "h265" | "prores";
@@ -16,6 +16,9 @@ const getVideoCodecFromIsoTrak = (trakBox) => {
16
16
  if (videoSample.format === 'av01') {
17
17
  return 'av1';
18
18
  }
19
+ if (videoSample.format === 'vp09') {
20
+ return 'vp9';
21
+ }
19
22
  // ap4h: ProRes 4444
20
23
  if (videoSample.format === 'ap4h') {
21
24
  return 'prores';
@@ -22,6 +22,15 @@ const findBestJump = ({ sampleMap, offsetsSorted, visited, progresses, }) => {
22
22
  const firstSampleAboveMinProgress = offsetsSorted.findIndex((offset) => sampleMap.get(offset).track.trackId ===
23
23
  Number(trackNumberWithLowestProgress) &&
24
24
  !visited.has(getKey(sampleMap.get(offset))));
25
+ if (firstSampleAboveMinProgress === -1) {
26
+ // Track might be done, so we don't care about minimum progress
27
+ // then
28
+ const backup = offsetsSorted.findIndex((offset) => !visited.has(getKey(sampleMap.get(offset))));
29
+ if (backup === -1) {
30
+ throw new Error('this should not happen');
31
+ }
32
+ return backup;
33
+ }
25
34
  return firstSampleAboveMinProgress;
26
35
  };
27
36
  const calculateJumpMarks = ({ sampleMap, offsetsSorted, trackIds, endOfMdat, }) => {
@@ -32,12 +41,10 @@ const calculateJumpMarks = ({ sampleMap, offsetsSorted, trackIds, endOfMdat, })
32
41
  const jumpMarks = [];
33
42
  let indexToVisit = 0;
34
43
  const visited = new Set();
35
- let rollOverToProcess = false;
36
44
  const increaseIndex = () => {
37
45
  indexToVisit++;
38
46
  if (indexToVisit >= offsetsSorted.length) {
39
- rollOverToProcess = true;
40
- indexToVisit = 0;
47
+ throw new Error('should not roll over, should jump');
41
48
  }
42
49
  };
43
50
  let lastVisitedSample = null;
@@ -49,6 +56,11 @@ const calculateJumpMarks = ({ sampleMap, offsetsSorted, trackIds, endOfMdat, })
49
56
  afterSampleWithOffset: lastVisitedSample.samplePosition.offset,
50
57
  jumpToOffset: offsetsSorted[firstSampleAboveMinProgress],
51
58
  };
59
+ if (firstSampleAboveMinProgress ===
60
+ offsetsSorted.indexOf(lastVisitedSample.samplePosition.offset) + 1) {
61
+ indexToVisit = firstSampleAboveMinProgress;
62
+ return;
63
+ }
52
64
  indexToVisit = firstSampleAboveMinProgress;
53
65
  jumpMarks.push(jumpMark);
54
66
  };
@@ -68,19 +80,7 @@ const calculateJumpMarks = ({ sampleMap, offsetsSorted, trackIds, endOfMdat, })
68
80
  visited,
69
81
  progresses,
70
82
  });
71
- if (firstSampleAboveMinProgress > -1 &&
72
- firstSampleAboveMinProgress !== indexToVisit + 1) {
73
- addJumpMark({ firstSampleAboveMinProgress });
74
- indexToVisit = firstSampleAboveMinProgress;
75
- }
76
- else {
77
- while (true) {
78
- increaseIndex();
79
- if (!visited.has(getKey(sampleMap.get(offsetsSorted[indexToVisit])))) {
80
- break;
81
- }
82
- }
83
- }
83
+ addJumpMark({ firstSampleAboveMinProgress });
84
84
  };
85
85
  while (true) {
86
86
  const currentSamplePosition = sampleMap.get(offsetsSorted[indexToVisit]);
@@ -90,16 +90,6 @@ const calculateJumpMarks = ({ sampleMap, offsetsSorted, trackIds, endOfMdat, })
90
90
  continue;
91
91
  }
92
92
  visited.add(sampleKey);
93
- if (rollOverToProcess) {
94
- if (!lastVisitedSample) {
95
- throw new Error('no last visited sample');
96
- }
97
- jumpMarks.push({
98
- afterSampleWithOffset: lastVisitedSample.samplePosition.offset,
99
- jumpToOffset: currentSamplePosition.samplePosition.offset,
100
- });
101
- rollOverToProcess = false;
102
- }
103
93
  lastVisitedSample = currentSamplePosition;
104
94
  if (visited.size === offsetsSorted.length) {
105
95
  addFinalJumpIfNecessary();
@@ -120,6 +110,9 @@ const calculateJumpMarks = ({ sampleMap, offsetsSorted, trackIds, endOfMdat, })
120
110
  if (spread > MAX_SPREAD_IN_SECONDS) {
121
111
  considerJump();
122
112
  }
113
+ else if (indexToVisit === offsetsSorted.length - 1) {
114
+ considerJump();
115
+ }
123
116
  else {
124
117
  increaseIndex();
125
118
  }
@@ -11,7 +11,6 @@ const may_skip_video_data_1 = require("../../../state/may-skip-video-data");
11
11
  const video_section_1 = require("../../../state/video-section");
12
12
  const webcodecs_timescale_1 = require("../../../webcodecs-timescale");
13
13
  const get_moov_atom_1 = require("../get-moov-atom");
14
- const calculate_jump_marks_1 = require("./calculate-jump-marks");
15
14
  const postprocess_bytes_1 = require("./postprocess-bytes");
16
15
  const parseMdatSection = async (state) => {
17
16
  const mediaSection = (0, video_section_1.getCurrentMediaSection)({
@@ -57,63 +56,60 @@ const parseMdatSection = async (state) => {
57
56
  endOfMdat,
58
57
  state,
59
58
  });
59
+ const tracksFromMoov = (0, get_tracks_1.getTracksFromMoovBox)(moov);
60
60
  state.iso.moov.setMoovBox({
61
61
  moovBox: moov,
62
62
  precomputed: false,
63
63
  });
64
+ const existingTracks = state.callbacks.tracks.getTracks();
65
+ for (const trackFromMoov of tracksFromMoov) {
66
+ if (existingTracks.find((t) => t.trackId === trackFromMoov.trackId)) {
67
+ continue;
68
+ }
69
+ if (trackFromMoov.type === 'other') {
70
+ continue;
71
+ }
72
+ state.callbacks.tracks.addTrack(trackFromMoov);
73
+ }
64
74
  state.callbacks.tracks.setIsDone(state.logLevel);
65
75
  state.structure.getIsoStructure().boxes.push(moov);
66
76
  return (0, exports.parseMdatSection)(state);
67
77
  }
78
+ const tracks = state.callbacks.tracks.getTracks();
68
79
  if (!state.iso.flatSamples.getSamples(mediaSection.start)) {
69
- const { flatSamples: flatSamplesMap, offsets, trackIds, } = (0, cached_sample_positions_1.calculateFlatSamples)({
80
+ const samplePosition = (0, cached_sample_positions_1.calculateSamplePositions)({
70
81
  state,
71
82
  mediaSectionStart: mediaSection.start,
83
+ trackIds: tracks.map((t) => t.trackId),
72
84
  });
73
- const calcedJumpMarks = (0, calculate_jump_marks_1.calculateJumpMarks)({
74
- sampleMap: flatSamplesMap,
75
- offsetsSorted: offsets,
76
- trackIds,
77
- endOfMdat,
78
- });
79
- state.iso.flatSamples.setJumpMarks(mediaSection.start, calcedJumpMarks);
80
- state.iso.flatSamples.setSamples(mediaSection.start, flatSamplesMap);
85
+ state.iso.flatSamples.setSamples(mediaSection.start, samplePosition);
81
86
  }
82
- const flatSamples = state.iso.flatSamples.getSamples(mediaSection.start);
83
- const jumpMarks = state.iso.flatSamples.getJumpMarks(mediaSection.start);
84
- const { iterator } = state;
85
- const samplesWithIndex = flatSamples.get(iterator.counter.getOffset());
86
- if (!samplesWithIndex) {
87
- // There are various reasons why in mdat we find weird stuff:
88
- // - iphonevideo.hevc has a fake hoov atom which is not mapped
89
- // - corrupted.mp4 has a corrupt table
90
- const offsets = Array.from(flatSamples.keys());
91
- const nextSample_ = offsets
92
- .filter((s) => s > iterator.counter.getOffset())
93
- .sort((a, b) => a - b)[0];
94
- if (nextSample_) {
95
- iterator.discard(nextSample_ - iterator.counter.getOffset());
96
- return null;
97
- }
98
- // guess we reached the end!
99
- // iphonevideo.mov has extra padding here, so let's make sure to jump ahead
100
- log_1.Log.verbose(state.logLevel, 'Could not find sample at offset', iterator.counter.getOffset(), 'skipping to end of mdat');
87
+ const samplePositions = state.iso.flatSamples.getSamples(mediaSection.start);
88
+ const sampleIndices = state.iso.flatSamples.getCurrentSampleIndices(mediaSection.start);
89
+ const nextSampleArray = (0, cached_sample_positions_1.getSampleWithLowestDts)(samplePositions, sampleIndices);
90
+ if (nextSampleArray.length === 0) {
91
+ log_1.Log.verbose(state.logLevel, 'Iterated over all samples.', endOfMdat);
101
92
  return (0, skip_1.makeSkip)(endOfMdat);
102
93
  }
94
+ const exactMatch = nextSampleArray.find((s) => s.samplePosition.offset === state.iterator.counter.getOffset());
95
+ const nextSample = exactMatch !== null && exactMatch !== void 0 ? exactMatch : nextSampleArray[0];
96
+ if (nextSample.samplePosition.offset !== state.iterator.counter.getOffset()) {
97
+ return (0, skip_1.makeSkip)(nextSample.samplePosition.offset);
98
+ }
103
99
  // Corrupt file: Sample is beyond the end of the file. Don't process it.
104
- if (samplesWithIndex.samplePosition.offset +
105
- samplesWithIndex.samplePosition.size >
100
+ if (nextSample.samplePosition.offset + nextSample.samplePosition.size >
106
101
  state.contentLength) {
107
- log_1.Log.verbose(state.logLevel, "Sample is beyond the end of the file. Don't process it.", samplesWithIndex.samplePosition.offset +
108
- samplesWithIndex.samplePosition.size, endOfMdat);
102
+ log_1.Log.verbose(state.logLevel, "Sample is beyond the end of the file. Don't process it.", nextSample.samplePosition.offset + nextSample.samplePosition.size, endOfMdat);
109
103
  return (0, skip_1.makeSkip)(endOfMdat);
110
104
  }
105
+ const { iterator } = state;
111
106
  // Need to fetch more data
112
- if (iterator.bytesRemaining() < samplesWithIndex.samplePosition.size) {
113
- return (0, skip_1.makeFetchMoreData)(samplesWithIndex.samplePosition.size - iterator.bytesRemaining());
107
+ if (iterator.bytesRemaining() < nextSample.samplePosition.size) {
108
+ return (0, skip_1.makeFetchMoreData)(nextSample.samplePosition.size - iterator.bytesRemaining());
114
109
  }
115
- const { timestamp: rawCts, decodingTimestamp: rawDts, duration, isKeyframe, offset, bigEndian, chunkSize, } = samplesWithIndex.samplePosition;
116
- const { originalTimescale, startInSeconds, trackMediaTimeOffsetInTrackTimescale, timescale: trackTimescale, } = samplesWithIndex.track;
110
+ const { timestamp: rawCts, decodingTimestamp: rawDts, duration, isKeyframe, offset, bigEndian, chunkSize, } = nextSample.samplePosition;
111
+ const track = tracks.find((t) => t.trackId === nextSample.trackId);
112
+ const { originalTimescale, startInSeconds, trackMediaTimeOffsetInTrackTimescale, timescale: trackTimescale, } = track;
117
113
  const cts = rawCts +
118
114
  startInSeconds * originalTimescale -
119
115
  (trackMediaTimeOffsetInTrackTimescale / trackTimescale) *
@@ -123,11 +119,11 @@ const parseMdatSection = async (state) => {
123
119
  (trackMediaTimeOffsetInTrackTimescale / trackTimescale) *
124
120
  webcodecs_timescale_1.WEBCODECS_TIMESCALE;
125
121
  const bytes = (0, postprocess_bytes_1.postprocessBytes)({
126
- bytes: iterator.getSlice(samplesWithIndex.samplePosition.size),
122
+ bytes: iterator.getSlice(nextSample.samplePosition.size),
127
123
  bigEndian,
128
124
  chunkSize,
129
125
  });
130
- if (samplesWithIndex.track.type === 'audio') {
126
+ if (track.type === 'audio') {
131
127
  const audioSample = (0, convert_audio_or_video_sample_1.convertAudioOrVideoSampleToWebCodecsTimestamps)({
132
128
  sample: {
133
129
  data: bytes,
@@ -141,10 +137,10 @@ const parseMdatSection = async (state) => {
141
137
  });
142
138
  await state.callbacks.onAudioSample({
143
139
  audioSample,
144
- trackId: samplesWithIndex.track.trackId,
140
+ trackId: track.trackId,
145
141
  });
146
142
  }
147
- if (samplesWithIndex.track.type === 'video') {
143
+ if (track.type === 'video') {
148
144
  // https://pub-646d808d9cb240cea53bedc76dd3cd0c.r2.dev/sei_checkpoint.mp4
149
145
  // Position in file 0x0001aba615
150
146
  // https://github.com/remotion-dev/remotion/issues/4680
@@ -170,14 +166,10 @@ const parseMdatSection = async (state) => {
170
166
  });
171
167
  await state.callbacks.onVideoSample({
172
168
  videoSample,
173
- trackId: samplesWithIndex.track.trackId,
169
+ trackId: track.trackId,
174
170
  });
175
171
  }
176
- const jump = jumpMarks.find((j) => j.afterSampleWithOffset === offset);
177
- if (jump) {
178
- log_1.Log.verbose(state.logLevel, 'Found jump mark', jump.jumpToOffset, 'skipping to jump mark');
179
- return (0, skip_1.makeSkip)(jump.jumpToOffset);
180
- }
172
+ state.iso.flatSamples.setCurrentSampleIndex(mediaSection.start, nextSample.trackId, nextSample.index + 1);
181
173
  return null;
182
174
  };
183
175
  exports.parseMdatSection = parseMdatSection;
@@ -31,6 +31,7 @@ const stsd_1 = require("./stsd/stsd");
31
31
  const stss_1 = require("./stsd/stss");
32
32
  const stsz_1 = require("./stsd/stsz");
33
33
  const stts_1 = require("./stsd/stts");
34
+ const vpcc_1 = require("./stsd/vpcc");
34
35
  const tfdt_1 = require("./tfdt");
35
36
  const tfhd_1 = require("./tfhd");
36
37
  const tkhd_1 = require("./tkhd");
@@ -154,7 +155,7 @@ const processBox = async ({ iterator, logLevel, onlyIfMoovAtomExpected, onlyIfMd
154
155
  if (boxType === 'stsz') {
155
156
  return {
156
157
  type: 'box',
157
- box: await (0, stsz_1.parseStsz)({
158
+ box: (0, stsz_1.parseStsz)({
158
159
  iterator,
159
160
  offset: fileOffset,
160
161
  size: boxSize,
@@ -164,7 +165,7 @@ const processBox = async ({ iterator, logLevel, onlyIfMoovAtomExpected, onlyIfMd
164
165
  if (boxType === 'stco' || boxType === 'co64') {
165
166
  return {
166
167
  type: 'box',
167
- box: await (0, stco_1.parseStco)({
168
+ box: (0, stco_1.parseStco)({
168
169
  iterator,
169
170
  offset: fileOffset,
170
171
  size: boxSize,
@@ -175,7 +176,7 @@ const processBox = async ({ iterator, logLevel, onlyIfMoovAtomExpected, onlyIfMd
175
176
  if (boxType === 'pasp') {
176
177
  return {
177
178
  type: 'box',
178
- box: await (0, pasp_1.parsePasp)({
179
+ box: (0, pasp_1.parsePasp)({
179
180
  iterator,
180
181
  offset: fileOffset,
181
182
  size: boxSize,
@@ -185,7 +186,7 @@ const processBox = async ({ iterator, logLevel, onlyIfMoovAtomExpected, onlyIfMd
185
186
  if (boxType === 'stss') {
186
187
  return {
187
188
  type: 'box',
188
- box: await (0, stss_1.parseStss)({
189
+ box: (0, stss_1.parseStss)({
189
190
  iterator,
190
191
  offset: fileOffset,
191
192
  boxSize,
@@ -195,7 +196,7 @@ const processBox = async ({ iterator, logLevel, onlyIfMoovAtomExpected, onlyIfMd
195
196
  if (boxType === 'ctts') {
196
197
  return {
197
198
  type: 'box',
198
- box: await (0, ctts_1.parseCtts)({
199
+ box: (0, ctts_1.parseCtts)({
199
200
  iterator,
200
201
  offset: fileOffset,
201
202
  size: boxSize,
@@ -205,7 +206,7 @@ const processBox = async ({ iterator, logLevel, onlyIfMoovAtomExpected, onlyIfMd
205
206
  if (boxType === 'stsc') {
206
207
  return {
207
208
  type: 'box',
208
- box: await (0, stsc_1.parseStsc)({
209
+ box: (0, stsc_1.parseStsc)({
209
210
  iterator,
210
211
  offset: fileOffset,
211
212
  size: boxSize,
@@ -326,7 +327,7 @@ const processBox = async ({ iterator, logLevel, onlyIfMoovAtomExpected, onlyIfMd
326
327
  if (boxType === 'stts') {
327
328
  return {
328
329
  type: 'box',
329
- box: await (0, stts_1.parseStts)({
330
+ box: (0, stts_1.parseStts)({
330
331
  data: iterator,
331
332
  size: boxSize,
332
333
  fileOffset,
@@ -336,16 +337,22 @@ const processBox = async ({ iterator, logLevel, onlyIfMoovAtomExpected, onlyIfMd
336
337
  if (boxType === 'avcC') {
337
338
  return {
338
339
  type: 'box',
339
- box: await (0, avcc_1.parseAvcc)({
340
+ box: (0, avcc_1.parseAvcc)({
340
341
  data: iterator,
341
342
  size: boxSize,
342
343
  }),
343
344
  };
344
345
  }
346
+ if (boxType === 'vpcC') {
347
+ return {
348
+ type: 'box',
349
+ box: (0, vpcc_1.parseVpcc)({ data: iterator, size: boxSize }),
350
+ };
351
+ }
345
352
  if (boxType === 'av1C') {
346
353
  return {
347
354
  type: 'box',
348
- box: await (0, av1c_1.parseAv1C)({
355
+ box: (0, av1c_1.parseAv1C)({
349
356
  data: iterator,
350
357
  size: boxSize,
351
358
  }),
@@ -354,7 +361,7 @@ const processBox = async ({ iterator, logLevel, onlyIfMoovAtomExpected, onlyIfMd
354
361
  if (boxType === 'hvcC') {
355
362
  return {
356
363
  type: 'box',
357
- box: await (0, hvcc_1.parseHvcc)({
364
+ box: (0, hvcc_1.parseHvcc)({
358
365
  data: iterator,
359
366
  size: boxSize,
360
367
  offset: fileOffset,
@@ -364,7 +371,7 @@ const processBox = async ({ iterator, logLevel, onlyIfMoovAtomExpected, onlyIfMd
364
371
  if (boxType === 'tfhd') {
365
372
  return {
366
373
  type: 'box',
367
- box: await (0, tfhd_1.getTfhd)({
374
+ box: (0, tfhd_1.getTfhd)({
368
375
  iterator,
369
376
  offset: fileOffset,
370
377
  size: boxSize,
@@ -374,7 +381,7 @@ const processBox = async ({ iterator, logLevel, onlyIfMoovAtomExpected, onlyIfMd
374
381
  if (boxType === 'mdhd') {
375
382
  return {
376
383
  type: 'box',
377
- box: await (0, mdhd_1.parseMdhd)({
384
+ box: (0, mdhd_1.parseMdhd)({
378
385
  data: iterator,
379
386
  size: boxSize,
380
387
  fileOffset,
@@ -384,7 +391,7 @@ const processBox = async ({ iterator, logLevel, onlyIfMoovAtomExpected, onlyIfMd
384
391
  if (boxType === 'esds') {
385
392
  return {
386
393
  type: 'box',
387
- box: await (0, esds_1.parseEsds)({
394
+ box: (0, esds_1.parseEsds)({
388
395
  data: iterator,
389
396
  size: boxSize,
390
397
  fileOffset,
@@ -394,7 +401,7 @@ const processBox = async ({ iterator, logLevel, onlyIfMoovAtomExpected, onlyIfMd
394
401
  if (boxType === 'trex') {
395
402
  return {
396
403
  type: 'box',
397
- box: await (0, trex_1.parseTrex)({ iterator, offset: fileOffset, size: boxSize }),
404
+ box: (0, trex_1.parseTrex)({ iterator, offset: fileOffset, size: boxSize }),
398
405
  };
399
406
  }
400
407
  if (boxType === 'moof') {
@@ -34,6 +34,8 @@ const videoTags = [
34
34
  'hev1',
35
35
  'ap4h',
36
36
  'av01',
37
+ 'vp08',
38
+ 'vp09',
37
39
  ];
38
40
  // https://developer.apple.com/documentation/quicktime-file-format/sound_sample_descriptions
39
41
  const audioTags = [
@@ -0,0 +1,19 @@
1
+ import type { BufferIterator } from '../../../iterator/buffer-iterator';
2
+ export interface VpccBox {
3
+ type: 'vpcc-box';
4
+ profile: number;
5
+ level: number;
6
+ bitDepth: number;
7
+ chromaSubsampling: number;
8
+ videoFullRangeFlag: number;
9
+ videoColorPrimaries: number;
10
+ videoTransferCharacteristics: number;
11
+ videoMatrixCoefficients: number;
12
+ codecInitializationDataSize: number;
13
+ codecInitializationData: Uint8Array;
14
+ codecString: string;
15
+ }
16
+ export declare const parseVpcc: ({ data, size, }: {
17
+ data: BufferIterator;
18
+ size: number;
19
+ }) => VpccBox;
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseVpcc = void 0;
4
+ const getvp09ConfigurationString = ({ profile, level, bitDepth, }) => {
5
+ return `${String(profile).padStart(2, '0')}.${String(level).padStart(2, '0')}.${String(bitDepth).padStart(2, '0')}`;
6
+ };
7
+ const parseVpcc = ({ data, size, }) => {
8
+ const box = data.startBox(size - 8);
9
+ const confVersion = data.getUint8();
10
+ if (confVersion !== 1) {
11
+ throw new Error(`Unsupported AVCC version ${confVersion}`);
12
+ }
13
+ data.discard(3); // flags
14
+ const profile = data.getUint8();
15
+ const level = data.getUint8();
16
+ data.startReadingBits();
17
+ const bitDepth = data.getBits(4);
18
+ const chromaSubsampling = data.getBits(3);
19
+ const videoFullRangeFlag = data.getBits(1);
20
+ const videoColorPrimaries = data.getBits(8);
21
+ const videoTransferCharacteristics = data.getBits(8);
22
+ const videoMatrixCoefficients = data.getBits(8);
23
+ data.stopReadingBits();
24
+ const codecInitializationDataSize = data.getUint16();
25
+ const codecInitializationData = data.getSlice(codecInitializationDataSize);
26
+ box.expectNoMoreBytes();
27
+ return {
28
+ type: 'vpcc-box',
29
+ profile,
30
+ level,
31
+ bitDepth,
32
+ chromaSubsampling,
33
+ videoFullRangeFlag,
34
+ videoColorPrimaries,
35
+ videoTransferCharacteristics,
36
+ videoMatrixCoefficients,
37
+ codecInitializationDataSize,
38
+ codecInitializationData,
39
+ codecString: getvp09ConfigurationString({ profile, level, bitDepth }),
40
+ };
41
+ };
42
+ exports.parseVpcc = parseVpcc;
@@ -170,10 +170,7 @@ const innerParseMp3PacketHeader = (iterator) => {
170
170
  throw new Error('Expected Layer I, II or III');
171
171
  }
172
172
  const layer = layerBits === 0b11 ? 1 : layerBits === 0b10 ? 2 : 3;
173
- const protectionBit = iterator.getBits(1);
174
- if (protectionBit !== 0b1) {
175
- throw new Error('Does not support CRC yet');
176
- }
173
+ iterator.getBits(1); // 0b1 means that there is no CRC, 0b0 means there is. Not validating checksum though
177
174
  const bitrateIndex = iterator.getBits(4);
178
175
  const bitrateInKbit = getBitrateKB({
179
176
  bits: bitrateIndex,
@@ -33,7 +33,7 @@ const parseWav = (state) => {
33
33
  if (type === 'id3') {
34
34
  return (0, parse_id3_1.parseId3)({ state });
35
35
  }
36
- if (type === 'junk' || type === 'fllr') {
36
+ if (type === 'junk' || type === 'fllr' || type === 'bext') {
37
37
  return (0, parse_junk_1.parseJunk)({ state });
38
38
  }
39
39
  if (type === 'fact') {