@remotion/media-parser 4.0.232 → 4.0.234

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 (41) hide show
  1. package/dist/boxes/iso-base-media/esds/decoder-specific-config.d.ts +1 -2
  2. package/dist/boxes/iso-base-media/esds/decoder-specific-config.js +1 -5
  3. package/dist/boxes/iso-base-media/esds/esds-descriptors.d.ts +2 -4
  4. package/dist/boxes/iso-base-media/esds/esds-descriptors.js +3 -4
  5. package/dist/boxes/iso-base-media/esds/esds.d.ts +1 -3
  6. package/dist/boxes/iso-base-media/esds/esds.js +2 -2
  7. package/dist/boxes/iso-base-media/get-sample-positions-from-track.js +7 -1
  8. package/dist/boxes/iso-base-media/process-box.js +0 -1
  9. package/dist/boxes/iso-base-media/stsd/samples.js +6 -5
  10. package/dist/create/event-emitter.d.ts +31 -0
  11. package/dist/create/event-emitter.js +25 -0
  12. package/dist/create/iso-base-media/create-iso-base-media.d.ts +1 -1
  13. package/dist/create/iso-base-media/create-iso-base-media.js +3 -1
  14. package/dist/create/matroska/cluster.js +1 -1
  15. package/dist/create/matroska/create-matroska-media.d.ts +1 -1
  16. package/dist/create/matroska/create-matroska-media.js +7 -10
  17. package/dist/create/media-fn.d.ts +2 -0
  18. package/dist/create/progress-tracker.d.ts +7 -0
  19. package/dist/create/progress-tracker.js +43 -0
  20. package/dist/create/wav/create-wav.d.ts +1 -1
  21. package/dist/create/wav/create-wav.js +3 -1
  22. package/dist/create/with-resolvers.d.ts +10 -0
  23. package/dist/create/with-resolvers.js +28 -0
  24. package/dist/emit-available-info.js +11 -2
  25. package/dist/esm/index.mjs +235 -68
  26. package/dist/get-audio-codec.d.ts +1 -0
  27. package/dist/get-audio-codec.js +15 -1
  28. package/dist/get-is-hdr.d.ts +4 -0
  29. package/dist/get-is-hdr.js +18 -0
  30. package/dist/get-sample-positions-from-lpcm.d.ts +3 -0
  31. package/dist/get-sample-positions-from-lpcm.js +46 -0
  32. package/dist/get-tracks.d.ts +3 -3
  33. package/dist/get-video-codec.js +9 -3
  34. package/dist/has-all-info.js +6 -1
  35. package/dist/index.d.ts +23 -4
  36. package/dist/index.js +7 -0
  37. package/dist/options.d.ts +7 -0
  38. package/dist/parse-media.js +1 -1
  39. package/dist/version.d.ts +1 -1
  40. package/dist/version.js +1 -1
  41. package/package.json +3 -3
@@ -105,6 +105,27 @@ var fetchReader = {
105
105
  }
106
106
  };
107
107
 
108
+ // src/create/event-emitter.ts
109
+ class IoEventEmitter {
110
+ listeners = {
111
+ input: [],
112
+ output: [],
113
+ processed: [],
114
+ progress: []
115
+ };
116
+ addEventListener(name, callback) {
117
+ this.listeners[name].push(callback);
118
+ }
119
+ removeEventListener(name, callback) {
120
+ this.listeners[name] = this.listeners[name].filter((l) => l !== callback);
121
+ }
122
+ dispatchEvent(dispatchName, context) {
123
+ this.listeners[dispatchName].forEach((callback) => {
124
+ callback({ detail: context });
125
+ });
126
+ }
127
+ }
128
+
108
129
  // src/boxes/webm/ebml.ts
109
130
  var measureEBMLVarInt = (value) => {
110
131
  if (value < (1 << 7) - 1) {
@@ -848,6 +869,15 @@ var incrementOffsetAndChildren = (offset, increment) => {
848
869
  };
849
870
 
850
871
  // src/boxes/webm/make-header.ts
872
+ var webmPattern = new Uint8Array([26, 69, 223, 163]);
873
+ var matroskaToHex = (matrId) => {
874
+ const numbers = new Uint8Array((matrId.length - 2) / 2);
875
+ for (let i = 2;i < matrId.length; i += 2) {
876
+ const hex = matrId.substring(i, i + 2);
877
+ numbers[(i - 2) / 2] = parseInt(hex, 16);
878
+ }
879
+ return numbers;
880
+ };
851
881
  function putUintDynamic(number, minimumLength) {
852
882
  if (number < 0) {
853
883
  throw new Error("This function is designed for non-negative integers only.");
@@ -859,21 +889,6 @@ function putUintDynamic(number, minimumLength) {
859
889
  }
860
890
  return bytes;
861
891
  }
862
- function serializeUint16(value) {
863
- const buffer = new ArrayBuffer(2);
864
- const view = new DataView(buffer);
865
- view.setUint16(0, value);
866
- return new Uint8Array(buffer);
867
- }
868
- var webmPattern = new Uint8Array([26, 69, 223, 163]);
869
- var matroskaToHex = (matrId) => {
870
- const numbers = new Uint8Array((matrId.length - 2) / 2);
871
- for (let i = 2;i < matrId.length; i += 2) {
872
- const hex = matrId.substring(i, i + 2);
873
- numbers[(i - 2) / 2] = parseInt(hex, 16);
874
- }
875
- return numbers;
876
- };
877
892
  var makeFromStructure = (fields) => {
878
893
  if ("bytes" in fields) {
879
894
  return fields;
@@ -1020,6 +1035,12 @@ var combineUint8Arrays = (arrays) => {
1020
1035
  }
1021
1036
  return result;
1022
1037
  };
1038
+ function serializeUint16(value) {
1039
+ const buffer = new ArrayBuffer(2);
1040
+ const view = new DataView(buffer);
1041
+ view.setUint16(0, value);
1042
+ return new Uint8Array(buffer);
1043
+ }
1023
1044
 
1024
1045
  // src/log.ts
1025
1046
  var logLevels = ["trace", "verbose", "info", "warn", "error"];
@@ -1855,7 +1876,7 @@ var createHdlr = (type) => {
1855
1876
  type === "mdir" ? numberTo32BitUIntOrInt(1634758764) : new Uint8Array([0, 0, 0, 0]),
1856
1877
  new Uint8Array([0, 0, 0, 0]),
1857
1878
  new Uint8Array([0, 0, 0, 0]),
1858
- stringsToUint8Array(type === "mdir" ? "\0" : type === "video" ? "VideoHandler\0" : "SoundHandler\0")
1879
+ stringsToUint8Array(type === "mdir" ? "\x00" : type === "video" ? "VideoHandler\x00" : "SoundHandler\x00")
1859
1880
  ]));
1860
1881
  };
1861
1882
 
@@ -1966,7 +1987,8 @@ var createIsoBaseMedia = async ({
1966
1987
  onBytesProgress,
1967
1988
  onMillisecondsProgress,
1968
1989
  logLevel,
1969
- filename
1990
+ filename,
1991
+ progressTracker
1970
1992
  }) => {
1971
1993
  const header = createIsoBaseMediaFtyp({
1972
1994
  compatibleBrands: ["isom", "iso2", "avc1", "mp42"],
@@ -2036,6 +2058,7 @@ var createIsoBaseMedia = async ({
2036
2058
  await w.write(chunk.data);
2037
2059
  mdatSize += chunk.data.length;
2038
2060
  onBytesProgress(w.getWrittenByteCount());
2061
+ progressTracker.updateTrackProgress(trackNumber2, chunk.timestamp);
2039
2062
  if (codecPrivate2) {
2040
2063
  addCodecPrivateToTrack({ trackNumber: trackNumber2, codecPrivate: codecPrivate2 });
2041
2064
  }
@@ -2069,6 +2092,7 @@ var createIsoBaseMedia = async ({
2069
2092
  const addTrack = (track) => {
2070
2093
  const trackNumber2 = currentTracks.length + 1;
2071
2094
  currentTracks.push({ ...track, trackNumber: trackNumber2 });
2095
+ progressTracker.registerTrack(trackNumber2);
2072
2096
  return Promise.resolve({ trackNumber: trackNumber2 });
2073
2097
  };
2074
2098
  const waitForFinishPromises = [];
@@ -2174,7 +2198,7 @@ var canFitInCluster = ({
2174
2198
  }) => {
2175
2199
  const timecodeRelativeToCluster = timestampToClusterTimestamp(chunk.timestamp, timescale) - timestampToClusterTimestamp(clusterStartTimestamp, timescale);
2176
2200
  if (timecodeRelativeToCluster < 0) {
2177
- throw new Error(`timecodeRelativeToCluster is negative`);
2201
+ throw new Error(`timecodeRelativeToCluster is negative, tried to add ${chunk.timestamp} to ${clusterStartTimestamp}`);
2178
2202
  }
2179
2203
  return timecodeRelativeToCluster <= maxClusterTimestamp;
2180
2204
  };
@@ -2943,7 +2967,8 @@ var createMatroskaMedia = async ({
2943
2967
  onBytesProgress,
2944
2968
  onMillisecondsProgress,
2945
2969
  filename,
2946
- logLevel
2970
+ logLevel,
2971
+ progressTracker
2947
2972
  }) => {
2948
2973
  const header = makeMatroskaHeader();
2949
2974
  const w = await writer.createContent({ filename, mimeType: "video/webm" });
@@ -3008,17 +3033,11 @@ var createMatroskaMedia = async ({
3008
3033
  hexString: matroskaElements.Cluster,
3009
3034
  byte: clusterOffset - seekHeadOffset
3010
3035
  });
3011
- const trackNumberProgresses = {};
3012
3036
  const getClusterOrMakeNew = async ({
3013
3037
  chunk,
3014
- isVideo,
3015
- trackNumber: trackNumber2
3038
+ isVideo
3016
3039
  }) => {
3017
- const trackProgressValues = Object.values(trackNumberProgresses);
3018
- const smallestProgress = trackProgressValues.length === 0 ? 0 : Math.min(...trackProgressValues);
3019
- if (chunk.type === "key") {
3020
- trackNumberProgresses[trackNumber2] = chunk.timestamp;
3021
- }
3040
+ const smallestProgress = progressTracker.getSmallestProgress();
3022
3041
  if (!currentCluster.shouldMakeNewCluster({
3023
3042
  newT: smallestProgress,
3024
3043
  isVideo,
@@ -3046,8 +3065,7 @@ var createMatroskaMedia = async ({
3046
3065
  }) => {
3047
3066
  const { cluster, isNew, smallestProgress } = await getClusterOrMakeNew({
3048
3067
  chunk,
3049
- isVideo,
3050
- trackNumber: trackNumber2
3068
+ isVideo
3051
3069
  });
3052
3070
  const newDuration = Math.round((chunk.timestamp + (chunk.duration ?? 0)) / 1000);
3053
3071
  await updateDuration(newDuration);
@@ -3060,12 +3078,16 @@ var createMatroskaMedia = async ({
3060
3078
  trackNumber: trackNumber2
3061
3079
  });
3062
3080
  }
3081
+ if (chunk.type === "key") {
3082
+ progressTracker.updateTrackProgress(trackNumber2, chunk.timestamp);
3083
+ }
3063
3084
  onBytesProgress(w.getWrittenByteCount());
3064
3085
  onMillisecondsProgress(newDuration);
3065
3086
  };
3066
3087
  const addTrack = async (track) => {
3067
3088
  currentTracks.push(track);
3068
3089
  const newTracks = makeMatroskaTracks(currentTracks);
3090
+ progressTracker.registerTrack(track.trackNumber);
3069
3091
  await w.updateDataAt(tracksOffset, combineUint8Arrays(newTracks.map((b) => b.bytes)));
3070
3092
  };
3071
3093
  const operationProm = { current: Promise.resolve() };
@@ -3116,6 +3138,70 @@ var createMatroskaMedia = async ({
3116
3138
  };
3117
3139
  };
3118
3140
 
3141
+ // src/create/with-resolvers.ts
3142
+ var withResolvers = function() {
3143
+ let resolve;
3144
+ let reject;
3145
+ const promise = new Promise((res, rej) => {
3146
+ resolve = res;
3147
+ reject = rej;
3148
+ });
3149
+ return { promise, resolve, reject };
3150
+ };
3151
+ var withResolversAndWaitForReturn = () => {
3152
+ const { promise, reject, resolve } = withResolvers();
3153
+ const { promise: returnPromise, resolve: resolveReturn } = withResolvers();
3154
+ return {
3155
+ getPromiseToImmediatelyReturn: () => {
3156
+ resolveReturn(undefined);
3157
+ return promise;
3158
+ },
3159
+ reject: (reason) => {
3160
+ returnPromise.then(() => reject(reason));
3161
+ },
3162
+ resolve
3163
+ };
3164
+ };
3165
+
3166
+ // src/create/progress-tracker.ts
3167
+ var makeProgressTracker = () => {
3168
+ const trackNumberProgresses = {};
3169
+ const eventEmitter = new IoEventEmitter;
3170
+ const calculateSmallestProgress = () => {
3171
+ const progressValues = Object.values(trackNumberProgresses);
3172
+ if (progressValues.length === 0) {
3173
+ return 0;
3174
+ }
3175
+ return Math.min(...progressValues);
3176
+ };
3177
+ return {
3178
+ registerTrack: (trackNumber2) => {
3179
+ trackNumberProgresses[trackNumber2] = 0;
3180
+ },
3181
+ getSmallestProgress: () => {
3182
+ return calculateSmallestProgress();
3183
+ },
3184
+ updateTrackProgress: (trackNumber2, progress) => {
3185
+ if (trackNumberProgresses[trackNumber2] === undefined) {
3186
+ throw new Error(`Tried to update progress for a track that was not registered: ${trackNumber2}`);
3187
+ }
3188
+ trackNumberProgresses[trackNumber2] = progress;
3189
+ eventEmitter.dispatchEvent("progress", {
3190
+ smallestProgress: calculateSmallestProgress()
3191
+ });
3192
+ },
3193
+ waitForProgress: () => {
3194
+ const { promise, resolve } = withResolvers();
3195
+ const on = () => {
3196
+ eventEmitter.removeEventListener("processed", on);
3197
+ resolve();
3198
+ };
3199
+ eventEmitter.addEventListener("processed", on);
3200
+ return promise;
3201
+ }
3202
+ };
3203
+ };
3204
+
3119
3205
  // src/create/wav/create-wav.ts
3120
3206
  var numberTo32BiIntLittleEndian = (num) => {
3121
3207
  return new Uint8Array([
@@ -3135,7 +3221,8 @@ var createWav = async ({
3135
3221
  logLevel,
3136
3222
  onBytesProgress,
3137
3223
  onMillisecondsProgress,
3138
- writer
3224
+ writer,
3225
+ progressTracker
3139
3226
  }) => {
3140
3227
  const w = await writer.createContent({ filename, mimeType: "audio/wav" });
3141
3228
  await w.write(new Uint8Array([82, 73, 70, 70]));
@@ -3198,6 +3285,7 @@ var createWav = async ({
3198
3285
  throw new Error("Only one track supported for WAV");
3199
3286
  }
3200
3287
  operationProm.current = operationProm.current.then(() => addSample(chunk));
3288
+ progressTracker.updateTrackProgress(trackNumber2, chunk.timestamp);
3201
3289
  return operationProm.current;
3202
3290
  },
3203
3291
  updateTrackSampleRate: () => {
@@ -3224,6 +3312,7 @@ var createWav = async ({
3224
3312
  numberOfChannels: track.numberOfChannels
3225
3313
  });
3226
3314
  await updateBlockAlign(track.numberOfChannels);
3315
+ progressTracker.registerTrack(1);
3227
3316
  return Promise.resolve({ trackNumber: 1 });
3228
3317
  }
3229
3318
  };
@@ -3662,11 +3751,20 @@ var getAudioCodecFromTrak = (trak) => {
3662
3751
  }
3663
3752
  return null;
3664
3753
  };
3754
+ var isLpcmAudioCodec = (trak) => {
3755
+ return getAudioCodecFromTrak(trak)?.format === "lpcm";
3756
+ };
3665
3757
  var getAudioCodecStringFromTrak = (trak) => {
3666
3758
  const codec = getAudioCodecFromTrak(trak);
3667
3759
  if (!codec) {
3668
3760
  throw new Error("Expected codec");
3669
3761
  }
3762
+ if (codec.format === "lpcm") {
3763
+ return {
3764
+ codecString: "pcm-s16",
3765
+ description: codec.description
3766
+ };
3767
+ }
3670
3768
  const codecStringWithoutMp3Exception = [
3671
3769
  codec.format,
3672
3770
  codec.primarySpecificator ? codec.primarySpecificator.toString(16) : null,
@@ -3682,6 +3780,9 @@ var getAudioCodecFromAudioCodecInfo = (codec) => {
3682
3780
  if (codec.format === "twos") {
3683
3781
  return "pcm-s16";
3684
3782
  }
3783
+ if (codec.format === "lpcm") {
3784
+ return "pcm-s16";
3785
+ }
3685
3786
  if (codec.format === "sowt") {
3686
3787
  return "aiff";
3687
3788
  }
@@ -3708,16 +3809,6 @@ var getAudioCodecFromTrack = (track) => {
3708
3809
  };
3709
3810
 
3710
3811
  // src/get-sample-aspect-ratio.ts
3711
- function gcd(a, b) {
3712
- return b === 0 ? a : gcd(b, a % b);
3713
- }
3714
- function reduceFraction(numerator, denominator) {
3715
- const greatestCommonDivisor = gcd(Math.abs(numerator), Math.abs(denominator));
3716
- return {
3717
- numerator: numerator / greatestCommonDivisor,
3718
- denominator: denominator / greatestCommonDivisor
3719
- };
3720
- }
3721
3812
  var getStsdVideoConfig = (trakBox) => {
3722
3813
  const stsdBox = getStsdBox(trakBox);
3723
3814
  if (!stsdBox) {
@@ -3829,6 +3920,16 @@ var applyAspectRatios = ({
3829
3920
  height: newHeight
3830
3921
  };
3831
3922
  };
3923
+ function gcd(a, b) {
3924
+ return b === 0 ? a : gcd(b, a % b);
3925
+ }
3926
+ function reduceFraction(numerator, denominator) {
3927
+ const greatestCommonDivisor = gcd(Math.abs(numerator), Math.abs(denominator));
3928
+ return {
3929
+ numerator: numerator / greatestCommonDivisor,
3930
+ denominator: denominator / greatestCommonDivisor
3931
+ };
3932
+ }
3832
3933
  var getDisplayAspectRatio = ({
3833
3934
  sampleAspectRatio,
3834
3935
  nativeDimensions
@@ -4488,9 +4589,9 @@ var getIsoBmColrConfig = (trakBox) => {
4488
4589
  }
4489
4590
  return {
4490
4591
  fullRange: colrAtom.fullRangeFlag,
4491
- matrixCoefficients: colrAtom.matrixIndex === 1 ? "bt709" : colrAtom.matrixIndex === 5 ? "bt470bg" : colrAtom.matrixIndex === 6 ? "smpte170m" : null,
4492
- primaries: colrAtom.primaries === 1 ? "bt709" : colrAtom.primaries === 5 ? "bt470bg" : colrAtom.primaries === 6 ? "smpte170m" : null,
4493
- transferCharacteristics: colrAtom.transfer === 1 ? "bt709" : colrAtom.transfer === 6 ? "smpte170m" : colrAtom.transfer === 13 ? "iec61966-2-1" : null
4592
+ matrixCoefficients: colrAtom.matrixIndex === 1 ? "bt709" : colrAtom.matrixIndex === 5 ? "bt470bg" : colrAtom.matrixIndex === 6 ? "smpte170m" : colrAtom.matrixIndex === 9 ? "bt2020" : null,
4593
+ primaries: colrAtom.primaries === 1 ? "bt709" : colrAtom.primaries === 5 ? "bt470bg" : colrAtom.primaries === 6 ? "smpte170m" : colrAtom.primaries === 9 ? "bt2020" : null,
4594
+ transferCharacteristics: colrAtom.transfer === 1 ? "bt709" : colrAtom.transfer === 6 ? "smpte170m" : colrAtom.transfer === 13 ? "iec61966-2-1" : colrAtom.transfer === 18 ? "arib-std-b67" : null
4494
4595
  };
4495
4596
  };
4496
4597
  var getVideoCodecString = (trakBox) => {
@@ -5304,6 +5405,46 @@ var getSamplePositions = ({
5304
5405
  return samples;
5305
5406
  };
5306
5407
 
5408
+ // src/get-sample-positions-from-lpcm.ts
5409
+ var getSamplePositionsFromLpcm = (trakBox) => {
5410
+ const stscBox = getStscBox(trakBox);
5411
+ const stszBox = getStszBox(trakBox);
5412
+ const stcoBox = getStcoBox(trakBox);
5413
+ if (!stscBox) {
5414
+ throw new Error("Expected stsc box in trak box");
5415
+ }
5416
+ if (!stcoBox) {
5417
+ throw new Error("Expected stco box in trak box");
5418
+ }
5419
+ if (!stszBox) {
5420
+ throw new Error("Expected stsz box in trak box");
5421
+ }
5422
+ if (stszBox.countType !== "fixed") {
5423
+ throw new Error("Only supporting fixed count type in stsz box");
5424
+ }
5425
+ const samples = [];
5426
+ let timestamp = 0;
5427
+ for (let i = 0;i < stcoBox.entries.length; i++) {
5428
+ const entry = stcoBox.entries[i];
5429
+ const chunk = i + 1;
5430
+ const stscEntry = stscBox.entries.findLast((e) => e.firstChunk <= chunk);
5431
+ if (!stscEntry) {
5432
+ throw new Error("should not be");
5433
+ }
5434
+ samples.push({
5435
+ chunk,
5436
+ cts: timestamp,
5437
+ dts: timestamp,
5438
+ offset: Number(entry),
5439
+ size: stszBox.sampleSize * stscEntry.samplesPerChunk,
5440
+ duration: stscEntry.samplesPerChunk,
5441
+ isKeyframe: true
5442
+ });
5443
+ timestamp += stscEntry.samplesPerChunk;
5444
+ }
5445
+ return samples;
5446
+ };
5447
+
5307
5448
  // src/samples-from-moof.ts
5308
5449
  var getSamplesFromTraf = (trafSegment, moofOffset) => {
5309
5450
  if (trafSegment.type !== "regular-box" || trafSegment.boxType !== "traf") {
@@ -5375,6 +5516,11 @@ var getSamplesFromMoof = ({
5375
5516
 
5376
5517
  // src/boxes/iso-base-media/get-sample-positions-from-track.ts
5377
5518
  var getSamplePositionsFromTrack = (trakBox, moofBox) => {
5519
+ const isLpcm = isLpcmAudioCodec(trakBox);
5520
+ const timescaleAndDuration = getTimescaleAndDuration(trakBox);
5521
+ if (isLpcm) {
5522
+ return getSamplePositionsFromLpcm(trakBox);
5523
+ }
5378
5524
  const stszBox = getStszBox(trakBox);
5379
5525
  const stcoBox = getStcoBox(trakBox);
5380
5526
  const stscBox = getStscBox(trakBox);
@@ -5382,7 +5528,6 @@ var getSamplePositionsFromTrack = (trakBox, moofBox) => {
5382
5528
  const sttsBox = getSttsBox(trakBox);
5383
5529
  const tkhdBox = getTkhdBox(trakBox);
5384
5530
  const cttsBox = getCttsBox(trakBox);
5385
- const timescaleAndDuration = getTimescaleAndDuration(trakBox);
5386
5531
  if (!tkhdBox) {
5387
5532
  throw new Error("Expected tkhd box in trak box");
5388
5533
  }
@@ -5501,6 +5646,18 @@ var hasDuration = (structure, parserState) => {
5501
5646
  return hasTracks(structure, parserState);
5502
5647
  };
5503
5648
 
5649
+ // src/get-is-hdr.ts
5650
+ var isVideoTrackHdr = (track) => {
5651
+ return track.color.matrixCoefficients === "bt2020" && track.color.transferCharacteristics === "arib-std-b67" && track.color.primaries === "bt2020";
5652
+ };
5653
+ var getIsHdr = (boxes, state) => {
5654
+ const { videoTracks } = getTracks(boxes, state);
5655
+ return videoTracks.some((track) => isVideoTrackHdr(track));
5656
+ };
5657
+ var hasHdr = (boxes, state) => {
5658
+ return hasTracks(boxes, state);
5659
+ };
5660
+
5504
5661
  // src/emit-available-info.ts
5505
5662
  var emitAvailableInfo = ({
5506
5663
  hasInfo,
@@ -5616,6 +5773,14 @@ var emitAvailableInfo = ({
5616
5773
  }
5617
5774
  continue;
5618
5775
  }
5776
+ if (key === "isHdr") {
5777
+ if (returnValue.isHdr === undefined && hasInfo.isHdr && parseResult) {
5778
+ const isHdr = getIsHdr(parseResult.segments, state);
5779
+ moreFields.onIsHdr?.(isHdr);
5780
+ returnValue.isHdr = isHdr;
5781
+ }
5782
+ continue;
5783
+ }
5619
5784
  if (key === "container") {
5620
5785
  if (returnValue.container === undefined && hasInfo.container && parseResult) {
5621
5786
  const container = getContainer(parseResult.segments);
@@ -5631,7 +5796,8 @@ var emitAvailableInfo = ({
5631
5796
  // src/has-all-info.ts
5632
5797
  var getAvailableInfo = (options, parseResult, state) => {
5633
5798
  const keys = Object.entries(options).filter(([, value]) => value);
5634
- const infos = keys.map(([key]) => {
5799
+ const infos = keys.map(([_key]) => {
5800
+ const key = _key;
5635
5801
  if (key === "structure") {
5636
5802
  return Boolean(parseResult && parseResult.status === "done");
5637
5803
  }
@@ -5644,6 +5810,9 @@ var getAvailableInfo = (options, parseResult, state) => {
5644
5810
  if (key === "fps") {
5645
5811
  return Boolean(parseResult && hasFps(parseResult.segments));
5646
5812
  }
5813
+ if (key === "isHdr") {
5814
+ return Boolean(parseResult && hasHdr(parseResult.segments, state));
5815
+ }
5647
5816
  if (key === "videoCodec") {
5648
5817
  return Boolean(parseResult && hasVideoCodec(parseResult.segments, state));
5649
5818
  }
@@ -5705,7 +5874,7 @@ var registerVideoTrackWhenProfileIsAvailable = ({
5705
5874
  };
5706
5875
 
5707
5876
  // src/boxes/iso-base-media/esds/decoder-specific-config.ts
5708
- var parseDecoderSpecificConfig = (iterator, logLevel) => {
5877
+ var parseDecoderSpecificConfig = (iterator) => {
5709
5878
  const layerTag = iterator.getUint8();
5710
5879
  const layerSize = iterator.getPaddedFourByteNumber();
5711
5880
  const start = iterator.counter.getOffset();
@@ -5729,9 +5898,6 @@ var parseDecoderSpecificConfig = (iterator, logLevel) => {
5729
5898
  if (read < layerSize) {
5730
5899
  iterator.discard(layerSize - read);
5731
5900
  }
5732
- if (bytes.byteLength === 2 && bytes[0] === 17 && bytes[1] === 136) {
5733
- Log.warn(logLevel, "Chrome has a bug and might not be able to decode this audio. It will be fixed, see: https://issues.chromium.org/issues/360083330");
5734
- }
5735
5901
  return {
5736
5902
  type: "mp4a-specific-config",
5737
5903
  audioObjectType,
@@ -5752,8 +5918,7 @@ var mapToObjectAudioIndicator = (num) => {
5752
5918
  return "unknown";
5753
5919
  };
5754
5920
  var processDescriptor = ({
5755
- iterator,
5756
- logLevel
5921
+ iterator
5757
5922
  }) => {
5758
5923
  const tag = iterator.getUint8();
5759
5924
  if (tag === 4) {
@@ -5770,7 +5935,7 @@ var processDescriptor = ({
5770
5935
  const avgBitrate = iterator.getUint32();
5771
5936
  const decoderSpecificConfigs = [];
5772
5937
  while (size - (iterator.counter.getOffset() - initialOffset) > 0) {
5773
- const decoderSpecificConfig = parseDecoderSpecificConfig(iterator, logLevel);
5938
+ const decoderSpecificConfig = parseDecoderSpecificConfig(iterator);
5774
5939
  decoderSpecificConfigs.push(decoderSpecificConfig);
5775
5940
  }
5776
5941
  return {
@@ -5800,13 +5965,12 @@ var processDescriptor = ({
5800
5965
  descriptor: null
5801
5966
  };
5802
5967
  };
5803
- var parseDescriptors = (iterator, maxBytes, logLevel) => {
5968
+ var parseDescriptors = (iterator, maxBytes) => {
5804
5969
  const descriptors = [];
5805
5970
  const initialOffset = iterator.counter.getOffset();
5806
5971
  while (iterator.bytesRemaining() > 0 && iterator.counter.getOffset() - initialOffset < maxBytes) {
5807
5972
  const { descriptor } = processDescriptor({
5808
- iterator,
5809
- logLevel
5973
+ iterator
5810
5974
  });
5811
5975
  if (descriptor) {
5812
5976
  descriptors.push(descriptor);
@@ -5821,8 +5985,7 @@ var parseDescriptors = (iterator, maxBytes, logLevel) => {
5821
5985
  var parseEsds = ({
5822
5986
  data,
5823
5987
  size,
5824
- fileOffset,
5825
- logLevel
5988
+ fileOffset
5826
5989
  }) => {
5827
5990
  const version = data.getUint8();
5828
5991
  data.discard(3);
@@ -5831,7 +5994,7 @@ var parseEsds = ({
5831
5994
  const esId = data.getUint16();
5832
5995
  data.discard(1);
5833
5996
  const remaining = size - (data.counter.getOffset() - fileOffset);
5834
- const descriptors = parseDescriptors(data, remaining, logLevel);
5997
+ const descriptors = parseDescriptors(data, remaining);
5835
5998
  const remainingNow = size - (data.counter.getOffset() - fileOffset);
5836
5999
  data.discard(remainingNow);
5837
6000
  return {
@@ -6495,6 +6658,7 @@ var audioTags = [
6495
6658
  "MAC6 ",
6496
6659
  "ima4",
6497
6660
  "fl32",
6661
+ "lpcm",
6498
6662
  "fl64",
6499
6663
  "in24",
6500
6664
  "in32",
@@ -6636,16 +6800,16 @@ var processSample = async ({
6636
6800
  };
6637
6801
  }
6638
6802
  if (version === 2) {
6639
- const numberOfChannels = iterator.getUint16();
6803
+ iterator.getUint16();
6640
6804
  const sampleSize = iterator.getUint16();
6641
6805
  const compressionId = iterator.getUint16();
6642
6806
  const packetSize = iterator.getUint16();
6643
6807
  iterator.getFixedPointUnsigned1616Number();
6644
6808
  iterator.getUint32();
6645
6809
  const higherSampleRate = iterator.getFloat64();
6810
+ const numAudioChannel = iterator.getUint32();
6646
6811
  iterator.getUint32();
6647
- iterator.getUint32();
6648
- const bitsPerCodedSample = iterator.getUint32();
6812
+ const bitsPerChannel = iterator.getUint32();
6649
6813
  iterator.getUint32();
6650
6814
  const bytesPerFrame = iterator.getUint32();
6651
6815
  const samplesPerPacket = iterator.getUint32();
@@ -6673,7 +6837,7 @@ var processSample = async ({
6673
6837
  vendor: [...Array.from(new Uint8Array(vendor))],
6674
6838
  size: boxSize,
6675
6839
  type: "audio",
6676
- numberOfChannels,
6840
+ numberOfChannels: numAudioChannel,
6677
6841
  sampleSize,
6678
6842
  compressionId,
6679
6843
  packetSize,
@@ -6681,7 +6845,7 @@ var processSample = async ({
6681
6845
  samplesPerPacket,
6682
6846
  bytesPerPacket: null,
6683
6847
  bytesPerFrame,
6684
- bitsPerSample: bitsPerCodedSample,
6848
+ bitsPerSample: bitsPerChannel,
6685
6849
  children: children.segments.boxes
6686
6850
  }
6687
6851
  };
@@ -7543,8 +7707,7 @@ var processBox = async ({
7543
7707
  const box = parseEsds({
7544
7708
  data: iterator,
7545
7709
  size: boxSize,
7546
- fileOffset,
7547
- logLevel
7710
+ fileOffset
7548
7711
  });
7549
7712
  return {
7550
7713
  type: "complete",
@@ -9256,7 +9419,7 @@ var parseMedia = async ({
9256
9419
  });
9257
9420
  triggerInfoEmit();
9258
9421
  if (parseResult && parseResult.status === "incomplete") {
9259
- Log.verbose(logLevel, "Continuing parsing of file, currently at position", iterator.counter.getOffset(), getAvailableInfo(fields ?? {}, parseResult, state));
9422
+ Log.verbose(logLevel, "Continuing parsing of file, currently at position", iterator.counter.getOffset());
9260
9423
  parseResult = await parseResult.continueParsing();
9261
9424
  } else {
9262
9425
  parseResult = await parseVideo({
@@ -9297,14 +9460,18 @@ var parseMedia = async ({
9297
9460
  return returnValue;
9298
9461
  };
9299
9462
  // src/version.ts
9300
- var VERSION = "4.0.232";
9463
+ var VERSION = "4.0.234";
9301
9464
 
9302
9465
  // src/index.ts
9303
9466
  var MediaParserInternals = {
9304
9467
  createMatroskaMedia,
9305
9468
  createIsoBaseMedia,
9306
9469
  createWav,
9307
- Log
9470
+ Log,
9471
+ IoEventEmitter,
9472
+ makeProgressTracker,
9473
+ withResolvers,
9474
+ withResolversAndWaitForReturn
9308
9475
  };
9309
9476
  export {
9310
9477
  parseMedia,
@@ -15,6 +15,7 @@ export declare const getCodecPrivateFromTrak: (trakBox: TrakBox) => Uint8Array |
15
15
  export declare const getNumberOfChannelsFromTrak: (trak: TrakBox) => number | null;
16
16
  export declare const getSampleRate: (trak: TrakBox) => number | null;
17
17
  export declare const getAudioCodecFromTrak: (trak: TrakBox) => AudioCodecInfo | null;
18
+ export declare const isLpcmAudioCodec: (trak: TrakBox) => boolean;
18
19
  export declare const getAudioCodecFromIso: (moov: MoovBox) => AudioCodecInfo | null;
19
20
  export declare const getAudioCodecStringFromTrak: (trak: TrakBox) => {
20
21
  codecString: string;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getAudioCodecFromTrack = exports.getAudioCodecStringFromTrak = exports.getAudioCodecFromIso = exports.getAudioCodecFromTrak = exports.getSampleRate = exports.getNumberOfChannelsFromTrak = exports.getCodecPrivateFromTrak = exports.hasAudioCodec = exports.getAudioCodec = void 0;
3
+ exports.getAudioCodecFromTrack = exports.getAudioCodecStringFromTrak = exports.getAudioCodecFromIso = exports.isLpcmAudioCodec = exports.getAudioCodecFromTrak = exports.getSampleRate = exports.getNumberOfChannelsFromTrak = exports.getCodecPrivateFromTrak = exports.hasAudioCodec = exports.getAudioCodec = void 0;
4
4
  const traversal_1 = require("./boxes/iso-base-media/traversal");
5
5
  const get_fps_1 = require("./get-fps");
6
6
  const get_tracks_1 = require("./get-tracks");
@@ -143,6 +143,11 @@ const getAudioCodecFromTrak = (trak) => {
143
143
  return null;
144
144
  };
145
145
  exports.getAudioCodecFromTrak = getAudioCodecFromTrak;
146
+ const isLpcmAudioCodec = (trak) => {
147
+ var _a;
148
+ return ((_a = (0, exports.getAudioCodecFromTrak)(trak)) === null || _a === void 0 ? void 0 : _a.format) === 'lpcm';
149
+ };
150
+ exports.isLpcmAudioCodec = isLpcmAudioCodec;
146
151
  const getAudioCodecFromIso = (moov) => {
147
152
  const traks = (0, traversal_1.getTraks)(moov);
148
153
  const trakBox = traks.find((b) => b.type === 'trak-box' && (0, get_fps_1.trakBoxContainsAudio)(b));
@@ -157,6 +162,12 @@ const getAudioCodecStringFromTrak = (trak) => {
157
162
  if (!codec) {
158
163
  throw new Error('Expected codec');
159
164
  }
165
+ if (codec.format === 'lpcm') {
166
+ return {
167
+ codecString: 'pcm-s16',
168
+ description: codec.description,
169
+ };
170
+ }
160
171
  const codecStringWithoutMp3Exception = [
161
172
  codec.format,
162
173
  codec.primarySpecificator ? codec.primarySpecificator.toString(16) : null,
@@ -178,6 +189,9 @@ const getAudioCodecFromAudioCodecInfo = (codec) => {
178
189
  if (codec.format === 'twos') {
179
190
  return 'pcm-s16';
180
191
  }
192
+ if (codec.format === 'lpcm') {
193
+ return 'pcm-s16';
194
+ }
181
195
  if (codec.format === 'sowt') {
182
196
  return 'aiff';
183
197
  }
@@ -0,0 +1,4 @@
1
+ import type { Structure } from './parse-result';
2
+ import type { ParserState } from './parser-state';
3
+ export declare const getIsHdr: (boxes: Structure, state: ParserState) => boolean;
4
+ export declare const hasHdr: (boxes: Structure, state: ParserState) => boolean;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.hasHdr = exports.getIsHdr = void 0;
4
+ const get_tracks_1 = require("./get-tracks");
5
+ const isVideoTrackHdr = (track) => {
6
+ return (track.color.matrixCoefficients === 'bt2020' &&
7
+ track.color.transferCharacteristics === 'arib-std-b67' &&
8
+ track.color.primaries === 'bt2020');
9
+ };
10
+ const getIsHdr = (boxes, state) => {
11
+ const { videoTracks } = (0, get_tracks_1.getTracks)(boxes, state);
12
+ return videoTracks.some((track) => isVideoTrackHdr(track));
13
+ };
14
+ exports.getIsHdr = getIsHdr;
15
+ const hasHdr = (boxes, state) => {
16
+ return (0, get_tracks_1.hasTracks)(boxes, state);
17
+ };
18
+ exports.hasHdr = hasHdr;