@remotion/media-parser 4.0.327 → 4.0.330

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 (32) hide show
  1. package/dist/containers/aac/parse-aac.js +1 -0
  2. package/dist/containers/flac/parse-streaminfo.js +1 -0
  3. package/dist/containers/iso-base-media/make-track.js +12 -1
  4. package/dist/containers/iso-base-media/mdat/calculate-jump-marks.d.ts +6 -1
  5. package/dist/containers/iso-base-media/mdat/calculate-jump-marks.js +18 -21
  6. package/dist/containers/iso-base-media/mdat/get-editlist.d.ts +3 -0
  7. package/dist/containers/iso-base-media/mdat/get-editlist.js +18 -1
  8. package/dist/containers/iso-base-media/mdat/mdat.js +24 -13
  9. package/dist/containers/mp3/parse-mpeg-header.js +1 -0
  10. package/dist/containers/riff/get-tracks-from-avi.js +2 -0
  11. package/dist/containers/transport-stream/handle-aac-packet.js +1 -0
  12. package/dist/containers/transport-stream/handle-avc-packet.js +1 -0
  13. package/dist/containers/wav/parse-fmt.js +1 -0
  14. package/dist/containers/webm/make-track.js +2 -0
  15. package/dist/esm/index.mjs +121 -50
  16. package/dist/esm/worker-server-entry.mjs +141 -70
  17. package/dist/esm/worker-web-entry.mjs +141 -70
  18. package/dist/get-tracks.d.ts +3 -0
  19. package/dist/index.d.ts +3 -2
  20. package/dist/normalize-video-rotation.d.ts +1 -0
  21. package/dist/normalize-video-rotation.js +7 -0
  22. package/dist/parse-loop.js +2 -0
  23. package/dist/print-timings.js +1 -0
  24. package/dist/state/iso-base-media/cached-sample-positions.d.ts +6 -5
  25. package/dist/state/iso-base-media/cached-sample-positions.js +14 -7
  26. package/dist/state/iso-base-media/iso-state.d.ts +2 -2
  27. package/dist/state/parser-state.d.ts +3 -2
  28. package/dist/state/timings.d.ts +1 -0
  29. package/dist/state/timings.js +1 -0
  30. package/dist/version.d.ts +1 -1
  31. package/dist/version.js +1 -1
  32. package/package.json +4 -3
@@ -3071,6 +3071,11 @@ var getVideoCodecString = (trakBox) => {
3071
3071
  return videoSample.format;
3072
3072
  };
3073
3073
 
3074
+ // src/normalize-video-rotation.ts
3075
+ var normalizeVideoRotation = (rotation) => {
3076
+ return (rotation % 360 + 360) % 360;
3077
+ };
3078
+
3074
3079
  // src/webcodecs-timescale.ts
3075
3080
  var WEBCODECS_TIMESCALE = 1e6;
3076
3081
 
@@ -3311,6 +3316,45 @@ var getVideoCodecFromIsoTrak = (trakBox) => {
3311
3316
  throw new Error("Could not find video codec");
3312
3317
  };
3313
3318
 
3319
+ // src/containers/iso-base-media/mdat/get-editlist.ts
3320
+ var findTrackStartTimeInSeconds = ({
3321
+ movieTimeScale,
3322
+ trakBox
3323
+ }) => {
3324
+ const elstBox = getElstBox(trakBox);
3325
+ if (!elstBox) {
3326
+ return 0;
3327
+ }
3328
+ const { entries } = elstBox;
3329
+ let dwellTime = 0;
3330
+ for (const entry of entries) {
3331
+ const { editDuration, mediaTime } = entry;
3332
+ if (mediaTime !== -1) {
3333
+ continue;
3334
+ }
3335
+ dwellTime += editDuration;
3336
+ }
3337
+ return dwellTime / movieTimeScale;
3338
+ };
3339
+ var findTrackMediaTimeOffsetInTrackTimescale = ({
3340
+ trakBox
3341
+ }) => {
3342
+ const elstBox = getElstBox(trakBox);
3343
+ if (!elstBox) {
3344
+ return 0;
3345
+ }
3346
+ const { entries } = elstBox;
3347
+ let dwellTime = 0;
3348
+ for (const entry of entries) {
3349
+ const { mediaTime } = entry;
3350
+ if (mediaTime === -1) {
3351
+ continue;
3352
+ }
3353
+ dwellTime += mediaTime;
3354
+ }
3355
+ return dwellTime;
3356
+ };
3357
+
3314
3358
  // src/containers/iso-base-media/make-track.ts
3315
3359
  var makeBaseMediaTrack = (trakBox, startTimeInSeconds) => {
3316
3360
  const tkhdBox = getTkhdBox(trakBox);
@@ -3351,7 +3395,10 @@ var makeBaseMediaTrack = (trakBox, startTimeInSeconds) => {
3351
3395
  codecData: actual.codecPrivate,
3352
3396
  codecEnum,
3353
3397
  startInSeconds: startTimeInSeconds,
3354
- timescale: WEBCODECS_TIMESCALE
3398
+ timescale: WEBCODECS_TIMESCALE,
3399
+ trackMediaTimeOffsetInTrackTimescale: findTrackMediaTimeOffsetInTrackTimescale({
3400
+ trakBox
3401
+ })
3355
3402
  };
3356
3403
  }
3357
3404
  if (!trakBoxContainsVideo(trakBox)) {
@@ -3361,7 +3408,10 @@ var makeBaseMediaTrack = (trakBox, startTimeInSeconds) => {
3361
3408
  originalTimescale: timescaleAndDuration.timescale,
3362
3409
  trakBox,
3363
3410
  startInSeconds: startTimeInSeconds,
3364
- timescale: WEBCODECS_TIMESCALE
3411
+ timescale: WEBCODECS_TIMESCALE,
3412
+ trackMediaTimeOffsetInTrackTimescale: findTrackMediaTimeOffsetInTrackTimescale({
3413
+ trakBox
3414
+ })
3365
3415
  };
3366
3416
  }
3367
3417
  const videoSample = getStsdVideoConfig(trakBox);
@@ -3403,39 +3453,21 @@ var makeBaseMediaTrack = (trakBox, startTimeInSeconds) => {
3403
3453
  codedHeight: videoSample.height,
3404
3454
  displayAspectWidth,
3405
3455
  displayAspectHeight,
3406
- rotation,
3456
+ rotation: normalizeVideoRotation(0 - rotation),
3407
3457
  codecData: privateData,
3408
3458
  colorSpace: mediaParserAdvancedColorToWebCodecsColor(advancedColor),
3409
3459
  advancedColor,
3410
3460
  codecEnum: getVideoCodecFromIsoTrak(trakBox),
3411
3461
  fps: getFpsFromMp4TrakBox(trakBox),
3412
3462
  startInSeconds: startTimeInSeconds,
3413
- timescale: WEBCODECS_TIMESCALE
3463
+ timescale: WEBCODECS_TIMESCALE,
3464
+ trackMediaTimeOffsetInTrackTimescale: findTrackMediaTimeOffsetInTrackTimescale({
3465
+ trakBox
3466
+ })
3414
3467
  };
3415
3468
  return track;
3416
3469
  };
3417
3470
 
3418
- // src/containers/iso-base-media/mdat/get-editlist.ts
3419
- var findTrackStartTimeInSeconds = ({
3420
- movieTimeScale,
3421
- trakBox
3422
- }) => {
3423
- const elstBox = getElstBox(trakBox);
3424
- if (!elstBox) {
3425
- return 0;
3426
- }
3427
- const { entries } = elstBox;
3428
- let dwellTime = 0;
3429
- for (const entry of entries) {
3430
- const { editDuration, mediaTime } = entry;
3431
- if (mediaTime !== -1) {
3432
- continue;
3433
- }
3434
- dwellTime += editDuration;
3435
- }
3436
- return dwellTime / movieTimeScale;
3437
- };
3438
-
3439
3471
  // src/containers/avc/codec-string.ts
3440
3472
  var getCodecStringFromSpsAndPps = (sps) => {
3441
3473
  return `avc1.${sps.spsData.profile.toString(16).padStart(2, "0")}${sps.spsData.compatibility.toString(16).padStart(2, "0")}${sps.spsData.level.toString(16).padStart(2, "0")}`;
@@ -3536,7 +3568,8 @@ var makeAviAudioTrack = ({
3536
3568
  originalTimescale: MEDIA_PARSER_RIFF_TIMESCALE,
3537
3569
  trackId: index,
3538
3570
  startInSeconds: 0,
3539
- timescale: WEBCODECS_TIMESCALE
3571
+ timescale: WEBCODECS_TIMESCALE,
3572
+ trackMediaTimeOffsetInTrackTimescale: 0
3540
3573
  };
3541
3574
  };
3542
3575
  var makeAviVideoTrack = ({
@@ -3581,7 +3614,8 @@ var makeAviVideoTrack = ({
3581
3614
  },
3582
3615
  fps: strh.rate / strh.scale,
3583
3616
  startInSeconds: 0,
3584
- timescale: WEBCODECS_TIMESCALE
3617
+ timescale: WEBCODECS_TIMESCALE,
3618
+ trackMediaTimeOffsetInTrackTimescale: 0
3585
3619
  };
3586
3620
  };
3587
3621
  var getTracksFromAvi = (structure, state) => {
@@ -4248,7 +4282,8 @@ var getTrack = ({
4248
4282
  codecEnum,
4249
4283
  fps: null,
4250
4284
  startInSeconds: 0,
4251
- timescale: WEBCODECS_TIMESCALE
4285
+ timescale: WEBCODECS_TIMESCALE,
4286
+ trackMediaTimeOffsetInTrackTimescale: 0
4252
4287
  };
4253
4288
  }
4254
4289
  if (trackTypeToString(trackType2.value.value) === "audio") {
@@ -4272,7 +4307,8 @@ var getTrack = ({
4272
4307
  track
4273
4308
  }),
4274
4309
  startInSeconds: 0,
4275
- timescale: WEBCODECS_TIMESCALE
4310
+ timescale: WEBCODECS_TIMESCALE,
4311
+ trackMediaTimeOffsetInTrackTimescale: 0
4276
4312
  };
4277
4313
  }
4278
4314
  return null;
@@ -7110,7 +7146,8 @@ var handleAvcPacket = async ({
7110
7146
  colorSpace: mediaParserAdvancedColorToWebCodecsColor(advancedColor),
7111
7147
  advancedColor,
7112
7148
  startInSeconds: 0,
7113
- timescale: WEBCODECS_TIMESCALE
7149
+ timescale: WEBCODECS_TIMESCALE,
7150
+ trackMediaTimeOffsetInTrackTimescale: 0
7114
7151
  };
7115
7152
  await registerVideoTrack({
7116
7153
  track,
@@ -8762,7 +8799,8 @@ var parseAac = async (state) => {
8762
8799
  trackId: 0,
8763
8800
  type: "audio",
8764
8801
  startInSeconds: 0,
8765
- timescale: WEBCODECS_TIMESCALE
8802
+ timescale: WEBCODECS_TIMESCALE,
8803
+ trackMediaTimeOffsetInTrackTimescale: 0
8766
8804
  },
8767
8805
  registerAudioSampleCallback: state.callbacks.registerAudioSampleCallback,
8768
8806
  tracks: state.callbacks.tracks,
@@ -9169,7 +9207,8 @@ var parseStreamInfo = async ({
9169
9207
  originalTimescale: WEBCODECS_TIMESCALE,
9170
9208
  trackId: 0,
9171
9209
  startInSeconds: 0,
9172
- timescale: WEBCODECS_TIMESCALE
9210
+ timescale: WEBCODECS_TIMESCALE,
9211
+ trackMediaTimeOffsetInTrackTimescale: 0
9173
9212
  },
9174
9213
  registerAudioSampleCallback: state.callbacks.registerAudioSampleCallback,
9175
9214
  tracks: state.callbacks.tracks,
@@ -9270,7 +9309,10 @@ var calculateFlatSamples = ({
9270
9309
  if (!moov) {
9271
9310
  throw new Error("No moov box found");
9272
9311
  }
9273
- const flatSamples = tracks2.map((track) => {
9312
+ const offsets = [];
9313
+ const trackIds = [];
9314
+ const map = new Map;
9315
+ for (const track of tracks2) {
9274
9316
  const trakBox = getTrakBoxByTrackId(moov, track.trackId);
9275
9317
  if (!trakBox) {
9276
9318
  throw new Error("No trak box found");
@@ -9281,14 +9323,17 @@ var calculateFlatSamples = ({
9281
9323
  moofComplete,
9282
9324
  trexBoxes: getTrexBoxes(moov)
9283
9325
  });
9284
- return samplePositions.map((samplePosition) => {
9285
- return {
9326
+ trackIds.push(track.trackId);
9327
+ for (const samplePosition of samplePositions) {
9328
+ offsets.push(samplePosition.offset);
9329
+ map.set(samplePosition.offset, {
9286
9330
  track,
9287
9331
  samplePosition
9288
- };
9289
- });
9290
- });
9291
- return flatSamples;
9332
+ });
9333
+ }
9334
+ }
9335
+ offsets.sort((a, b) => a - b);
9336
+ return { flatSamples: map, offsets, trackIds };
9292
9337
  };
9293
9338
  var cachedSamplePositionsState = () => {
9294
9339
  const cachedForMdatStart = {};
@@ -11612,31 +11657,36 @@ var getMoovAtom = async ({
11612
11657
  // src/containers/iso-base-media/mdat/calculate-jump-marks.ts
11613
11658
  var MAX_SPREAD_IN_SECONDS = 8;
11614
11659
  var getKey = (samplePositionTrack) => {
11615
- return `${samplePositionTrack.track.trackId}-${samplePositionTrack.samplePosition.decodingTimestamp}`;
11660
+ return `${samplePositionTrack.track.trackId}-${samplePositionTrack.samplePosition.decodingTimestamp}.${samplePositionTrack.samplePosition.offset}`;
11616
11661
  };
11617
11662
  var findBestJump = ({
11618
- allSamplesSortedByOffset,
11663
+ sampleMap,
11664
+ offsetsSorted,
11619
11665
  visited,
11620
11666
  progresses
11621
11667
  }) => {
11622
11668
  const minProgress = Math.min(...Object.values(progresses));
11623
11669
  const trackNumberWithLowestProgress = Object.entries(progresses).find(([, progress]) => progress === minProgress)?.[0];
11624
- const firstSampleAboveMinProgress = allSamplesSortedByOffset.findIndex((sample) => sample.track.trackId === Number(trackNumberWithLowestProgress) && !visited.has(getKey(sample)));
11670
+ const firstSampleAboveMinProgress = offsetsSorted.findIndex((offset) => sampleMap.get(offset).track.trackId === Number(trackNumberWithLowestProgress) && !visited.has(getKey(sampleMap.get(offset))));
11625
11671
  return firstSampleAboveMinProgress;
11626
11672
  };
11627
- var calculateJumpMarks = (samplePositionTracks, endOfMdat) => {
11673
+ var calculateJumpMarks = ({
11674
+ sampleMap,
11675
+ offsetsSorted,
11676
+ trackIds,
11677
+ endOfMdat
11678
+ }) => {
11628
11679
  const progresses = {};
11629
- for (const track of samplePositionTracks) {
11630
- progresses[track[0].track.trackId] = 0;
11680
+ for (const trackId of trackIds) {
11681
+ progresses[trackId] = 0;
11631
11682
  }
11632
11683
  const jumpMarks = [];
11633
- const allSamplesSortedByOffset = samplePositionTracks.flat(1).filter((s) => s.track.type === "audio" || s.track.type === "video").sort((a, b) => a.samplePosition.offset - b.samplePosition.offset);
11634
11684
  let indexToVisit = 0;
11635
11685
  const visited = new Set;
11636
11686
  let rollOverToProcess = false;
11637
11687
  const increaseIndex = () => {
11638
11688
  indexToVisit++;
11639
- if (indexToVisit >= allSamplesSortedByOffset.length) {
11689
+ if (indexToVisit >= offsetsSorted.length) {
11640
11690
  rollOverToProcess = true;
11641
11691
  indexToVisit = 0;
11642
11692
  }
@@ -11650,23 +11700,24 @@ var calculateJumpMarks = (samplePositionTracks, endOfMdat) => {
11650
11700
  }
11651
11701
  const jumpMark = {
11652
11702
  afterSampleWithOffset: lastVisitedSample.samplePosition.offset,
11653
- jumpToOffset: allSamplesSortedByOffset[firstSampleAboveMinProgress].samplePosition.offset
11703
+ jumpToOffset: offsetsSorted[firstSampleAboveMinProgress]
11654
11704
  };
11655
11705
  indexToVisit = firstSampleAboveMinProgress;
11656
11706
  jumpMarks.push(jumpMark);
11657
11707
  };
11658
11708
  const addFinalJumpIfNecessary = () => {
11659
- if (indexToVisit === allSamplesSortedByOffset.length - 1) {
11709
+ if (indexToVisit === offsetsSorted.length - 1) {
11660
11710
  return;
11661
11711
  }
11662
11712
  jumpMarks.push({
11663
- afterSampleWithOffset: allSamplesSortedByOffset[indexToVisit].samplePosition.offset,
11713
+ afterSampleWithOffset: offsetsSorted[indexToVisit],
11664
11714
  jumpToOffset: endOfMdat
11665
11715
  });
11666
11716
  };
11667
11717
  const considerJump = () => {
11668
11718
  const firstSampleAboveMinProgress = findBestJump({
11669
- allSamplesSortedByOffset,
11719
+ sampleMap,
11720
+ offsetsSorted,
11670
11721
  visited,
11671
11722
  progresses
11672
11723
  });
@@ -11676,14 +11727,14 @@ var calculateJumpMarks = (samplePositionTracks, endOfMdat) => {
11676
11727
  } else {
11677
11728
  while (true) {
11678
11729
  increaseIndex();
11679
- if (!visited.has(getKey(allSamplesSortedByOffset[indexToVisit]))) {
11730
+ if (!visited.has(getKey(sampleMap.get(offsetsSorted[indexToVisit])))) {
11680
11731
  break;
11681
11732
  }
11682
11733
  }
11683
11734
  }
11684
11735
  };
11685
11736
  while (true) {
11686
- const currentSamplePosition = allSamplesSortedByOffset[indexToVisit];
11737
+ const currentSamplePosition = sampleMap.get(offsetsSorted[indexToVisit]);
11687
11738
  const sampleKey = getKey(currentSamplePosition);
11688
11739
  if (visited.has(sampleKey)) {
11689
11740
  considerJump();
@@ -11701,7 +11752,7 @@ var calculateJumpMarks = (samplePositionTracks, endOfMdat) => {
11701
11752
  rollOverToProcess = false;
11702
11753
  }
11703
11754
  lastVisitedSample = currentSamplePosition;
11704
- if (visited.size === allSamplesSortedByOffset.length) {
11755
+ if (visited.size === offsetsSorted.length) {
11705
11756
  addFinalJumpIfNecessary();
11706
11757
  break;
11707
11758
  }
@@ -11711,7 +11762,7 @@ var calculateJumpMarks = (samplePositionTracks, endOfMdat) => {
11711
11762
  const maxProgress = Math.max(...progressValues);
11712
11763
  const minProgress = Math.min(...progressValues);
11713
11764
  const spread = maxProgress - minProgress;
11714
- if (visited.size === allSamplesSortedByOffset.length) {
11765
+ if (visited.size === offsetsSorted.length) {
11715
11766
  addFinalJumpIfNecessary();
11716
11767
  break;
11717
11768
  }
@@ -11793,24 +11844,32 @@ var parseMdatSection = async (state) => {
11793
11844
  return parseMdatSection(state);
11794
11845
  }
11795
11846
  if (!state.iso.flatSamples.getSamples(mediaSection.start)) {
11796
- const flattedSamples = calculateFlatSamples({
11847
+ const {
11848
+ flatSamples: flatSamplesMap,
11849
+ offsets,
11850
+ trackIds
11851
+ } = calculateFlatSamples({
11797
11852
  state,
11798
11853
  mediaSectionStart: mediaSection.start
11799
11854
  });
11800
- const calcedJumpMarks = calculateJumpMarks(flattedSamples, endOfMdat);
11855
+ const calcedJumpMarks = calculateJumpMarks({
11856
+ sampleMap: flatSamplesMap,
11857
+ offsetsSorted: offsets,
11858
+ trackIds,
11859
+ endOfMdat
11860
+ });
11801
11861
  state.iso.flatSamples.setJumpMarks(mediaSection.start, calcedJumpMarks);
11802
- state.iso.flatSamples.setSamples(mediaSection.start, flattedSamples.flat(1));
11862
+ state.iso.flatSamples.setSamples(mediaSection.start, flatSamplesMap);
11803
11863
  }
11804
11864
  const flatSamples = state.iso.flatSamples.getSamples(mediaSection.start);
11805
11865
  const jumpMarks = state.iso.flatSamples.getJumpMarks(mediaSection.start);
11806
11866
  const { iterator } = state;
11807
- const samplesWithIndex = flatSamples.find((sample) => {
11808
- return sample.samplePosition.offset === iterator.counter.getOffset();
11809
- });
11867
+ const samplesWithIndex = flatSamples.get(iterator.counter.getOffset());
11810
11868
  if (!samplesWithIndex) {
11811
- const nextSample_ = flatSamples.filter((s) => s.samplePosition.offset > iterator.counter.getOffset()).sort((a, b) => a.samplePosition.offset - b.samplePosition.offset)[0];
11869
+ const offsets = Array.from(flatSamples.keys());
11870
+ const nextSample_ = offsets.filter((s) => s > iterator.counter.getOffset()).sort((a, b) => a - b)[0];
11812
11871
  if (nextSample_) {
11813
- iterator.discard(nextSample_.samplePosition.offset - iterator.counter.getOffset());
11872
+ iterator.discard(nextSample_ - iterator.counter.getOffset());
11814
11873
  return null;
11815
11874
  }
11816
11875
  Log.verbose(state.logLevel, "Could not find sample at offset", iterator.counter.getOffset(), "skipping to end of mdat");
@@ -11832,9 +11891,14 @@ var parseMdatSection = async (state) => {
11832
11891
  bigEndian,
11833
11892
  chunkSize
11834
11893
  } = samplesWithIndex.samplePosition;
11835
- const { originalTimescale, startInSeconds } = samplesWithIndex.track;
11836
- const cts = rawCts + startInSeconds * originalTimescale;
11837
- const dts = rawDts + startInSeconds * originalTimescale;
11894
+ const {
11895
+ originalTimescale,
11896
+ startInSeconds,
11897
+ trackMediaTimeOffsetInTrackTimescale,
11898
+ timescale: trackTimescale
11899
+ } = samplesWithIndex.track;
11900
+ const cts = rawCts + startInSeconds * originalTimescale - trackMediaTimeOffsetInTrackTimescale / trackTimescale * WEBCODECS_TIMESCALE;
11901
+ const dts = rawDts + startInSeconds * originalTimescale - trackMediaTimeOffsetInTrackTimescale / trackTimescale * WEBCODECS_TIMESCALE;
11838
11902
  const bytes = postprocessBytes({
11839
11903
  bytes: iterator.getSlice(samplesWithIndex.samplePosition.size),
11840
11904
  bigEndian,
@@ -13184,7 +13248,8 @@ var parseMpegHeader = async ({
13184
13248
  originalTimescale: 1e6,
13185
13249
  trackId: 0,
13186
13250
  startInSeconds: 0,
13187
- timescale: WEBCODECS_TIMESCALE
13251
+ timescale: WEBCODECS_TIMESCALE,
13252
+ trackMediaTimeOffsetInTrackTimescale: 0
13188
13253
  },
13189
13254
  registerAudioSampleCallback: state.callbacks.registerAudioSampleCallback,
13190
13255
  tracks: state.callbacks.tracks,
@@ -14271,7 +14336,8 @@ var handleAacPacket = async ({
14271
14336
  numberOfChannels: channelConfiguration,
14272
14337
  sampleRate,
14273
14338
  startInSeconds: 0,
14274
- timescale: WEBCODECS_TIMESCALE
14339
+ timescale: WEBCODECS_TIMESCALE,
14340
+ trackMediaTimeOffsetInTrackTimescale: 0
14275
14341
  };
14276
14342
  await registerAudioTrack({
14277
14343
  track,
@@ -14904,7 +14970,8 @@ var parseFmt = async ({
14904
14970
  originalTimescale: 1e6,
14905
14971
  trackId: 0,
14906
14972
  startInSeconds: 0,
14907
- timescale: WEBCODECS_TIMESCALE
14973
+ timescale: WEBCODECS_TIMESCALE,
14974
+ trackMediaTimeOffsetInTrackTimescale: 0
14908
14975
  },
14909
14976
  container: "wav",
14910
14977
  registerAudioSampleCallback: state.callbacks.registerAudioSampleCallback,
@@ -15902,9 +15969,11 @@ var parseLoop = async ({
15902
15969
  try {
15903
15970
  await triggerInfoEmit(state);
15904
15971
  await state.controller._internals.checkForAbortAndPause();
15972
+ const parseLoopStart = Date.now();
15905
15973
  const result = await runParseIteration({
15906
15974
  state
15907
15975
  });
15976
+ state.timings.timeInParseLoop += Date.now() - parseLoopStart;
15908
15977
  if (result !== null && result.action === "fetch-more-data") {
15909
15978
  Log.verbose(state.logLevel, `Need to fetch ${result.bytesNeeded} more bytes before we can continue`);
15910
15979
  const startBytesRemaining = state.iterator.bytesRemaining();
@@ -15993,6 +16062,7 @@ var printTimings = (state) => {
15993
16062
  Log.verbose(state.logLevel, `Time seeking: ${state.timings.timeSeeking}ms`);
15994
16063
  Log.verbose(state.logLevel, `Time checking if done: ${state.timings.timeCheckingIfDone}ms`);
15995
16064
  Log.verbose(state.logLevel, `Time freeing data: ${state.timings.timeFreeingData}ms`);
16065
+ Log.verbose(state.logLevel, `Time in parse loop: ${state.timings.timeInParseLoop}ms`);
15996
16066
  };
15997
16067
 
15998
16068
  // src/remotion-license-acknowledge.ts
@@ -17597,7 +17667,8 @@ var timingsState = () => {
17597
17667
  timeReadingData: 0,
17598
17668
  timeSeeking: 0,
17599
17669
  timeCheckingIfDone: 0,
17600
- timeFreeingData: 0
17670
+ timeFreeingData: 0,
17671
+ timeInParseLoop: 0
17601
17672
  };
17602
17673
  };
17603
17674
 
@@ -40,6 +40,7 @@ export type MediaParserVideoTrack = {
40
40
  advancedColor: MediaParserAdvancedColor;
41
41
  m3uStreamFormat: 'ts' | 'mp4' | null;
42
42
  startInSeconds: number;
43
+ trackMediaTimeOffsetInTrackTimescale: number;
43
44
  };
44
45
  export type MediaParserAudioTrack = {
45
46
  codec: string;
@@ -53,6 +54,7 @@ export type MediaParserAudioTrack = {
53
54
  originalTimescale: number;
54
55
  codecData: MediaParserCodecData | null;
55
56
  startInSeconds: number;
57
+ trackMediaTimeOffsetInTrackTimescale: number;
56
58
  };
57
59
  export type MediaParserOtherTrack = {
58
60
  type: 'other';
@@ -61,6 +63,7 @@ export type MediaParserOtherTrack = {
61
63
  originalTimescale: number;
62
64
  trakBox: TrakBox | null;
63
65
  startInSeconds: number;
66
+ trackMediaTimeOffsetInTrackTimescale: number;
64
67
  };
65
68
  export type MediaParserTrack = MediaParserVideoTrack | MediaParserAudioTrack | MediaParserOtherTrack;
66
69
  export declare const getNumberOfTracks: (moovBox: MoovBox) => number;
package/dist/index.d.ts CHANGED
@@ -900,8 +900,8 @@ export declare const MediaParserInternals: {
900
900
  };
901
901
  iso: {
902
902
  flatSamples: {
903
- getSamples: (mdatStart: number) => import("./state/iso-base-media/cached-sample-positions").FlatSample[];
904
- setSamples: (mdatStart: number, samples: import("./state/iso-base-media/cached-sample-positions").FlatSample[]) => void;
903
+ getSamples: (mdatStart: number) => Map<number, import("./state/iso-base-media/cached-sample-positions").FlatSample> | null;
904
+ setSamples: (mdatStart: number, samples: Map<number, import("./state/iso-base-media/cached-sample-positions").FlatSample>) => void;
905
905
  setJumpMarks: (mdatStart: number, marks: import("./containers/iso-base-media/mdat/calculate-jump-marks").JumpMark[]) => void;
906
906
  getJumpMarks: (mdatStart: number) => import("./containers/iso-base-media/mdat/calculate-jump-marks").JumpMark[];
907
907
  };
@@ -1027,6 +1027,7 @@ export declare const MediaParserInternals: {
1027
1027
  timeSeeking: number;
1028
1028
  timeCheckingIfDone: number;
1029
1029
  timeFreeingData: number;
1030
+ timeInParseLoop: number;
1030
1031
  };
1031
1032
  callbacks: {
1032
1033
  registerVideoSampleCallback: (id: number, callback: import("./webcodec-sample-types").MediaParserOnVideoSample | null) => Promise<void>;
@@ -0,0 +1 @@
1
+ export declare const normalizeVideoRotation: (rotation: number) => number;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.normalizeVideoRotation = void 0;
4
+ const normalizeVideoRotation = (rotation) => {
5
+ return ((rotation % 360) + 360) % 360;
6
+ };
7
+ exports.normalizeVideoRotation = normalizeVideoRotation;
@@ -45,9 +45,11 @@ const parseLoop = async ({ state, throttledState, onError, }) => {
45
45
  try {
46
46
  await (0, emit_all_info_1.triggerInfoEmit)(state);
47
47
  await state.controller._internals.checkForAbortAndPause();
48
+ const parseLoopStart = Date.now();
48
49
  const result = await (0, run_parse_iteration_1.runParseIteration)({
49
50
  state,
50
51
  });
52
+ state.timings.timeInParseLoop += Date.now() - parseLoopStart;
51
53
  if (result !== null && result.action === 'fetch-more-data') {
52
54
  log_1.Log.verbose(state.logLevel, `Need to fetch ${result.bytesNeeded} more bytes before we can continue`);
53
55
  const startBytesRemaining = state.iterator.bytesRemaining();
@@ -8,5 +8,6 @@ const printTimings = (state) => {
8
8
  log_1.Log.verbose(state.logLevel, `Time seeking: ${state.timings.timeSeeking}ms`);
9
9
  log_1.Log.verbose(state.logLevel, `Time checking if done: ${state.timings.timeCheckingIfDone}ms`);
10
10
  log_1.Log.verbose(state.logLevel, `Time freeing data: ${state.timings.timeFreeingData}ms`);
11
+ log_1.Log.verbose(state.logLevel, `Time in parse loop: ${state.timings.timeInParseLoop}ms`);
11
12
  };
12
13
  exports.printTimings = printTimings;
@@ -21,12 +21,13 @@ export declare const calculateFlatSamples: ({ state, mediaSectionStart, }: {
21
21
  state: ParserState;
22
22
  mediaSectionStart: number;
23
23
  }) => {
24
- track: import("../../get-tracks").MediaParserTrack;
25
- samplePosition: SamplePosition;
26
- }[][];
24
+ flatSamples: Map<number, FlatSample>;
25
+ offsets: number[];
26
+ trackIds: number[];
27
+ };
27
28
  export declare const cachedSamplePositionsState: () => {
28
- getSamples: (mdatStart: number) => FlatSample[];
29
- setSamples: (mdatStart: number, samples: FlatSample[]) => void;
29
+ getSamples: (mdatStart: number) => Map<number, FlatSample> | null;
30
+ setSamples: (mdatStart: number, samples: Map<number, FlatSample>) => void;
30
31
  setJumpMarks: (mdatStart: number, marks: JumpMark[]) => void;
31
32
  getJumpMarks: (mdatStart: number) => JumpMark[];
32
33
  };
@@ -28,7 +28,10 @@ const calculateFlatSamples = ({ state, mediaSectionStart, }) => {
28
28
  if (!moov) {
29
29
  throw new Error('No moov box found');
30
30
  }
31
- const flatSamples = tracks.map((track) => {
31
+ const offsets = [];
32
+ const trackIds = [];
33
+ const map = new Map();
34
+ for (const track of tracks) {
32
35
  const trakBox = (0, traversal_1.getTrakBoxByTrackId)(moov, track.trackId);
33
36
  if (!trakBox) {
34
37
  throw new Error('No trak box found');
@@ -39,17 +42,21 @@ const calculateFlatSamples = ({ state, mediaSectionStart, }) => {
39
42
  moofComplete,
40
43
  trexBoxes: (0, traversal_1.getTrexBoxes)(moov),
41
44
  });
42
- return samplePositions.map((samplePosition) => {
43
- return {
45
+ trackIds.push(track.trackId);
46
+ for (const samplePosition of samplePositions) {
47
+ offsets.push(samplePosition.offset);
48
+ map.set(samplePosition.offset, {
44
49
  track,
45
50
  samplePosition,
46
- };
47
- });
48
- });
49
- return flatSamples;
51
+ });
52
+ }
53
+ }
54
+ offsets.sort((a, b) => a - b);
55
+ return { flatSamples: map, offsets, trackIds };
50
56
  };
51
57
  exports.calculateFlatSamples = calculateFlatSamples;
52
58
  const cachedSamplePositionsState = () => {
59
+ // offset -> flat sample
53
60
  const cachedForMdatStart = {};
54
61
  const jumpMarksForMdatStart = {};
55
62
  return {
@@ -12,8 +12,8 @@ export declare const isoBaseMediaState: ({ contentLength, controller, readerInte
12
12
  prefetchCache: PrefetchCache;
13
13
  }) => {
14
14
  flatSamples: {
15
- getSamples: (mdatStart: number) => import("./cached-sample-positions").FlatSample[];
16
- setSamples: (mdatStart: number, samples: import("./cached-sample-positions").FlatSample[]) => void;
15
+ getSamples: (mdatStart: number) => Map<number, import("./cached-sample-positions").FlatSample> | null;
16
+ setSamples: (mdatStart: number, samples: Map<number, import("./cached-sample-positions").FlatSample>) => void;
17
17
  setJumpMarks: (mdatStart: number, marks: import("../../containers/iso-base-media/mdat/calculate-jump-marks").JumpMark[]) => void;
18
18
  getJumpMarks: (mdatStart: number) => import("../../containers/iso-base-media/mdat/calculate-jump-marks").JumpMark[];
19
19
  };
@@ -164,8 +164,8 @@ export declare const makeParserState: ({ hasAudioTrackHandlers, hasVideoTrackHan
164
164
  };
165
165
  iso: {
166
166
  flatSamples: {
167
- getSamples: (mdatStart: number) => import("./iso-base-media/cached-sample-positions").FlatSample[];
168
- setSamples: (mdatStart: number, samples: import("./iso-base-media/cached-sample-positions").FlatSample[]) => void;
167
+ getSamples: (mdatStart: number) => Map<number, import("./iso-base-media/cached-sample-positions").FlatSample> | null;
168
+ setSamples: (mdatStart: number, samples: Map<number, import("./iso-base-media/cached-sample-positions").FlatSample>) => void;
169
169
  setJumpMarks: (mdatStart: number, marks: import("../containers/iso-base-media/mdat/calculate-jump-marks").JumpMark[]) => void;
170
170
  getJumpMarks: (mdatStart: number) => import("../containers/iso-base-media/mdat/calculate-jump-marks").JumpMark[];
171
171
  };
@@ -291,6 +291,7 @@ export declare const makeParserState: ({ hasAudioTrackHandlers, hasVideoTrackHan
291
291
  timeSeeking: number;
292
292
  timeCheckingIfDone: number;
293
293
  timeFreeingData: number;
294
+ timeInParseLoop: number;
294
295
  };
295
296
  callbacks: {
296
297
  registerVideoSampleCallback: (id: number, callback: import("../webcodec-sample-types").MediaParserOnVideoSample | null) => Promise<void>;
@@ -4,5 +4,6 @@ export declare const timingsState: () => {
4
4
  timeSeeking: number;
5
5
  timeCheckingIfDone: number;
6
6
  timeFreeingData: number;
7
+ timeInParseLoop: number;
7
8
  };
8
9
  export type TimingsState = ReturnType<typeof timingsState>;
@@ -8,6 +8,7 @@ const timingsState = () => {
8
8
  timeSeeking: 0,
9
9
  timeCheckingIfDone: 0,
10
10
  timeFreeingData: 0,
11
+ timeInParseLoop: 0,
11
12
  };
12
13
  };
13
14
  exports.timingsState = timingsState;
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const VERSION = "4.0.327";
1
+ export declare const VERSION = "4.0.330";
package/dist/version.js CHANGED
@@ -2,4 +2,4 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.VERSION = void 0;
4
4
  // Automatically generated on publish
5
- exports.VERSION = '4.0.327';
5
+ exports.VERSION = '4.0.330';
package/package.json CHANGED
@@ -3,15 +3,16 @@
3
3
  "url": "https://github.com/remotion-dev/remotion/tree/main/packages/media-parser"
4
4
  },
5
5
  "name": "@remotion/media-parser",
6
- "version": "4.0.327",
6
+ "version": "4.0.330",
7
7
  "main": "dist/index.js",
8
8
  "sideEffects": false,
9
9
  "devDependencies": {
10
10
  "@types/wicg-file-system-access": "2023.10.5",
11
11
  "eslint": "9.19.0",
12
+ "mediabunny": "1.3.0",
12
13
  "@types/bun": "1.2.8",
13
- "@remotion/example-videos": "4.0.327",
14
- "@remotion/eslint-config-internal": "4.0.327"
14
+ "@remotion/example-videos": "4.0.330",
15
+ "@remotion/eslint-config-internal": "4.0.330"
15
16
  },
16
17
  "publishConfig": {
17
18
  "access": "public"