@remotion/studio 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.
@@ -24335,6 +24335,17 @@ var getAvccBox = (trakBox) => {
24335
24335
  }
24336
24336
  return avccBox;
24337
24337
  };
24338
+ var getVpccBox = (trakBox) => {
24339
+ const videoConfig = getStsdVideoConfig(trakBox);
24340
+ if (!videoConfig) {
24341
+ return null;
24342
+ }
24343
+ const vpccBox = videoConfig.descriptors.find((c) => c.type === "vpcc-box");
24344
+ if (!vpccBox || vpccBox.type !== "vpcc-box") {
24345
+ return null;
24346
+ }
24347
+ return vpccBox;
24348
+ };
24338
24349
  var getAv1CBox = (trakBox) => {
24339
24350
  const videoConfig = getStsdVideoConfig(trakBox);
24340
24351
  if (!videoConfig) {
@@ -24490,21 +24501,25 @@ var getIsoBmColrConfig = (trakBox) => {
24490
24501
  var getVideoCodecString = (trakBox) => {
24491
24502
  const videoSample = getStsdVideoConfig(trakBox);
24492
24503
  const avccBox = getAvccBox(trakBox);
24493
- const hvccBox = getHvccBox(trakBox);
24494
- const av1cBox = getAv1CBox(trakBox);
24495
24504
  if (!videoSample) {
24496
24505
  return null;
24497
24506
  }
24498
24507
  if (avccBox) {
24499
24508
  return `${videoSample.format}.${avccBox.configurationString}`;
24500
24509
  }
24510
+ const hvccBox = getHvccBox(trakBox);
24501
24511
  if (hvccBox) {
24502
24512
  return `${videoSample.format}.${hvccBox.configurationString}`;
24503
24513
  }
24514
+ const av1cBox = getAv1CBox(trakBox);
24504
24515
  if (av1cBox) {
24505
24516
  const colrAtom = getColrBox(videoSample);
24506
24517
  return parseAv1PrivateData(av1cBox.privateData, colrAtom);
24507
24518
  }
24519
+ const vpccBox = getVpccBox(trakBox);
24520
+ if (vpccBox) {
24521
+ return `${videoSample.format}.${vpccBox.codecString}`;
24522
+ }
24508
24523
  return videoSample.format;
24509
24524
  };
24510
24525
  var normalizeVideoRotation = (rotation) => {
@@ -24554,6 +24569,9 @@ var getVideoCodecFromIsoTrak = (trakBox) => {
24554
24569
  if (videoSample.format === "av01") {
24555
24570
  return "av1";
24556
24571
  }
24572
+ if (videoSample.format === "vp09") {
24573
+ return "vp9";
24574
+ }
24557
24575
  if (videoSample.format === "ap4h") {
24558
24576
  return "prores";
24559
24577
  }
@@ -25486,6 +25504,51 @@ var parseStts = ({
25486
25504
  sampleDistribution: sampleDistributions
25487
25505
  };
25488
25506
  };
25507
+ var getvp09ConfigurationString = ({
25508
+ profile,
25509
+ level,
25510
+ bitDepth: bitDepth2
25511
+ }) => {
25512
+ return `${String(profile).padStart(2, "0")}.${String(level).padStart(2, "0")}.${String(bitDepth2).padStart(2, "0")}`;
25513
+ };
25514
+ var parseVpcc = ({
25515
+ data,
25516
+ size: size4
25517
+ }) => {
25518
+ const box2 = data.startBox(size4 - 8);
25519
+ const confVersion = data.getUint8();
25520
+ if (confVersion !== 1) {
25521
+ throw new Error(`Unsupported AVCC version ${confVersion}`);
25522
+ }
25523
+ data.discard(3);
25524
+ const profile = data.getUint8();
25525
+ const level = data.getUint8();
25526
+ data.startReadingBits();
25527
+ const bitDepth2 = data.getBits(4);
25528
+ const chromaSubsampling = data.getBits(3);
25529
+ const videoFullRangeFlag = data.getBits(1);
25530
+ const videoColorPrimaries = data.getBits(8);
25531
+ const videoTransferCharacteristics = data.getBits(8);
25532
+ const videoMatrixCoefficients = data.getBits(8);
25533
+ data.stopReadingBits();
25534
+ const codecInitializationDataSize = data.getUint16();
25535
+ const codecInitializationData = data.getSlice(codecInitializationDataSize);
25536
+ box2.expectNoMoreBytes();
25537
+ return {
25538
+ type: "vpcc-box",
25539
+ profile,
25540
+ level,
25541
+ bitDepth: bitDepth2,
25542
+ chromaSubsampling,
25543
+ videoFullRangeFlag,
25544
+ videoColorPrimaries,
25545
+ videoTransferCharacteristics,
25546
+ videoMatrixCoefficients,
25547
+ codecInitializationDataSize,
25548
+ codecInitializationData,
25549
+ codecString: getvp09ConfigurationString({ profile, level, bitDepth: bitDepth2 })
25550
+ };
25551
+ };
25489
25552
  var parseTfdt = ({
25490
25553
  iterator,
25491
25554
  size: size4,
@@ -25802,7 +25865,7 @@ var processBox = async ({
25802
25865
  if (boxType === "stsz") {
25803
25866
  return {
25804
25867
  type: "box",
25805
- box: await parseStsz({
25868
+ box: parseStsz({
25806
25869
  iterator,
25807
25870
  offset: fileOffset,
25808
25871
  size: boxSize
@@ -25812,7 +25875,7 @@ var processBox = async ({
25812
25875
  if (boxType === "stco" || boxType === "co64") {
25813
25876
  return {
25814
25877
  type: "box",
25815
- box: await parseStco({
25878
+ box: parseStco({
25816
25879
  iterator,
25817
25880
  offset: fileOffset,
25818
25881
  size: boxSize,
@@ -25823,7 +25886,7 @@ var processBox = async ({
25823
25886
  if (boxType === "pasp") {
25824
25887
  return {
25825
25888
  type: "box",
25826
- box: await parsePasp({
25889
+ box: parsePasp({
25827
25890
  iterator,
25828
25891
  offset: fileOffset,
25829
25892
  size: boxSize
@@ -25833,7 +25896,7 @@ var processBox = async ({
25833
25896
  if (boxType === "stss") {
25834
25897
  return {
25835
25898
  type: "box",
25836
- box: await parseStss({
25899
+ box: parseStss({
25837
25900
  iterator,
25838
25901
  offset: fileOffset,
25839
25902
  boxSize
@@ -25843,7 +25906,7 @@ var processBox = async ({
25843
25906
  if (boxType === "ctts") {
25844
25907
  return {
25845
25908
  type: "box",
25846
- box: await parseCtts({
25909
+ box: parseCtts({
25847
25910
  iterator,
25848
25911
  offset: fileOffset,
25849
25912
  size: boxSize
@@ -25853,7 +25916,7 @@ var processBox = async ({
25853
25916
  if (boxType === "stsc") {
25854
25917
  return {
25855
25918
  type: "box",
25856
- box: await parseStsc({
25919
+ box: parseStsc({
25857
25920
  iterator,
25858
25921
  offset: fileOffset,
25859
25922
  size: boxSize
@@ -25972,7 +26035,7 @@ var processBox = async ({
25972
26035
  if (boxType === "stts") {
25973
26036
  return {
25974
26037
  type: "box",
25975
- box: await parseStts({
26038
+ box: parseStts({
25976
26039
  data: iterator,
25977
26040
  size: boxSize,
25978
26041
  fileOffset
@@ -25982,16 +26045,22 @@ var processBox = async ({
25982
26045
  if (boxType === "avcC") {
25983
26046
  return {
25984
26047
  type: "box",
25985
- box: await parseAvcc({
26048
+ box: parseAvcc({
25986
26049
  data: iterator,
25987
26050
  size: boxSize
25988
26051
  })
25989
26052
  };
25990
26053
  }
26054
+ if (boxType === "vpcC") {
26055
+ return {
26056
+ type: "box",
26057
+ box: parseVpcc({ data: iterator, size: boxSize })
26058
+ };
26059
+ }
25991
26060
  if (boxType === "av1C") {
25992
26061
  return {
25993
26062
  type: "box",
25994
- box: await parseAv1C({
26063
+ box: parseAv1C({
25995
26064
  data: iterator,
25996
26065
  size: boxSize
25997
26066
  })
@@ -26000,7 +26069,7 @@ var processBox = async ({
26000
26069
  if (boxType === "hvcC") {
26001
26070
  return {
26002
26071
  type: "box",
26003
- box: await parseHvcc({
26072
+ box: parseHvcc({
26004
26073
  data: iterator,
26005
26074
  size: boxSize,
26006
26075
  offset: fileOffset
@@ -26010,7 +26079,7 @@ var processBox = async ({
26010
26079
  if (boxType === "tfhd") {
26011
26080
  return {
26012
26081
  type: "box",
26013
- box: await getTfhd({
26082
+ box: getTfhd({
26014
26083
  iterator,
26015
26084
  offset: fileOffset,
26016
26085
  size: boxSize
@@ -26020,7 +26089,7 @@ var processBox = async ({
26020
26089
  if (boxType === "mdhd") {
26021
26090
  return {
26022
26091
  type: "box",
26023
- box: await parseMdhd({
26092
+ box: parseMdhd({
26024
26093
  data: iterator,
26025
26094
  size: boxSize,
26026
26095
  fileOffset
@@ -26030,7 +26099,7 @@ var processBox = async ({
26030
26099
  if (boxType === "esds") {
26031
26100
  return {
26032
26101
  type: "box",
26033
- box: await parseEsds({
26102
+ box: parseEsds({
26034
26103
  data: iterator,
26035
26104
  size: boxSize,
26036
26105
  fileOffset
@@ -26040,7 +26109,7 @@ var processBox = async ({
26040
26109
  if (boxType === "trex") {
26041
26110
  return {
26042
26111
  type: "box",
26043
- box: await parseTrex({ iterator, offset: fileOffset, size: boxSize })
26112
+ box: parseTrex({ iterator, offset: fileOffset, size: boxSize })
26044
26113
  };
26045
26114
  }
26046
26115
  if (boxType === "moof") {
@@ -26135,7 +26204,9 @@ var videoTags = [
26135
26204
  "hvc1",
26136
26205
  "hev1",
26137
26206
  "ap4h",
26138
- "av01"
26207
+ "av01",
26208
+ "vp08",
26209
+ "vp09"
26139
26210
  ];
26140
26211
  var audioTags = [
26141
26212
  0,
@@ -30091,7 +30162,8 @@ var performSeek = async ({
30091
30162
  src,
30092
30163
  discardReadBytes,
30093
30164
  fields,
30094
- prefetchCache
30165
+ prefetchCache,
30166
+ isoState
30095
30167
  }) => {
30096
30168
  const byteInMediaSection = isByteInMediaSection({
30097
30169
  position: seekTo,
@@ -30155,6 +30227,9 @@ var performSeek = async ({
30155
30227
  prefetchCache
30156
30228
  });
30157
30229
  }
30230
+ if (userInitiated) {
30231
+ isoState.flatSamples.updateAfterSeek(seekTo);
30232
+ }
30158
30233
  await controller._internals.checkForAbortAndPause();
30159
30234
  };
30160
30235
  var turnSeekIntoByte = async ({
@@ -30331,7 +30406,8 @@ var workOnSeekRequest = async (options) => {
30331
30406
  src,
30332
30407
  discardReadBytes,
30333
30408
  fields,
30334
- prefetchCache
30409
+ prefetchCache,
30410
+ isoState
30335
30411
  });
30336
30412
  return;
30337
30413
  }
@@ -30351,7 +30427,8 @@ var workOnSeekRequest = async (options) => {
30351
30427
  src,
30352
30428
  discardReadBytes,
30353
30429
  fields,
30354
- prefetchCache
30430
+ prefetchCache,
30431
+ isoState
30355
30432
  });
30356
30433
  const { hasChanged } = controller._internals.seekSignal.clearSeekIfStillSame(seek2);
30357
30434
  if (hasChanged) {
@@ -31415,9 +31492,10 @@ var parseFlac = ({
31415
31492
  state
31416
31493
  });
31417
31494
  };
31418
- var calculateFlatSamples = ({
31495
+ var calculateSamplePositions = ({
31419
31496
  state,
31420
- mediaSectionStart
31497
+ mediaSectionStart,
31498
+ trackIds
31421
31499
  }) => {
31422
31500
  const tracks2 = getTracks(state, true);
31423
31501
  const moofBoxes = getMoofBoxes(state.structure.getIsoStructure().boxes);
@@ -31439,11 +31517,13 @@ var calculateFlatSamples = ({
31439
31517
  if (!moov) {
31440
31518
  throw new Error("No moov box found");
31441
31519
  }
31442
- const offsets = [];
31443
- const trackIds = [];
31444
- const map = new Map;
31520
+ const trackIdAndSamplePositions = [];
31445
31521
  for (const track of tracks2) {
31446
31522
  const trakBox = getTrakBoxByTrackId(moov, track.trackId);
31523
+ if (!trackIds.includes(track.trackId)) {
31524
+ Log.verbose(state.logLevel, "Skipping calculating sample positions for track", track.trackId);
31525
+ continue;
31526
+ }
31447
31527
  if (!trakBox) {
31448
31528
  throw new Error("No trak box found");
31449
31529
  }
@@ -31453,36 +31533,88 @@ var calculateFlatSamples = ({
31453
31533
  moofComplete,
31454
31534
  trexBoxes: getTrexBoxes(moov)
31455
31535
  });
31456
- trackIds.push(track.trackId);
31457
- for (const samplePosition of samplePositions) {
31458
- offsets.push(samplePosition.offset);
31459
- map.set(samplePosition.offset, {
31460
- track,
31461
- samplePosition
31462
- });
31536
+ trackIdAndSamplePositions.push({
31537
+ trackId: track.trackId,
31538
+ samplePositions
31539
+ });
31540
+ }
31541
+ return trackIdAndSamplePositions;
31542
+ };
31543
+ var updateSampleIndicesAfterSeek = ({
31544
+ samplePositionsForMdatStart,
31545
+ seekedByte
31546
+ }) => {
31547
+ const currentSampleIndices = {};
31548
+ const keys = Object.keys(samplePositionsForMdatStart).map(Number).sort();
31549
+ const mdat = keys.find((key4) => seekedByte >= key4);
31550
+ if (!mdat) {
31551
+ return currentSampleIndices;
31552
+ }
31553
+ const samplePositions = samplePositionsForMdatStart[mdat];
31554
+ if (!samplePositions) {
31555
+ return currentSampleIndices;
31556
+ }
31557
+ for (const track of samplePositions) {
31558
+ const currentSampleIndex = track.samplePositions.findIndex((sample) => sample.offset >= seekedByte);
31559
+ if (!currentSampleIndices[mdat]) {
31560
+ currentSampleIndices[mdat] = {};
31561
+ }
31562
+ if (!currentSampleIndices[mdat][track.trackId]) {
31563
+ currentSampleIndices[mdat][track.trackId] = 0;
31564
+ }
31565
+ if (currentSampleIndex === -1) {
31566
+ currentSampleIndices[mdat][track.trackId] = track.samplePositions.length;
31567
+ } else {
31568
+ currentSampleIndices[mdat][track.trackId] = currentSampleIndex;
31463
31569
  }
31464
31570
  }
31465
- offsets.sort((a, b) => a - b);
31466
- return { flatSamples: map, offsets, trackIds };
31571
+ return currentSampleIndices;
31467
31572
  };
31468
31573
  var cachedSamplePositionsState = () => {
31469
- const cachedForMdatStart = {};
31470
- const jumpMarksForMdatStart = {};
31574
+ const samplePositionsForMdatStart = {};
31575
+ let currentSampleIndex = {};
31471
31576
  return {
31472
31577
  getSamples: (mdatStart) => {
31473
- return cachedForMdatStart[mdatStart] ?? null;
31578
+ return samplePositionsForMdatStart[mdatStart] ?? null;
31474
31579
  },
31475
31580
  setSamples: (mdatStart, samples) => {
31476
- cachedForMdatStart[mdatStart] = samples;
31581
+ samplePositionsForMdatStart[mdatStart] = samples;
31477
31582
  },
31478
- setJumpMarks: (mdatStart, marks) => {
31479
- jumpMarksForMdatStart[mdatStart] = marks;
31583
+ setCurrentSampleIndex: (mdatStart, trackId, index) => {
31584
+ if (!currentSampleIndex[mdatStart]) {
31585
+ currentSampleIndex[mdatStart] = {};
31586
+ }
31587
+ if (!currentSampleIndex[mdatStart][trackId]) {
31588
+ currentSampleIndex[mdatStart][trackId] = 0;
31589
+ }
31590
+ currentSampleIndex[mdatStart][trackId] = index;
31480
31591
  },
31481
- getJumpMarks: (mdatStart) => {
31482
- return jumpMarksForMdatStart[mdatStart];
31592
+ getCurrentSampleIndices: (mdatStart) => {
31593
+ return currentSampleIndex[mdatStart] ?? {};
31594
+ },
31595
+ updateAfterSeek: (seekedByte) => {
31596
+ currentSampleIndex = updateSampleIndicesAfterSeek({
31597
+ samplePositionsForMdatStart,
31598
+ seekedByte
31599
+ });
31483
31600
  }
31484
31601
  };
31485
31602
  };
31603
+ var getSampleWithLowestDts = (samplePositions, currentSampleIndexMap) => {
31604
+ const lowestDts = [];
31605
+ for (const track of samplePositions) {
31606
+ const currentSampleIndex = currentSampleIndexMap[track.trackId] ?? 0;
31607
+ const currentSample = track.samplePositions[currentSampleIndex];
31608
+ if (currentSample && (lowestDts.length === 0 || currentSample.decodingTimestamp <= lowestDts[0].samplePosition.decodingTimestamp)) {
31609
+ lowestDts.push({
31610
+ samplePosition: currentSample,
31611
+ trackId: track.trackId,
31612
+ index: currentSampleIndex
31613
+ });
31614
+ }
31615
+ }
31616
+ return lowestDts;
31617
+ };
31486
31618
  var getLastMoofBox = (boxes) => {
31487
31619
  if (boxes) {
31488
31620
  const tfras = boxes.filter((b) => b.type === "tfra-box");
@@ -31752,125 +31884,6 @@ var getMoovAtom = async ({
31752
31884
  Log.verbose(state.logLevel, `Finished fetching moov atom in ${Date.now() - start}ms`);
31753
31885
  return moov;
31754
31886
  };
31755
- var MAX_SPREAD_IN_SECONDS = 8;
31756
- var getKey = (samplePositionTrack) => {
31757
- return `${samplePositionTrack.track.trackId}-${samplePositionTrack.samplePosition.decodingTimestamp}.${samplePositionTrack.samplePosition.offset}`;
31758
- };
31759
- var findBestJump = ({
31760
- sampleMap,
31761
- offsetsSorted,
31762
- visited,
31763
- progresses
31764
- }) => {
31765
- const minProgress = Math.min(...Object.values(progresses));
31766
- const trackNumberWithLowestProgress = Object.entries(progresses).find(([, progress]) => progress === minProgress)?.[0];
31767
- const firstSampleAboveMinProgress = offsetsSorted.findIndex((offset) => sampleMap.get(offset).track.trackId === Number(trackNumberWithLowestProgress) && !visited.has(getKey(sampleMap.get(offset))));
31768
- return firstSampleAboveMinProgress;
31769
- };
31770
- var calculateJumpMarks = ({
31771
- sampleMap,
31772
- offsetsSorted,
31773
- trackIds,
31774
- endOfMdat
31775
- }) => {
31776
- const progresses = {};
31777
- for (const trackId of trackIds) {
31778
- progresses[trackId] = 0;
31779
- }
31780
- const jumpMarks = [];
31781
- let indexToVisit = 0;
31782
- const visited = new Set;
31783
- let rollOverToProcess = false;
31784
- const increaseIndex = () => {
31785
- indexToVisit++;
31786
- if (indexToVisit >= offsetsSorted.length) {
31787
- rollOverToProcess = true;
31788
- indexToVisit = 0;
31789
- }
31790
- };
31791
- let lastVisitedSample = null;
31792
- const addJumpMark = ({
31793
- firstSampleAboveMinProgress
31794
- }) => {
31795
- if (!lastVisitedSample) {
31796
- throw new Error("no last visited sample");
31797
- }
31798
- const jumpMark = {
31799
- afterSampleWithOffset: lastVisitedSample.samplePosition.offset,
31800
- jumpToOffset: offsetsSorted[firstSampleAboveMinProgress]
31801
- };
31802
- indexToVisit = firstSampleAboveMinProgress;
31803
- jumpMarks.push(jumpMark);
31804
- };
31805
- const addFinalJumpIfNecessary = () => {
31806
- if (indexToVisit === offsetsSorted.length - 1) {
31807
- return;
31808
- }
31809
- jumpMarks.push({
31810
- afterSampleWithOffset: offsetsSorted[indexToVisit],
31811
- jumpToOffset: endOfMdat
31812
- });
31813
- };
31814
- const considerJump = () => {
31815
- const firstSampleAboveMinProgress = findBestJump({
31816
- sampleMap,
31817
- offsetsSorted,
31818
- visited,
31819
- progresses
31820
- });
31821
- if (firstSampleAboveMinProgress > -1 && firstSampleAboveMinProgress !== indexToVisit + 1) {
31822
- addJumpMark({ firstSampleAboveMinProgress });
31823
- indexToVisit = firstSampleAboveMinProgress;
31824
- } else {
31825
- while (true) {
31826
- increaseIndex();
31827
- if (!visited.has(getKey(sampleMap.get(offsetsSorted[indexToVisit])))) {
31828
- break;
31829
- }
31830
- }
31831
- }
31832
- };
31833
- while (true) {
31834
- const currentSamplePosition = sampleMap.get(offsetsSorted[indexToVisit]);
31835
- const sampleKey = getKey(currentSamplePosition);
31836
- if (visited.has(sampleKey)) {
31837
- considerJump();
31838
- continue;
31839
- }
31840
- visited.add(sampleKey);
31841
- if (rollOverToProcess) {
31842
- if (!lastVisitedSample) {
31843
- throw new Error("no last visited sample");
31844
- }
31845
- jumpMarks.push({
31846
- afterSampleWithOffset: lastVisitedSample.samplePosition.offset,
31847
- jumpToOffset: currentSamplePosition.samplePosition.offset
31848
- });
31849
- rollOverToProcess = false;
31850
- }
31851
- lastVisitedSample = currentSamplePosition;
31852
- if (visited.size === offsetsSorted.length) {
31853
- addFinalJumpIfNecessary();
31854
- break;
31855
- }
31856
- const timestamp = currentSamplePosition.samplePosition.decodingTimestamp / currentSamplePosition.track.originalTimescale;
31857
- progresses[currentSamplePosition.track.trackId] = timestamp;
31858
- const progressValues = Object.values(progresses);
31859
- const maxProgress = Math.max(...progressValues);
31860
- const minProgress = Math.min(...progressValues);
31861
- const spread = maxProgress - minProgress;
31862
- if (visited.size === offsetsSorted.length) {
31863
- addFinalJumpIfNecessary();
31864
- break;
31865
- }
31866
- if (spread > MAX_SPREAD_IN_SECONDS) {
31867
- considerJump();
31868
- } else {
31869
- increaseIndex();
31870
- }
31871
- }
31872
- return jumpMarks;
31873
- };
31874
31887
  var postprocessBytes = ({
31875
31888
  bytes,
31876
31889
  bigEndian,
@@ -31928,52 +31941,53 @@ var parseMdatSection = async (state) => {
31928
31941
  endOfMdat,
31929
31942
  state
31930
31943
  });
31944
+ const tracksFromMoov = getTracksFromMoovBox(moov);
31931
31945
  state.iso.moov.setMoovBox({
31932
31946
  moovBox: moov,
31933
31947
  precomputed: false
31934
31948
  });
31949
+ const existingTracks = state.callbacks.tracks.getTracks();
31950
+ for (const trackFromMoov of tracksFromMoov) {
31951
+ if (existingTracks.find((t) => t.trackId === trackFromMoov.trackId)) {
31952
+ continue;
31953
+ }
31954
+ if (trackFromMoov.type === "other") {
31955
+ continue;
31956
+ }
31957
+ state.callbacks.tracks.addTrack(trackFromMoov);
31958
+ }
31935
31959
  state.callbacks.tracks.setIsDone(state.logLevel);
31936
31960
  state.structure.getIsoStructure().boxes.push(moov);
31937
31961
  return parseMdatSection(state);
31938
31962
  }
31963
+ const tracks2 = state.callbacks.tracks.getTracks();
31939
31964
  if (!state.iso.flatSamples.getSamples(mediaSection.start)) {
31940
- const {
31941
- flatSamples: flatSamplesMap,
31942
- offsets,
31943
- trackIds
31944
- } = calculateFlatSamples({
31965
+ const samplePosition = calculateSamplePositions({
31945
31966
  state,
31946
- mediaSectionStart: mediaSection.start
31967
+ mediaSectionStart: mediaSection.start,
31968
+ trackIds: tracks2.map((t) => t.trackId)
31947
31969
  });
31948
- const calcedJumpMarks = calculateJumpMarks({
31949
- sampleMap: flatSamplesMap,
31950
- offsetsSorted: offsets,
31951
- trackIds,
31952
- endOfMdat
31953
- });
31954
- state.iso.flatSamples.setJumpMarks(mediaSection.start, calcedJumpMarks);
31955
- state.iso.flatSamples.setSamples(mediaSection.start, flatSamplesMap);
31970
+ state.iso.flatSamples.setSamples(mediaSection.start, samplePosition);
31956
31971
  }
31957
- const flatSamples = state.iso.flatSamples.getSamples(mediaSection.start);
31958
- const jumpMarks = state.iso.flatSamples.getJumpMarks(mediaSection.start);
31959
- const { iterator } = state;
31960
- const samplesWithIndex = flatSamples.get(iterator.counter.getOffset());
31961
- if (!samplesWithIndex) {
31962
- const offsets = Array.from(flatSamples.keys());
31963
- const nextSample_ = offsets.filter((s) => s > iterator.counter.getOffset()).sort((a, b) => a - b)[0];
31964
- if (nextSample_) {
31965
- iterator.discard(nextSample_ - iterator.counter.getOffset());
31966
- return null;
31967
- }
31968
- Log.verbose(state.logLevel, "Could not find sample at offset", iterator.counter.getOffset(), "skipping to end of mdat");
31972
+ const samplePositions = state.iso.flatSamples.getSamples(mediaSection.start);
31973
+ const sampleIndices = state.iso.flatSamples.getCurrentSampleIndices(mediaSection.start);
31974
+ const nextSampleArray = getSampleWithLowestDts(samplePositions, sampleIndices);
31975
+ if (nextSampleArray.length === 0) {
31976
+ Log.verbose(state.logLevel, "Iterated over all samples.", endOfMdat);
31969
31977
  return makeSkip(endOfMdat);
31970
31978
  }
31971
- if (samplesWithIndex.samplePosition.offset + samplesWithIndex.samplePosition.size > state.contentLength) {
31972
- Log.verbose(state.logLevel, "Sample is beyond the end of the file. Don't process it.", samplesWithIndex.samplePosition.offset + samplesWithIndex.samplePosition.size, endOfMdat);
31979
+ const exactMatch = nextSampleArray.find((s) => s.samplePosition.offset === state.iterator.counter.getOffset());
31980
+ const nextSample = exactMatch ?? nextSampleArray[0];
31981
+ if (nextSample.samplePosition.offset !== state.iterator.counter.getOffset()) {
31982
+ return makeSkip(nextSample.samplePosition.offset);
31983
+ }
31984
+ if (nextSample.samplePosition.offset + nextSample.samplePosition.size > state.contentLength) {
31985
+ Log.verbose(state.logLevel, "Sample is beyond the end of the file. Don't process it.", nextSample.samplePosition.offset + nextSample.samplePosition.size, endOfMdat);
31973
31986
  return makeSkip(endOfMdat);
31974
31987
  }
31975
- if (iterator.bytesRemaining() < samplesWithIndex.samplePosition.size) {
31976
- return makeFetchMoreData(samplesWithIndex.samplePosition.size - iterator.bytesRemaining());
31988
+ const { iterator } = state;
31989
+ if (iterator.bytesRemaining() < nextSample.samplePosition.size) {
31990
+ return makeFetchMoreData(nextSample.samplePosition.size - iterator.bytesRemaining());
31977
31991
  }
31978
31992
  const {
31979
31993
  timestamp: rawCts,
@@ -31983,21 +31997,22 @@ var parseMdatSection = async (state) => {
31983
31997
  offset,
31984
31998
  bigEndian,
31985
31999
  chunkSize
31986
- } = samplesWithIndex.samplePosition;
32000
+ } = nextSample.samplePosition;
32001
+ const track = tracks2.find((t) => t.trackId === nextSample.trackId);
31987
32002
  const {
31988
32003
  originalTimescale,
31989
32004
  startInSeconds,
31990
32005
  trackMediaTimeOffsetInTrackTimescale,
31991
32006
  timescale: trackTimescale
31992
- } = samplesWithIndex.track;
32007
+ } = track;
31993
32008
  const cts = rawCts + startInSeconds * originalTimescale - trackMediaTimeOffsetInTrackTimescale / trackTimescale * WEBCODECS_TIMESCALE;
31994
32009
  const dts = rawDts + startInSeconds * originalTimescale - trackMediaTimeOffsetInTrackTimescale / trackTimescale * WEBCODECS_TIMESCALE;
31995
32010
  const bytes = postprocessBytes({
31996
- bytes: iterator.getSlice(samplesWithIndex.samplePosition.size),
32011
+ bytes: iterator.getSlice(nextSample.samplePosition.size),
31997
32012
  bigEndian,
31998
32013
  chunkSize
31999
32014
  });
32000
- if (samplesWithIndex.track.type === "audio") {
32015
+ if (track.type === "audio") {
32001
32016
  const audioSample = convertAudioOrVideoSampleToWebCodecsTimestamps({
32002
32017
  sample: {
32003
32018
  data: bytes,
@@ -32011,10 +32026,10 @@ var parseMdatSection = async (state) => {
32011
32026
  });
32012
32027
  await state.callbacks.onAudioSample({
32013
32028
  audioSample,
32014
- trackId: samplesWithIndex.track.trackId
32029
+ trackId: track.trackId
32015
32030
  });
32016
32031
  }
32017
- if (samplesWithIndex.track.type === "video") {
32032
+ if (track.type === "video") {
32018
32033
  const nalUnitType = bytes[4] & 31;
32019
32034
  let isRecoveryPoint = false;
32020
32035
  if (nalUnitType === 6) {
@@ -32034,14 +32049,10 @@ var parseMdatSection = async (state) => {
32034
32049
  });
32035
32050
  await state.callbacks.onVideoSample({
32036
32051
  videoSample,
32037
- trackId: samplesWithIndex.track.trackId
32052
+ trackId: track.trackId
32038
32053
  });
32039
32054
  }
32040
- const jump = jumpMarks.find((j) => j.afterSampleWithOffset === offset);
32041
- if (jump) {
32042
- Log.verbose(state.logLevel, "Found jump mark", jump.jumpToOffset, "skipping to jump mark");
32043
- return makeSkip(jump.jumpToOffset);
32044
- }
32055
+ state.iso.flatSamples.setCurrentSampleIndex(mediaSection.start, nextSample.trackId, nextSample.index + 1);
32045
32056
  return null;
32046
32057
  };
32047
32058
  var parseIsoBaseMedia = async (state) => {
@@ -33442,10 +33453,7 @@ var innerParseMp3PacketHeader = (iterator) => {
33442
33453
  throw new Error("Expected Layer I, II or III");
33443
33454
  }
33444
33455
  const layer = layerBits === 3 ? 1 : layerBits === 2 ? 2 : 3;
33445
- const protectionBit = iterator.getBits(1);
33446
- if (protectionBit !== 1) {
33447
- throw new Error("Does not support CRC yet");
33448
- }
33456
+ iterator.getBits(1);
33449
33457
  const bitrateIndex = iterator.getBits(4);
33450
33458
  const bitrateInKbit = getBitrateKB({
33451
33459
  bits: bitrateIndex,
@@ -35459,7 +35467,7 @@ var parseWav = (state) => {
35459
35467
  if (type === "id3") {
35460
35468
  return parseId32({ state });
35461
35469
  }
35462
- if (type === "junk" || type === "fllr") {
35470
+ if (type === "junk" || type === "fllr" || type === "bext") {
35463
35471
  return parseJunk({ state });
35464
35472
  }
35465
35473
  if (type === "fact") {
@@ -35936,7 +35944,8 @@ var parseLoop = async ({
35936
35944
  fields: state.fields,
35937
35945
  src: state.src,
35938
35946
  discardReadBytes: state.discardReadBytes,
35939
- prefetchCache: state.prefetchCache
35947
+ prefetchCache: state.prefetchCache,
35948
+ isoState: state.iso
35940
35949
  });
35941
35950
  state.timings.timeSeeking += Date.now() - seekStart;
35942
35951
  }