@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
@@ -1331,6 +1331,17 @@ var getAvccBox = (trakBox) => {
1331
1331
  }
1332
1332
  return avccBox;
1333
1333
  };
1334
+ var getVpccBox = (trakBox) => {
1335
+ const videoConfig = getStsdVideoConfig(trakBox);
1336
+ if (!videoConfig) {
1337
+ return null;
1338
+ }
1339
+ const vpccBox = videoConfig.descriptors.find((c) => c.type === "vpcc-box");
1340
+ if (!vpccBox || vpccBox.type !== "vpcc-box") {
1341
+ return null;
1342
+ }
1343
+ return vpccBox;
1344
+ };
1334
1345
  var getAv1CBox = (trakBox) => {
1335
1346
  const videoConfig = getStsdVideoConfig(trakBox);
1336
1347
  if (!videoConfig) {
@@ -3156,21 +3167,25 @@ var getIsoBmColrConfig = (trakBox) => {
3156
3167
  var getVideoCodecString = (trakBox) => {
3157
3168
  const videoSample = getStsdVideoConfig(trakBox);
3158
3169
  const avccBox = getAvccBox(trakBox);
3159
- const hvccBox = getHvccBox(trakBox);
3160
- const av1cBox = getAv1CBox(trakBox);
3161
3170
  if (!videoSample) {
3162
3171
  return null;
3163
3172
  }
3164
3173
  if (avccBox) {
3165
3174
  return `${videoSample.format}.${avccBox.configurationString}`;
3166
3175
  }
3176
+ const hvccBox = getHvccBox(trakBox);
3167
3177
  if (hvccBox) {
3168
3178
  return `${videoSample.format}.${hvccBox.configurationString}`;
3169
3179
  }
3180
+ const av1cBox = getAv1CBox(trakBox);
3170
3181
  if (av1cBox) {
3171
3182
  const colrAtom = getColrBox(videoSample);
3172
3183
  return parseAv1PrivateData(av1cBox.privateData, colrAtom);
3173
3184
  }
3185
+ const vpccBox = getVpccBox(trakBox);
3186
+ if (vpccBox) {
3187
+ return `${videoSample.format}.${vpccBox.codecString}`;
3188
+ }
3174
3189
  return videoSample.format;
3175
3190
  };
3176
3191
 
@@ -3390,6 +3405,9 @@ var getVideoCodecFromIsoTrak = (trakBox) => {
3390
3405
  if (videoSample.format === "av01") {
3391
3406
  return "av1";
3392
3407
  }
3408
+ if (videoSample.format === "vp09") {
3409
+ return "vp9";
3410
+ }
3393
3411
  if (videoSample.format === "ap4h") {
3394
3412
  return "prores";
3395
3413
  }
@@ -8016,7 +8034,8 @@ var performSeek = async ({
8016
8034
  src,
8017
8035
  discardReadBytes,
8018
8036
  fields,
8019
- prefetchCache
8037
+ prefetchCache,
8038
+ isoState
8020
8039
  }) => {
8021
8040
  const byteInMediaSection = isByteInMediaSection({
8022
8041
  position: seekTo,
@@ -8080,6 +8099,9 @@ var performSeek = async ({
8080
8099
  prefetchCache
8081
8100
  });
8082
8101
  }
8102
+ if (userInitiated) {
8103
+ isoState.flatSamples.updateAfterSeek(seekTo);
8104
+ }
8083
8105
  await controller._internals.checkForAbortAndPause();
8084
8106
  };
8085
8107
 
@@ -8258,7 +8280,8 @@ var workOnSeekRequest = async (options) => {
8258
8280
  src,
8259
8281
  discardReadBytes,
8260
8282
  fields,
8261
- prefetchCache
8283
+ prefetchCache,
8284
+ isoState
8262
8285
  });
8263
8286
  return;
8264
8287
  }
@@ -8278,7 +8301,8 @@ var workOnSeekRequest = async (options) => {
8278
8301
  src,
8279
8302
  discardReadBytes,
8280
8303
  fields,
8281
- prefetchCache
8304
+ prefetchCache,
8305
+ isoState
8282
8306
  });
8283
8307
  const { hasChanged } = controller._internals.seekSignal.clearSeekIfStillSame(seek2);
8284
8308
  if (hasChanged) {
@@ -9388,9 +9412,10 @@ var parseFlac = ({
9388
9412
  };
9389
9413
 
9390
9414
  // src/state/iso-base-media/cached-sample-positions.ts
9391
- var calculateFlatSamples = ({
9415
+ var calculateSamplePositions = ({
9392
9416
  state,
9393
- mediaSectionStart
9417
+ mediaSectionStart,
9418
+ trackIds
9394
9419
  }) => {
9395
9420
  const tracks2 = getTracks(state, true);
9396
9421
  const moofBoxes = getMoofBoxes(state.structure.getIsoStructure().boxes);
@@ -9412,11 +9437,13 @@ var calculateFlatSamples = ({
9412
9437
  if (!moov) {
9413
9438
  throw new Error("No moov box found");
9414
9439
  }
9415
- const offsets = [];
9416
- const trackIds = [];
9417
- const map = new Map;
9440
+ const trackIdAndSamplePositions = [];
9418
9441
  for (const track of tracks2) {
9419
9442
  const trakBox = getTrakBoxByTrackId(moov, track.trackId);
9443
+ if (!trackIds.includes(track.trackId)) {
9444
+ Log.verbose(state.logLevel, "Skipping calculating sample positions for track", track.trackId);
9445
+ continue;
9446
+ }
9420
9447
  if (!trakBox) {
9421
9448
  throw new Error("No trak box found");
9422
9449
  }
@@ -9426,36 +9453,88 @@ var calculateFlatSamples = ({
9426
9453
  moofComplete,
9427
9454
  trexBoxes: getTrexBoxes(moov)
9428
9455
  });
9429
- trackIds.push(track.trackId);
9430
- for (const samplePosition of samplePositions) {
9431
- offsets.push(samplePosition.offset);
9432
- map.set(samplePosition.offset, {
9433
- track,
9434
- samplePosition
9435
- });
9456
+ trackIdAndSamplePositions.push({
9457
+ trackId: track.trackId,
9458
+ samplePositions
9459
+ });
9460
+ }
9461
+ return trackIdAndSamplePositions;
9462
+ };
9463
+ var updateSampleIndicesAfterSeek = ({
9464
+ samplePositionsForMdatStart,
9465
+ seekedByte
9466
+ }) => {
9467
+ const currentSampleIndices = {};
9468
+ const keys = Object.keys(samplePositionsForMdatStart).map(Number).sort();
9469
+ const mdat = keys.find((key) => seekedByte >= key);
9470
+ if (!mdat) {
9471
+ return currentSampleIndices;
9472
+ }
9473
+ const samplePositions = samplePositionsForMdatStart[mdat];
9474
+ if (!samplePositions) {
9475
+ return currentSampleIndices;
9476
+ }
9477
+ for (const track of samplePositions) {
9478
+ const currentSampleIndex = track.samplePositions.findIndex((sample) => sample.offset >= seekedByte);
9479
+ if (!currentSampleIndices[mdat]) {
9480
+ currentSampleIndices[mdat] = {};
9481
+ }
9482
+ if (!currentSampleIndices[mdat][track.trackId]) {
9483
+ currentSampleIndices[mdat][track.trackId] = 0;
9484
+ }
9485
+ if (currentSampleIndex === -1) {
9486
+ currentSampleIndices[mdat][track.trackId] = track.samplePositions.length;
9487
+ } else {
9488
+ currentSampleIndices[mdat][track.trackId] = currentSampleIndex;
9436
9489
  }
9437
9490
  }
9438
- offsets.sort((a, b) => a - b);
9439
- return { flatSamples: map, offsets, trackIds };
9491
+ return currentSampleIndices;
9440
9492
  };
9441
9493
  var cachedSamplePositionsState = () => {
9442
- const cachedForMdatStart = {};
9443
- const jumpMarksForMdatStart = {};
9494
+ const samplePositionsForMdatStart = {};
9495
+ let currentSampleIndex = {};
9444
9496
  return {
9445
9497
  getSamples: (mdatStart) => {
9446
- return cachedForMdatStart[mdatStart] ?? null;
9498
+ return samplePositionsForMdatStart[mdatStart] ?? null;
9447
9499
  },
9448
9500
  setSamples: (mdatStart, samples) => {
9449
- cachedForMdatStart[mdatStart] = samples;
9501
+ samplePositionsForMdatStart[mdatStart] = samples;
9450
9502
  },
9451
- setJumpMarks: (mdatStart, marks) => {
9452
- jumpMarksForMdatStart[mdatStart] = marks;
9503
+ setCurrentSampleIndex: (mdatStart, trackId, index) => {
9504
+ if (!currentSampleIndex[mdatStart]) {
9505
+ currentSampleIndex[mdatStart] = {};
9506
+ }
9507
+ if (!currentSampleIndex[mdatStart][trackId]) {
9508
+ currentSampleIndex[mdatStart][trackId] = 0;
9509
+ }
9510
+ currentSampleIndex[mdatStart][trackId] = index;
9453
9511
  },
9454
- getJumpMarks: (mdatStart) => {
9455
- return jumpMarksForMdatStart[mdatStart];
9512
+ getCurrentSampleIndices: (mdatStart) => {
9513
+ return currentSampleIndex[mdatStart] ?? {};
9514
+ },
9515
+ updateAfterSeek: (seekedByte) => {
9516
+ currentSampleIndex = updateSampleIndicesAfterSeek({
9517
+ samplePositionsForMdatStart,
9518
+ seekedByte
9519
+ });
9456
9520
  }
9457
9521
  };
9458
9522
  };
9523
+ var getSampleWithLowestDts = (samplePositions, currentSampleIndexMap) => {
9524
+ const lowestDts = [];
9525
+ for (const track of samplePositions) {
9526
+ const currentSampleIndex = currentSampleIndexMap[track.trackId] ?? 0;
9527
+ const currentSample = track.samplePositions[currentSampleIndex];
9528
+ if (currentSample && (lowestDts.length === 0 || currentSample.decodingTimestamp <= lowestDts[0].samplePosition.decodingTimestamp)) {
9529
+ lowestDts.push({
9530
+ samplePosition: currentSample,
9531
+ trackId: track.trackId,
9532
+ index: currentSampleIndex
9533
+ });
9534
+ }
9535
+ }
9536
+ return lowestDts;
9537
+ };
9459
9538
 
9460
9539
  // src/state/iso-base-media/last-moof-box.ts
9461
9540
  var getLastMoofBox = (boxes) => {
@@ -10654,7 +10733,9 @@ var videoTags = [
10654
10733
  "hvc1",
10655
10734
  "hev1",
10656
10735
  "ap4h",
10657
- "av01"
10736
+ "av01",
10737
+ "vp08",
10738
+ "vp09"
10658
10739
  ];
10659
10740
  var audioTags = [
10660
10741
  0,
@@ -11053,6 +11134,53 @@ var parseStts = ({
11053
11134
  };
11054
11135
  };
11055
11136
 
11137
+ // src/containers/iso-base-media/stsd/vpcc.ts
11138
+ var getvp09ConfigurationString = ({
11139
+ profile,
11140
+ level,
11141
+ bitDepth: bitDepth2
11142
+ }) => {
11143
+ return `${String(profile).padStart(2, "0")}.${String(level).padStart(2, "0")}.${String(bitDepth2).padStart(2, "0")}`;
11144
+ };
11145
+ var parseVpcc = ({
11146
+ data,
11147
+ size
11148
+ }) => {
11149
+ const box = data.startBox(size - 8);
11150
+ const confVersion = data.getUint8();
11151
+ if (confVersion !== 1) {
11152
+ throw new Error(`Unsupported AVCC version ${confVersion}`);
11153
+ }
11154
+ data.discard(3);
11155
+ const profile = data.getUint8();
11156
+ const level = data.getUint8();
11157
+ data.startReadingBits();
11158
+ const bitDepth2 = data.getBits(4);
11159
+ const chromaSubsampling = data.getBits(3);
11160
+ const videoFullRangeFlag = data.getBits(1);
11161
+ const videoColorPrimaries = data.getBits(8);
11162
+ const videoTransferCharacteristics = data.getBits(8);
11163
+ const videoMatrixCoefficients = data.getBits(8);
11164
+ data.stopReadingBits();
11165
+ const codecInitializationDataSize = data.getUint16();
11166
+ const codecInitializationData = data.getSlice(codecInitializationDataSize);
11167
+ box.expectNoMoreBytes();
11168
+ return {
11169
+ type: "vpcc-box",
11170
+ profile,
11171
+ level,
11172
+ bitDepth: bitDepth2,
11173
+ chromaSubsampling,
11174
+ videoFullRangeFlag,
11175
+ videoColorPrimaries,
11176
+ videoTransferCharacteristics,
11177
+ videoMatrixCoefficients,
11178
+ codecInitializationDataSize,
11179
+ codecInitializationData,
11180
+ codecString: getvp09ConfigurationString({ profile, level, bitDepth: bitDepth2 })
11181
+ };
11182
+ };
11183
+
11056
11184
  // src/containers/iso-base-media/tfdt.ts
11057
11185
  var parseTfdt = ({
11058
11186
  iterator,
@@ -11380,7 +11508,7 @@ var processBox = async ({
11380
11508
  if (boxType === "stsz") {
11381
11509
  return {
11382
11510
  type: "box",
11383
- box: await parseStsz({
11511
+ box: parseStsz({
11384
11512
  iterator,
11385
11513
  offset: fileOffset,
11386
11514
  size: boxSize
@@ -11390,7 +11518,7 @@ var processBox = async ({
11390
11518
  if (boxType === "stco" || boxType === "co64") {
11391
11519
  return {
11392
11520
  type: "box",
11393
- box: await parseStco({
11521
+ box: parseStco({
11394
11522
  iterator,
11395
11523
  offset: fileOffset,
11396
11524
  size: boxSize,
@@ -11401,7 +11529,7 @@ var processBox = async ({
11401
11529
  if (boxType === "pasp") {
11402
11530
  return {
11403
11531
  type: "box",
11404
- box: await parsePasp({
11532
+ box: parsePasp({
11405
11533
  iterator,
11406
11534
  offset: fileOffset,
11407
11535
  size: boxSize
@@ -11411,7 +11539,7 @@ var processBox = async ({
11411
11539
  if (boxType === "stss") {
11412
11540
  return {
11413
11541
  type: "box",
11414
- box: await parseStss({
11542
+ box: parseStss({
11415
11543
  iterator,
11416
11544
  offset: fileOffset,
11417
11545
  boxSize
@@ -11421,7 +11549,7 @@ var processBox = async ({
11421
11549
  if (boxType === "ctts") {
11422
11550
  return {
11423
11551
  type: "box",
11424
- box: await parseCtts({
11552
+ box: parseCtts({
11425
11553
  iterator,
11426
11554
  offset: fileOffset,
11427
11555
  size: boxSize
@@ -11431,7 +11559,7 @@ var processBox = async ({
11431
11559
  if (boxType === "stsc") {
11432
11560
  return {
11433
11561
  type: "box",
11434
- box: await parseStsc({
11562
+ box: parseStsc({
11435
11563
  iterator,
11436
11564
  offset: fileOffset,
11437
11565
  size: boxSize
@@ -11550,7 +11678,7 @@ var processBox = async ({
11550
11678
  if (boxType === "stts") {
11551
11679
  return {
11552
11680
  type: "box",
11553
- box: await parseStts({
11681
+ box: parseStts({
11554
11682
  data: iterator,
11555
11683
  size: boxSize,
11556
11684
  fileOffset
@@ -11560,16 +11688,22 @@ var processBox = async ({
11560
11688
  if (boxType === "avcC") {
11561
11689
  return {
11562
11690
  type: "box",
11563
- box: await parseAvcc({
11691
+ box: parseAvcc({
11564
11692
  data: iterator,
11565
11693
  size: boxSize
11566
11694
  })
11567
11695
  };
11568
11696
  }
11697
+ if (boxType === "vpcC") {
11698
+ return {
11699
+ type: "box",
11700
+ box: parseVpcc({ data: iterator, size: boxSize })
11701
+ };
11702
+ }
11569
11703
  if (boxType === "av1C") {
11570
11704
  return {
11571
11705
  type: "box",
11572
- box: await parseAv1C({
11706
+ box: parseAv1C({
11573
11707
  data: iterator,
11574
11708
  size: boxSize
11575
11709
  })
@@ -11578,7 +11712,7 @@ var processBox = async ({
11578
11712
  if (boxType === "hvcC") {
11579
11713
  return {
11580
11714
  type: "box",
11581
- box: await parseHvcc({
11715
+ box: parseHvcc({
11582
11716
  data: iterator,
11583
11717
  size: boxSize,
11584
11718
  offset: fileOffset
@@ -11588,7 +11722,7 @@ var processBox = async ({
11588
11722
  if (boxType === "tfhd") {
11589
11723
  return {
11590
11724
  type: "box",
11591
- box: await getTfhd({
11725
+ box: getTfhd({
11592
11726
  iterator,
11593
11727
  offset: fileOffset,
11594
11728
  size: boxSize
@@ -11598,7 +11732,7 @@ var processBox = async ({
11598
11732
  if (boxType === "mdhd") {
11599
11733
  return {
11600
11734
  type: "box",
11601
- box: await parseMdhd({
11735
+ box: parseMdhd({
11602
11736
  data: iterator,
11603
11737
  size: boxSize,
11604
11738
  fileOffset
@@ -11608,7 +11742,7 @@ var processBox = async ({
11608
11742
  if (boxType === "esds") {
11609
11743
  return {
11610
11744
  type: "box",
11611
- box: await parseEsds({
11745
+ box: parseEsds({
11612
11746
  data: iterator,
11613
11747
  size: boxSize,
11614
11748
  fileOffset
@@ -11618,7 +11752,7 @@ var processBox = async ({
11618
11752
  if (boxType === "trex") {
11619
11753
  return {
11620
11754
  type: "box",
11621
- box: await parseTrex({ iterator, offset: fileOffset, size: boxSize })
11755
+ box: parseTrex({ iterator, offset: fileOffset, size: boxSize })
11622
11756
  };
11623
11757
  }
11624
11758
  if (boxType === "moof") {
@@ -11757,127 +11891,6 @@ var getMoovAtom = async ({
11757
11891
  return moov;
11758
11892
  };
11759
11893
 
11760
- // src/containers/iso-base-media/mdat/calculate-jump-marks.ts
11761
- var MAX_SPREAD_IN_SECONDS = 8;
11762
- var getKey = (samplePositionTrack) => {
11763
- return `${samplePositionTrack.track.trackId}-${samplePositionTrack.samplePosition.decodingTimestamp}.${samplePositionTrack.samplePosition.offset}`;
11764
- };
11765
- var findBestJump = ({
11766
- sampleMap,
11767
- offsetsSorted,
11768
- visited,
11769
- progresses
11770
- }) => {
11771
- const minProgress = Math.min(...Object.values(progresses));
11772
- const trackNumberWithLowestProgress = Object.entries(progresses).find(([, progress]) => progress === minProgress)?.[0];
11773
- const firstSampleAboveMinProgress = offsetsSorted.findIndex((offset) => sampleMap.get(offset).track.trackId === Number(trackNumberWithLowestProgress) && !visited.has(getKey(sampleMap.get(offset))));
11774
- return firstSampleAboveMinProgress;
11775
- };
11776
- var calculateJumpMarks = ({
11777
- sampleMap,
11778
- offsetsSorted,
11779
- trackIds,
11780
- endOfMdat
11781
- }) => {
11782
- const progresses = {};
11783
- for (const trackId of trackIds) {
11784
- progresses[trackId] = 0;
11785
- }
11786
- const jumpMarks = [];
11787
- let indexToVisit = 0;
11788
- const visited = new Set;
11789
- let rollOverToProcess = false;
11790
- const increaseIndex = () => {
11791
- indexToVisit++;
11792
- if (indexToVisit >= offsetsSorted.length) {
11793
- rollOverToProcess = true;
11794
- indexToVisit = 0;
11795
- }
11796
- };
11797
- let lastVisitedSample = null;
11798
- const addJumpMark = ({
11799
- firstSampleAboveMinProgress
11800
- }) => {
11801
- if (!lastVisitedSample) {
11802
- throw new Error("no last visited sample");
11803
- }
11804
- const jumpMark = {
11805
- afterSampleWithOffset: lastVisitedSample.samplePosition.offset,
11806
- jumpToOffset: offsetsSorted[firstSampleAboveMinProgress]
11807
- };
11808
- indexToVisit = firstSampleAboveMinProgress;
11809
- jumpMarks.push(jumpMark);
11810
- };
11811
- const addFinalJumpIfNecessary = () => {
11812
- if (indexToVisit === offsetsSorted.length - 1) {
11813
- return;
11814
- }
11815
- jumpMarks.push({
11816
- afterSampleWithOffset: offsetsSorted[indexToVisit],
11817
- jumpToOffset: endOfMdat
11818
- });
11819
- };
11820
- const considerJump = () => {
11821
- const firstSampleAboveMinProgress = findBestJump({
11822
- sampleMap,
11823
- offsetsSorted,
11824
- visited,
11825
- progresses
11826
- });
11827
- if (firstSampleAboveMinProgress > -1 && firstSampleAboveMinProgress !== indexToVisit + 1) {
11828
- addJumpMark({ firstSampleAboveMinProgress });
11829
- indexToVisit = firstSampleAboveMinProgress;
11830
- } else {
11831
- while (true) {
11832
- increaseIndex();
11833
- if (!visited.has(getKey(sampleMap.get(offsetsSorted[indexToVisit])))) {
11834
- break;
11835
- }
11836
- }
11837
- }
11838
- };
11839
- while (true) {
11840
- const currentSamplePosition = sampleMap.get(offsetsSorted[indexToVisit]);
11841
- const sampleKey = getKey(currentSamplePosition);
11842
- if (visited.has(sampleKey)) {
11843
- considerJump();
11844
- continue;
11845
- }
11846
- visited.add(sampleKey);
11847
- if (rollOverToProcess) {
11848
- if (!lastVisitedSample) {
11849
- throw new Error("no last visited sample");
11850
- }
11851
- jumpMarks.push({
11852
- afterSampleWithOffset: lastVisitedSample.samplePosition.offset,
11853
- jumpToOffset: currentSamplePosition.samplePosition.offset
11854
- });
11855
- rollOverToProcess = false;
11856
- }
11857
- lastVisitedSample = currentSamplePosition;
11858
- if (visited.size === offsetsSorted.length) {
11859
- addFinalJumpIfNecessary();
11860
- break;
11861
- }
11862
- const timestamp = currentSamplePosition.samplePosition.decodingTimestamp / currentSamplePosition.track.originalTimescale;
11863
- progresses[currentSamplePosition.track.trackId] = timestamp;
11864
- const progressValues = Object.values(progresses);
11865
- const maxProgress = Math.max(...progressValues);
11866
- const minProgress = Math.min(...progressValues);
11867
- const spread = maxProgress - minProgress;
11868
- if (visited.size === offsetsSorted.length) {
11869
- addFinalJumpIfNecessary();
11870
- break;
11871
- }
11872
- if (spread > MAX_SPREAD_IN_SECONDS) {
11873
- considerJump();
11874
- } else {
11875
- increaseIndex();
11876
- }
11877
- }
11878
- return jumpMarks;
11879
- };
11880
-
11881
11894
  // src/containers/iso-base-media/mdat/postprocess-bytes.ts
11882
11895
  var postprocessBytes = ({
11883
11896
  bytes,
@@ -11938,52 +11951,53 @@ var parseMdatSection = async (state) => {
11938
11951
  endOfMdat,
11939
11952
  state
11940
11953
  });
11954
+ const tracksFromMoov = getTracksFromMoovBox(moov);
11941
11955
  state.iso.moov.setMoovBox({
11942
11956
  moovBox: moov,
11943
11957
  precomputed: false
11944
11958
  });
11959
+ const existingTracks = state.callbacks.tracks.getTracks();
11960
+ for (const trackFromMoov of tracksFromMoov) {
11961
+ if (existingTracks.find((t) => t.trackId === trackFromMoov.trackId)) {
11962
+ continue;
11963
+ }
11964
+ if (trackFromMoov.type === "other") {
11965
+ continue;
11966
+ }
11967
+ state.callbacks.tracks.addTrack(trackFromMoov);
11968
+ }
11945
11969
  state.callbacks.tracks.setIsDone(state.logLevel);
11946
11970
  state.structure.getIsoStructure().boxes.push(moov);
11947
11971
  return parseMdatSection(state);
11948
11972
  }
11973
+ const tracks2 = state.callbacks.tracks.getTracks();
11949
11974
  if (!state.iso.flatSamples.getSamples(mediaSection.start)) {
11950
- const {
11951
- flatSamples: flatSamplesMap,
11952
- offsets,
11953
- trackIds
11954
- } = calculateFlatSamples({
11975
+ const samplePosition = calculateSamplePositions({
11955
11976
  state,
11956
- mediaSectionStart: mediaSection.start
11977
+ mediaSectionStart: mediaSection.start,
11978
+ trackIds: tracks2.map((t) => t.trackId)
11957
11979
  });
11958
- const calcedJumpMarks = calculateJumpMarks({
11959
- sampleMap: flatSamplesMap,
11960
- offsetsSorted: offsets,
11961
- trackIds,
11962
- endOfMdat
11963
- });
11964
- state.iso.flatSamples.setJumpMarks(mediaSection.start, calcedJumpMarks);
11965
- state.iso.flatSamples.setSamples(mediaSection.start, flatSamplesMap);
11980
+ state.iso.flatSamples.setSamples(mediaSection.start, samplePosition);
11966
11981
  }
11967
- const flatSamples = state.iso.flatSamples.getSamples(mediaSection.start);
11968
- const jumpMarks = state.iso.flatSamples.getJumpMarks(mediaSection.start);
11969
- const { iterator } = state;
11970
- const samplesWithIndex = flatSamples.get(iterator.counter.getOffset());
11971
- if (!samplesWithIndex) {
11972
- const offsets = Array.from(flatSamples.keys());
11973
- const nextSample_ = offsets.filter((s) => s > iterator.counter.getOffset()).sort((a, b) => a - b)[0];
11974
- if (nextSample_) {
11975
- iterator.discard(nextSample_ - iterator.counter.getOffset());
11976
- return null;
11977
- }
11978
- Log.verbose(state.logLevel, "Could not find sample at offset", iterator.counter.getOffset(), "skipping to end of mdat");
11982
+ const samplePositions = state.iso.flatSamples.getSamples(mediaSection.start);
11983
+ const sampleIndices = state.iso.flatSamples.getCurrentSampleIndices(mediaSection.start);
11984
+ const nextSampleArray = getSampleWithLowestDts(samplePositions, sampleIndices);
11985
+ if (nextSampleArray.length === 0) {
11986
+ Log.verbose(state.logLevel, "Iterated over all samples.", endOfMdat);
11979
11987
  return makeSkip(endOfMdat);
11980
11988
  }
11981
- if (samplesWithIndex.samplePosition.offset + samplesWithIndex.samplePosition.size > state.contentLength) {
11982
- Log.verbose(state.logLevel, "Sample is beyond the end of the file. Don't process it.", samplesWithIndex.samplePosition.offset + samplesWithIndex.samplePosition.size, endOfMdat);
11989
+ const exactMatch = nextSampleArray.find((s) => s.samplePosition.offset === state.iterator.counter.getOffset());
11990
+ const nextSample = exactMatch ?? nextSampleArray[0];
11991
+ if (nextSample.samplePosition.offset !== state.iterator.counter.getOffset()) {
11992
+ return makeSkip(nextSample.samplePosition.offset);
11993
+ }
11994
+ if (nextSample.samplePosition.offset + nextSample.samplePosition.size > state.contentLength) {
11995
+ Log.verbose(state.logLevel, "Sample is beyond the end of the file. Don't process it.", nextSample.samplePosition.offset + nextSample.samplePosition.size, endOfMdat);
11983
11996
  return makeSkip(endOfMdat);
11984
11997
  }
11985
- if (iterator.bytesRemaining() < samplesWithIndex.samplePosition.size) {
11986
- return makeFetchMoreData(samplesWithIndex.samplePosition.size - iterator.bytesRemaining());
11998
+ const { iterator } = state;
11999
+ if (iterator.bytesRemaining() < nextSample.samplePosition.size) {
12000
+ return makeFetchMoreData(nextSample.samplePosition.size - iterator.bytesRemaining());
11987
12001
  }
11988
12002
  const {
11989
12003
  timestamp: rawCts,
@@ -11993,21 +12007,22 @@ var parseMdatSection = async (state) => {
11993
12007
  offset,
11994
12008
  bigEndian,
11995
12009
  chunkSize
11996
- } = samplesWithIndex.samplePosition;
12010
+ } = nextSample.samplePosition;
12011
+ const track = tracks2.find((t) => t.trackId === nextSample.trackId);
11997
12012
  const {
11998
12013
  originalTimescale,
11999
12014
  startInSeconds,
12000
12015
  trackMediaTimeOffsetInTrackTimescale,
12001
12016
  timescale: trackTimescale
12002
- } = samplesWithIndex.track;
12017
+ } = track;
12003
12018
  const cts = rawCts + startInSeconds * originalTimescale - trackMediaTimeOffsetInTrackTimescale / trackTimescale * WEBCODECS_TIMESCALE;
12004
12019
  const dts = rawDts + startInSeconds * originalTimescale - trackMediaTimeOffsetInTrackTimescale / trackTimescale * WEBCODECS_TIMESCALE;
12005
12020
  const bytes = postprocessBytes({
12006
- bytes: iterator.getSlice(samplesWithIndex.samplePosition.size),
12021
+ bytes: iterator.getSlice(nextSample.samplePosition.size),
12007
12022
  bigEndian,
12008
12023
  chunkSize
12009
12024
  });
12010
- if (samplesWithIndex.track.type === "audio") {
12025
+ if (track.type === "audio") {
12011
12026
  const audioSample = convertAudioOrVideoSampleToWebCodecsTimestamps({
12012
12027
  sample: {
12013
12028
  data: bytes,
@@ -12021,10 +12036,10 @@ var parseMdatSection = async (state) => {
12021
12036
  });
12022
12037
  await state.callbacks.onAudioSample({
12023
12038
  audioSample,
12024
- trackId: samplesWithIndex.track.trackId
12039
+ trackId: track.trackId
12025
12040
  });
12026
12041
  }
12027
- if (samplesWithIndex.track.type === "video") {
12042
+ if (track.type === "video") {
12028
12043
  const nalUnitType = bytes[4] & 31;
12029
12044
  let isRecoveryPoint = false;
12030
12045
  if (nalUnitType === 6) {
@@ -12044,14 +12059,10 @@ var parseMdatSection = async (state) => {
12044
12059
  });
12045
12060
  await state.callbacks.onVideoSample({
12046
12061
  videoSample,
12047
- trackId: samplesWithIndex.track.trackId
12062
+ trackId: track.trackId
12048
12063
  });
12049
12064
  }
12050
- const jump = jumpMarks.find((j) => j.afterSampleWithOffset === offset);
12051
- if (jump) {
12052
- Log.verbose(state.logLevel, "Found jump mark", jump.jumpToOffset, "skipping to jump mark");
12053
- return makeSkip(jump.jumpToOffset);
12054
- }
12065
+ state.iso.flatSamples.setCurrentSampleIndex(mediaSection.start, nextSample.trackId, nextSample.index + 1);
12055
12066
  return null;
12056
12067
  };
12057
12068
 
@@ -13147,10 +13158,7 @@ var innerParseMp3PacketHeader = (iterator) => {
13147
13158
  throw new Error("Expected Layer I, II or III");
13148
13159
  }
13149
13160
  const layer = layerBits === 3 ? 1 : layerBits === 2 ? 2 : 3;
13150
- const protectionBit = iterator.getBits(1);
13151
- if (protectionBit !== 1) {
13152
- throw new Error("Does not support CRC yet");
13153
- }
13161
+ iterator.getBits(1);
13154
13162
  const bitrateIndex = iterator.getBits(4);
13155
13163
  const bitrateInKbit = getBitrateKB({
13156
13164
  bits: bitrateIndex,
@@ -15254,7 +15262,7 @@ var parseWav = (state) => {
15254
15262
  if (type === "id3") {
15255
15263
  return parseId32({ state });
15256
15264
  }
15257
- if (type === "junk" || type === "fllr") {
15265
+ if (type === "junk" || type === "fllr" || type === "bext") {
15258
15266
  return parseJunk({ state });
15259
15267
  }
15260
15268
  if (type === "fact") {
@@ -16142,7 +16150,8 @@ var parseLoop = async ({
16142
16150
  fields: state.fields,
16143
16151
  src: state.src,
16144
16152
  discardReadBytes: state.discardReadBytes,
16145
- prefetchCache: state.prefetchCache
16153
+ prefetchCache: state.prefetchCache,
16154
+ isoState: state.iso
16146
16155
  });
16147
16156
  state.timings.timeSeeking += Date.now() - seekStart;
16148
16157
  }