@remotion/media-parser 4.0.326 → 4.0.329

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 +17 -20
  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 +120 -49
  16. package/dist/esm/worker-server-entry.mjs +140 -69
  17. package/dist/esm/worker-web-entry.mjs +140 -69
  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
@@ -2398,6 +2398,24 @@ var findTrackStartTimeInSeconds = ({
2398
2398
  }
2399
2399
  return dwellTime / movieTimeScale;
2400
2400
  };
2401
+ var findTrackMediaTimeOffsetInTrackTimescale = ({
2402
+ trakBox
2403
+ }) => {
2404
+ const elstBox = getElstBox(trakBox);
2405
+ if (!elstBox) {
2406
+ return 0;
2407
+ }
2408
+ const { entries } = elstBox;
2409
+ let dwellTime = 0;
2410
+ for (const entry of entries) {
2411
+ const { mediaTime } = entry;
2412
+ if (mediaTime === -1) {
2413
+ continue;
2414
+ }
2415
+ dwellTime += mediaTime;
2416
+ }
2417
+ return dwellTime;
2418
+ };
2401
2419
 
2402
2420
  // src/webcodecs-timescale.ts
2403
2421
  var WEBCODECS_TIMESCALE = 1e6;
@@ -2457,7 +2475,8 @@ var makeAviAudioTrack = ({
2457
2475
  originalTimescale: MEDIA_PARSER_RIFF_TIMESCALE,
2458
2476
  trackId: index,
2459
2477
  startInSeconds: 0,
2460
- timescale: WEBCODECS_TIMESCALE
2478
+ timescale: WEBCODECS_TIMESCALE,
2479
+ trackMediaTimeOffsetInTrackTimescale: 0
2461
2480
  };
2462
2481
  };
2463
2482
  var makeAviVideoTrack = ({
@@ -2502,7 +2521,8 @@ var makeAviVideoTrack = ({
2502
2521
  },
2503
2522
  fps: strh.rate / strh.scale,
2504
2523
  startInSeconds: 0,
2505
- timescale: WEBCODECS_TIMESCALE
2524
+ timescale: WEBCODECS_TIMESCALE,
2525
+ trackMediaTimeOffsetInTrackTimescale: 0
2506
2526
  };
2507
2527
  };
2508
2528
  var getTracksFromAvi = (structure, state) => {
@@ -3304,7 +3324,8 @@ var getTrack = ({
3304
3324
  codecEnum,
3305
3325
  fps: null,
3306
3326
  startInSeconds: 0,
3307
- timescale: WEBCODECS_TIMESCALE
3327
+ timescale: WEBCODECS_TIMESCALE,
3328
+ trackMediaTimeOffsetInTrackTimescale: 0
3308
3329
  };
3309
3330
  }
3310
3331
  if (trackTypeToString(trackType2.value.value) === "audio") {
@@ -3328,7 +3349,8 @@ var getTrack = ({
3328
3349
  track
3329
3350
  }),
3330
3351
  startInSeconds: 0,
3331
- timescale: WEBCODECS_TIMESCALE
3352
+ timescale: WEBCODECS_TIMESCALE,
3353
+ trackMediaTimeOffsetInTrackTimescale: 0
3332
3354
  };
3333
3355
  }
3334
3356
  return null;
@@ -4119,6 +4141,11 @@ var getVideoCodecString = (trakBox) => {
4119
4141
  return videoSample.format;
4120
4142
  };
4121
4143
 
4144
+ // src/normalize-video-rotation.ts
4145
+ var normalizeVideoRotation = (rotation) => {
4146
+ return (rotation % 360 + 360) % 360;
4147
+ };
4148
+
4122
4149
  // src/containers/iso-base-media/get-actual-number-of-channels.ts
4123
4150
  var getActualDecoderParameters = ({
4124
4151
  audioCodec,
@@ -4235,7 +4262,10 @@ var makeBaseMediaTrack = (trakBox, startTimeInSeconds) => {
4235
4262
  codecData: actual.codecPrivate,
4236
4263
  codecEnum,
4237
4264
  startInSeconds: startTimeInSeconds,
4238
- timescale: WEBCODECS_TIMESCALE
4265
+ timescale: WEBCODECS_TIMESCALE,
4266
+ trackMediaTimeOffsetInTrackTimescale: findTrackMediaTimeOffsetInTrackTimescale({
4267
+ trakBox
4268
+ })
4239
4269
  };
4240
4270
  }
4241
4271
  if (!trakBoxContainsVideo(trakBox)) {
@@ -4245,7 +4275,10 @@ var makeBaseMediaTrack = (trakBox, startTimeInSeconds) => {
4245
4275
  originalTimescale: timescaleAndDuration.timescale,
4246
4276
  trakBox,
4247
4277
  startInSeconds: startTimeInSeconds,
4248
- timescale: WEBCODECS_TIMESCALE
4278
+ timescale: WEBCODECS_TIMESCALE,
4279
+ trackMediaTimeOffsetInTrackTimescale: findTrackMediaTimeOffsetInTrackTimescale({
4280
+ trakBox
4281
+ })
4249
4282
  };
4250
4283
  }
4251
4284
  const videoSample = getStsdVideoConfig(trakBox);
@@ -4287,14 +4320,17 @@ var makeBaseMediaTrack = (trakBox, startTimeInSeconds) => {
4287
4320
  codedHeight: videoSample.height,
4288
4321
  displayAspectWidth,
4289
4322
  displayAspectHeight,
4290
- rotation,
4323
+ rotation: normalizeVideoRotation(0 - rotation),
4291
4324
  codecData: privateData,
4292
4325
  colorSpace: mediaParserAdvancedColorToWebCodecsColor(advancedColor),
4293
4326
  advancedColor,
4294
4327
  codecEnum: getVideoCodecFromIsoTrak(trakBox),
4295
4328
  fps: getFpsFromMp4TrakBox(trakBox),
4296
4329
  startInSeconds: startTimeInSeconds,
4297
- timescale: WEBCODECS_TIMESCALE
4330
+ timescale: WEBCODECS_TIMESCALE,
4331
+ trackMediaTimeOffsetInTrackTimescale: findTrackMediaTimeOffsetInTrackTimescale({
4332
+ trakBox
4333
+ })
4298
4334
  };
4299
4335
  return track;
4300
4336
  };
@@ -9159,7 +9195,8 @@ var handleAvcPacket = async ({
9159
9195
  colorSpace: mediaParserAdvancedColorToWebCodecsColor(advancedColor),
9160
9196
  advancedColor,
9161
9197
  startInSeconds: 0,
9162
- timescale: WEBCODECS_TIMESCALE
9198
+ timescale: WEBCODECS_TIMESCALE,
9199
+ trackMediaTimeOffsetInTrackTimescale: 0
9163
9200
  };
9164
9201
  await registerVideoTrack({
9165
9202
  track,
@@ -10811,7 +10848,8 @@ var parseAac = async (state) => {
10811
10848
  trackId: 0,
10812
10849
  type: "audio",
10813
10850
  startInSeconds: 0,
10814
- timescale: WEBCODECS_TIMESCALE
10851
+ timescale: WEBCODECS_TIMESCALE,
10852
+ trackMediaTimeOffsetInTrackTimescale: 0
10815
10853
  },
10816
10854
  registerAudioSampleCallback: state.callbacks.registerAudioSampleCallback,
10817
10855
  tracks: state.callbacks.tracks,
@@ -11208,7 +11246,8 @@ var parseStreamInfo = async ({
11208
11246
  originalTimescale: WEBCODECS_TIMESCALE,
11209
11247
  trackId: 0,
11210
11248
  startInSeconds: 0,
11211
- timescale: WEBCODECS_TIMESCALE
11249
+ timescale: WEBCODECS_TIMESCALE,
11250
+ trackMediaTimeOffsetInTrackTimescale: 0
11212
11251
  },
11213
11252
  registerAudioSampleCallback: state.callbacks.registerAudioSampleCallback,
11214
11253
  tracks: state.callbacks.tracks,
@@ -11309,7 +11348,10 @@ var calculateFlatSamples = ({
11309
11348
  if (!moov) {
11310
11349
  throw new Error("No moov box found");
11311
11350
  }
11312
- const flatSamples = tracks2.map((track) => {
11351
+ const offsets = [];
11352
+ const trackIds = [];
11353
+ const map = new Map;
11354
+ for (const track of tracks2) {
11313
11355
  const trakBox = getTrakBoxByTrackId(moov, track.trackId);
11314
11356
  if (!trakBox) {
11315
11357
  throw new Error("No trak box found");
@@ -11320,14 +11362,17 @@ var calculateFlatSamples = ({
11320
11362
  moofComplete,
11321
11363
  trexBoxes: getTrexBoxes(moov)
11322
11364
  });
11323
- return samplePositions.map((samplePosition) => {
11324
- return {
11365
+ trackIds.push(track.trackId);
11366
+ for (const samplePosition of samplePositions) {
11367
+ offsets.push(samplePosition.offset);
11368
+ map.set(samplePosition.offset, {
11325
11369
  track,
11326
11370
  samplePosition
11327
- };
11328
- });
11329
- });
11330
- return flatSamples;
11371
+ });
11372
+ }
11373
+ }
11374
+ offsets.sort((a, b) => a - b);
11375
+ return { flatSamples: map, offsets, trackIds };
11331
11376
  };
11332
11377
  var cachedSamplePositionsState = () => {
11333
11378
  const cachedForMdatStart = {};
@@ -11633,28 +11678,33 @@ var getKey = (samplePositionTrack) => {
11633
11678
  return `${samplePositionTrack.track.trackId}-${samplePositionTrack.samplePosition.decodingTimestamp}`;
11634
11679
  };
11635
11680
  var findBestJump = ({
11636
- allSamplesSortedByOffset,
11681
+ sampleMap,
11682
+ offsetsSorted,
11637
11683
  visited,
11638
11684
  progresses
11639
11685
  }) => {
11640
11686
  const minProgress = Math.min(...Object.values(progresses));
11641
11687
  const trackNumberWithLowestProgress = Object.entries(progresses).find(([, progress]) => progress === minProgress)?.[0];
11642
- const firstSampleAboveMinProgress = allSamplesSortedByOffset.findIndex((sample) => sample.track.trackId === Number(trackNumberWithLowestProgress) && !visited.has(getKey(sample)));
11688
+ const firstSampleAboveMinProgress = offsetsSorted.findIndex((offset) => sampleMap.get(offset).track.trackId === Number(trackNumberWithLowestProgress) && !visited.has(getKey(sampleMap.get(offset))));
11643
11689
  return firstSampleAboveMinProgress;
11644
11690
  };
11645
- var calculateJumpMarks = (samplePositionTracks, endOfMdat) => {
11691
+ var calculateJumpMarks = ({
11692
+ sampleMap,
11693
+ offsetsSorted,
11694
+ trackIds,
11695
+ endOfMdat
11696
+ }) => {
11646
11697
  const progresses = {};
11647
- for (const track of samplePositionTracks) {
11648
- progresses[track[0].track.trackId] = 0;
11698
+ for (const trackId of trackIds) {
11699
+ progresses[trackId] = 0;
11649
11700
  }
11650
11701
  const jumpMarks = [];
11651
- const allSamplesSortedByOffset = samplePositionTracks.flat(1).filter((s) => s.track.type === "audio" || s.track.type === "video").sort((a, b) => a.samplePosition.offset - b.samplePosition.offset);
11652
11702
  let indexToVisit = 0;
11653
11703
  const visited = new Set;
11654
11704
  let rollOverToProcess = false;
11655
11705
  const increaseIndex = () => {
11656
11706
  indexToVisit++;
11657
- if (indexToVisit >= allSamplesSortedByOffset.length) {
11707
+ if (indexToVisit >= offsetsSorted.length) {
11658
11708
  rollOverToProcess = true;
11659
11709
  indexToVisit = 0;
11660
11710
  }
@@ -11668,23 +11718,24 @@ var calculateJumpMarks = (samplePositionTracks, endOfMdat) => {
11668
11718
  }
11669
11719
  const jumpMark = {
11670
11720
  afterSampleWithOffset: lastVisitedSample.samplePosition.offset,
11671
- jumpToOffset: allSamplesSortedByOffset[firstSampleAboveMinProgress].samplePosition.offset
11721
+ jumpToOffset: offsetsSorted[firstSampleAboveMinProgress]
11672
11722
  };
11673
11723
  indexToVisit = firstSampleAboveMinProgress;
11674
11724
  jumpMarks.push(jumpMark);
11675
11725
  };
11676
11726
  const addFinalJumpIfNecessary = () => {
11677
- if (indexToVisit === allSamplesSortedByOffset.length - 1) {
11727
+ if (indexToVisit === offsetsSorted.length - 1) {
11678
11728
  return;
11679
11729
  }
11680
11730
  jumpMarks.push({
11681
- afterSampleWithOffset: allSamplesSortedByOffset[indexToVisit].samplePosition.offset,
11731
+ afterSampleWithOffset: offsetsSorted[indexToVisit],
11682
11732
  jumpToOffset: endOfMdat
11683
11733
  });
11684
11734
  };
11685
11735
  const considerJump = () => {
11686
11736
  const firstSampleAboveMinProgress = findBestJump({
11687
- allSamplesSortedByOffset,
11737
+ sampleMap,
11738
+ offsetsSorted,
11688
11739
  visited,
11689
11740
  progresses
11690
11741
  });
@@ -11694,14 +11745,14 @@ var calculateJumpMarks = (samplePositionTracks, endOfMdat) => {
11694
11745
  } else {
11695
11746
  while (true) {
11696
11747
  increaseIndex();
11697
- if (!visited.has(getKey(allSamplesSortedByOffset[indexToVisit]))) {
11748
+ if (!visited.has(getKey(sampleMap.get(offsetsSorted[indexToVisit])))) {
11698
11749
  break;
11699
11750
  }
11700
11751
  }
11701
11752
  }
11702
11753
  };
11703
11754
  while (true) {
11704
- const currentSamplePosition = allSamplesSortedByOffset[indexToVisit];
11755
+ const currentSamplePosition = sampleMap.get(offsetsSorted[indexToVisit]);
11705
11756
  const sampleKey = getKey(currentSamplePosition);
11706
11757
  if (visited.has(sampleKey)) {
11707
11758
  considerJump();
@@ -11719,7 +11770,7 @@ var calculateJumpMarks = (samplePositionTracks, endOfMdat) => {
11719
11770
  rollOverToProcess = false;
11720
11771
  }
11721
11772
  lastVisitedSample = currentSamplePosition;
11722
- if (visited.size === allSamplesSortedByOffset.length) {
11773
+ if (visited.size === offsetsSorted.length) {
11723
11774
  addFinalJumpIfNecessary();
11724
11775
  break;
11725
11776
  }
@@ -11729,7 +11780,7 @@ var calculateJumpMarks = (samplePositionTracks, endOfMdat) => {
11729
11780
  const maxProgress = Math.max(...progressValues);
11730
11781
  const minProgress = Math.min(...progressValues);
11731
11782
  const spread = maxProgress - minProgress;
11732
- if (visited.size === allSamplesSortedByOffset.length) {
11783
+ if (visited.size === offsetsSorted.length) {
11733
11784
  addFinalJumpIfNecessary();
11734
11785
  break;
11735
11786
  }
@@ -11811,24 +11862,32 @@ var parseMdatSection = async (state) => {
11811
11862
  return parseMdatSection(state);
11812
11863
  }
11813
11864
  if (!state.iso.flatSamples.getSamples(mediaSection.start)) {
11814
- const flattedSamples = calculateFlatSamples({
11865
+ const {
11866
+ flatSamples: flatSamplesMap,
11867
+ offsets,
11868
+ trackIds
11869
+ } = calculateFlatSamples({
11815
11870
  state,
11816
11871
  mediaSectionStart: mediaSection.start
11817
11872
  });
11818
- const calcedJumpMarks = calculateJumpMarks(flattedSamples, endOfMdat);
11873
+ const calcedJumpMarks = calculateJumpMarks({
11874
+ sampleMap: flatSamplesMap,
11875
+ offsetsSorted: offsets,
11876
+ trackIds,
11877
+ endOfMdat
11878
+ });
11819
11879
  state.iso.flatSamples.setJumpMarks(mediaSection.start, calcedJumpMarks);
11820
- state.iso.flatSamples.setSamples(mediaSection.start, flattedSamples.flat(1));
11880
+ state.iso.flatSamples.setSamples(mediaSection.start, flatSamplesMap);
11821
11881
  }
11822
11882
  const flatSamples = state.iso.flatSamples.getSamples(mediaSection.start);
11823
11883
  const jumpMarks = state.iso.flatSamples.getJumpMarks(mediaSection.start);
11824
11884
  const { iterator } = state;
11825
- const samplesWithIndex = flatSamples.find((sample) => {
11826
- return sample.samplePosition.offset === iterator.counter.getOffset();
11827
- });
11885
+ const samplesWithIndex = flatSamples.get(iterator.counter.getOffset());
11828
11886
  if (!samplesWithIndex) {
11829
- const nextSample_ = flatSamples.filter((s) => s.samplePosition.offset > iterator.counter.getOffset()).sort((a, b) => a.samplePosition.offset - b.samplePosition.offset)[0];
11887
+ const offsets = Array.from(flatSamples.keys());
11888
+ const nextSample_ = offsets.filter((s) => s > iterator.counter.getOffset()).sort((a, b) => a - b)[0];
11830
11889
  if (nextSample_) {
11831
- iterator.discard(nextSample_.samplePosition.offset - iterator.counter.getOffset());
11890
+ iterator.discard(nextSample_ - iterator.counter.getOffset());
11832
11891
  return null;
11833
11892
  }
11834
11893
  Log.verbose(state.logLevel, "Could not find sample at offset", iterator.counter.getOffset(), "skipping to end of mdat");
@@ -11850,9 +11909,14 @@ var parseMdatSection = async (state) => {
11850
11909
  bigEndian,
11851
11910
  chunkSize
11852
11911
  } = samplesWithIndex.samplePosition;
11853
- const { originalTimescale, startInSeconds } = samplesWithIndex.track;
11854
- const cts = rawCts + startInSeconds * originalTimescale;
11855
- const dts = rawDts + startInSeconds * originalTimescale;
11912
+ const {
11913
+ originalTimescale,
11914
+ startInSeconds,
11915
+ trackMediaTimeOffsetInTrackTimescale,
11916
+ timescale: trackTimescale
11917
+ } = samplesWithIndex.track;
11918
+ const cts = rawCts + startInSeconds * originalTimescale - trackMediaTimeOffsetInTrackTimescale / trackTimescale * WEBCODECS_TIMESCALE;
11919
+ const dts = rawDts + startInSeconds * originalTimescale - trackMediaTimeOffsetInTrackTimescale / trackTimescale * WEBCODECS_TIMESCALE;
11856
11920
  const bytes = postprocessBytes({
11857
11921
  bytes: iterator.getSlice(samplesWithIndex.samplePosition.size),
11858
11922
  bigEndian,
@@ -13584,7 +13648,8 @@ var parseMpegHeader = async ({
13584
13648
  originalTimescale: 1e6,
13585
13649
  trackId: 0,
13586
13650
  startInSeconds: 0,
13587
- timescale: WEBCODECS_TIMESCALE
13651
+ timescale: WEBCODECS_TIMESCALE,
13652
+ trackMediaTimeOffsetInTrackTimescale: 0
13588
13653
  },
13589
13654
  registerAudioSampleCallback: state.callbacks.registerAudioSampleCallback,
13590
13655
  tracks: state.callbacks.tracks,
@@ -14671,7 +14736,8 @@ var handleAacPacket = async ({
14671
14736
  numberOfChannels: channelConfiguration,
14672
14737
  sampleRate,
14673
14738
  startInSeconds: 0,
14674
- timescale: WEBCODECS_TIMESCALE
14739
+ timescale: WEBCODECS_TIMESCALE,
14740
+ trackMediaTimeOffsetInTrackTimescale: 0
14675
14741
  };
14676
14742
  await registerAudioTrack({
14677
14743
  track,
@@ -15304,7 +15370,8 @@ var parseFmt = async ({
15304
15370
  originalTimescale: 1e6,
15305
15371
  trackId: 0,
15306
15372
  startInSeconds: 0,
15307
- timescale: WEBCODECS_TIMESCALE
15373
+ timescale: WEBCODECS_TIMESCALE,
15374
+ trackMediaTimeOffsetInTrackTimescale: 0
15308
15375
  },
15309
15376
  container: "wav",
15310
15377
  registerAudioSampleCallback: state.callbacks.registerAudioSampleCallback,
@@ -15905,9 +15972,11 @@ var parseLoop = async ({
15905
15972
  try {
15906
15973
  await triggerInfoEmit(state);
15907
15974
  await state.controller._internals.checkForAbortAndPause();
15975
+ const parseLoopStart = Date.now();
15908
15976
  const result = await runParseIteration({
15909
15977
  state
15910
15978
  });
15979
+ state.timings.timeInParseLoop += Date.now() - parseLoopStart;
15911
15980
  if (result !== null && result.action === "fetch-more-data") {
15912
15981
  Log.verbose(state.logLevel, `Need to fetch ${result.bytesNeeded} more bytes before we can continue`);
15913
15982
  const startBytesRemaining = state.iterator.bytesRemaining();
@@ -15996,6 +16065,7 @@ var printTimings = (state) => {
15996
16065
  Log.verbose(state.logLevel, `Time seeking: ${state.timings.timeSeeking}ms`);
15997
16066
  Log.verbose(state.logLevel, `Time checking if done: ${state.timings.timeCheckingIfDone}ms`);
15998
16067
  Log.verbose(state.logLevel, `Time freeing data: ${state.timings.timeFreeingData}ms`);
16068
+ Log.verbose(state.logLevel, `Time in parse loop: ${state.timings.timeInParseLoop}ms`);
15999
16069
  };
16000
16070
 
16001
16071
  // src/remotion-license-acknowledge.ts
@@ -17600,7 +17670,8 @@ var timingsState = () => {
17600
17670
  timeReadingData: 0,
17601
17671
  timeSeeking: 0,
17602
17672
  timeCheckingIfDone: 0,
17603
- timeFreeingData: 0
17673
+ timeFreeingData: 0,
17674
+ timeInParseLoop: 0
17604
17675
  };
17605
17676
  };
17606
17677
 
@@ -18105,7 +18176,7 @@ var downloadAndParseMedia = async (options) => {
18105
18176
  return returnValue;
18106
18177
  };
18107
18178
  // src/version.ts
18108
- var VERSION = "4.0.326";
18179
+ var VERSION = "4.0.329";
18109
18180
 
18110
18181
  // src/index.ts
18111
18182
  var MediaParserInternals = {