@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
@@ -3966,6 +3966,17 @@ var getAvccBox = (trakBox) => {
3966
3966
  }
3967
3967
  return avccBox;
3968
3968
  };
3969
+ var getVpccBox = (trakBox) => {
3970
+ const videoConfig = getStsdVideoConfig(trakBox);
3971
+ if (!videoConfig) {
3972
+ return null;
3973
+ }
3974
+ const vpccBox = videoConfig.descriptors.find((c) => c.type === "vpcc-box");
3975
+ if (!vpccBox || vpccBox.type !== "vpcc-box") {
3976
+ return null;
3977
+ }
3978
+ return vpccBox;
3979
+ };
3969
3980
  var getAv1CBox = (trakBox) => {
3970
3981
  const videoConfig = getStsdVideoConfig(trakBox);
3971
3982
  if (!videoConfig) {
@@ -4123,21 +4134,25 @@ var getIsoBmColrConfig = (trakBox) => {
4123
4134
  var getVideoCodecString = (trakBox) => {
4124
4135
  const videoSample = getStsdVideoConfig(trakBox);
4125
4136
  const avccBox = getAvccBox(trakBox);
4126
- const hvccBox = getHvccBox(trakBox);
4127
- const av1cBox = getAv1CBox(trakBox);
4128
4137
  if (!videoSample) {
4129
4138
  return null;
4130
4139
  }
4131
4140
  if (avccBox) {
4132
4141
  return `${videoSample.format}.${avccBox.configurationString}`;
4133
4142
  }
4143
+ const hvccBox = getHvccBox(trakBox);
4134
4144
  if (hvccBox) {
4135
4145
  return `${videoSample.format}.${hvccBox.configurationString}`;
4136
4146
  }
4147
+ const av1cBox = getAv1CBox(trakBox);
4137
4148
  if (av1cBox) {
4138
4149
  const colrAtom = getColrBox(videoSample);
4139
4150
  return parseAv1PrivateData(av1cBox.privateData, colrAtom);
4140
4151
  }
4152
+ const vpccBox = getVpccBox(trakBox);
4153
+ if (vpccBox) {
4154
+ return `${videoSample.format}.${vpccBox.codecString}`;
4155
+ }
4141
4156
  return videoSample.format;
4142
4157
  };
4143
4158
 
@@ -4193,6 +4208,9 @@ var getVideoCodecFromIsoTrak = (trakBox) => {
4193
4208
  if (videoSample.format === "av01") {
4194
4209
  return "av1";
4195
4210
  }
4211
+ if (videoSample.format === "vp09") {
4212
+ return "vp9";
4213
+ }
4196
4214
  if (videoSample.format === "ap4h") {
4197
4215
  return "prores";
4198
4216
  }
@@ -5170,6 +5188,53 @@ var parseStts = ({
5170
5188
  };
5171
5189
  };
5172
5190
 
5191
+ // src/containers/iso-base-media/stsd/vpcc.ts
5192
+ var getvp09ConfigurationString = ({
5193
+ profile,
5194
+ level,
5195
+ bitDepth: bitDepth2
5196
+ }) => {
5197
+ return `${String(profile).padStart(2, "0")}.${String(level).padStart(2, "0")}.${String(bitDepth2).padStart(2, "0")}`;
5198
+ };
5199
+ var parseVpcc = ({
5200
+ data,
5201
+ size
5202
+ }) => {
5203
+ const box = data.startBox(size - 8);
5204
+ const confVersion = data.getUint8();
5205
+ if (confVersion !== 1) {
5206
+ throw new Error(`Unsupported AVCC version ${confVersion}`);
5207
+ }
5208
+ data.discard(3);
5209
+ const profile = data.getUint8();
5210
+ const level = data.getUint8();
5211
+ data.startReadingBits();
5212
+ const bitDepth2 = data.getBits(4);
5213
+ const chromaSubsampling = data.getBits(3);
5214
+ const videoFullRangeFlag = data.getBits(1);
5215
+ const videoColorPrimaries = data.getBits(8);
5216
+ const videoTransferCharacteristics = data.getBits(8);
5217
+ const videoMatrixCoefficients = data.getBits(8);
5218
+ data.stopReadingBits();
5219
+ const codecInitializationDataSize = data.getUint16();
5220
+ const codecInitializationData = data.getSlice(codecInitializationDataSize);
5221
+ box.expectNoMoreBytes();
5222
+ return {
5223
+ type: "vpcc-box",
5224
+ profile,
5225
+ level,
5226
+ bitDepth: bitDepth2,
5227
+ chromaSubsampling,
5228
+ videoFullRangeFlag,
5229
+ videoColorPrimaries,
5230
+ videoTransferCharacteristics,
5231
+ videoMatrixCoefficients,
5232
+ codecInitializationDataSize,
5233
+ codecInitializationData,
5234
+ codecString: getvp09ConfigurationString({ profile, level, bitDepth: bitDepth2 })
5235
+ };
5236
+ };
5237
+
5173
5238
  // src/containers/iso-base-media/tfdt.ts
5174
5239
  var parseTfdt = ({
5175
5240
  iterator,
@@ -5497,7 +5562,7 @@ var processBox = async ({
5497
5562
  if (boxType === "stsz") {
5498
5563
  return {
5499
5564
  type: "box",
5500
- box: await parseStsz({
5565
+ box: parseStsz({
5501
5566
  iterator,
5502
5567
  offset: fileOffset,
5503
5568
  size: boxSize
@@ -5507,7 +5572,7 @@ var processBox = async ({
5507
5572
  if (boxType === "stco" || boxType === "co64") {
5508
5573
  return {
5509
5574
  type: "box",
5510
- box: await parseStco({
5575
+ box: parseStco({
5511
5576
  iterator,
5512
5577
  offset: fileOffset,
5513
5578
  size: boxSize,
@@ -5518,7 +5583,7 @@ var processBox = async ({
5518
5583
  if (boxType === "pasp") {
5519
5584
  return {
5520
5585
  type: "box",
5521
- box: await parsePasp({
5586
+ box: parsePasp({
5522
5587
  iterator,
5523
5588
  offset: fileOffset,
5524
5589
  size: boxSize
@@ -5528,7 +5593,7 @@ var processBox = async ({
5528
5593
  if (boxType === "stss") {
5529
5594
  return {
5530
5595
  type: "box",
5531
- box: await parseStss({
5596
+ box: parseStss({
5532
5597
  iterator,
5533
5598
  offset: fileOffset,
5534
5599
  boxSize
@@ -5538,7 +5603,7 @@ var processBox = async ({
5538
5603
  if (boxType === "ctts") {
5539
5604
  return {
5540
5605
  type: "box",
5541
- box: await parseCtts({
5606
+ box: parseCtts({
5542
5607
  iterator,
5543
5608
  offset: fileOffset,
5544
5609
  size: boxSize
@@ -5548,7 +5613,7 @@ var processBox = async ({
5548
5613
  if (boxType === "stsc") {
5549
5614
  return {
5550
5615
  type: "box",
5551
- box: await parseStsc({
5616
+ box: parseStsc({
5552
5617
  iterator,
5553
5618
  offset: fileOffset,
5554
5619
  size: boxSize
@@ -5667,7 +5732,7 @@ var processBox = async ({
5667
5732
  if (boxType === "stts") {
5668
5733
  return {
5669
5734
  type: "box",
5670
- box: await parseStts({
5735
+ box: parseStts({
5671
5736
  data: iterator,
5672
5737
  size: boxSize,
5673
5738
  fileOffset
@@ -5677,16 +5742,22 @@ var processBox = async ({
5677
5742
  if (boxType === "avcC") {
5678
5743
  return {
5679
5744
  type: "box",
5680
- box: await parseAvcc({
5745
+ box: parseAvcc({
5681
5746
  data: iterator,
5682
5747
  size: boxSize
5683
5748
  })
5684
5749
  };
5685
5750
  }
5751
+ if (boxType === "vpcC") {
5752
+ return {
5753
+ type: "box",
5754
+ box: parseVpcc({ data: iterator, size: boxSize })
5755
+ };
5756
+ }
5686
5757
  if (boxType === "av1C") {
5687
5758
  return {
5688
5759
  type: "box",
5689
- box: await parseAv1C({
5760
+ box: parseAv1C({
5690
5761
  data: iterator,
5691
5762
  size: boxSize
5692
5763
  })
@@ -5695,7 +5766,7 @@ var processBox = async ({
5695
5766
  if (boxType === "hvcC") {
5696
5767
  return {
5697
5768
  type: "box",
5698
- box: await parseHvcc({
5769
+ box: parseHvcc({
5699
5770
  data: iterator,
5700
5771
  size: boxSize,
5701
5772
  offset: fileOffset
@@ -5705,7 +5776,7 @@ var processBox = async ({
5705
5776
  if (boxType === "tfhd") {
5706
5777
  return {
5707
5778
  type: "box",
5708
- box: await getTfhd({
5779
+ box: getTfhd({
5709
5780
  iterator,
5710
5781
  offset: fileOffset,
5711
5782
  size: boxSize
@@ -5715,7 +5786,7 @@ var processBox = async ({
5715
5786
  if (boxType === "mdhd") {
5716
5787
  return {
5717
5788
  type: "box",
5718
- box: await parseMdhd({
5789
+ box: parseMdhd({
5719
5790
  data: iterator,
5720
5791
  size: boxSize,
5721
5792
  fileOffset
@@ -5725,7 +5796,7 @@ var processBox = async ({
5725
5796
  if (boxType === "esds") {
5726
5797
  return {
5727
5798
  type: "box",
5728
- box: await parseEsds({
5799
+ box: parseEsds({
5729
5800
  data: iterator,
5730
5801
  size: boxSize,
5731
5802
  fileOffset
@@ -5735,7 +5806,7 @@ var processBox = async ({
5735
5806
  if (boxType === "trex") {
5736
5807
  return {
5737
5808
  type: "box",
5738
- box: await parseTrex({ iterator, offset: fileOffset, size: boxSize })
5809
+ box: parseTrex({ iterator, offset: fileOffset, size: boxSize })
5739
5810
  };
5740
5811
  }
5741
5812
  if (boxType === "moof") {
@@ -5834,7 +5905,9 @@ var videoTags = [
5834
5905
  "hvc1",
5835
5906
  "hev1",
5836
5907
  "ap4h",
5837
- "av01"
5908
+ "av01",
5909
+ "vp08",
5910
+ "vp09"
5838
5911
  ];
5839
5912
  var audioTags = [
5840
5913
  0,
@@ -9962,7 +10035,8 @@ var performSeek = async ({
9962
10035
  src,
9963
10036
  discardReadBytes,
9964
10037
  fields,
9965
- prefetchCache
10038
+ prefetchCache,
10039
+ isoState
9966
10040
  }) => {
9967
10041
  const byteInMediaSection = isByteInMediaSection({
9968
10042
  position: seekTo,
@@ -10026,6 +10100,9 @@ var performSeek = async ({
10026
10100
  prefetchCache
10027
10101
  });
10028
10102
  }
10103
+ if (userInitiated) {
10104
+ isoState.flatSamples.updateAfterSeek(seekTo);
10105
+ }
10029
10106
  await controller._internals.checkForAbortAndPause();
10030
10107
  };
10031
10108
 
@@ -10204,7 +10281,8 @@ var workOnSeekRequest = async (options) => {
10204
10281
  src,
10205
10282
  discardReadBytes,
10206
10283
  fields,
10207
- prefetchCache
10284
+ prefetchCache,
10285
+ isoState
10208
10286
  });
10209
10287
  return;
10210
10288
  }
@@ -10224,7 +10302,8 @@ var workOnSeekRequest = async (options) => {
10224
10302
  src,
10225
10303
  discardReadBytes,
10226
10304
  fields,
10227
- prefetchCache
10305
+ prefetchCache,
10306
+ isoState
10228
10307
  });
10229
10308
  const { hasChanged } = controller._internals.seekSignal.clearSeekIfStillSame(seek2);
10230
10309
  if (hasChanged) {
@@ -11324,9 +11403,10 @@ var parseFlac = ({
11324
11403
  };
11325
11404
 
11326
11405
  // src/state/iso-base-media/cached-sample-positions.ts
11327
- var calculateFlatSamples = ({
11406
+ var calculateSamplePositions = ({
11328
11407
  state,
11329
- mediaSectionStart
11408
+ mediaSectionStart,
11409
+ trackIds
11330
11410
  }) => {
11331
11411
  const tracks2 = getTracks(state, true);
11332
11412
  const moofBoxes = getMoofBoxes(state.structure.getIsoStructure().boxes);
@@ -11348,11 +11428,13 @@ var calculateFlatSamples = ({
11348
11428
  if (!moov) {
11349
11429
  throw new Error("No moov box found");
11350
11430
  }
11351
- const offsets = [];
11352
- const trackIds = [];
11353
- const map = new Map;
11431
+ const trackIdAndSamplePositions = [];
11354
11432
  for (const track of tracks2) {
11355
11433
  const trakBox = getTrakBoxByTrackId(moov, track.trackId);
11434
+ if (!trackIds.includes(track.trackId)) {
11435
+ Log.verbose(state.logLevel, "Skipping calculating sample positions for track", track.trackId);
11436
+ continue;
11437
+ }
11356
11438
  if (!trakBox) {
11357
11439
  throw new Error("No trak box found");
11358
11440
  }
@@ -11362,36 +11444,88 @@ var calculateFlatSamples = ({
11362
11444
  moofComplete,
11363
11445
  trexBoxes: getTrexBoxes(moov)
11364
11446
  });
11365
- trackIds.push(track.trackId);
11366
- for (const samplePosition of samplePositions) {
11367
- offsets.push(samplePosition.offset);
11368
- map.set(samplePosition.offset, {
11369
- track,
11370
- samplePosition
11371
- });
11447
+ trackIdAndSamplePositions.push({
11448
+ trackId: track.trackId,
11449
+ samplePositions
11450
+ });
11451
+ }
11452
+ return trackIdAndSamplePositions;
11453
+ };
11454
+ var updateSampleIndicesAfterSeek = ({
11455
+ samplePositionsForMdatStart,
11456
+ seekedByte
11457
+ }) => {
11458
+ const currentSampleIndices = {};
11459
+ const keys = Object.keys(samplePositionsForMdatStart).map(Number).sort();
11460
+ const mdat = keys.find((key) => seekedByte >= key);
11461
+ if (!mdat) {
11462
+ return currentSampleIndices;
11463
+ }
11464
+ const samplePositions = samplePositionsForMdatStart[mdat];
11465
+ if (!samplePositions) {
11466
+ return currentSampleIndices;
11467
+ }
11468
+ for (const track of samplePositions) {
11469
+ const currentSampleIndex = track.samplePositions.findIndex((sample) => sample.offset >= seekedByte);
11470
+ if (!currentSampleIndices[mdat]) {
11471
+ currentSampleIndices[mdat] = {};
11472
+ }
11473
+ if (!currentSampleIndices[mdat][track.trackId]) {
11474
+ currentSampleIndices[mdat][track.trackId] = 0;
11475
+ }
11476
+ if (currentSampleIndex === -1) {
11477
+ currentSampleIndices[mdat][track.trackId] = track.samplePositions.length;
11478
+ } else {
11479
+ currentSampleIndices[mdat][track.trackId] = currentSampleIndex;
11372
11480
  }
11373
11481
  }
11374
- offsets.sort((a, b) => a - b);
11375
- return { flatSamples: map, offsets, trackIds };
11482
+ return currentSampleIndices;
11376
11483
  };
11377
11484
  var cachedSamplePositionsState = () => {
11378
- const cachedForMdatStart = {};
11379
- const jumpMarksForMdatStart = {};
11485
+ const samplePositionsForMdatStart = {};
11486
+ let currentSampleIndex = {};
11380
11487
  return {
11381
11488
  getSamples: (mdatStart) => {
11382
- return cachedForMdatStart[mdatStart] ?? null;
11489
+ return samplePositionsForMdatStart[mdatStart] ?? null;
11383
11490
  },
11384
11491
  setSamples: (mdatStart, samples) => {
11385
- cachedForMdatStart[mdatStart] = samples;
11492
+ samplePositionsForMdatStart[mdatStart] = samples;
11493
+ },
11494
+ setCurrentSampleIndex: (mdatStart, trackId, index) => {
11495
+ if (!currentSampleIndex[mdatStart]) {
11496
+ currentSampleIndex[mdatStart] = {};
11497
+ }
11498
+ if (!currentSampleIndex[mdatStart][trackId]) {
11499
+ currentSampleIndex[mdatStart][trackId] = 0;
11500
+ }
11501
+ currentSampleIndex[mdatStart][trackId] = index;
11386
11502
  },
11387
- setJumpMarks: (mdatStart, marks) => {
11388
- jumpMarksForMdatStart[mdatStart] = marks;
11503
+ getCurrentSampleIndices: (mdatStart) => {
11504
+ return currentSampleIndex[mdatStart] ?? {};
11389
11505
  },
11390
- getJumpMarks: (mdatStart) => {
11391
- return jumpMarksForMdatStart[mdatStart];
11506
+ updateAfterSeek: (seekedByte) => {
11507
+ currentSampleIndex = updateSampleIndicesAfterSeek({
11508
+ samplePositionsForMdatStart,
11509
+ seekedByte
11510
+ });
11392
11511
  }
11393
11512
  };
11394
11513
  };
11514
+ var getSampleWithLowestDts = (samplePositions, currentSampleIndexMap) => {
11515
+ const lowestDts = [];
11516
+ for (const track of samplePositions) {
11517
+ const currentSampleIndex = currentSampleIndexMap[track.trackId] ?? 0;
11518
+ const currentSample = track.samplePositions[currentSampleIndex];
11519
+ if (currentSample && (lowestDts.length === 0 || currentSample.decodingTimestamp <= lowestDts[0].samplePosition.decodingTimestamp)) {
11520
+ lowestDts.push({
11521
+ samplePosition: currentSample,
11522
+ trackId: track.trackId,
11523
+ index: currentSampleIndex
11524
+ });
11525
+ }
11526
+ }
11527
+ return lowestDts;
11528
+ };
11395
11529
 
11396
11530
  // src/state/iso-base-media/last-moof-box.ts
11397
11531
  var getLastMoofBox = (boxes) => {
@@ -11672,127 +11806,6 @@ var getMoovAtom = async ({
11672
11806
  return moov;
11673
11807
  };
11674
11808
 
11675
- // src/containers/iso-base-media/mdat/calculate-jump-marks.ts
11676
- var MAX_SPREAD_IN_SECONDS = 8;
11677
- var getKey = (samplePositionTrack) => {
11678
- return `${samplePositionTrack.track.trackId}-${samplePositionTrack.samplePosition.decodingTimestamp}.${samplePositionTrack.samplePosition.offset}`;
11679
- };
11680
- var findBestJump = ({
11681
- sampleMap,
11682
- offsetsSorted,
11683
- visited,
11684
- progresses
11685
- }) => {
11686
- const minProgress = Math.min(...Object.values(progresses));
11687
- const trackNumberWithLowestProgress = Object.entries(progresses).find(([, progress]) => progress === minProgress)?.[0];
11688
- const firstSampleAboveMinProgress = offsetsSorted.findIndex((offset) => sampleMap.get(offset).track.trackId === Number(trackNumberWithLowestProgress) && !visited.has(getKey(sampleMap.get(offset))));
11689
- return firstSampleAboveMinProgress;
11690
- };
11691
- var calculateJumpMarks = ({
11692
- sampleMap,
11693
- offsetsSorted,
11694
- trackIds,
11695
- endOfMdat
11696
- }) => {
11697
- const progresses = {};
11698
- for (const trackId of trackIds) {
11699
- progresses[trackId] = 0;
11700
- }
11701
- const jumpMarks = [];
11702
- let indexToVisit = 0;
11703
- const visited = new Set;
11704
- let rollOverToProcess = false;
11705
- const increaseIndex = () => {
11706
- indexToVisit++;
11707
- if (indexToVisit >= offsetsSorted.length) {
11708
- rollOverToProcess = true;
11709
- indexToVisit = 0;
11710
- }
11711
- };
11712
- let lastVisitedSample = null;
11713
- const addJumpMark = ({
11714
- firstSampleAboveMinProgress
11715
- }) => {
11716
- if (!lastVisitedSample) {
11717
- throw new Error("no last visited sample");
11718
- }
11719
- const jumpMark = {
11720
- afterSampleWithOffset: lastVisitedSample.samplePosition.offset,
11721
- jumpToOffset: offsetsSorted[firstSampleAboveMinProgress]
11722
- };
11723
- indexToVisit = firstSampleAboveMinProgress;
11724
- jumpMarks.push(jumpMark);
11725
- };
11726
- const addFinalJumpIfNecessary = () => {
11727
- if (indexToVisit === offsetsSorted.length - 1) {
11728
- return;
11729
- }
11730
- jumpMarks.push({
11731
- afterSampleWithOffset: offsetsSorted[indexToVisit],
11732
- jumpToOffset: endOfMdat
11733
- });
11734
- };
11735
- const considerJump = () => {
11736
- const firstSampleAboveMinProgress = findBestJump({
11737
- sampleMap,
11738
- offsetsSorted,
11739
- visited,
11740
- progresses
11741
- });
11742
- if (firstSampleAboveMinProgress > -1 && firstSampleAboveMinProgress !== indexToVisit + 1) {
11743
- addJumpMark({ firstSampleAboveMinProgress });
11744
- indexToVisit = firstSampleAboveMinProgress;
11745
- } else {
11746
- while (true) {
11747
- increaseIndex();
11748
- if (!visited.has(getKey(sampleMap.get(offsetsSorted[indexToVisit])))) {
11749
- break;
11750
- }
11751
- }
11752
- }
11753
- };
11754
- while (true) {
11755
- const currentSamplePosition = sampleMap.get(offsetsSorted[indexToVisit]);
11756
- const sampleKey = getKey(currentSamplePosition);
11757
- if (visited.has(sampleKey)) {
11758
- considerJump();
11759
- continue;
11760
- }
11761
- visited.add(sampleKey);
11762
- if (rollOverToProcess) {
11763
- if (!lastVisitedSample) {
11764
- throw new Error("no last visited sample");
11765
- }
11766
- jumpMarks.push({
11767
- afterSampleWithOffset: lastVisitedSample.samplePosition.offset,
11768
- jumpToOffset: currentSamplePosition.samplePosition.offset
11769
- });
11770
- rollOverToProcess = false;
11771
- }
11772
- lastVisitedSample = currentSamplePosition;
11773
- if (visited.size === offsetsSorted.length) {
11774
- addFinalJumpIfNecessary();
11775
- break;
11776
- }
11777
- const timestamp = currentSamplePosition.samplePosition.decodingTimestamp / currentSamplePosition.track.originalTimescale;
11778
- progresses[currentSamplePosition.track.trackId] = timestamp;
11779
- const progressValues = Object.values(progresses);
11780
- const maxProgress = Math.max(...progressValues);
11781
- const minProgress = Math.min(...progressValues);
11782
- const spread = maxProgress - minProgress;
11783
- if (visited.size === offsetsSorted.length) {
11784
- addFinalJumpIfNecessary();
11785
- break;
11786
- }
11787
- if (spread > MAX_SPREAD_IN_SECONDS) {
11788
- considerJump();
11789
- } else {
11790
- increaseIndex();
11791
- }
11792
- }
11793
- return jumpMarks;
11794
- };
11795
-
11796
11809
  // src/containers/iso-base-media/mdat/postprocess-bytes.ts
11797
11810
  var postprocessBytes = ({
11798
11811
  bytes,
@@ -11853,52 +11866,53 @@ var parseMdatSection = async (state) => {
11853
11866
  endOfMdat,
11854
11867
  state
11855
11868
  });
11869
+ const tracksFromMoov = getTracksFromMoovBox(moov);
11856
11870
  state.iso.moov.setMoovBox({
11857
11871
  moovBox: moov,
11858
11872
  precomputed: false
11859
11873
  });
11874
+ const existingTracks = state.callbacks.tracks.getTracks();
11875
+ for (const trackFromMoov of tracksFromMoov) {
11876
+ if (existingTracks.find((t) => t.trackId === trackFromMoov.trackId)) {
11877
+ continue;
11878
+ }
11879
+ if (trackFromMoov.type === "other") {
11880
+ continue;
11881
+ }
11882
+ state.callbacks.tracks.addTrack(trackFromMoov);
11883
+ }
11860
11884
  state.callbacks.tracks.setIsDone(state.logLevel);
11861
11885
  state.structure.getIsoStructure().boxes.push(moov);
11862
11886
  return parseMdatSection(state);
11863
11887
  }
11888
+ const tracks2 = state.callbacks.tracks.getTracks();
11864
11889
  if (!state.iso.flatSamples.getSamples(mediaSection.start)) {
11865
- const {
11866
- flatSamples: flatSamplesMap,
11867
- offsets,
11868
- trackIds
11869
- } = calculateFlatSamples({
11890
+ const samplePosition = calculateSamplePositions({
11870
11891
  state,
11871
- mediaSectionStart: mediaSection.start
11892
+ mediaSectionStart: mediaSection.start,
11893
+ trackIds: tracks2.map((t) => t.trackId)
11872
11894
  });
11873
- const calcedJumpMarks = calculateJumpMarks({
11874
- sampleMap: flatSamplesMap,
11875
- offsetsSorted: offsets,
11876
- trackIds,
11877
- endOfMdat
11878
- });
11879
- state.iso.flatSamples.setJumpMarks(mediaSection.start, calcedJumpMarks);
11880
- state.iso.flatSamples.setSamples(mediaSection.start, flatSamplesMap);
11895
+ state.iso.flatSamples.setSamples(mediaSection.start, samplePosition);
11881
11896
  }
11882
- const flatSamples = state.iso.flatSamples.getSamples(mediaSection.start);
11883
- const jumpMarks = state.iso.flatSamples.getJumpMarks(mediaSection.start);
11884
- const { iterator } = state;
11885
- const samplesWithIndex = flatSamples.get(iterator.counter.getOffset());
11886
- if (!samplesWithIndex) {
11887
- const offsets = Array.from(flatSamples.keys());
11888
- const nextSample_ = offsets.filter((s) => s > iterator.counter.getOffset()).sort((a, b) => a - b)[0];
11889
- if (nextSample_) {
11890
- iterator.discard(nextSample_ - iterator.counter.getOffset());
11891
- return null;
11892
- }
11893
- Log.verbose(state.logLevel, "Could not find sample at offset", iterator.counter.getOffset(), "skipping to end of mdat");
11897
+ const samplePositions = state.iso.flatSamples.getSamples(mediaSection.start);
11898
+ const sampleIndices = state.iso.flatSamples.getCurrentSampleIndices(mediaSection.start);
11899
+ const nextSampleArray = getSampleWithLowestDts(samplePositions, sampleIndices);
11900
+ if (nextSampleArray.length === 0) {
11901
+ Log.verbose(state.logLevel, "Iterated over all samples.", endOfMdat);
11894
11902
  return makeSkip(endOfMdat);
11895
11903
  }
11896
- if (samplesWithIndex.samplePosition.offset + samplesWithIndex.samplePosition.size > state.contentLength) {
11897
- Log.verbose(state.logLevel, "Sample is beyond the end of the file. Don't process it.", samplesWithIndex.samplePosition.offset + samplesWithIndex.samplePosition.size, endOfMdat);
11904
+ const exactMatch = nextSampleArray.find((s) => s.samplePosition.offset === state.iterator.counter.getOffset());
11905
+ const nextSample = exactMatch ?? nextSampleArray[0];
11906
+ if (nextSample.samplePosition.offset !== state.iterator.counter.getOffset()) {
11907
+ return makeSkip(nextSample.samplePosition.offset);
11908
+ }
11909
+ if (nextSample.samplePosition.offset + nextSample.samplePosition.size > state.contentLength) {
11910
+ Log.verbose(state.logLevel, "Sample is beyond the end of the file. Don't process it.", nextSample.samplePosition.offset + nextSample.samplePosition.size, endOfMdat);
11898
11911
  return makeSkip(endOfMdat);
11899
11912
  }
11900
- if (iterator.bytesRemaining() < samplesWithIndex.samplePosition.size) {
11901
- return makeFetchMoreData(samplesWithIndex.samplePosition.size - iterator.bytesRemaining());
11913
+ const { iterator } = state;
11914
+ if (iterator.bytesRemaining() < nextSample.samplePosition.size) {
11915
+ return makeFetchMoreData(nextSample.samplePosition.size - iterator.bytesRemaining());
11902
11916
  }
11903
11917
  const {
11904
11918
  timestamp: rawCts,
@@ -11908,21 +11922,22 @@ var parseMdatSection = async (state) => {
11908
11922
  offset,
11909
11923
  bigEndian,
11910
11924
  chunkSize
11911
- } = samplesWithIndex.samplePosition;
11925
+ } = nextSample.samplePosition;
11926
+ const track = tracks2.find((t) => t.trackId === nextSample.trackId);
11912
11927
  const {
11913
11928
  originalTimescale,
11914
11929
  startInSeconds,
11915
11930
  trackMediaTimeOffsetInTrackTimescale,
11916
11931
  timescale: trackTimescale
11917
- } = samplesWithIndex.track;
11932
+ } = track;
11918
11933
  const cts = rawCts + startInSeconds * originalTimescale - trackMediaTimeOffsetInTrackTimescale / trackTimescale * WEBCODECS_TIMESCALE;
11919
11934
  const dts = rawDts + startInSeconds * originalTimescale - trackMediaTimeOffsetInTrackTimescale / trackTimescale * WEBCODECS_TIMESCALE;
11920
11935
  const bytes = postprocessBytes({
11921
- bytes: iterator.getSlice(samplesWithIndex.samplePosition.size),
11936
+ bytes: iterator.getSlice(nextSample.samplePosition.size),
11922
11937
  bigEndian,
11923
11938
  chunkSize
11924
11939
  });
11925
- if (samplesWithIndex.track.type === "audio") {
11940
+ if (track.type === "audio") {
11926
11941
  const audioSample = convertAudioOrVideoSampleToWebCodecsTimestamps({
11927
11942
  sample: {
11928
11943
  data: bytes,
@@ -11936,10 +11951,10 @@ var parseMdatSection = async (state) => {
11936
11951
  });
11937
11952
  await state.callbacks.onAudioSample({
11938
11953
  audioSample,
11939
- trackId: samplesWithIndex.track.trackId
11954
+ trackId: track.trackId
11940
11955
  });
11941
11956
  }
11942
- if (samplesWithIndex.track.type === "video") {
11957
+ if (track.type === "video") {
11943
11958
  const nalUnitType = bytes[4] & 31;
11944
11959
  let isRecoveryPoint = false;
11945
11960
  if (nalUnitType === 6) {
@@ -11959,14 +11974,10 @@ var parseMdatSection = async (state) => {
11959
11974
  });
11960
11975
  await state.callbacks.onVideoSample({
11961
11976
  videoSample,
11962
- trackId: samplesWithIndex.track.trackId
11977
+ trackId: track.trackId
11963
11978
  });
11964
11979
  }
11965
- const jump = jumpMarks.find((j) => j.afterSampleWithOffset === offset);
11966
- if (jump) {
11967
- Log.verbose(state.logLevel, "Found jump mark", jump.jumpToOffset, "skipping to jump mark");
11968
- return makeSkip(jump.jumpToOffset);
11969
- }
11980
+ state.iso.flatSamples.setCurrentSampleIndex(mediaSection.start, nextSample.trackId, nextSample.index + 1);
11970
11981
  return null;
11971
11982
  };
11972
11983
 
@@ -13416,10 +13427,7 @@ var innerParseMp3PacketHeader = (iterator) => {
13416
13427
  throw new Error("Expected Layer I, II or III");
13417
13428
  }
13418
13429
  const layer = layerBits === 3 ? 1 : layerBits === 2 ? 2 : 3;
13419
- const protectionBit = iterator.getBits(1);
13420
- if (protectionBit !== 1) {
13421
- throw new Error("Does not support CRC yet");
13422
- }
13430
+ iterator.getBits(1);
13423
13431
  const bitrateIndex = iterator.getBits(4);
13424
13432
  const bitrateInKbit = getBitrateKB({
13425
13433
  bits: bitrateIndex,
@@ -15523,7 +15531,7 @@ var parseWav = (state) => {
15523
15531
  if (type === "id3") {
15524
15532
  return parseId32({ state });
15525
15533
  }
15526
- if (type === "junk" || type === "fllr") {
15534
+ if (type === "junk" || type === "fllr" || type === "bext") {
15527
15535
  return parseJunk({ state });
15528
15536
  }
15529
15537
  if (type === "fact") {
@@ -16014,7 +16022,8 @@ var parseLoop = async ({
16014
16022
  fields: state.fields,
16015
16023
  src: state.src,
16016
16024
  discardReadBytes: state.discardReadBytes,
16017
- prefetchCache: state.prefetchCache
16025
+ prefetchCache: state.prefetchCache,
16026
+ isoState: state.iso
16018
16027
  });
16019
16028
  state.timings.timeSeeking += Date.now() - seekStart;
16020
16029
  }
@@ -18176,7 +18185,7 @@ var downloadAndParseMedia = async (options) => {
18176
18185
  return returnValue;
18177
18186
  };
18178
18187
  // src/version.ts
18179
- var VERSION = "4.0.332";
18188
+ var VERSION = "4.0.334";
18180
18189
 
18181
18190
  // src/index.ts
18182
18191
  var MediaParserInternals = {