@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
@@ -1228,6 +1228,17 @@ var getAvccBox = (trakBox) => {
1228
1228
  }
1229
1229
  return avccBox;
1230
1230
  };
1231
+ var getVpccBox = (trakBox) => {
1232
+ const videoConfig = getStsdVideoConfig(trakBox);
1233
+ if (!videoConfig) {
1234
+ return null;
1235
+ }
1236
+ const vpccBox = videoConfig.descriptors.find((c) => c.type === "vpcc-box");
1237
+ if (!vpccBox || vpccBox.type !== "vpcc-box") {
1238
+ return null;
1239
+ }
1240
+ return vpccBox;
1241
+ };
1231
1242
  var getAv1CBox = (trakBox) => {
1232
1243
  const videoConfig = getStsdVideoConfig(trakBox);
1233
1244
  if (!videoConfig) {
@@ -3053,21 +3064,25 @@ var getIsoBmColrConfig = (trakBox) => {
3053
3064
  var getVideoCodecString = (trakBox) => {
3054
3065
  const videoSample = getStsdVideoConfig(trakBox);
3055
3066
  const avccBox = getAvccBox(trakBox);
3056
- const hvccBox = getHvccBox(trakBox);
3057
- const av1cBox = getAv1CBox(trakBox);
3058
3067
  if (!videoSample) {
3059
3068
  return null;
3060
3069
  }
3061
3070
  if (avccBox) {
3062
3071
  return `${videoSample.format}.${avccBox.configurationString}`;
3063
3072
  }
3073
+ const hvccBox = getHvccBox(trakBox);
3064
3074
  if (hvccBox) {
3065
3075
  return `${videoSample.format}.${hvccBox.configurationString}`;
3066
3076
  }
3077
+ const av1cBox = getAv1CBox(trakBox);
3067
3078
  if (av1cBox) {
3068
3079
  const colrAtom = getColrBox(videoSample);
3069
3080
  return parseAv1PrivateData(av1cBox.privateData, colrAtom);
3070
3081
  }
3082
+ const vpccBox = getVpccBox(trakBox);
3083
+ if (vpccBox) {
3084
+ return `${videoSample.format}.${vpccBox.codecString}`;
3085
+ }
3071
3086
  return videoSample.format;
3072
3087
  };
3073
3088
 
@@ -3287,6 +3302,9 @@ var getVideoCodecFromIsoTrak = (trakBox) => {
3287
3302
  if (videoSample.format === "av01") {
3288
3303
  return "av1";
3289
3304
  }
3305
+ if (videoSample.format === "vp09") {
3306
+ return "vp9";
3307
+ }
3290
3308
  if (videoSample.format === "ap4h") {
3291
3309
  return "prores";
3292
3310
  }
@@ -7913,7 +7931,8 @@ var performSeek = async ({
7913
7931
  src,
7914
7932
  discardReadBytes,
7915
7933
  fields,
7916
- prefetchCache
7934
+ prefetchCache,
7935
+ isoState
7917
7936
  }) => {
7918
7937
  const byteInMediaSection = isByteInMediaSection({
7919
7938
  position: seekTo,
@@ -7977,6 +7996,9 @@ var performSeek = async ({
7977
7996
  prefetchCache
7978
7997
  });
7979
7998
  }
7999
+ if (userInitiated) {
8000
+ isoState.flatSamples.updateAfterSeek(seekTo);
8001
+ }
7980
8002
  await controller._internals.checkForAbortAndPause();
7981
8003
  };
7982
8004
 
@@ -8155,7 +8177,8 @@ var workOnSeekRequest = async (options) => {
8155
8177
  src,
8156
8178
  discardReadBytes,
8157
8179
  fields,
8158
- prefetchCache
8180
+ prefetchCache,
8181
+ isoState
8159
8182
  });
8160
8183
  return;
8161
8184
  }
@@ -8175,7 +8198,8 @@ var workOnSeekRequest = async (options) => {
8175
8198
  src,
8176
8199
  discardReadBytes,
8177
8200
  fields,
8178
- prefetchCache
8201
+ prefetchCache,
8202
+ isoState
8179
8203
  });
8180
8204
  const { hasChanged } = controller._internals.seekSignal.clearSeekIfStillSame(seek2);
8181
8205
  if (hasChanged) {
@@ -9285,9 +9309,10 @@ var parseFlac = ({
9285
9309
  };
9286
9310
 
9287
9311
  // src/state/iso-base-media/cached-sample-positions.ts
9288
- var calculateFlatSamples = ({
9312
+ var calculateSamplePositions = ({
9289
9313
  state,
9290
- mediaSectionStart
9314
+ mediaSectionStart,
9315
+ trackIds
9291
9316
  }) => {
9292
9317
  const tracks2 = getTracks(state, true);
9293
9318
  const moofBoxes = getMoofBoxes(state.structure.getIsoStructure().boxes);
@@ -9309,11 +9334,13 @@ var calculateFlatSamples = ({
9309
9334
  if (!moov) {
9310
9335
  throw new Error("No moov box found");
9311
9336
  }
9312
- const offsets = [];
9313
- const trackIds = [];
9314
- const map = new Map;
9337
+ const trackIdAndSamplePositions = [];
9315
9338
  for (const track of tracks2) {
9316
9339
  const trakBox = getTrakBoxByTrackId(moov, track.trackId);
9340
+ if (!trackIds.includes(track.trackId)) {
9341
+ Log.verbose(state.logLevel, "Skipping calculating sample positions for track", track.trackId);
9342
+ continue;
9343
+ }
9317
9344
  if (!trakBox) {
9318
9345
  throw new Error("No trak box found");
9319
9346
  }
@@ -9323,36 +9350,88 @@ var calculateFlatSamples = ({
9323
9350
  moofComplete,
9324
9351
  trexBoxes: getTrexBoxes(moov)
9325
9352
  });
9326
- trackIds.push(track.trackId);
9327
- for (const samplePosition of samplePositions) {
9328
- offsets.push(samplePosition.offset);
9329
- map.set(samplePosition.offset, {
9330
- track,
9331
- samplePosition
9332
- });
9353
+ trackIdAndSamplePositions.push({
9354
+ trackId: track.trackId,
9355
+ samplePositions
9356
+ });
9357
+ }
9358
+ return trackIdAndSamplePositions;
9359
+ };
9360
+ var updateSampleIndicesAfterSeek = ({
9361
+ samplePositionsForMdatStart,
9362
+ seekedByte
9363
+ }) => {
9364
+ const currentSampleIndices = {};
9365
+ const keys = Object.keys(samplePositionsForMdatStart).map(Number).sort();
9366
+ const mdat = keys.find((key) => seekedByte >= key);
9367
+ if (!mdat) {
9368
+ return currentSampleIndices;
9369
+ }
9370
+ const samplePositions = samplePositionsForMdatStart[mdat];
9371
+ if (!samplePositions) {
9372
+ return currentSampleIndices;
9373
+ }
9374
+ for (const track of samplePositions) {
9375
+ const currentSampleIndex = track.samplePositions.findIndex((sample) => sample.offset >= seekedByte);
9376
+ if (!currentSampleIndices[mdat]) {
9377
+ currentSampleIndices[mdat] = {};
9378
+ }
9379
+ if (!currentSampleIndices[mdat][track.trackId]) {
9380
+ currentSampleIndices[mdat][track.trackId] = 0;
9381
+ }
9382
+ if (currentSampleIndex === -1) {
9383
+ currentSampleIndices[mdat][track.trackId] = track.samplePositions.length;
9384
+ } else {
9385
+ currentSampleIndices[mdat][track.trackId] = currentSampleIndex;
9333
9386
  }
9334
9387
  }
9335
- offsets.sort((a, b) => a - b);
9336
- return { flatSamples: map, offsets, trackIds };
9388
+ return currentSampleIndices;
9337
9389
  };
9338
9390
  var cachedSamplePositionsState = () => {
9339
- const cachedForMdatStart = {};
9340
- const jumpMarksForMdatStart = {};
9391
+ const samplePositionsForMdatStart = {};
9392
+ let currentSampleIndex = {};
9341
9393
  return {
9342
9394
  getSamples: (mdatStart) => {
9343
- return cachedForMdatStart[mdatStart] ?? null;
9395
+ return samplePositionsForMdatStart[mdatStart] ?? null;
9344
9396
  },
9345
9397
  setSamples: (mdatStart, samples) => {
9346
- cachedForMdatStart[mdatStart] = samples;
9398
+ samplePositionsForMdatStart[mdatStart] = samples;
9347
9399
  },
9348
- setJumpMarks: (mdatStart, marks) => {
9349
- jumpMarksForMdatStart[mdatStart] = marks;
9400
+ setCurrentSampleIndex: (mdatStart, trackId, index) => {
9401
+ if (!currentSampleIndex[mdatStart]) {
9402
+ currentSampleIndex[mdatStart] = {};
9403
+ }
9404
+ if (!currentSampleIndex[mdatStart][trackId]) {
9405
+ currentSampleIndex[mdatStart][trackId] = 0;
9406
+ }
9407
+ currentSampleIndex[mdatStart][trackId] = index;
9350
9408
  },
9351
- getJumpMarks: (mdatStart) => {
9352
- return jumpMarksForMdatStart[mdatStart];
9409
+ getCurrentSampleIndices: (mdatStart) => {
9410
+ return currentSampleIndex[mdatStart] ?? {};
9411
+ },
9412
+ updateAfterSeek: (seekedByte) => {
9413
+ currentSampleIndex = updateSampleIndicesAfterSeek({
9414
+ samplePositionsForMdatStart,
9415
+ seekedByte
9416
+ });
9353
9417
  }
9354
9418
  };
9355
9419
  };
9420
+ var getSampleWithLowestDts = (samplePositions, currentSampleIndexMap) => {
9421
+ const lowestDts = [];
9422
+ for (const track of samplePositions) {
9423
+ const currentSampleIndex = currentSampleIndexMap[track.trackId] ?? 0;
9424
+ const currentSample = track.samplePositions[currentSampleIndex];
9425
+ if (currentSample && (lowestDts.length === 0 || currentSample.decodingTimestamp <= lowestDts[0].samplePosition.decodingTimestamp)) {
9426
+ lowestDts.push({
9427
+ samplePosition: currentSample,
9428
+ trackId: track.trackId,
9429
+ index: currentSampleIndex
9430
+ });
9431
+ }
9432
+ }
9433
+ return lowestDts;
9434
+ };
9356
9435
 
9357
9436
  // src/state/iso-base-media/last-moof-box.ts
9358
9437
  var getLastMoofBox = (boxes) => {
@@ -10551,7 +10630,9 @@ var videoTags = [
10551
10630
  "hvc1",
10552
10631
  "hev1",
10553
10632
  "ap4h",
10554
- "av01"
10633
+ "av01",
10634
+ "vp08",
10635
+ "vp09"
10555
10636
  ];
10556
10637
  var audioTags = [
10557
10638
  0,
@@ -10950,6 +11031,53 @@ var parseStts = ({
10950
11031
  };
10951
11032
  };
10952
11033
 
11034
+ // src/containers/iso-base-media/stsd/vpcc.ts
11035
+ var getvp09ConfigurationString = ({
11036
+ profile,
11037
+ level,
11038
+ bitDepth: bitDepth2
11039
+ }) => {
11040
+ return `${String(profile).padStart(2, "0")}.${String(level).padStart(2, "0")}.${String(bitDepth2).padStart(2, "0")}`;
11041
+ };
11042
+ var parseVpcc = ({
11043
+ data,
11044
+ size
11045
+ }) => {
11046
+ const box = data.startBox(size - 8);
11047
+ const confVersion = data.getUint8();
11048
+ if (confVersion !== 1) {
11049
+ throw new Error(`Unsupported AVCC version ${confVersion}`);
11050
+ }
11051
+ data.discard(3);
11052
+ const profile = data.getUint8();
11053
+ const level = data.getUint8();
11054
+ data.startReadingBits();
11055
+ const bitDepth2 = data.getBits(4);
11056
+ const chromaSubsampling = data.getBits(3);
11057
+ const videoFullRangeFlag = data.getBits(1);
11058
+ const videoColorPrimaries = data.getBits(8);
11059
+ const videoTransferCharacteristics = data.getBits(8);
11060
+ const videoMatrixCoefficients = data.getBits(8);
11061
+ data.stopReadingBits();
11062
+ const codecInitializationDataSize = data.getUint16();
11063
+ const codecInitializationData = data.getSlice(codecInitializationDataSize);
11064
+ box.expectNoMoreBytes();
11065
+ return {
11066
+ type: "vpcc-box",
11067
+ profile,
11068
+ level,
11069
+ bitDepth: bitDepth2,
11070
+ chromaSubsampling,
11071
+ videoFullRangeFlag,
11072
+ videoColorPrimaries,
11073
+ videoTransferCharacteristics,
11074
+ videoMatrixCoefficients,
11075
+ codecInitializationDataSize,
11076
+ codecInitializationData,
11077
+ codecString: getvp09ConfigurationString({ profile, level, bitDepth: bitDepth2 })
11078
+ };
11079
+ };
11080
+
10953
11081
  // src/containers/iso-base-media/tfdt.ts
10954
11082
  var parseTfdt = ({
10955
11083
  iterator,
@@ -11277,7 +11405,7 @@ var processBox = async ({
11277
11405
  if (boxType === "stsz") {
11278
11406
  return {
11279
11407
  type: "box",
11280
- box: await parseStsz({
11408
+ box: parseStsz({
11281
11409
  iterator,
11282
11410
  offset: fileOffset,
11283
11411
  size: boxSize
@@ -11287,7 +11415,7 @@ var processBox = async ({
11287
11415
  if (boxType === "stco" || boxType === "co64") {
11288
11416
  return {
11289
11417
  type: "box",
11290
- box: await parseStco({
11418
+ box: parseStco({
11291
11419
  iterator,
11292
11420
  offset: fileOffset,
11293
11421
  size: boxSize,
@@ -11298,7 +11426,7 @@ var processBox = async ({
11298
11426
  if (boxType === "pasp") {
11299
11427
  return {
11300
11428
  type: "box",
11301
- box: await parsePasp({
11429
+ box: parsePasp({
11302
11430
  iterator,
11303
11431
  offset: fileOffset,
11304
11432
  size: boxSize
@@ -11308,7 +11436,7 @@ var processBox = async ({
11308
11436
  if (boxType === "stss") {
11309
11437
  return {
11310
11438
  type: "box",
11311
- box: await parseStss({
11439
+ box: parseStss({
11312
11440
  iterator,
11313
11441
  offset: fileOffset,
11314
11442
  boxSize
@@ -11318,7 +11446,7 @@ var processBox = async ({
11318
11446
  if (boxType === "ctts") {
11319
11447
  return {
11320
11448
  type: "box",
11321
- box: await parseCtts({
11449
+ box: parseCtts({
11322
11450
  iterator,
11323
11451
  offset: fileOffset,
11324
11452
  size: boxSize
@@ -11328,7 +11456,7 @@ var processBox = async ({
11328
11456
  if (boxType === "stsc") {
11329
11457
  return {
11330
11458
  type: "box",
11331
- box: await parseStsc({
11459
+ box: parseStsc({
11332
11460
  iterator,
11333
11461
  offset: fileOffset,
11334
11462
  size: boxSize
@@ -11447,7 +11575,7 @@ var processBox = async ({
11447
11575
  if (boxType === "stts") {
11448
11576
  return {
11449
11577
  type: "box",
11450
- box: await parseStts({
11578
+ box: parseStts({
11451
11579
  data: iterator,
11452
11580
  size: boxSize,
11453
11581
  fileOffset
@@ -11457,16 +11585,22 @@ var processBox = async ({
11457
11585
  if (boxType === "avcC") {
11458
11586
  return {
11459
11587
  type: "box",
11460
- box: await parseAvcc({
11588
+ box: parseAvcc({
11461
11589
  data: iterator,
11462
11590
  size: boxSize
11463
11591
  })
11464
11592
  };
11465
11593
  }
11594
+ if (boxType === "vpcC") {
11595
+ return {
11596
+ type: "box",
11597
+ box: parseVpcc({ data: iterator, size: boxSize })
11598
+ };
11599
+ }
11466
11600
  if (boxType === "av1C") {
11467
11601
  return {
11468
11602
  type: "box",
11469
- box: await parseAv1C({
11603
+ box: parseAv1C({
11470
11604
  data: iterator,
11471
11605
  size: boxSize
11472
11606
  })
@@ -11475,7 +11609,7 @@ var processBox = async ({
11475
11609
  if (boxType === "hvcC") {
11476
11610
  return {
11477
11611
  type: "box",
11478
- box: await parseHvcc({
11612
+ box: parseHvcc({
11479
11613
  data: iterator,
11480
11614
  size: boxSize,
11481
11615
  offset: fileOffset
@@ -11485,7 +11619,7 @@ var processBox = async ({
11485
11619
  if (boxType === "tfhd") {
11486
11620
  return {
11487
11621
  type: "box",
11488
- box: await getTfhd({
11622
+ box: getTfhd({
11489
11623
  iterator,
11490
11624
  offset: fileOffset,
11491
11625
  size: boxSize
@@ -11495,7 +11629,7 @@ var processBox = async ({
11495
11629
  if (boxType === "mdhd") {
11496
11630
  return {
11497
11631
  type: "box",
11498
- box: await parseMdhd({
11632
+ box: parseMdhd({
11499
11633
  data: iterator,
11500
11634
  size: boxSize,
11501
11635
  fileOffset
@@ -11505,7 +11639,7 @@ var processBox = async ({
11505
11639
  if (boxType === "esds") {
11506
11640
  return {
11507
11641
  type: "box",
11508
- box: await parseEsds({
11642
+ box: parseEsds({
11509
11643
  data: iterator,
11510
11644
  size: boxSize,
11511
11645
  fileOffset
@@ -11515,7 +11649,7 @@ var processBox = async ({
11515
11649
  if (boxType === "trex") {
11516
11650
  return {
11517
11651
  type: "box",
11518
- box: await parseTrex({ iterator, offset: fileOffset, size: boxSize })
11652
+ box: parseTrex({ iterator, offset: fileOffset, size: boxSize })
11519
11653
  };
11520
11654
  }
11521
11655
  if (boxType === "moof") {
@@ -11654,127 +11788,6 @@ var getMoovAtom = async ({
11654
11788
  return moov;
11655
11789
  };
11656
11790
 
11657
- // src/containers/iso-base-media/mdat/calculate-jump-marks.ts
11658
- var MAX_SPREAD_IN_SECONDS = 8;
11659
- var getKey = (samplePositionTrack) => {
11660
- return `${samplePositionTrack.track.trackId}-${samplePositionTrack.samplePosition.decodingTimestamp}.${samplePositionTrack.samplePosition.offset}`;
11661
- };
11662
- var findBestJump = ({
11663
- sampleMap,
11664
- offsetsSorted,
11665
- visited,
11666
- progresses
11667
- }) => {
11668
- const minProgress = Math.min(...Object.values(progresses));
11669
- const trackNumberWithLowestProgress = Object.entries(progresses).find(([, progress]) => progress === minProgress)?.[0];
11670
- const firstSampleAboveMinProgress = offsetsSorted.findIndex((offset) => sampleMap.get(offset).track.trackId === Number(trackNumberWithLowestProgress) && !visited.has(getKey(sampleMap.get(offset))));
11671
- return firstSampleAboveMinProgress;
11672
- };
11673
- var calculateJumpMarks = ({
11674
- sampleMap,
11675
- offsetsSorted,
11676
- trackIds,
11677
- endOfMdat
11678
- }) => {
11679
- const progresses = {};
11680
- for (const trackId of trackIds) {
11681
- progresses[trackId] = 0;
11682
- }
11683
- const jumpMarks = [];
11684
- let indexToVisit = 0;
11685
- const visited = new Set;
11686
- let rollOverToProcess = false;
11687
- const increaseIndex = () => {
11688
- indexToVisit++;
11689
- if (indexToVisit >= offsetsSorted.length) {
11690
- rollOverToProcess = true;
11691
- indexToVisit = 0;
11692
- }
11693
- };
11694
- let lastVisitedSample = null;
11695
- const addJumpMark = ({
11696
- firstSampleAboveMinProgress
11697
- }) => {
11698
- if (!lastVisitedSample) {
11699
- throw new Error("no last visited sample");
11700
- }
11701
- const jumpMark = {
11702
- afterSampleWithOffset: lastVisitedSample.samplePosition.offset,
11703
- jumpToOffset: offsetsSorted[firstSampleAboveMinProgress]
11704
- };
11705
- indexToVisit = firstSampleAboveMinProgress;
11706
- jumpMarks.push(jumpMark);
11707
- };
11708
- const addFinalJumpIfNecessary = () => {
11709
- if (indexToVisit === offsetsSorted.length - 1) {
11710
- return;
11711
- }
11712
- jumpMarks.push({
11713
- afterSampleWithOffset: offsetsSorted[indexToVisit],
11714
- jumpToOffset: endOfMdat
11715
- });
11716
- };
11717
- const considerJump = () => {
11718
- const firstSampleAboveMinProgress = findBestJump({
11719
- sampleMap,
11720
- offsetsSorted,
11721
- visited,
11722
- progresses
11723
- });
11724
- if (firstSampleAboveMinProgress > -1 && firstSampleAboveMinProgress !== indexToVisit + 1) {
11725
- addJumpMark({ firstSampleAboveMinProgress });
11726
- indexToVisit = firstSampleAboveMinProgress;
11727
- } else {
11728
- while (true) {
11729
- increaseIndex();
11730
- if (!visited.has(getKey(sampleMap.get(offsetsSorted[indexToVisit])))) {
11731
- break;
11732
- }
11733
- }
11734
- }
11735
- };
11736
- while (true) {
11737
- const currentSamplePosition = sampleMap.get(offsetsSorted[indexToVisit]);
11738
- const sampleKey = getKey(currentSamplePosition);
11739
- if (visited.has(sampleKey)) {
11740
- considerJump();
11741
- continue;
11742
- }
11743
- visited.add(sampleKey);
11744
- if (rollOverToProcess) {
11745
- if (!lastVisitedSample) {
11746
- throw new Error("no last visited sample");
11747
- }
11748
- jumpMarks.push({
11749
- afterSampleWithOffset: lastVisitedSample.samplePosition.offset,
11750
- jumpToOffset: currentSamplePosition.samplePosition.offset
11751
- });
11752
- rollOverToProcess = false;
11753
- }
11754
- lastVisitedSample = currentSamplePosition;
11755
- if (visited.size === offsetsSorted.length) {
11756
- addFinalJumpIfNecessary();
11757
- break;
11758
- }
11759
- const timestamp = currentSamplePosition.samplePosition.decodingTimestamp / currentSamplePosition.track.originalTimescale;
11760
- progresses[currentSamplePosition.track.trackId] = timestamp;
11761
- const progressValues = Object.values(progresses);
11762
- const maxProgress = Math.max(...progressValues);
11763
- const minProgress = Math.min(...progressValues);
11764
- const spread = maxProgress - minProgress;
11765
- if (visited.size === offsetsSorted.length) {
11766
- addFinalJumpIfNecessary();
11767
- break;
11768
- }
11769
- if (spread > MAX_SPREAD_IN_SECONDS) {
11770
- considerJump();
11771
- } else {
11772
- increaseIndex();
11773
- }
11774
- }
11775
- return jumpMarks;
11776
- };
11777
-
11778
11791
  // src/containers/iso-base-media/mdat/postprocess-bytes.ts
11779
11792
  var postprocessBytes = ({
11780
11793
  bytes,
@@ -11835,52 +11848,53 @@ var parseMdatSection = async (state) => {
11835
11848
  endOfMdat,
11836
11849
  state
11837
11850
  });
11851
+ const tracksFromMoov = getTracksFromMoovBox(moov);
11838
11852
  state.iso.moov.setMoovBox({
11839
11853
  moovBox: moov,
11840
11854
  precomputed: false
11841
11855
  });
11856
+ const existingTracks = state.callbacks.tracks.getTracks();
11857
+ for (const trackFromMoov of tracksFromMoov) {
11858
+ if (existingTracks.find((t) => t.trackId === trackFromMoov.trackId)) {
11859
+ continue;
11860
+ }
11861
+ if (trackFromMoov.type === "other") {
11862
+ continue;
11863
+ }
11864
+ state.callbacks.tracks.addTrack(trackFromMoov);
11865
+ }
11842
11866
  state.callbacks.tracks.setIsDone(state.logLevel);
11843
11867
  state.structure.getIsoStructure().boxes.push(moov);
11844
11868
  return parseMdatSection(state);
11845
11869
  }
11870
+ const tracks2 = state.callbacks.tracks.getTracks();
11846
11871
  if (!state.iso.flatSamples.getSamples(mediaSection.start)) {
11847
- const {
11848
- flatSamples: flatSamplesMap,
11849
- offsets,
11850
- trackIds
11851
- } = calculateFlatSamples({
11872
+ const samplePosition = calculateSamplePositions({
11852
11873
  state,
11853
- mediaSectionStart: mediaSection.start
11874
+ mediaSectionStart: mediaSection.start,
11875
+ trackIds: tracks2.map((t) => t.trackId)
11854
11876
  });
11855
- const calcedJumpMarks = calculateJumpMarks({
11856
- sampleMap: flatSamplesMap,
11857
- offsetsSorted: offsets,
11858
- trackIds,
11859
- endOfMdat
11860
- });
11861
- state.iso.flatSamples.setJumpMarks(mediaSection.start, calcedJumpMarks);
11862
- state.iso.flatSamples.setSamples(mediaSection.start, flatSamplesMap);
11877
+ state.iso.flatSamples.setSamples(mediaSection.start, samplePosition);
11863
11878
  }
11864
- const flatSamples = state.iso.flatSamples.getSamples(mediaSection.start);
11865
- const jumpMarks = state.iso.flatSamples.getJumpMarks(mediaSection.start);
11866
- const { iterator } = state;
11867
- const samplesWithIndex = flatSamples.get(iterator.counter.getOffset());
11868
- if (!samplesWithIndex) {
11869
- const offsets = Array.from(flatSamples.keys());
11870
- const nextSample_ = offsets.filter((s) => s > iterator.counter.getOffset()).sort((a, b) => a - b)[0];
11871
- if (nextSample_) {
11872
- iterator.discard(nextSample_ - iterator.counter.getOffset());
11873
- return null;
11874
- }
11875
- Log.verbose(state.logLevel, "Could not find sample at offset", iterator.counter.getOffset(), "skipping to end of mdat");
11879
+ const samplePositions = state.iso.flatSamples.getSamples(mediaSection.start);
11880
+ const sampleIndices = state.iso.flatSamples.getCurrentSampleIndices(mediaSection.start);
11881
+ const nextSampleArray = getSampleWithLowestDts(samplePositions, sampleIndices);
11882
+ if (nextSampleArray.length === 0) {
11883
+ Log.verbose(state.logLevel, "Iterated over all samples.", endOfMdat);
11876
11884
  return makeSkip(endOfMdat);
11877
11885
  }
11878
- if (samplesWithIndex.samplePosition.offset + samplesWithIndex.samplePosition.size > state.contentLength) {
11879
- Log.verbose(state.logLevel, "Sample is beyond the end of the file. Don't process it.", samplesWithIndex.samplePosition.offset + samplesWithIndex.samplePosition.size, endOfMdat);
11886
+ const exactMatch = nextSampleArray.find((s) => s.samplePosition.offset === state.iterator.counter.getOffset());
11887
+ const nextSample = exactMatch ?? nextSampleArray[0];
11888
+ if (nextSample.samplePosition.offset !== state.iterator.counter.getOffset()) {
11889
+ return makeSkip(nextSample.samplePosition.offset);
11890
+ }
11891
+ if (nextSample.samplePosition.offset + nextSample.samplePosition.size > state.contentLength) {
11892
+ Log.verbose(state.logLevel, "Sample is beyond the end of the file. Don't process it.", nextSample.samplePosition.offset + nextSample.samplePosition.size, endOfMdat);
11880
11893
  return makeSkip(endOfMdat);
11881
11894
  }
11882
- if (iterator.bytesRemaining() < samplesWithIndex.samplePosition.size) {
11883
- return makeFetchMoreData(samplesWithIndex.samplePosition.size - iterator.bytesRemaining());
11895
+ const { iterator } = state;
11896
+ if (iterator.bytesRemaining() < nextSample.samplePosition.size) {
11897
+ return makeFetchMoreData(nextSample.samplePosition.size - iterator.bytesRemaining());
11884
11898
  }
11885
11899
  const {
11886
11900
  timestamp: rawCts,
@@ -11890,21 +11904,22 @@ var parseMdatSection = async (state) => {
11890
11904
  offset,
11891
11905
  bigEndian,
11892
11906
  chunkSize
11893
- } = samplesWithIndex.samplePosition;
11907
+ } = nextSample.samplePosition;
11908
+ const track = tracks2.find((t) => t.trackId === nextSample.trackId);
11894
11909
  const {
11895
11910
  originalTimescale,
11896
11911
  startInSeconds,
11897
11912
  trackMediaTimeOffsetInTrackTimescale,
11898
11913
  timescale: trackTimescale
11899
- } = samplesWithIndex.track;
11914
+ } = track;
11900
11915
  const cts = rawCts + startInSeconds * originalTimescale - trackMediaTimeOffsetInTrackTimescale / trackTimescale * WEBCODECS_TIMESCALE;
11901
11916
  const dts = rawDts + startInSeconds * originalTimescale - trackMediaTimeOffsetInTrackTimescale / trackTimescale * WEBCODECS_TIMESCALE;
11902
11917
  const bytes = postprocessBytes({
11903
- bytes: iterator.getSlice(samplesWithIndex.samplePosition.size),
11918
+ bytes: iterator.getSlice(nextSample.samplePosition.size),
11904
11919
  bigEndian,
11905
11920
  chunkSize
11906
11921
  });
11907
- if (samplesWithIndex.track.type === "audio") {
11922
+ if (track.type === "audio") {
11908
11923
  const audioSample = convertAudioOrVideoSampleToWebCodecsTimestamps({
11909
11924
  sample: {
11910
11925
  data: bytes,
@@ -11918,10 +11933,10 @@ var parseMdatSection = async (state) => {
11918
11933
  });
11919
11934
  await state.callbacks.onAudioSample({
11920
11935
  audioSample,
11921
- trackId: samplesWithIndex.track.trackId
11936
+ trackId: track.trackId
11922
11937
  });
11923
11938
  }
11924
- if (samplesWithIndex.track.type === "video") {
11939
+ if (track.type === "video") {
11925
11940
  const nalUnitType = bytes[4] & 31;
11926
11941
  let isRecoveryPoint = false;
11927
11942
  if (nalUnitType === 6) {
@@ -11941,14 +11956,10 @@ var parseMdatSection = async (state) => {
11941
11956
  });
11942
11957
  await state.callbacks.onVideoSample({
11943
11958
  videoSample,
11944
- trackId: samplesWithIndex.track.trackId
11959
+ trackId: track.trackId
11945
11960
  });
11946
11961
  }
11947
- const jump = jumpMarks.find((j) => j.afterSampleWithOffset === offset);
11948
- if (jump) {
11949
- Log.verbose(state.logLevel, "Found jump mark", jump.jumpToOffset, "skipping to jump mark");
11950
- return makeSkip(jump.jumpToOffset);
11951
- }
11962
+ state.iso.flatSamples.setCurrentSampleIndex(mediaSection.start, nextSample.trackId, nextSample.index + 1);
11952
11963
  return null;
11953
11964
  };
11954
11965
 
@@ -13016,10 +13027,7 @@ var innerParseMp3PacketHeader = (iterator) => {
13016
13027
  throw new Error("Expected Layer I, II or III");
13017
13028
  }
13018
13029
  const layer = layerBits === 3 ? 1 : layerBits === 2 ? 2 : 3;
13019
- const protectionBit = iterator.getBits(1);
13020
- if (protectionBit !== 1) {
13021
- throw new Error("Does not support CRC yet");
13022
- }
13030
+ iterator.getBits(1);
13023
13031
  const bitrateIndex = iterator.getBits(4);
13024
13032
  const bitrateInKbit = getBitrateKB({
13025
13033
  bits: bitrateIndex,
@@ -15123,7 +15131,7 @@ var parseWav = (state) => {
15123
15131
  if (type === "id3") {
15124
15132
  return parseId32({ state });
15125
15133
  }
15126
- if (type === "junk" || type === "fllr") {
15134
+ if (type === "junk" || type === "fllr" || type === "bext") {
15127
15135
  return parseJunk({ state });
15128
15136
  }
15129
15137
  if (type === "fact") {
@@ -16011,7 +16019,8 @@ var parseLoop = async ({
16011
16019
  fields: state.fields,
16012
16020
  src: state.src,
16013
16021
  discardReadBytes: state.discardReadBytes,
16014
- prefetchCache: state.prefetchCache
16022
+ prefetchCache: state.prefetchCache,
16023
+ isoState: state.iso
16015
16024
  });
16016
16025
  state.timings.timeSeeking += Date.now() - seekStart;
16017
16026
  }