@remotion/media-parser 4.0.297 → 4.0.300

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 (180) hide show
  1. package/dist/add-avc-profile-to-track.d.ts +2 -2
  2. package/dist/add-avc-profile-to-track.js +7 -1
  3. package/dist/codec-data.d.ts +29 -0
  4. package/dist/codec-data.js +2 -0
  5. package/dist/containers/aac/parse-aac.js +2 -3
  6. package/dist/containers/avc/color.d.ts +6 -6
  7. package/dist/containers/avc/color.js +53 -27
  8. package/dist/containers/avc/create-avc-decoder-configuration-record.d.ts +2 -0
  9. package/dist/containers/avc/create-avc-decoder-configuration-record.js +35 -0
  10. package/dist/containers/avc/interpret-sps.d.ts +2 -2
  11. package/dist/containers/avc/interpret-sps.js +2 -2
  12. package/dist/containers/flac/parse-streaminfo.js +2 -3
  13. package/dist/containers/iso-base-media/collect-sample-positions-from-moof-boxes.d.ts +1 -1
  14. package/dist/containers/iso-base-media/color-to-webcodecs-colors.d.ts +2 -0
  15. package/dist/containers/iso-base-media/color-to-webcodecs-colors.js +12 -0
  16. package/dist/containers/iso-base-media/find-keyframe-before-time.d.ts +2 -2
  17. package/dist/containers/iso-base-media/find-track-to-seek.d.ts +5 -5
  18. package/dist/containers/iso-base-media/find-track-to-seek.js +18 -2
  19. package/dist/containers/iso-base-media/get-actual-number-of-channels.d.ts +3 -2
  20. package/dist/containers/iso-base-media/get-actual-number-of-channels.js +14 -3
  21. package/dist/containers/iso-base-media/get-children.d.ts +2 -2
  22. package/dist/containers/iso-base-media/get-keyframes.js +11 -2
  23. package/dist/containers/iso-base-media/get-mfra-seeking-box.d.ts +4 -4
  24. package/dist/containers/iso-base-media/get-moov-atom.js +1 -1
  25. package/dist/containers/iso-base-media/get-seeking-byte-from-fragmented-mp4.d.ts +9 -5
  26. package/dist/containers/iso-base-media/get-seeking-byte-from-fragmented-mp4.js +17 -4
  27. package/dist/containers/iso-base-media/get-seeking-byte.d.ts +2 -2
  28. package/dist/containers/iso-base-media/get-seeking-byte.js +5 -8
  29. package/dist/containers/iso-base-media/make-track.d.ts +2 -2
  30. package/dist/containers/iso-base-media/make-track.js +18 -17
  31. package/dist/containers/iso-base-media/mfra/find-best-segment-from-tfra.d.ts +2 -2
  32. package/dist/containers/iso-base-media/mfra/get-mfra-atom.d.ts +4 -4
  33. package/dist/containers/iso-base-media/mfra/get-mfro-atom.d.ts +4 -4
  34. package/dist/containers/iso-base-media/moov/moov.d.ts +2 -2
  35. package/dist/containers/iso-base-media/process-box.d.ts +5 -5
  36. package/dist/containers/iso-base-media/stsd/mebx.d.ts +2 -2
  37. package/dist/containers/iso-base-media/stsd/samples.d.ts +3 -3
  38. package/dist/containers/iso-base-media/stsd/stsd.d.ts +2 -2
  39. package/dist/containers/iso-base-media/trak/trak.d.ts +2 -2
  40. package/dist/containers/iso-base-media/traversal.d.ts +1 -0
  41. package/dist/containers/iso-base-media/traversal.js +13 -1
  42. package/dist/containers/m3u/after-manifest-fetch.d.ts +6 -6
  43. package/dist/containers/m3u/after-manifest-fetch.js +1 -1
  44. package/dist/containers/m3u/fetch-m3u8-stream.d.ts +2 -2
  45. package/dist/containers/m3u/first-sample-in-m3u-chunk.d.ts +3 -3
  46. package/dist/containers/m3u/first-sample-in-m3u-chunk.js +2 -8
  47. package/dist/containers/m3u/get-seeking-byte.d.ts +3 -3
  48. package/dist/containers/m3u/get-streams.d.ts +6 -6
  49. package/dist/containers/m3u/get-streams.js +9 -9
  50. package/dist/containers/m3u/parse-stream-inf.js +3 -3
  51. package/dist/containers/m3u/process-m3u-chunk.js +3 -3
  52. package/dist/containers/m3u/run-over-m3u.d.ts +2 -2
  53. package/dist/containers/m3u/sample-sorter.d.ts +7 -7
  54. package/dist/containers/m3u/types.d.ts +3 -3
  55. package/dist/containers/mp3/parse-mpeg-header.js +2 -3
  56. package/dist/containers/mp3/seek/audio-sample-from-cbr.d.ts +2 -2
  57. package/dist/containers/riff/get-tracks-from-avi.d.ts +4 -9
  58. package/dist/containers/riff/get-tracks-from-avi.js +19 -20
  59. package/dist/containers/riff/parse-video-section.js +1 -1
  60. package/dist/containers/riff/seek/fetch-idx1.d.ts +4 -4
  61. package/dist/containers/transport-stream/get-tracks.d.ts +2 -2
  62. package/dist/containers/transport-stream/get-tracks.js +1 -5
  63. package/dist/containers/transport-stream/handle-aac-packet.d.ts +4 -4
  64. package/dist/containers/transport-stream/handle-aac-packet.js +5 -4
  65. package/dist/containers/transport-stream/handle-avc-packet.d.ts +4 -4
  66. package/dist/containers/transport-stream/handle-avc-packet.js +10 -4
  67. package/dist/containers/transport-stream/process-audio.d.ts +5 -5
  68. package/dist/containers/transport-stream/process-stream-buffers.d.ts +8 -8
  69. package/dist/containers/transport-stream/process-video.d.ts +5 -5
  70. package/dist/containers/wav/parse-fmt.js +2 -3
  71. package/dist/containers/webm/color.d.ts +2 -2
  72. package/dist/containers/webm/color.js +6 -25
  73. package/dist/containers/webm/get-ready-tracks.d.ts +3 -3
  74. package/dist/containers/webm/get-sample-from-block.d.ts +7 -7
  75. package/dist/containers/webm/make-track.d.ts +3 -3
  76. package/dist/containers/webm/make-track.js +53 -21
  77. package/dist/containers/webm/parse-webm-header.js +5 -0
  78. package/dist/containers/webm/seek/fetch-web-cues.d.ts +4 -4
  79. package/dist/containers/webm/seek/get-seeking-byte.d.ts +2 -2
  80. package/dist/containers/webm/segments.d.ts +2 -2
  81. package/dist/containers/webm/segments.js +1 -1
  82. package/dist/containers/webm/state-for-processing.d.ts +5 -5
  83. package/dist/containers/webm/traversal.js +2 -1
  84. package/dist/controller/emitter.d.ts +2 -3
  85. package/dist/controller/seek-signal.d.ts +3 -9
  86. package/dist/controller/seek-signal.js +2 -2
  87. package/dist/convert-audio-or-video-sample.d.ts +4 -4
  88. package/dist/download-and-parse-media.js +1 -1
  89. package/dist/emit-available-info.js +9 -9
  90. package/dist/errors.d.ts +4 -18
  91. package/dist/errors.js +1 -15
  92. package/dist/esm/index.mjs +654 -544
  93. package/dist/esm/node.mjs +63 -51
  94. package/dist/esm/server-worker.mjs +13 -34
  95. package/dist/esm/universal.mjs +63 -51
  96. package/dist/esm/worker-server-entry.mjs +500 -388
  97. package/dist/esm/worker-web-entry.mjs +437 -337
  98. package/dist/esm/worker.mjs +14 -35
  99. package/dist/fields.d.ts +2 -2
  100. package/dist/file-types/bmp.d.ts +2 -2
  101. package/dist/file-types/detect-file-type.d.ts +2 -1
  102. package/dist/file-types/detect-file-type.js +1 -6
  103. package/dist/file-types/gif.d.ts +2 -0
  104. package/dist/file-types/gif.js +18 -0
  105. package/dist/file-types/index.js +4 -2
  106. package/dist/file-types/png.d.ts +2 -2
  107. package/dist/file-types/webp.d.ts +2 -2
  108. package/dist/get-audio-codec.d.ts +3 -4
  109. package/dist/get-audio-codec.js +44 -23
  110. package/dist/get-dimensions.d.ts +2 -2
  111. package/dist/get-dimensions.js +6 -3
  112. package/dist/get-duration.js +6 -7
  113. package/dist/get-fields-from-callbacks.js +1 -1
  114. package/dist/get-is-hdr.js +6 -5
  115. package/dist/get-sample-aspect-ratio.d.ts +5 -5
  116. package/dist/get-seeking-byte.d.ts +2 -2
  117. package/dist/get-tracks.d.ts +34 -44
  118. package/dist/get-tracks.js +6 -46
  119. package/dist/get-video-codec.d.ts +4 -3
  120. package/dist/get-video-codec.js +6 -6
  121. package/dist/has-all-info.js +1 -1
  122. package/dist/index.d.ts +114 -55
  123. package/dist/index.js +6 -4
  124. package/dist/init-video.js +4 -11
  125. package/dist/internal-parse-media.js +1 -1
  126. package/dist/log.d.ts +6 -6
  127. package/dist/metadata/get-metadata.js +6 -4
  128. package/dist/options.d.ts +19 -23
  129. package/dist/parse-loop.js +2 -2
  130. package/dist/parse-media-on-worker-entry.js +13 -5
  131. package/dist/parse-media.js +1 -1
  132. package/dist/perform-seek.d.ts +4 -4
  133. package/dist/readers/from-fetch.d.ts +2 -2
  134. package/dist/readers/from-node.d.ts +2 -2
  135. package/dist/readers/from-node.js +64 -55
  136. package/dist/readers/from-web-file.d.ts +2 -2
  137. package/dist/readers/reader.d.ts +5 -5
  138. package/dist/readers/universal.d.ts +2 -2
  139. package/dist/readers/web.d.ts +2 -2
  140. package/dist/register-track.d.ts +12 -12
  141. package/dist/remotion-license-acknowledge.d.ts +2 -2
  142. package/dist/seek-backwards.d.ts +4 -4
  143. package/dist/seek-forwards.d.ts +4 -4
  144. package/dist/server-worker.module.d.ts +2 -0
  145. package/dist/server-worker.module.js +12 -0
  146. package/dist/state/can-skip-tracks.js +1 -1
  147. package/dist/state/emitted-fields.js +1 -1
  148. package/dist/state/has-tracks-section.d.ts +5 -5
  149. package/dist/state/iso-base-media/cached-sample-positions.d.ts +3 -3
  150. package/dist/state/iso-base-media/cached-sample-positions.js +16 -7
  151. package/dist/state/iso-base-media/iso-state.d.ts +4 -4
  152. package/dist/state/iso-base-media/lazy-mfra-load.d.ts +4 -4
  153. package/dist/state/m3u-state.d.ts +11 -11
  154. package/dist/state/matroska/lazy-cues-fetch.d.ts +4 -4
  155. package/dist/state/matroska/webm.d.ts +4 -4
  156. package/dist/state/matroska/webm.js +1 -1
  157. package/dist/state/may-skip-video-data.d.ts +1 -0
  158. package/dist/state/may-skip-video-data.js +23 -2
  159. package/dist/state/need-samples-for-fields.js +1 -1
  160. package/dist/state/parser-state.d.ts +67 -38
  161. package/dist/state/riff/lazy-idx1-fetch.d.ts +4 -4
  162. package/dist/state/riff/sample-counter.d.ts +3 -3
  163. package/dist/state/riff.d.ts +6 -6
  164. package/dist/state/sample-callbacks.d.ts +12 -12
  165. package/dist/state/sample-callbacks.js +2 -2
  166. package/dist/state/samples-observed/slow-duration-fps.d.ts +3 -3
  167. package/dist/state/transport-stream/last-emitted-sample.d.ts +3 -3
  168. package/dist/state/transport-stream/transport-stream.d.ts +2 -2
  169. package/dist/version.d.ts +1 -1
  170. package/dist/version.js +1 -1
  171. package/dist/webcodec-sample-types.d.ts +21 -10
  172. package/dist/work-on-seek-request.d.ts +4 -4
  173. package/dist/work-on-seek-request.js +40 -43
  174. package/dist/worker/serialize-error.d.ts +2 -2
  175. package/dist/worker/serialize-error.js +7 -25
  176. package/dist/worker/worker-types.d.ts +22 -24
  177. package/dist/worker-server.d.ts +2 -2
  178. package/dist/worker-server.js +5 -5
  179. package/dist/writers/writer.d.ts +2 -2
  180. package/package.json +3 -3
@@ -914,10 +914,6 @@ var isMp3 = (data) => {
914
914
  const subarray = data.subarray(0, 4);
915
915
  return matchesPattern(mpegPattern)(subarray) || matchesPattern(mpegPattern2)(subarray) || matchesPattern(id3v4Pattern)(subarray) || matchesPattern(id3v3Pattern)(subarray) || matchesPattern(id3v2Pattern)(subarray);
916
916
  };
917
- var isGif = (data) => {
918
- const gifPattern = new Uint8Array([71, 73, 70, 56]);
919
- return matchesPattern(gifPattern)(data.subarray(0, 4));
920
- };
921
917
  var isAac = (data) => {
922
918
  const aacPattern = new Uint8Array([255, 241]);
923
919
  return matchesPattern(aacPattern)(data.subarray(0, 2));
@@ -950,6 +946,21 @@ var isBmp = (data) => {
950
946
  return null;
951
947
  };
952
948
 
949
+ // src/file-types/gif.ts
950
+ var getGifDimensions = (data) => {
951
+ const view = new DataView(data.buffer, data.byteOffset);
952
+ const width = view.getUint16(6, true);
953
+ const height = view.getUint16(8, true);
954
+ return { width, height };
955
+ };
956
+ var isGif = (data) => {
957
+ const gifPattern = new Uint8Array([71, 73, 70, 56]);
958
+ if (matchesPattern(gifPattern)(data.subarray(0, 4))) {
959
+ return { type: "gif", dimensions: getGifDimensions(data) };
960
+ }
961
+ return null;
962
+ };
963
+
953
964
  // src/file-types/jpeg.ts
954
965
  function getJpegDimensions(data) {
955
966
  let offset = 0;
@@ -1095,8 +1106,9 @@ var detectFileType = (data) => {
1095
1106
  if (isMp3(data)) {
1096
1107
  return { type: "mp3" };
1097
1108
  }
1098
- if (isGif(data)) {
1099
- return { type: "gif" };
1109
+ const gif = isGif(data);
1110
+ if (gif) {
1111
+ return gif;
1100
1112
  }
1101
1113
  const png = isPng(data);
1102
1114
  if (png) {
@@ -1830,7 +1842,8 @@ var addAvcProfileToTrack = (track, avc1Profile) => {
1830
1842
  return {
1831
1843
  ...track,
1832
1844
  codec: getCodecStringFromSpsAndPps(avc1Profile.sps),
1833
- codecPrivate: createSpsPpsData(avc1Profile)
1845
+ codecData: { type: "avc-sps-pps", data: createSpsPpsData(avc1Profile) },
1846
+ description: undefined
1834
1847
  };
1835
1848
  };
1836
1849
 
@@ -2250,6 +2263,19 @@ var getTfraBoxes = (structure) => {
2250
2263
  }
2251
2264
  return getTfraBoxesFromMfraBoxChildren(mfraBox.children);
2252
2265
  };
2266
+ var getTrakBoxByTrackId = (moovBox, trackId) => {
2267
+ const trakBoxes = getTraks(moovBox);
2268
+ return trakBoxes.find((t) => {
2269
+ const tkhd = getTkhdBox(t);
2270
+ if (!tkhd) {
2271
+ return false;
2272
+ }
2273
+ return tkhd.trackId === trackId;
2274
+ }) ?? null;
2275
+ };
2276
+
2277
+ // src/containers/riff/timescale.ts
2278
+ var MEDIA_PARSER_RIFF_TIMESCALE = 1e6;
2253
2279
 
2254
2280
  // src/containers/riff/traversal.ts
2255
2281
  var isRiffAvi2 = (structure) => {
@@ -2276,179 +2302,6 @@ var getStrhBox = (strlBoxChildren) => {
2276
2302
  return strlBoxChildren.find((box) => box.type === "strh-box");
2277
2303
  };
2278
2304
 
2279
- // src/is-audio-structure.ts
2280
- var isAudioStructure = (structure) => {
2281
- if (structure.type === "mp3") {
2282
- return true;
2283
- }
2284
- if (structure.type === "wav") {
2285
- return true;
2286
- }
2287
- if (structure.type === "aac") {
2288
- return true;
2289
- }
2290
- if (structure.type === "flac") {
2291
- return true;
2292
- }
2293
- if (structure.type === "iso-base-media") {
2294
- return false;
2295
- }
2296
- if (structure.type === "matroska") {
2297
- return false;
2298
- }
2299
- if (structure.type === "transport-stream") {
2300
- return false;
2301
- }
2302
- if (structure.type === "riff") {
2303
- return false;
2304
- }
2305
- if (structure.type === "m3u") {
2306
- return false;
2307
- }
2308
- throw new Error(`Unhandled structure type: ${structure}`);
2309
- };
2310
-
2311
- // src/get-fps.ts
2312
- var calculateFps = ({
2313
- sttsBox,
2314
- timeScale,
2315
- durationInSamples
2316
- }) => {
2317
- let totalSamples = 0;
2318
- for (const sample of sttsBox.sampleDistribution) {
2319
- totalSamples += sample.sampleCount;
2320
- }
2321
- if (totalSamples === 0) {
2322
- return null;
2323
- }
2324
- const durationInSeconds = durationInSamples / timeScale;
2325
- const fps = totalSamples / durationInSeconds;
2326
- return fps;
2327
- };
2328
- var trakBoxContainsAudio = (trakBox) => {
2329
- const stsd = getStsdBox(trakBox);
2330
- if (!stsd) {
2331
- return false;
2332
- }
2333
- const videoSample = stsd.samples.find((s) => s.type === "audio");
2334
- if (!videoSample || videoSample.type !== "audio") {
2335
- return false;
2336
- }
2337
- return true;
2338
- };
2339
- var trakBoxContainsVideo = (trakBox) => {
2340
- const stsd = getStsdBox(trakBox);
2341
- if (!stsd) {
2342
- return false;
2343
- }
2344
- const videoSample = stsd.samples.find((s) => s.type === "video");
2345
- if (!videoSample || videoSample.type !== "video") {
2346
- return false;
2347
- }
2348
- return true;
2349
- };
2350
- var getTimescaleAndDuration = (trakBox) => {
2351
- const mdhdBox = getMdhdBox(trakBox);
2352
- if (mdhdBox) {
2353
- return { timescale: mdhdBox.timescale, duration: mdhdBox.duration };
2354
- }
2355
- return null;
2356
- };
2357
- var getFpsFromMp4TrakBox = (trakBox) => {
2358
- const timescaleAndDuration = getTimescaleAndDuration(trakBox);
2359
- if (!timescaleAndDuration) {
2360
- return null;
2361
- }
2362
- const sttsBox = getSttsBox(trakBox);
2363
- if (!sttsBox) {
2364
- return null;
2365
- }
2366
- return calculateFps({
2367
- sttsBox,
2368
- timeScale: timescaleAndDuration.timescale,
2369
- durationInSamples: timescaleAndDuration.duration
2370
- });
2371
- };
2372
- var getFpsFromIsoMaseMedia = (state) => {
2373
- const moovBox = getMoovBoxFromState({
2374
- structureState: state.structure,
2375
- isoState: state.iso,
2376
- mp4HeaderSegment: state.m3uPlaylistContext?.mp4HeaderSegment ?? null,
2377
- mayUsePrecomputed: true
2378
- });
2379
- if (!moovBox) {
2380
- return null;
2381
- }
2382
- const trackBoxes = getTraks(moovBox);
2383
- const trackBox = trackBoxes.find(trakBoxContainsVideo);
2384
- if (!trackBox) {
2385
- return null;
2386
- }
2387
- return getFpsFromMp4TrakBox(trackBox);
2388
- };
2389
- var getFpsFromAvi = (structure) => {
2390
- const strl = getStrlBoxes(structure);
2391
- for (const s of strl) {
2392
- const strh = getStrhBox(s.children);
2393
- if (!strh) {
2394
- throw new Error("No strh box");
2395
- }
2396
- if (strh.fccType === "auds") {
2397
- continue;
2398
- }
2399
- return strh.rate;
2400
- }
2401
- return null;
2402
- };
2403
- var getFps = (state) => {
2404
- const segments = state.structure.getStructure();
2405
- if (segments.type === "iso-base-media") {
2406
- return getFpsFromIsoMaseMedia(state);
2407
- }
2408
- if (segments.type === "riff") {
2409
- return getFpsFromAvi(segments);
2410
- }
2411
- if (segments.type === "matroska") {
2412
- return null;
2413
- }
2414
- if (segments.type === "transport-stream") {
2415
- return null;
2416
- }
2417
- if (segments.type === "m3u") {
2418
- return null;
2419
- }
2420
- if (segments.type === "mp3" || segments.type === "wav" || segments.type === "flac" || segments.type === "aac") {
2421
- return null;
2422
- }
2423
- throw new Error("Cannot get fps, not implemented: " + segments);
2424
- };
2425
- var hasFpsSuitedForSlowFps = (state) => {
2426
- try {
2427
- return getFps(state) !== null;
2428
- } catch {
2429
- return false;
2430
- }
2431
- };
2432
- var hasFps = (state) => {
2433
- const structure = state.structure.getStructure();
2434
- if (isAudioStructure(structure)) {
2435
- return true;
2436
- }
2437
- if (structure.type === "matroska") {
2438
- return true;
2439
- }
2440
- if (structure.type === "transport-stream") {
2441
- return true;
2442
- }
2443
- if (structure.type === "m3u") {
2444
- return true;
2445
- }
2446
- return hasFpsSuitedForSlowFps(state);
2447
- };
2448
-
2449
- // src/containers/riff/timescale.ts
2450
- var MEDIA_PARSER_RIFF_TIMESCALE = 1e6;
2451
-
2452
2305
  // src/containers/riff/get-tracks-from-avi.ts
2453
2306
  var TO_BE_OVERRIDDEN_LATER = "to-be-overriden-later";
2454
2307
  var getNumberOfTracks = (structure) => {
@@ -2468,14 +2321,13 @@ var makeAviAudioTrack = ({
2468
2321
  return {
2469
2322
  type: "audio",
2470
2323
  codec: "mp4a.40.2",
2471
- codecPrivate: new Uint8Array([18, 16]),
2472
- codecWithoutConfig: "aac",
2324
+ codecData: { type: "aac-config", data: new Uint8Array([18, 16]) },
2325
+ codecEnum: "aac",
2473
2326
  description: new Uint8Array([18, 16]),
2474
2327
  numberOfChannels: strf.numberOfChannels,
2475
2328
  sampleRate: strf.sampleRate,
2476
2329
  timescale: MEDIA_PARSER_RIFF_TIMESCALE,
2477
- trackId: index,
2478
- trakBox: null
2330
+ trackId: index
2479
2331
  };
2480
2332
  };
2481
2333
  var makeAviVideoTrack = ({
@@ -2487,9 +2339,9 @@ var makeAviVideoTrack = ({
2487
2339
  throw new Error(`Unsupported video codec ${strh.handler}`);
2488
2340
  }
2489
2341
  return {
2490
- codecPrivate: null,
2342
+ codecData: null,
2491
2343
  codec: TO_BE_OVERRIDDEN_LATER,
2492
- codecWithoutConfig: "h264",
2344
+ codecEnum: "h264",
2493
2345
  codedHeight: strf.height,
2494
2346
  codedWidth: strf.width,
2495
2347
  width: strf.width,
@@ -2500,14 +2352,19 @@ var makeAviVideoTrack = ({
2500
2352
  description: undefined,
2501
2353
  m3uStreamFormat: null,
2502
2354
  trackId: index,
2503
- color: {
2355
+ colorSpace: {
2356
+ fullRange: null,
2357
+ matrix: null,
2358
+ primaries: null,
2359
+ transfer: null
2360
+ },
2361
+ advancedColor: {
2504
2362
  fullRange: null,
2505
- matrixCoefficients: null,
2363
+ matrix: null,
2506
2364
  primaries: null,
2507
- transferCharacteristics: null
2365
+ transfer: null
2508
2366
  },
2509
2367
  displayAspectWidth: strf.width,
2510
- trakBox: null,
2511
2368
  rotation: 0,
2512
2369
  sampleAspectRatio: {
2513
2370
  numerator: 1,
@@ -2517,9 +2374,7 @@ var makeAviVideoTrack = ({
2517
2374
  };
2518
2375
  };
2519
2376
  var getTracksFromAvi = (structure, state) => {
2520
- const videoTracks = [];
2521
- const audioTracks = [];
2522
- const otherTracks = [];
2377
+ const tracks2 = [];
2523
2378
  const boxes = getStrlBoxes(structure);
2524
2379
  let i = 0;
2525
2380
  for (const box of boxes) {
@@ -2529,22 +2384,22 @@ var getTracksFromAvi = (structure, state) => {
2529
2384
  }
2530
2385
  const { strf } = strh;
2531
2386
  if (strf.type === "strf-box-video") {
2532
- videoTracks.push(addAvcProfileToTrack(makeAviVideoTrack({ strh, strf, index: i }), state.riff.getAvcProfile()));
2387
+ tracks2.push(addAvcProfileToTrack(makeAviVideoTrack({ strh, strf, index: i }), state.riff.getAvcProfile()));
2533
2388
  } else if (strh.fccType === "auds") {
2534
- audioTracks.push(makeAviAudioTrack({ strf, index: i }));
2389
+ tracks2.push(makeAviAudioTrack({ strf, index: i }));
2535
2390
  } else {
2536
2391
  throw new Error(`Unsupported track type ${strh.fccType}`);
2537
2392
  }
2538
2393
  i++;
2539
2394
  }
2540
- return { audioTracks, otherTracks, videoTracks };
2395
+ return tracks2;
2541
2396
  };
2542
2397
  var hasAllTracksFromAvi = (state) => {
2543
2398
  try {
2544
2399
  const structure = state.structure.getRiffStructure();
2545
2400
  const numberOfTracks = getNumberOfTracks(structure);
2546
2401
  const tracks2 = getTracksFromAvi(structure, state);
2547
- return tracks2.videoTracks.length + tracks2.audioTracks.length + tracks2.otherTracks.length === numberOfTracks && !tracks2.videoTracks.find((t) => t.codec === TO_BE_OVERRIDDEN_LATER);
2402
+ return tracks2.length === numberOfTracks && !tracks2.find((t) => t.type === "video" && t.codec === TO_BE_OVERRIDDEN_LATER);
2548
2403
  } catch {
2549
2404
  return false;
2550
2405
  }
@@ -2597,11 +2452,7 @@ var getTracksFromTransportStream = (parserState) => {
2597
2452
  if (mapped.length !== filterStreamsBySupportedTypes(programMapTable.streams).length) {
2598
2453
  throw new Error("Not all tracks found");
2599
2454
  }
2600
- return {
2601
- videoTracks: mapped.filter((track) => track.type === "video"),
2602
- audioTracks: mapped.filter((track) => track.type === "audio"),
2603
- otherTracks: []
2604
- };
2455
+ return mapped;
2605
2456
  };
2606
2457
  var hasAllTracksFromTransportStream = (parserState) => {
2607
2458
  try {
@@ -2646,6 +2497,16 @@ var getHvc1CodecString = (data) => {
2646
2497
  return `${profileSpaceChar}${generalProfileIdc.toString(16)}.${profileId.toString(16)}.${generalTierChar}${generalLevelIdc}${generalConstraintString ? "." : ""}${generalConstraintString}`;
2647
2498
  };
2648
2499
 
2500
+ // src/containers/iso-base-media/color-to-webcodecs-colors.ts
2501
+ var mediaParserAdvancedColorToWebCodecsColor = (color2) => {
2502
+ return {
2503
+ transfer: color2.transfer,
2504
+ matrix: color2.matrix,
2505
+ primaries: color2.primaries,
2506
+ fullRange: color2.fullRange
2507
+ };
2508
+ };
2509
+
2649
2510
  // src/containers/webm/av1-codec-private.ts
2650
2511
  var parseAv1PrivateData = (data, colrAtom) => {
2651
2512
  const iterator = getArrayBufferIterator(data, data.byteLength);
@@ -2708,9 +2569,68 @@ var parseAv1PrivateData = (data, colrAtom) => {
2708
2569
  return str;
2709
2570
  };
2710
2571
 
2572
+ // src/containers/avc/color.ts
2573
+ var getMatrixCoefficientsFromIndex = (index) => {
2574
+ if (index === 0) {
2575
+ return "rgb";
2576
+ }
2577
+ if (index === 1) {
2578
+ return "bt709";
2579
+ }
2580
+ if (index === 5) {
2581
+ return "bt470bg";
2582
+ }
2583
+ if (index === 6) {
2584
+ return "smpte170m";
2585
+ }
2586
+ if (index === 9) {
2587
+ return "bt2020-ncl";
2588
+ }
2589
+ return null;
2590
+ };
2591
+ var getTransferCharacteristicsFromIndex = (index) => {
2592
+ if (index === 1) {
2593
+ return "bt709";
2594
+ }
2595
+ if (index === 6) {
2596
+ return "smpte170m";
2597
+ }
2598
+ if (index === 8) {
2599
+ return "linear";
2600
+ }
2601
+ if (index === 13) {
2602
+ return "iec61966-2-1";
2603
+ }
2604
+ if (index === 16) {
2605
+ return "pq";
2606
+ }
2607
+ if (index === 18) {
2608
+ return "hlg";
2609
+ }
2610
+ return null;
2611
+ };
2612
+ var getPrimariesFromIndex = (index) => {
2613
+ if (index === 1) {
2614
+ return "bt709";
2615
+ }
2616
+ if (index === 5) {
2617
+ return "bt470bg";
2618
+ }
2619
+ if (index === 6) {
2620
+ return "smpte170m";
2621
+ }
2622
+ if (index === 9) {
2623
+ return "bt2020";
2624
+ }
2625
+ if (index === 12) {
2626
+ return "smpte432";
2627
+ }
2628
+ return null;
2629
+ };
2630
+
2711
2631
  // src/containers/webm/traversal.ts
2712
2632
  var getMainSegment = (segments) => {
2713
- return segments.find((s) => s.type === "Segment");
2633
+ return segments.find((s) => s.type === "Segment") ?? null;
2714
2634
  };
2715
2635
  var getTrackCodec = (track) => {
2716
2636
  const child = track.value.find((b) => b.type === "CodecID");
@@ -2925,9 +2845,9 @@ var parseColorSegment = (colourSegment) => {
2925
2845
  const primaries2 = getPrimariesSegment(colourSegment);
2926
2846
  const range2 = getRangeSegment(colourSegment);
2927
2847
  return {
2928
- transferCharacteristics: transferCharacteristics2 ? transferCharacteristics2.value.value === 1 ? "bt709" : transferCharacteristics2.value.value === 6 ? "smpte170m" : transferCharacteristics2.value.value === 13 ? "iec61966-2-1" : null : null,
2929
- matrixCoefficients: matrixCoefficients2 ? matrixCoefficients2.value.value === 1 ? "bt709" : matrixCoefficients2.value.value === 6 ? "smpte170m" : matrixCoefficients2.value.value === 5 ? "bt470bg" : null : null,
2930
- primaries: primaries2 ? primaries2.value.value === 1 ? "bt709" : primaries2.value.value === 6 ? "smpte170m" : primaries2.value.value === 5 ? "bt470bg" : null : null,
2848
+ transfer: transferCharacteristics2 ? getTransferCharacteristicsFromIndex(transferCharacteristics2.value.value) : null,
2849
+ matrix: matrixCoefficients2 ? getMatrixCoefficientsFromIndex(matrixCoefficients2.value.value) : null,
2850
+ primaries: primaries2 ? getPrimariesFromIndex(primaries2.value.value) : null,
2931
2851
  fullRange: transferCharacteristics2?.value.value && matrixCoefficients2?.value.value ? null : range2 ? Boolean(range2?.value.value) : null
2932
2852
  };
2933
2853
  };
@@ -3030,7 +2950,7 @@ var getDescription = (track) => {
3030
2950
  }
3031
2951
  return;
3032
2952
  };
3033
- var getMatroskaVideoCodecWithoutConfigString = ({
2953
+ var getMatroskaVideoCodecEnum = ({
3034
2954
  codecSegment: codec
3035
2955
  }) => {
3036
2956
  if (codec.value === "V_VP8") {
@@ -3085,7 +3005,7 @@ var getMatroskaVideoCodecString = ({
3085
3005
  }
3086
3006
  throw new Error(`Unknown codec: ${codec.value}`);
3087
3007
  };
3088
- var getMatroskaAudioCodecWithoutConfigString = ({
3008
+ var getMatroskaAudioCodecEnum = ({
3089
3009
  track
3090
3010
  }) => {
3091
3011
  const codec = getCodecSegment(track);
@@ -3190,6 +3110,28 @@ var getTrack = ({
3190
3110
  if (!codecString) {
3191
3111
  return null;
3192
3112
  }
3113
+ const codecEnum = getMatroskaVideoCodecEnum({
3114
+ codecSegment: codec
3115
+ });
3116
+ const codecData = codecPrivate2 === null ? null : codecEnum === "h264" ? { type: "avc-sps-pps", data: codecPrivate2 } : codecEnum === "av1" ? {
3117
+ type: "av1c-data",
3118
+ data: codecPrivate2
3119
+ } : codecEnum === "h265" ? {
3120
+ type: "hvcc-data",
3121
+ data: codecPrivate2
3122
+ } : codecEnum === "vp8" ? {
3123
+ type: "unknown-data",
3124
+ data: codecPrivate2
3125
+ } : codecEnum === "vp9" ? {
3126
+ type: "unknown-data",
3127
+ data: codecPrivate2
3128
+ } : null;
3129
+ const advancedColor = colour ? parseColorSegment(colour) : {
3130
+ fullRange: null,
3131
+ matrix: null,
3132
+ primaries: null,
3133
+ transfer: null
3134
+ };
3193
3135
  return {
3194
3136
  m3uStreamFormat: null,
3195
3137
  type: "video",
@@ -3208,17 +3150,10 @@ var getTrack = ({
3208
3150
  displayAspectHeight: displayHeight2 ? displayHeight2.value.value : height.value.value,
3209
3151
  displayAspectWidth: displayWidth2 ? displayWidth2.value.value : width.value.value,
3210
3152
  rotation: 0,
3211
- trakBox: null,
3212
- codecPrivate: codecPrivate2,
3213
- color: colour ? parseColorSegment(colour) : {
3214
- fullRange: null,
3215
- matrixCoefficients: null,
3216
- primaries: null,
3217
- transferCharacteristics: null
3218
- },
3219
- codecWithoutConfig: getMatroskaVideoCodecWithoutConfigString({
3220
- codecSegment: codec
3221
- }),
3153
+ codecData,
3154
+ colorSpace: mediaParserAdvancedColorToWebCodecsColor(advancedColor),
3155
+ advancedColor,
3156
+ codecEnum,
3222
3157
  fps: null
3223
3158
  };
3224
3159
  }
@@ -3229,17 +3164,17 @@ var getTrack = ({
3229
3164
  if (sampleRate === null) {
3230
3165
  throw new Error("Could not find sample rate or number of channels");
3231
3166
  }
3167
+ const codecString = getMatroskaAudioCodecString(track);
3232
3168
  return {
3233
3169
  type: "audio",
3234
3170
  trackId,
3235
- codec: getMatroskaAudioCodecString(track),
3171
+ codec: codecString,
3236
3172
  timescale,
3237
3173
  numberOfChannels,
3238
3174
  sampleRate,
3239
3175
  description: getAudioDescription(track),
3240
- trakBox: null,
3241
- codecPrivate: codecPrivate2,
3242
- codecWithoutConfig: getMatroskaAudioCodecWithoutConfigString({
3176
+ codecData: codecPrivate2 ? codecString === "opus" ? { type: "ogg-identification", data: codecPrivate2 } : { type: "unknown-data", data: codecPrivate2 } : null,
3177
+ codecEnum: getMatroskaAudioCodecEnum({
3243
3178
  track
3244
3179
  })
3245
3180
  };
@@ -3352,51 +3287,23 @@ var getHasTracks = (state, mayUsePrecomputed) => {
3352
3287
  throw new Error("Unknown container " + structure);
3353
3288
  };
3354
3289
  var getCategorizedTracksFromMatroska = (state) => {
3355
- const videoTracks = [];
3356
- const audioTracks = [];
3357
- const otherTracks = [];
3358
3290
  const { resolved } = getTracksFromMatroska({
3359
3291
  structureState: state.structure,
3360
3292
  webmState: state.webm
3361
3293
  });
3362
- for (const track of resolved) {
3363
- if (track.type === "video") {
3364
- videoTracks.push(track);
3365
- } else if (track.type === "audio") {
3366
- audioTracks.push(track);
3367
- } else if (track.type === "other") {
3368
- otherTracks.push(track);
3369
- }
3370
- }
3371
- return {
3372
- videoTracks,
3373
- audioTracks,
3374
- otherTracks
3375
- };
3294
+ return resolved;
3376
3295
  };
3377
3296
  var getTracksFromMoovBox = (moovBox) => {
3378
- const videoTracks = [];
3379
- const audioTracks = [];
3380
- const otherTracks = [];
3297
+ const mediaParserTracks = [];
3381
3298
  const tracks2 = getTraks(moovBox);
3382
3299
  for (const trakBox of tracks2) {
3383
3300
  const track = makeBaseMediaTrack(trakBox);
3384
3301
  if (!track) {
3385
3302
  continue;
3386
3303
  }
3387
- if (track.type === "video") {
3388
- videoTracks.push(track);
3389
- } else if (track.type === "audio") {
3390
- audioTracks.push(track);
3391
- } else if (track.type === "other") {
3392
- otherTracks.push(track);
3393
- }
3304
+ mediaParserTracks.push(track);
3394
3305
  }
3395
- return {
3396
- videoTracks,
3397
- audioTracks,
3398
- otherTracks
3399
- };
3306
+ return mediaParserTracks;
3400
3307
  };
3401
3308
  var getTracksFromIsoBaseMedia = ({
3402
3309
  mayUsePrecomputed,
@@ -3411,11 +3318,7 @@ var getTracksFromIsoBaseMedia = ({
3411
3318
  mayUsePrecomputed
3412
3319
  });
3413
3320
  if (!moovBox) {
3414
- return {
3415
- videoTracks: [],
3416
- audioTracks: [],
3417
- otherTracks: []
3418
- };
3321
+ return [];
3419
3322
  }
3420
3323
  return getTracksFromMoovBox(moovBox);
3421
3324
  };
@@ -3424,11 +3327,7 @@ var defaultGetTracks = (parserState) => {
3424
3327
  if (tracks2.length === 0) {
3425
3328
  throw new Error("No tracks found");
3426
3329
  }
3427
- return {
3428
- audioTracks: tracks2.filter((t) => t.type === "audio"),
3429
- otherTracks: [],
3430
- videoTracks: tracks2.filter((t) => t.type === "video")
3431
- };
3330
+ return tracks2;
3432
3331
  };
3433
3332
  var getTracks = (state, mayUsePrecomputed) => {
3434
3333
  const structure = state.structure.getStructure();
@@ -3458,16 +3357,15 @@ var getTracks = (state, mayUsePrecomputed) => {
3458
3357
  // src/get-audio-codec.ts
3459
3358
  var getAudioCodec = (parserState) => {
3460
3359
  const tracks2 = getTracks(parserState, true);
3461
- const allTracks = tracks2.audioTracks.length + tracks2.otherTracks.length + tracks2.videoTracks.length;
3462
- if (allTracks === 0) {
3360
+ if (tracks2.length === 0) {
3463
3361
  throw new Error("No tracks yet");
3464
3362
  }
3465
- const audioTrack = tracks2.audioTracks[0];
3363
+ const audioTrack = tracks2.find((t) => t.type === "audio");
3466
3364
  if (!audioTrack) {
3467
3365
  return null;
3468
3366
  }
3469
3367
  if (audioTrack.type === "audio") {
3470
- return audioTrack.codecWithoutConfig;
3368
+ return audioTrack.codecEnum;
3471
3369
  }
3472
3370
  return null;
3473
3371
  };
@@ -3524,7 +3422,7 @@ var getCodecPrivateFromTrak = (trakBox) => {
3524
3422
  if (!mp4a) {
3525
3423
  return null;
3526
3424
  }
3527
- return mp4a.asBytes;
3425
+ return { type: "aac-config", data: mp4a.asBytes };
3528
3426
  };
3529
3427
  var onSample = (sample, children) => {
3530
3428
  const child = children.find((c) => c.type === "esds-box");
@@ -3605,71 +3503,262 @@ var getAudioCodecStringFromTrak = (trak) => {
3605
3503
  if (codec.format === "lpcm") {
3606
3504
  return {
3607
3505
  codecString: "pcm-s16",
3608
- description: codec.description
3506
+ description: codec.description ? { type: "unknown-data", data: codec.description } : undefined
3609
3507
  };
3610
3508
  }
3611
3509
  if (codec.format === "twos") {
3612
3510
  return {
3613
3511
  codecString: "pcm-s16",
3614
- description: codec.description
3512
+ description: codec.description ? { type: "unknown-data", data: codec.description } : undefined
3615
3513
  };
3616
3514
  }
3617
3515
  if (codec.format === "in24") {
3618
3516
  return {
3619
3517
  codecString: "pcm-s24",
3620
- description: codec.description
3518
+ description: codec.description ? { type: "unknown-data", data: codec.description } : undefined
3519
+ };
3520
+ }
3521
+ const codecStringWithoutMp3Exception = [
3522
+ codec.format,
3523
+ codec.primarySpecificator ? codec.primarySpecificator.toString(16) : null,
3524
+ codec.secondarySpecificator ? codec.secondarySpecificator.toString().padStart(2, "0") : null
3525
+ ].filter(Boolean).join(".");
3526
+ const codecString = codecStringWithoutMp3Exception.toLowerCase() === "mp4a.6b" || codecStringWithoutMp3Exception.toLowerCase() === "mp4a.69" ? "mp3" : codecStringWithoutMp3Exception;
3527
+ if (codecString === "mp3") {
3528
+ return {
3529
+ codecString,
3530
+ description: codec.description ? {
3531
+ type: "unknown-data",
3532
+ data: codec.description
3533
+ } : undefined
3534
+ };
3535
+ }
3536
+ if (codecString.startsWith("mp4a.")) {
3537
+ return {
3538
+ codecString,
3539
+ description: codec.description ? {
3540
+ type: "aac-config",
3541
+ data: codec.description
3542
+ } : undefined
3621
3543
  };
3622
3544
  }
3623
- const codecStringWithoutMp3Exception = [
3624
- codec.format,
3625
- codec.primarySpecificator ? codec.primarySpecificator.toString(16) : null,
3626
- codec.secondarySpecificator ? codec.secondarySpecificator.toString().padStart(2, "0") : null
3627
- ].filter(Boolean).join(".");
3628
- const codecString = codecStringWithoutMp3Exception === "mp4a.6b" ? "mp3" : codecStringWithoutMp3Exception;
3629
- return {
3630
- codecString,
3631
- description: codec.description
3632
- };
3545
+ return {
3546
+ codecString,
3547
+ description: codec.description ? {
3548
+ type: "unknown-data",
3549
+ data: codec.description
3550
+ } : undefined
3551
+ };
3552
+ };
3553
+ var getAudioCodecFromAudioCodecInfo = (codec) => {
3554
+ if (codec.format === "twos") {
3555
+ return "pcm-s16";
3556
+ }
3557
+ if (codec.format === "in24") {
3558
+ return "pcm-s24";
3559
+ }
3560
+ if (codec.format === "lpcm") {
3561
+ return "pcm-s16";
3562
+ }
3563
+ if (codec.format === "sowt") {
3564
+ return "aiff";
3565
+ }
3566
+ if (codec.format === "ac-3") {
3567
+ return "ac3";
3568
+ }
3569
+ if (codec.format === "Opus") {
3570
+ return "opus";
3571
+ }
3572
+ if (codec.format === "mp4a") {
3573
+ if (codec.primarySpecificator === 64) {
3574
+ return "aac";
3575
+ }
3576
+ if (codec.primarySpecificator === 107) {
3577
+ return "mp3";
3578
+ }
3579
+ if (codec.primarySpecificator === null) {
3580
+ return "aac";
3581
+ }
3582
+ throw new Error("Unknown mp4a codec: " + codec.primarySpecificator);
3583
+ }
3584
+ throw new Error(`Unknown audio format: ${codec.format}`);
3585
+ };
3586
+ var getAudioCodecFromTrack = (track) => {
3587
+ const audioSample = getAudioCodecFromTrak(track);
3588
+ if (!audioSample) {
3589
+ throw new Error("Could not find audio sample");
3590
+ }
3591
+ return getAudioCodecFromAudioCodecInfo(audioSample);
3592
+ };
3593
+
3594
+ // src/is-audio-structure.ts
3595
+ var isAudioStructure = (structure) => {
3596
+ if (structure.type === "mp3") {
3597
+ return true;
3598
+ }
3599
+ if (structure.type === "wav") {
3600
+ return true;
3601
+ }
3602
+ if (structure.type === "aac") {
3603
+ return true;
3604
+ }
3605
+ if (structure.type === "flac") {
3606
+ return true;
3607
+ }
3608
+ if (structure.type === "iso-base-media") {
3609
+ return false;
3610
+ }
3611
+ if (structure.type === "matroska") {
3612
+ return false;
3613
+ }
3614
+ if (structure.type === "transport-stream") {
3615
+ return false;
3616
+ }
3617
+ if (structure.type === "riff") {
3618
+ return false;
3619
+ }
3620
+ if (structure.type === "m3u") {
3621
+ return false;
3622
+ }
3623
+ throw new Error(`Unhandled structure type: ${structure}`);
3624
+ };
3625
+
3626
+ // src/get-fps.ts
3627
+ var calculateFps = ({
3628
+ sttsBox,
3629
+ timeScale,
3630
+ durationInSamples
3631
+ }) => {
3632
+ let totalSamples = 0;
3633
+ for (const sample of sttsBox.sampleDistribution) {
3634
+ totalSamples += sample.sampleCount;
3635
+ }
3636
+ if (totalSamples === 0) {
3637
+ return null;
3638
+ }
3639
+ const durationInSeconds = durationInSamples / timeScale;
3640
+ const fps = totalSamples / durationInSeconds;
3641
+ return fps;
3642
+ };
3643
+ var trakBoxContainsAudio = (trakBox) => {
3644
+ const stsd = getStsdBox(trakBox);
3645
+ if (!stsd) {
3646
+ return false;
3647
+ }
3648
+ const videoSample = stsd.samples.find((s) => s.type === "audio");
3649
+ if (!videoSample || videoSample.type !== "audio") {
3650
+ return false;
3651
+ }
3652
+ return true;
3653
+ };
3654
+ var trakBoxContainsVideo = (trakBox) => {
3655
+ const stsd = getStsdBox(trakBox);
3656
+ if (!stsd) {
3657
+ return false;
3658
+ }
3659
+ const videoSample = stsd.samples.find((s) => s.type === "video");
3660
+ if (!videoSample || videoSample.type !== "video") {
3661
+ return false;
3662
+ }
3663
+ return true;
3664
+ };
3665
+ var getTimescaleAndDuration = (trakBox) => {
3666
+ const mdhdBox = getMdhdBox(trakBox);
3667
+ if (mdhdBox) {
3668
+ return { timescale: mdhdBox.timescale, duration: mdhdBox.duration };
3669
+ }
3670
+ return null;
3671
+ };
3672
+ var getFpsFromMp4TrakBox = (trakBox) => {
3673
+ const timescaleAndDuration = getTimescaleAndDuration(trakBox);
3674
+ if (!timescaleAndDuration) {
3675
+ return null;
3676
+ }
3677
+ const sttsBox = getSttsBox(trakBox);
3678
+ if (!sttsBox) {
3679
+ return null;
3680
+ }
3681
+ return calculateFps({
3682
+ sttsBox,
3683
+ timeScale: timescaleAndDuration.timescale,
3684
+ durationInSamples: timescaleAndDuration.duration
3685
+ });
3686
+ };
3687
+ var getFpsFromIsoMaseMedia = (state) => {
3688
+ const moovBox = getMoovBoxFromState({
3689
+ structureState: state.structure,
3690
+ isoState: state.iso,
3691
+ mp4HeaderSegment: state.m3uPlaylistContext?.mp4HeaderSegment ?? null,
3692
+ mayUsePrecomputed: true
3693
+ });
3694
+ if (!moovBox) {
3695
+ return null;
3696
+ }
3697
+ const trackBoxes = getTraks(moovBox);
3698
+ const trackBox = trackBoxes.find(trakBoxContainsVideo);
3699
+ if (!trackBox) {
3700
+ return null;
3701
+ }
3702
+ return getFpsFromMp4TrakBox(trackBox);
3703
+ };
3704
+ var getFpsFromAvi = (structure) => {
3705
+ const strl = getStrlBoxes(structure);
3706
+ for (const s of strl) {
3707
+ const strh = getStrhBox(s.children);
3708
+ if (!strh) {
3709
+ throw new Error("No strh box");
3710
+ }
3711
+ if (strh.fccType === "auds") {
3712
+ continue;
3713
+ }
3714
+ return strh.rate;
3715
+ }
3716
+ return null;
3633
3717
  };
3634
- var getAudioCodecFromAudioCodecInfo = (codec) => {
3635
- if (codec.format === "twos") {
3636
- return "pcm-s16";
3718
+ var getFps = (state) => {
3719
+ const segments = state.structure.getStructure();
3720
+ if (segments.type === "iso-base-media") {
3721
+ return getFpsFromIsoMaseMedia(state);
3637
3722
  }
3638
- if (codec.format === "in24") {
3639
- return "pcm-s24";
3723
+ if (segments.type === "riff") {
3724
+ return getFpsFromAvi(segments);
3640
3725
  }
3641
- if (codec.format === "lpcm") {
3642
- return "pcm-s16";
3726
+ if (segments.type === "matroska") {
3727
+ return null;
3643
3728
  }
3644
- if (codec.format === "sowt") {
3645
- return "aiff";
3729
+ if (segments.type === "transport-stream") {
3730
+ return null;
3646
3731
  }
3647
- if (codec.format === "ac-3") {
3648
- return "ac3";
3732
+ if (segments.type === "m3u") {
3733
+ return null;
3649
3734
  }
3650
- if (codec.format === "Opus") {
3651
- return "opus";
3735
+ if (segments.type === "mp3" || segments.type === "wav" || segments.type === "flac" || segments.type === "aac") {
3736
+ return null;
3652
3737
  }
3653
- if (codec.format === "mp4a") {
3654
- if (codec.primarySpecificator === 64) {
3655
- return "aac";
3656
- }
3657
- if (codec.primarySpecificator === 107) {
3658
- return "mp3";
3659
- }
3660
- if (codec.primarySpecificator === null) {
3661
- return "aac";
3662
- }
3663
- throw new Error("Unknown mp4a codec: " + codec.primarySpecificator);
3738
+ throw new Error("Cannot get fps, not implemented: " + segments);
3739
+ };
3740
+ var hasFpsSuitedForSlowFps = (state) => {
3741
+ try {
3742
+ return getFps(state) !== null;
3743
+ } catch {
3744
+ return false;
3664
3745
  }
3665
- throw new Error(`Unknown audio format: ${codec.format}`);
3666
3746
  };
3667
- var getAudioCodecFromTrack = (track) => {
3668
- const audioSample = getAudioCodecFromTrak(track);
3669
- if (!audioSample) {
3670
- throw new Error("Could not find audio sample");
3747
+ var hasFps = (state) => {
3748
+ const structure = state.structure.getStructure();
3749
+ if (isAudioStructure(structure)) {
3750
+ return true;
3671
3751
  }
3672
- return getAudioCodecFromAudioCodecInfo(audioSample);
3752
+ if (structure.type === "matroska") {
3753
+ return true;
3754
+ }
3755
+ if (structure.type === "transport-stream") {
3756
+ return true;
3757
+ }
3758
+ if (structure.type === "m3u") {
3759
+ return true;
3760
+ }
3761
+ return hasFpsSuitedForSlowFps(state);
3673
3762
  };
3674
3763
 
3675
3764
  // src/get-sample-aspect-ratio.ts
@@ -3803,21 +3892,10 @@ var getDisplayAspectRatio = ({
3803
3892
  return reduceFraction(num, den);
3804
3893
  };
3805
3894
 
3806
- // src/containers/avc/color.ts
3807
- var getMatrixCoefficientsFromIndex = (index) => {
3808
- return index === 1 ? "bt709" : index === 5 ? "bt470bg" : index === 6 ? "smpte170m" : index === 9 ? "bt2020" : null;
3809
- };
3810
- var getTransferCharacteristicsFromIndex = (index) => {
3811
- return index === 1 ? "bt709" : index === 6 ? "smpte170m" : index === 13 ? "iec61966-2-1" : index === 18 ? "arib-std-b67" : null;
3812
- };
3813
- var getPrimariesFromIndex = (index) => {
3814
- return index === 1 ? "bt709" : index === 5 ? "bt470bg" : index === 6 ? "smpte170m" : index === 9 ? "bt2020" : null;
3815
- };
3816
-
3817
3895
  // src/get-video-codec.ts
3818
3896
  var getVideoCodec = (state) => {
3819
3897
  const track = getTracks(state, true);
3820
- return track.videoTracks[0]?.codecWithoutConfig ?? null;
3898
+ return track.find((t) => t.type === "video")?.codecEnum ?? null;
3821
3899
  };
3822
3900
  var hasVideoCodec = (state) => {
3823
3901
  return getHasTracks(state, true);
@@ -3831,13 +3909,13 @@ var getVideoPrivateData = (trakBox) => {
3831
3909
  return null;
3832
3910
  }
3833
3911
  if (avccBox) {
3834
- return avccBox.privateData;
3912
+ return { type: "avc-sps-pps", data: avccBox.privateData };
3835
3913
  }
3836
3914
  if (hvccBox) {
3837
- return hvccBox.privateData;
3915
+ return { type: "hvcc-data", data: hvccBox.privateData };
3838
3916
  }
3839
3917
  if (av1cBox) {
3840
- return av1cBox.privateData;
3918
+ return { type: "av1c-data", data: av1cBox.privateData };
3841
3919
  }
3842
3920
  return null;
3843
3921
  };
@@ -3855,9 +3933,9 @@ var getIsoBmColrConfig = (trakBox) => {
3855
3933
  }
3856
3934
  return {
3857
3935
  fullRange: colrAtom.fullRangeFlag,
3858
- matrixCoefficients: getMatrixCoefficientsFromIndex(colrAtom.matrixIndex),
3936
+ matrix: getMatrixCoefficientsFromIndex(colrAtom.matrixIndex),
3859
3937
  primaries: getPrimariesFromIndex(colrAtom.primaries),
3860
- transferCharacteristics: getTransferCharacteristicsFromIndex(colrAtom.transfer)
3938
+ transfer: getTransferCharacteristicsFromIndex(colrAtom.transfer)
3861
3939
  };
3862
3940
  };
3863
3941
  var getVideoCodecString = (trakBox) => {
@@ -3889,16 +3967,27 @@ var getActualDecoderParameters = ({
3889
3967
  sampleRate
3890
3968
  }) => {
3891
3969
  if (audioCodec !== "aac") {
3892
- return { numberOfChannels, sampleRate, codecPrivate: codecPrivate2 };
3970
+ return {
3971
+ numberOfChannels,
3972
+ sampleRate,
3973
+ codecPrivate: codecPrivate2
3974
+ };
3893
3975
  }
3894
3976
  if (codecPrivate2 === null) {
3895
3977
  return { numberOfChannels, sampleRate, codecPrivate: codecPrivate2 };
3896
3978
  }
3897
- const parsed = parseAacCodecPrivate(codecPrivate2);
3979
+ if (codecPrivate2.type !== "aac-config") {
3980
+ throw new Error("Expected AAC codec private data");
3981
+ }
3982
+ const parsed = parseAacCodecPrivate(codecPrivate2.data);
3983
+ const actual = createAacCodecPrivate({
3984
+ ...parsed,
3985
+ codecPrivate: codecPrivate2.data
3986
+ });
3898
3987
  return {
3899
3988
  numberOfChannels: parsed.channelConfiguration,
3900
3989
  sampleRate: parsed.sampleRate,
3901
- codecPrivate: createAacCodecPrivate({ ...parsed, codecPrivate: codecPrivate2 })
3990
+ codecPrivate: { type: "aac-config", data: actual }
3902
3991
  };
3903
3992
  };
3904
3993
 
@@ -3968,10 +4057,10 @@ var makeBaseMediaTrack = (trakBox) => {
3968
4057
  }
3969
4058
  const { codecString, description } = getAudioCodecStringFromTrak(trakBox);
3970
4059
  const codecPrivate2 = getCodecPrivateFromTrak(trakBox) ?? description ?? null;
3971
- const codecWithoutConfig = getAudioCodecFromTrack(trakBox);
4060
+ const codecEnum = getAudioCodecFromTrack(trakBox);
3972
4061
  const actual = getActualDecoderParameters({
3973
- audioCodec: codecWithoutConfig,
3974
- codecPrivate: codecPrivate2,
4062
+ audioCodec: codecEnum,
4063
+ codecPrivate: codecPrivate2 ?? null,
3975
4064
  numberOfChannels,
3976
4065
  sampleRate
3977
4066
  });
@@ -3982,10 +4071,9 @@ var makeBaseMediaTrack = (trakBox) => {
3982
4071
  codec: codecString,
3983
4072
  numberOfChannels: actual.numberOfChannels,
3984
4073
  sampleRate: actual.sampleRate,
3985
- description: actual.codecPrivate ?? undefined,
3986
- trakBox,
3987
- codecPrivate: actual.codecPrivate,
3988
- codecWithoutConfig
4074
+ description: actual.codecPrivate?.data ?? undefined,
4075
+ codecData: actual.codecPrivate,
4076
+ codecEnum
3989
4077
  };
3990
4078
  }
3991
4079
  if (!trakBoxContainsVideo(trakBox)) {
@@ -4015,6 +4103,12 @@ var makeBaseMediaTrack = (trakBox) => {
4015
4103
  throw new Error("Could not find video codec");
4016
4104
  }
4017
4105
  const privateData = getVideoPrivateData(trakBox);
4106
+ const advancedColor = getIsoBmColrConfig(trakBox) ?? {
4107
+ fullRange: null,
4108
+ matrix: null,
4109
+ primaries: null,
4110
+ transfer: null
4111
+ };
4018
4112
  const track = {
4019
4113
  m3uStreamFormat: null,
4020
4114
  type: "video",
@@ -4030,15 +4124,10 @@ var makeBaseMediaTrack = (trakBox) => {
4030
4124
  displayAspectWidth,
4031
4125
  displayAspectHeight,
4032
4126
  rotation,
4033
- trakBox,
4034
- codecPrivate: privateData,
4035
- color: getIsoBmColrConfig(trakBox) ?? {
4036
- fullRange: null,
4037
- matrixCoefficients: null,
4038
- primaries: null,
4039
- transferCharacteristics: null
4040
- },
4041
- codecWithoutConfig: getVideoCodecFromIsoTrak(trakBox),
4127
+ codecData: privateData,
4128
+ colorSpace: mediaParserAdvancedColorToWebCodecsColor(advancedColor),
4129
+ advancedColor,
4130
+ codecEnum: getVideoCodecFromIsoTrak(trakBox),
4042
4131
  fps: getFpsFromMp4TrakBox(trakBox)
4043
4132
  };
4044
4133
  return track;
@@ -6336,28 +6425,6 @@ var postprocessEbml = async ({
6336
6425
  };
6337
6426
 
6338
6427
  // src/errors.ts
6339
- class IsAGifError extends Error {
6340
- mimeType;
6341
- sizeInBytes;
6342
- fileName;
6343
- constructor({
6344
- message,
6345
- mimeType,
6346
- sizeInBytes,
6347
- fileName
6348
- }) {
6349
- super(message);
6350
- this.name = "IsAGifError";
6351
- this.fileName = "IsAGifError";
6352
- this.mimeType = mimeType;
6353
- this.sizeInBytes = sizeInBytes;
6354
- this.fileName = fileName;
6355
- if (Error.captureStackTrace) {
6356
- Error.captureStackTrace(this, IsAGifError);
6357
- }
6358
- }
6359
- }
6360
-
6361
6428
  class IsAnImageError extends Error {
6362
6429
  imageType;
6363
6430
  dimensions;
@@ -6556,7 +6623,7 @@ var performedSeeksStats = () => {
6556
6623
 
6557
6624
  // src/controller/seek-signal.ts
6558
6625
  var makeSeekSignal = (emitter) => {
6559
- let seek2;
6626
+ let seek2 = null;
6560
6627
  return {
6561
6628
  seek: (seekRequest) => {
6562
6629
  seek2 = seekRequest;
@@ -6567,7 +6634,7 @@ var makeSeekSignal = (emitter) => {
6567
6634
  },
6568
6635
  clearSeekIfStillSame(previousSeek) {
6569
6636
  if (seek2 === previousSeek) {
6570
- seek2 = undefined;
6637
+ seek2 = null;
6571
6638
  return { hasChanged: false };
6572
6639
  }
6573
6640
  return { hasChanged: true };
@@ -6671,10 +6738,10 @@ var getM3uStreams = ({
6671
6738
  }
6672
6739
  boxes.push({
6673
6740
  src: readerInterface.createAdjacentFileSource(next.value, originalSrc),
6674
- averageBandwidth: str.averageBandwidth,
6675
- bandwidth: str.bandwidth,
6741
+ averageBandwidthInBitsPerSec: str.averageBandwidthInBitsPerSec,
6742
+ bandwidthInBitsPerSec: str.bandwidthInBitsPerSec,
6676
6743
  codecs: str.codecs,
6677
- resolution: str.resolution,
6744
+ dimensions: str.dimensions,
6678
6745
  associatedPlaylists
6679
6746
  });
6680
6747
  }
@@ -6683,11 +6750,11 @@ var getM3uStreams = ({
6683
6750
  return null;
6684
6751
  }
6685
6752
  const sorted = boxes.slice().sort((a, b) => {
6686
- const aResolution = a.resolution ? a.resolution.width * a.resolution.height : 0;
6687
- const bResolution = b.resolution ? b.resolution.width * b.resolution.height : 0;
6753
+ const aResolution = a.dimensions ? a.dimensions.width * a.dimensions.height : 0;
6754
+ const bResolution = b.dimensions ? b.dimensions.width * b.dimensions.height : 0;
6688
6755
  if (aResolution === bResolution) {
6689
- const bandwidthA = a.averageBandwidth ?? a.bandwidth ?? 0;
6690
- const bandwidthB = b.averageBandwidth ?? b.bandwidth ?? 0;
6756
+ const bandwidthA = a.averageBandwidthInBitsPerSec ?? a.bandwidthInBitsPerSec ?? 0;
6757
+ const bandwidthB = b.averageBandwidthInBitsPerSec ?? b.bandwidthInBitsPerSec ?? 0;
6691
6758
  return bandwidthB - bandwidthA;
6692
6759
  }
6693
6760
  return bResolution - aResolution;
@@ -6753,11 +6820,14 @@ var getDimensions = (state) => {
6753
6820
  if (structure && isAudioStructure(structure)) {
6754
6821
  return null;
6755
6822
  }
6756
- const { videoTracks } = getTracks(state, true);
6757
- if (!videoTracks.length) {
6823
+ const tracks2 = getTracks(state, true);
6824
+ if (!tracks2.length) {
6825
+ return null;
6826
+ }
6827
+ const firstVideoTrack = tracks2.find((t) => t.type === "video");
6828
+ if (!firstVideoTrack) {
6758
6829
  return null;
6759
6830
  }
6760
- const firstVideoTrack = videoTracks[0];
6761
6831
  return {
6762
6832
  width: firstVideoTrack.width,
6763
6833
  height: firstVideoTrack.height,
@@ -7341,15 +7411,14 @@ var getDurationFromIsoBaseMedia = (parserState) => {
7341
7411
  return mvhdBox.durationInSeconds;
7342
7412
  }
7343
7413
  const tracks2 = getTracks(parserState, true);
7344
- const allTracks = [
7345
- ...tracks2.videoTracks,
7346
- ...tracks2.audioTracks,
7347
- ...tracks2.otherTracks
7348
- ];
7349
- const allSamples = allTracks.map((t) => {
7414
+ const allSamples = tracks2.map((t) => {
7350
7415
  const { timescale: ts } = t;
7416
+ const trakBox = getTrakBoxByTrackId(moovBox, t.trackId);
7417
+ if (!trakBox) {
7418
+ return null;
7419
+ }
7351
7420
  const { samplePositions, isComplete } = getSamplePositionsFromTrack({
7352
- trakBox: t.trakBox,
7421
+ trakBox,
7353
7422
  moofBoxes,
7354
7423
  moofComplete: areSamplesComplete({ moofBoxes, tfraBoxes })
7355
7424
  });
@@ -7419,11 +7488,11 @@ var hasSlowDuration = (parserState) => {
7419
7488
 
7420
7489
  // src/get-is-hdr.ts
7421
7490
  var isVideoTrackHdr = (track) => {
7422
- return track.color.matrixCoefficients === "bt2020" && track.color.transferCharacteristics === "arib-std-b67" && track.color.primaries === "bt2020";
7491
+ return track.advancedColor.matrix === "bt2020-ncl" && (track.advancedColor.transfer === "hlg" || track.advancedColor.transfer === "pq") && track.advancedColor.primaries === "bt2020";
7423
7492
  };
7424
7493
  var getIsHdr = (state) => {
7425
- const { videoTracks } = getTracks(state, true);
7426
- return videoTracks.some((track) => isVideoTrackHdr(track));
7494
+ const tracks2 = getTracks(state, true);
7495
+ return tracks2.some((track) => track.type === "video" && isVideoTrackHdr(track));
7427
7496
  };
7428
7497
  var hasHdr = (state) => {
7429
7498
  return getHasTracks(state, true);
@@ -7431,19 +7500,28 @@ var hasHdr = (state) => {
7431
7500
 
7432
7501
  // src/containers/iso-base-media/get-keyframes.ts
7433
7502
  var getKeyframesFromIsoBaseMedia = (state) => {
7434
- const { videoTracks } = getTracksFromIsoBaseMedia({
7503
+ const tracks2 = getTracksFromIsoBaseMedia({
7435
7504
  isoState: state.iso,
7436
7505
  m3uPlaylistContext: state.m3uPlaylistContext,
7437
7506
  structure: state.structure,
7438
7507
  mayUsePrecomputed: true
7439
7508
  });
7509
+ const videoTracks = tracks2.filter((t) => t.type === "video");
7440
7510
  const structure = state.structure.getIsoStructure();
7441
7511
  const moofBoxes = getMoofBoxes(structure.boxes);
7442
7512
  const tfraBoxes = getTfraBoxes(structure.boxes);
7513
+ const moov = getMoovFromFromIsoStructure(structure);
7514
+ if (!moov) {
7515
+ return [];
7516
+ }
7443
7517
  const allSamples = videoTracks.map((t) => {
7444
7518
  const { timescale: ts } = t;
7519
+ const trakBox = getTrakBoxByTrackId(moov, t.trackId);
7520
+ if (!trakBox) {
7521
+ return [];
7522
+ }
7445
7523
  const { samplePositions, isComplete } = getSamplePositionsFromTrack({
7446
- trakBox: t.trakBox,
7524
+ trakBox,
7447
7525
  moofBoxes,
7448
7526
  moofComplete: areSamplesComplete({
7449
7527
  moofBoxes,
@@ -7731,7 +7809,7 @@ var hasMetadata = (structure) => {
7731
7809
  if (structure.type === "wav") {
7732
7810
  return getMetadataFromWav(structure) !== null;
7733
7811
  }
7734
- if (structure.type === "m3u" || structure.type === "transport-stream") {
7812
+ if (structure.type === "m3u" || structure.type === "transport-stream" || structure.type === "aac") {
7735
7813
  return true;
7736
7814
  }
7737
7815
  if (structure.type === "flac") {
@@ -7746,9 +7824,6 @@ var hasMetadata = (structure) => {
7746
7824
  if (structure.type === "riff") {
7747
7825
  return false;
7748
7826
  }
7749
- if (structure.type === "aac") {
7750
- return true;
7751
- }
7752
7827
  throw new Error("Unknown container " + structure);
7753
7828
  };
7754
7829
 
@@ -7896,10 +7971,18 @@ var findKeyframeBeforeTime = ({
7896
7971
 
7897
7972
  // src/containers/iso-base-media/find-track-to-seek.ts
7898
7973
  var findAnyTrackWithSamplePositions = (allTracks, struc) => {
7974
+ const moov = getMoovFromFromIsoStructure(struc);
7975
+ if (!moov) {
7976
+ return null;
7977
+ }
7899
7978
  for (const track of allTracks) {
7900
7979
  if (track.type === "video" || track.type === "audio") {
7980
+ const trakBox = getTrakBoxByTrackId(moov, track.trackId);
7981
+ if (!trakBox) {
7982
+ continue;
7983
+ }
7901
7984
  const { samplePositions } = getSamplePositionsFromTrack({
7902
- trakBox: track.trakBox,
7985
+ trakBox,
7903
7986
  moofBoxes: getMoofBoxes(struc.boxes),
7904
7987
  moofComplete: areSamplesComplete({
7905
7988
  moofBoxes: getMoofBoxes(struc.boxes),
@@ -7920,8 +8003,16 @@ var findTrackToSeek = (allTracks, structure) => {
7920
8003
  if (!firstVideoTrack) {
7921
8004
  return findAnyTrackWithSamplePositions(allTracks, struc);
7922
8005
  }
8006
+ const moov = getMoovFromFromIsoStructure(struc);
8007
+ if (!moov) {
8008
+ return null;
8009
+ }
8010
+ const trakBox = getTrakBoxByTrackId(moov, firstVideoTrack.trackId);
8011
+ if (!trakBox) {
8012
+ return null;
8013
+ }
7923
8014
  const { samplePositions } = getSamplePositionsFromTrack({
7924
- trakBox: firstVideoTrack.trakBox,
8015
+ trakBox,
7925
8016
  moofBoxes: getMoofBoxes(struc.boxes),
7926
8017
  moofComplete: areSamplesComplete({
7927
8018
  moofBoxes: getMoofBoxes(struc.boxes),
@@ -8054,15 +8145,30 @@ var getSeekingByteFromFragmentedMp4 = async ({
8054
8145
  logLevel,
8055
8146
  currentPosition,
8056
8147
  isoState,
8057
- allTracks,
8058
- isLastChunkInPlaylist
8148
+ tracks: tracks2,
8149
+ isLastChunkInPlaylist,
8150
+ structure,
8151
+ mp4HeaderSegment
8059
8152
  }) => {
8060
- const firstVideoTrack = allTracks.find((t) => t.type === "video");
8061
- const firstTrack = firstVideoTrack ?? allTracks.find((t) => t.type === "audio");
8153
+ const firstVideoTrack = tracks2.find((t) => t.type === "video");
8154
+ const firstTrack = firstVideoTrack ?? tracks2.find((t) => t.type === "audio");
8062
8155
  if (!firstTrack) {
8063
8156
  throw new Error("no video and no audio tracks");
8064
8157
  }
8065
- const tkhdBox = getTkhdBox(firstTrack.trakBox);
8158
+ const moov = getMoovBoxFromState({
8159
+ structureState: structure,
8160
+ isoState,
8161
+ mp4HeaderSegment,
8162
+ mayUsePrecomputed: true
8163
+ });
8164
+ if (!moov) {
8165
+ throw new Error("No moov atom found");
8166
+ }
8167
+ const trakBox = getTrakBoxByTrackId(moov, firstTrack.trackId);
8168
+ if (!trakBox) {
8169
+ throw new Error("No trak box found");
8170
+ }
8171
+ const tkhdBox = getTkhdBox(trakBox);
8066
8172
  if (!tkhdBox) {
8067
8173
  throw new Error("Expected tkhd box in trak box");
8068
8174
  }
@@ -8150,11 +8256,6 @@ var getSeekingByteFromIsoBaseMedia = ({
8150
8256
  structure,
8151
8257
  mayUsePrecomputed: false
8152
8258
  });
8153
- const allTracks = [
8154
- ...tracks2.videoTracks,
8155
- ...tracks2.audioTracks,
8156
- ...tracks2.otherTracks
8157
- ];
8158
8259
  const hasMoov = Boolean(getMoovBoxFromState({
8159
8260
  structureState: structure,
8160
8261
  isoState,
@@ -8174,11 +8275,13 @@ var getSeekingByteFromIsoBaseMedia = ({
8174
8275
  logLevel,
8175
8276
  currentPosition,
8176
8277
  isoState,
8177
- allTracks,
8178
- isLastChunkInPlaylist: m3uPlaylistContext?.isLastChunkInPlaylist ?? false
8278
+ tracks: tracks2,
8279
+ isLastChunkInPlaylist: m3uPlaylistContext?.isLastChunkInPlaylist ?? false,
8280
+ structure,
8281
+ mp4HeaderSegment: m3uPlaylistContext?.mp4HeaderSegment ?? null
8179
8282
  });
8180
8283
  }
8181
- const trackWithSamplePositions = findTrackToSeek(allTracks, structure);
8284
+ const trackWithSamplePositions = findTrackToSeek(tracks2, structure);
8182
8285
  if (!trackWithSamplePositions) {
8183
8286
  return Promise.resolve({
8184
8287
  type: "valid-but-must-wait"
@@ -8717,8 +8820,8 @@ var getVideoColorFromSps = (sps) => {
8717
8820
  const transferCharacteristics2 = sps.vui_parameters?.transfer_characteristics;
8718
8821
  const colorPrimaries = sps.vui_parameters?.colour_primaries;
8719
8822
  return {
8720
- matrixCoefficients: matrixCoefficients2 ? getMatrixCoefficientsFromIndex(matrixCoefficients2) : null,
8721
- transferCharacteristics: transferCharacteristics2 ? getTransferCharacteristicsFromIndex(transferCharacteristics2) : null,
8823
+ matrix: matrixCoefficients2 ? getMatrixCoefficientsFromIndex(matrixCoefficients2) : null,
8824
+ transfer: transferCharacteristics2 ? getTransferCharacteristicsFromIndex(transferCharacteristics2) : null,
8722
8825
  primaries: colorPrimaries ? getPrimariesFromIndex(colorPrimaries) : null,
8723
8826
  fullRange: sps.vui_parameters?.video_full_range_flag ?? null
8724
8827
  };
@@ -8768,6 +8871,8 @@ var handleAvcPacket = async ({
8768
8871
  trackId: programId,
8769
8872
  newOffset: startOffset
8770
8873
  });
8874
+ const codecPrivate2 = createSpsPpsData(spsAndPps);
8875
+ const advancedColor = getVideoColorFromSps(spsAndPps.sps.spsData);
8771
8876
  const track = {
8772
8877
  m3uStreamFormat: null,
8773
8878
  rotation: 0,
@@ -8775,7 +8880,7 @@ var handleAvcPacket = async ({
8775
8880
  type: "video",
8776
8881
  timescale: MPEG_TIMESCALE,
8777
8882
  codec: getCodecStringFromSpsAndPps(spsAndPps.sps),
8778
- codecPrivate: createSpsPpsData(spsAndPps),
8883
+ codecData: { type: "avc-sps-pps", data: codecPrivate2 },
8779
8884
  fps: null,
8780
8885
  codedWidth: dimensions.width,
8781
8886
  codedHeight: dimensions.height,
@@ -8783,14 +8888,14 @@ var handleAvcPacket = async ({
8783
8888
  width: dimensions.width,
8784
8889
  displayAspectWidth: dimensions.width,
8785
8890
  displayAspectHeight: dimensions.height,
8786
- trakBox: null,
8787
- codecWithoutConfig: "h264",
8891
+ codecEnum: "h264",
8788
8892
  description: undefined,
8789
8893
  sampleAspectRatio: {
8790
8894
  denominator: sampleAspectRatio.height,
8791
8895
  numerator: sampleAspectRatio.width
8792
8896
  },
8793
- color: getVideoColorFromSps(spsAndPps.sps.spsData)
8897
+ colorSpace: mediaParserAdvancedColorToWebCodecsColor(advancedColor),
8898
+ advancedColor
8794
8899
  };
8795
8900
  await registerVideoTrack({
8796
8901
  track,
@@ -9305,7 +9410,7 @@ var fieldsNeedSamplesMap = {
9305
9410
  name: false,
9306
9411
  rotation: false,
9307
9412
  size: false,
9308
- structure: false,
9413
+ slowStructure: false,
9309
9414
  tracks: false,
9310
9415
  unrotatedDimensions: false,
9311
9416
  videoCodec: false,
@@ -9508,49 +9613,46 @@ var turnSeekIntoByte = async ({
9508
9613
  type: "valid-but-must-wait"
9509
9614
  };
9510
9615
  }
9511
- if (seek2.type === "keyframe-before-time") {
9512
- if (seek2.timeInSeconds < 0) {
9513
- throw new Error(`Cannot seek to a negative time: ${JSON.stringify(seek2)}`);
9514
- }
9515
- const seekingHints = getSeekingHints({
9516
- riffState,
9517
- samplesObserved,
9518
- structureState,
9519
- mediaSectionState: mediaSectionState2,
9520
- isoState,
9521
- transportStream,
9522
- tracksState,
9523
- keyframesState: keyframes,
9524
- webmState,
9525
- flacState,
9526
- mp3State,
9527
- contentLength,
9528
- aacState,
9529
- m3uPlaylistContext
9530
- });
9531
- if (!seekingHints) {
9532
- Log.trace(logLevel, "No seeking info, cannot seek yet");
9533
- return {
9534
- type: "valid-but-must-wait"
9535
- };
9536
- }
9537
- const seekingByte = await getSeekingByte({
9538
- info: seekingHints,
9539
- time: seek2.timeInSeconds,
9540
- logLevel,
9541
- currentPosition: iterator.counter.getOffset(),
9542
- isoState,
9543
- transportStream,
9544
- webmState,
9545
- mediaSection: mediaSectionState2,
9546
- m3uPlaylistContext,
9547
- structure: structureState,
9548
- riffState,
9549
- m3uState
9550
- });
9551
- return seekingByte;
9616
+ if (seek2 < 0) {
9617
+ throw new Error(`Cannot seek to a negative time: ${JSON.stringify(seek2)}`);
9618
+ }
9619
+ const seekingHints = getSeekingHints({
9620
+ riffState,
9621
+ samplesObserved,
9622
+ structureState,
9623
+ mediaSectionState: mediaSectionState2,
9624
+ isoState,
9625
+ transportStream,
9626
+ tracksState,
9627
+ keyframesState: keyframes,
9628
+ webmState,
9629
+ flacState,
9630
+ mp3State,
9631
+ contentLength,
9632
+ aacState,
9633
+ m3uPlaylistContext
9634
+ });
9635
+ if (!seekingHints) {
9636
+ Log.trace(logLevel, "No seeking info, cannot seek yet");
9637
+ return {
9638
+ type: "valid-but-must-wait"
9639
+ };
9552
9640
  }
9553
- throw new Error(`Cannot process seek request for ${seek2}: ${JSON.stringify(seek2)}`);
9641
+ const seekingByte = await getSeekingByte({
9642
+ info: seekingHints,
9643
+ time: seek2,
9644
+ logLevel,
9645
+ currentPosition: iterator.counter.getOffset(),
9646
+ isoState,
9647
+ transportStream,
9648
+ webmState,
9649
+ mediaSection: mediaSectionState2,
9650
+ m3uPlaylistContext,
9651
+ structure: structureState,
9652
+ riffState,
9653
+ m3uState
9654
+ });
9655
+ return seekingByte;
9554
9656
  };
9555
9657
  var getWorkOnSeekRequestOptions = (state) => {
9556
9658
  return {
@@ -9612,7 +9714,7 @@ var workOnSeekRequest = async (options) => {
9612
9714
  m3uState
9613
9715
  } = options;
9614
9716
  const seek2 = controller._internals.seekSignal.getSeek();
9615
- if (!seek2) {
9717
+ if (seek2 === null) {
9616
9718
  return;
9617
9719
  }
9618
9720
  Log.trace(logLevel, `Has seek request for ${src}: ${JSON.stringify(seek2)}`);
@@ -9705,13 +9807,13 @@ var emitAvailableInfo = async ({
9705
9807
  } = state;
9706
9808
  for (const key of keys) {
9707
9809
  await workOnSeekRequest(getWorkOnSeekRequestOptions(state));
9708
- if (key === "structure") {
9709
- if (hasInfo.structure && !emittedFields.structure) {
9710
- await callbackFunctions.onStructure?.(state.structure.getStructure());
9711
- if (fieldsInReturnValue.structure) {
9712
- returnValue.structure = state.structure.getStructure();
9810
+ if (key === "slowStructure") {
9811
+ if (hasInfo.slowStructure && !emittedFields.slowStructure) {
9812
+ await callbackFunctions.onSlowStructure?.(state.structure.getStructure());
9813
+ if (fieldsInReturnValue.slowStructure) {
9814
+ returnValue.slowStructure = state.structure.getStructure();
9713
9815
  }
9714
- emittedFields.structure = true;
9816
+ emittedFields.slowStructure = true;
9715
9817
  }
9716
9818
  continue;
9717
9819
  }
@@ -9839,10 +9941,10 @@ var emitAvailableInfo = async ({
9839
9941
  }
9840
9942
  if (key === "tracks") {
9841
9943
  if (!emittedFields.tracks && hasInfo.tracks) {
9842
- const { videoTracks, audioTracks } = getTracks(state, true);
9843
- await callbackFunctions.onTracks?.({ videoTracks, audioTracks });
9944
+ const tracks2 = getTracks(state, true);
9945
+ await callbackFunctions.onTracks?.(tracks2);
9844
9946
  if (fieldsInReturnValue.tracks) {
9845
- returnValue.tracks = { videoTracks, audioTracks };
9947
+ returnValue.tracks = tracks2;
9846
9948
  }
9847
9949
  emittedFields.tracks = true;
9848
9950
  }
@@ -10043,12 +10145,29 @@ var getHasCallbacks = (state) => {
10043
10145
  const hasAllTracksAndNoCallbacks = !state.callbacks.tracks.hasAllTracks() || Object.values(state.callbacks.videoSampleCallbacks).length > 0 || Object.values(state.callbacks.audioSampleCallbacks).length > 0;
10044
10146
  return hasAllTracksAndNoCallbacks;
10045
10147
  };
10148
+ var missesMatroskaTracks = (state) => {
10149
+ const struct = state.structure.getStructureOrNull();
10150
+ if (struct === null) {
10151
+ return false;
10152
+ }
10153
+ if (struct.type !== "matroska") {
10154
+ return false;
10155
+ }
10156
+ const mainSegment = getMainSegment(struct.boxes);
10157
+ if (mainSegment === null) {
10158
+ return false;
10159
+ }
10160
+ return getTracksFromMatroska({
10161
+ structureState: state.structure,
10162
+ webmState: state.webm
10163
+ }).missingInfo.length > 0;
10164
+ };
10046
10165
  var maySkipVideoData = ({ state }) => {
10047
10166
  const hasCallbacks = getHasCallbacks(state);
10048
10167
  return !hasCallbacks && !needsToIterateOverSamples({
10049
10168
  emittedFields: state.emittedFields,
10050
10169
  fields: state.fields
10051
- });
10170
+ }) && !missesMatroskaTracks(state);
10052
10171
  };
10053
10172
  var maySkipOverSamplesInTheMiddle = ({
10054
10173
  state
@@ -10068,7 +10187,7 @@ var getAvailableInfo = ({
10068
10187
  const structure = state.structure.getStructureOrNull();
10069
10188
  const infos = keys.map(([_key]) => {
10070
10189
  const key = _key;
10071
- if (key === "structure") {
10190
+ if (key === "slowStructure") {
10072
10191
  return false;
10073
10192
  }
10074
10193
  if (key === "durationInSeconds") {
@@ -10267,14 +10386,13 @@ var parseAac = async (state) => {
10267
10386
  container: "aac",
10268
10387
  track: {
10269
10388
  codec: mapAudioObjectTypeToCodecString(audioObjectType),
10270
- codecWithoutConfig: "aac",
10271
- codecPrivate: codecPrivate2,
10389
+ codecEnum: "aac",
10390
+ codecData: { type: "aac-config", data: codecPrivate2 },
10272
10391
  description: codecPrivate2,
10273
10392
  numberOfChannels: channelConfiguration,
10274
10393
  sampleRate,
10275
10394
  timescale: 1e6,
10276
10395
  trackId: 0,
10277
- trakBox: null,
10278
10396
  type: "audio"
10279
10397
  },
10280
10398
  registerAudioSampleCallback: state.callbacks.registerAudioSampleCallback,
@@ -10661,13 +10779,12 @@ var parseStreamInfo = async ({
10661
10779
  codec: "flac",
10662
10780
  type: "audio",
10663
10781
  description: asUint8Array,
10664
- codecPrivate: asUint8Array,
10665
- codecWithoutConfig: "flac",
10782
+ codecData: { type: "flac-description", data: asUint8Array },
10783
+ codecEnum: "flac",
10666
10784
  numberOfChannels: channels2,
10667
10785
  sampleRate,
10668
10786
  timescale: 1e6,
10669
- trackId: 0,
10670
- trakBox: null
10787
+ trackId: 0
10671
10788
  },
10672
10789
  registerAudioSampleCallback: state.callbacks.registerAudioSampleCallback,
10673
10790
  tracks: state.callbacks.tracks,
@@ -10749,11 +10866,6 @@ var calculateFlatSamples = ({
10749
10866
  mediaSectionStart
10750
10867
  }) => {
10751
10868
  const tracks2 = getTracks(state, true);
10752
- const allTracks = [
10753
- ...tracks2.videoTracks,
10754
- ...tracks2.audioTracks,
10755
- ...tracks2.otherTracks
10756
- ];
10757
10869
  const moofBoxes = getMoofBoxes(state.structure.getIsoStructure().boxes);
10758
10870
  const tfraBoxes = deduplicateTfraBoxesByOffset([
10759
10871
  ...state.iso.tfra.getTfraBoxes(),
@@ -10764,9 +10876,22 @@ var calculateFlatSamples = ({
10764
10876
  if (moofBoxes.length > 0 && !relevantMoofBox) {
10765
10877
  throw new Error("No relevant moof box found");
10766
10878
  }
10767
- const flatSamples = allTracks.map((track) => {
10879
+ const moov = getMoovBoxFromState({
10880
+ structureState: state.structure,
10881
+ isoState: state.iso,
10882
+ mp4HeaderSegment: state.m3uPlaylistContext?.mp4HeaderSegment ?? null,
10883
+ mayUsePrecomputed: true
10884
+ });
10885
+ if (!moov) {
10886
+ throw new Error("No moov box found");
10887
+ }
10888
+ const flatSamples = tracks2.map((track) => {
10889
+ const trakBox = getTrakBoxByTrackId(moov, track.trackId);
10890
+ if (!trakBox) {
10891
+ throw new Error("No trak box found");
10892
+ }
10768
10893
  const { samplePositions } = getSamplePositionsFromTrack({
10769
- trakBox: track.trakBox,
10894
+ trakBox,
10770
10895
  moofBoxes: relevantMoofBox ? [relevantMoofBox] : [],
10771
10896
  moofComplete
10772
10897
  });
@@ -10834,7 +10959,7 @@ var needsTracksForField = ({
10834
10959
  }
10835
10960
  return true;
10836
10961
  }
10837
- if (field === "audioCodec" || field === "durationInSeconds" || field === "slowDurationInSeconds" || field === "slowFps" || field === "fps" || field === "isHdr" || field === "rotation" || field === "structure" || field === "tracks" || field === "unrotatedDimensions" || field === "videoCodec" || field === "metadata" || field === "location" || field === "slowKeyframes" || field === "slowNumberOfFrames" || field === "keyframes" || field === "images" || field === "sampleRate" || field === "numberOfAudioChannels" || field === "slowAudioBitrate" || field === "slowVideoBitrate" || field === "m3uStreams") {
10962
+ if (field === "audioCodec" || field === "durationInSeconds" || field === "slowDurationInSeconds" || field === "slowFps" || field === "fps" || field === "isHdr" || field === "rotation" || field === "slowStructure" || field === "tracks" || field === "unrotatedDimensions" || field === "videoCodec" || field === "metadata" || field === "location" || field === "slowKeyframes" || field === "slowNumberOfFrames" || field === "keyframes" || field === "images" || field === "sampleRate" || field === "numberOfAudioChannels" || field === "slowAudioBitrate" || field === "slowVideoBitrate" || field === "m3uStreams") {
10838
10963
  return true;
10839
10964
  }
10840
10965
  if (field === "container" || field === "internalStats" || field === "mimeType" || field === "name" || field === "size") {
@@ -11034,7 +11159,7 @@ var getMoovAtom = async ({
11034
11159
  const boxes = [];
11035
11160
  const canSkipTracksState = makeCanSkipTracksState({
11036
11161
  hasAudioTrackHandlers: false,
11037
- fields: { structure: true },
11162
+ fields: { slowStructure: true },
11038
11163
  hasVideoTrackHandlers: false,
11039
11164
  structure: structureState()
11040
11165
  });
@@ -11409,10 +11534,10 @@ var parseStreamInf = (str) => {
11409
11534
  }
11410
11535
  return {
11411
11536
  type: "m3u-stream-info",
11412
- averageBandwidth: map["AVERAGE-BANDWIDTH"] ? parseInt(map["AVERAGE-BANDWIDTH"], 10) : null,
11413
- bandwidth: map.BANDWIDTH ? parseInt(map.BANDWIDTH, 10) : null,
11537
+ averageBandwidthInBitsPerSec: map["AVERAGE-BANDWIDTH"] ? parseInt(map["AVERAGE-BANDWIDTH"], 10) : null,
11538
+ bandwidthInBitsPerSec: map.BANDWIDTH ? parseInt(map.BANDWIDTH, 10) : null,
11414
11539
  codecs: map.CODECS ? map.CODECS.split(",") : null,
11415
- resolution: map.RESOLUTION ? {
11540
+ dimensions: map.RESOLUTION ? {
11416
11541
  width: parseInt(map.RESOLUTION.split("x")[0], 10),
11417
11542
  height: parseInt(map.RESOLUTION.split("x")[1], 10)
11418
11543
  } : null,
@@ -11676,7 +11801,7 @@ var afterManifestFetch = async ({
11676
11801
  throw new Error("No streams found");
11677
11802
  }
11678
11803
  const selectedPlaylist = await selectStream({ streams, fn: selectM3uStreamFn });
11679
- if (!selectedPlaylist.resolution) {
11804
+ if (!selectedPlaylist.dimensions) {
11680
11805
  throw new Error("Stream does not have a resolution");
11681
11806
  }
11682
11807
  m3uState.setSelectedMainPlaylist({
@@ -12113,7 +12238,7 @@ var parseMedia = (options) => {
12113
12238
  onSlowKeyframes: options.onSlowKeyframes ?? null,
12114
12239
  onSlowNumberOfFrames: options.onSlowNumberOfFrames ?? null,
12115
12240
  onSlowVideoBitrate: options.onSlowVideoBitrate ?? null,
12116
- onStructure: options.onStructure ?? null,
12241
+ onSlowStructure: options.onSlowStructure ?? null,
12117
12242
  onM3uStreams: options.onM3uStreams ?? null,
12118
12243
  onTracks: options.onTracks ?? null,
12119
12244
  onUnrotatedDimensions: options.onUnrotatedDimensions ?? null,
@@ -12155,16 +12280,10 @@ var considerSeekBasedOnChunk = async ({
12155
12280
  const timestamp = Math.min(sample.dts / sample.timescale, sample.cts / sample.timescale);
12156
12281
  if (timestamp > pendingSeek.targetTime && chunkIndex !== null && chunkIndex > 0) {
12157
12282
  m3uState.setNextSeekShouldSubtractChunks(playlistUrl, subtractChunks + 1);
12158
- parentController.seek({
12159
- type: "keyframe-before-time",
12160
- timeInSeconds: pendingSeek.targetTime
12161
- });
12283
+ parentController.seek(pendingSeek.targetTime);
12162
12284
  return;
12163
12285
  }
12164
- childController.seek({
12165
- type: "keyframe-before-time",
12166
- timeInSeconds: pendingSeek.targetTime
12167
- });
12286
+ childController.seek(pendingSeek.targetTime);
12168
12287
  m3uState.setNextSeekShouldSubtractChunks(playlistUrl, 0);
12169
12288
  m3uState.setSeekToSecondsToProcess(playlistUrl, null);
12170
12289
  };
@@ -12342,7 +12461,7 @@ var processM3uChunk = ({
12342
12461
  childController.pause();
12343
12462
  currentPromise.resolver(makeContinuationFn());
12344
12463
  },
12345
- fields: chunk.isHeader ? { structure: true } : undefined,
12464
+ fields: chunk.isHeader ? { slowStructure: true } : undefined,
12346
12465
  onTracks: () => {
12347
12466
  if (!state.m3u.hasEmittedDoneWithTracks(playlistUrl)) {
12348
12467
  state.m3u.setHasEmittedDoneWithTracks(playlistUrl);
@@ -12440,10 +12559,10 @@ var processM3uChunk = ({
12440
12559
  }
12441
12560
  });
12442
12561
  if (chunk.isHeader) {
12443
- if (data.structure.type !== "iso-base-media") {
12562
+ if (data.slowStructure.type !== "iso-base-media") {
12444
12563
  throw new Error("Expected an mp4 file");
12445
12564
  }
12446
- state.m3u.setMp4HeaderSegment(playlistUrl, data.structure);
12565
+ state.m3u.setMp4HeaderSegment(playlistUrl, data.slowStructure);
12447
12566
  }
12448
12567
  } catch (e) {
12449
12568
  currentPromise.rejector(e);
@@ -13017,14 +13136,13 @@ var parseMpegHeader = async ({
13017
13136
  track: {
13018
13137
  type: "audio",
13019
13138
  codec: "mp3",
13020
- codecPrivate: null,
13021
- codecWithoutConfig: "mp3",
13139
+ codecData: null,
13140
+ codecEnum: "mp3",
13022
13141
  description: undefined,
13023
13142
  numberOfChannels,
13024
13143
  sampleRate,
13025
13144
  timescale: 1e6,
13026
- trackId: 0,
13027
- trakBox: null
13145
+ trackId: 0
13028
13146
  },
13029
13147
  registerAudioSampleCallback: state.callbacks.registerAudioSampleCallback,
13030
13148
  tracks: state.callbacks.tracks,
@@ -13610,7 +13728,7 @@ var parseMediaSection = async (state) => {
13610
13728
  state
13611
13729
  });
13612
13730
  const tracks2 = getTracks(state, false);
13613
- if (!tracks2.videoTracks.some((t) => t.codec === TO_BE_OVERRIDDEN_LATER) && !state.callbacks.tracks.getIsDone()) {
13731
+ if (!tracks2.some((t) => t.type === "video" && t.codec === TO_BE_OVERRIDDEN_LATER) && !state.callbacks.tracks.getIsDone()) {
13614
13732
  state.callbacks.tracks.setIsDone(state.logLevel);
13615
13733
  }
13616
13734
  };
@@ -13990,13 +14108,12 @@ var handleAacPacket = async ({
13990
14108
  });
13991
14109
  const track = {
13992
14110
  type: "audio",
13993
- codecPrivate: codecPrivate2,
14111
+ codecData: { type: "aac-config", data: codecPrivate2 },
13994
14112
  trackId: programId,
13995
- trakBox: null,
13996
14113
  timescale: MPEG_TIMESCALE,
13997
- codecWithoutConfig: "aac",
14114
+ codecEnum: "aac",
13998
14115
  codec: mapAudioObjectTypeToCodecString(audioObjectType),
13999
- description: undefined,
14116
+ description: codecPrivate2,
14000
14117
  numberOfChannels: channelConfiguration,
14001
14118
  sampleRate
14002
14119
  };
@@ -14499,14 +14616,13 @@ var parseFmt = async ({
14499
14616
  track: {
14500
14617
  type: "audio",
14501
14618
  codec: format,
14502
- codecPrivate: null,
14619
+ codecData: null,
14503
14620
  description: undefined,
14504
- codecWithoutConfig: format,
14621
+ codecEnum: format,
14505
14622
  numberOfChannels,
14506
14623
  sampleRate,
14507
14624
  timescale: 1e6,
14508
- trackId: 0,
14509
- trakBox: null
14625
+ trackId: 0
14510
14626
  },
14511
14627
  container: "wav",
14512
14628
  registerAudioSampleCallback: state.callbacks.registerAudioSampleCallback,
@@ -14735,7 +14851,7 @@ var expectSegment = async ({
14735
14851
  }
14736
14852
  statesForProcessing.webmState.addCluster({
14737
14853
  start: offset,
14738
- size,
14854
+ size: size + (offsetAfterVInt - offset),
14739
14855
  segment: isInsideSegment.index
14740
14856
  });
14741
14857
  const newSegment = {
@@ -14825,6 +14941,9 @@ var parseWebm = async (state) => {
14825
14941
  return null;
14826
14942
  }
14827
14943
  if (isInsideCluster) {
14944
+ if (maySkipVideoData({ state })) {
14945
+ return makeSkip(Math.min(state.contentLength, isInsideCluster.size + isInsideCluster.start));
14946
+ }
14828
14947
  const segments = structure.boxes.filter((box) => box.type === "Segment");
14829
14948
  const segment = segments[isInsideCluster.segment];
14830
14949
  if (!segment) {
@@ -14869,7 +14988,7 @@ var initVideo = async ({ state }) => {
14869
14988
  throw new Error("No moov box found");
14870
14989
  }
14871
14990
  const tracks2 = getTracksFromMoovBox(moovAtom);
14872
- for (const track of tracks2.videoTracks) {
14991
+ for (const track of tracks2.filter((t) => t.type === "video")) {
14873
14992
  await registerVideoTrack({
14874
14993
  track,
14875
14994
  container: "mp4",
@@ -14879,7 +14998,7 @@ var initVideo = async ({ state }) => {
14879
14998
  tracks: state.callbacks.tracks
14880
14999
  });
14881
15000
  }
14882
- for (const track of tracks2.audioTracks) {
15001
+ for (const track of tracks2.filter((t) => t.type === "audio")) {
14883
15002
  await registerAudioTrack({
14884
15003
  track,
14885
15004
  container: "mp4",
@@ -14967,14 +15086,6 @@ var initVideo = async ({ state }) => {
14967
15086
  });
14968
15087
  return;
14969
15088
  }
14970
- if (fileType.type === "gif") {
14971
- return Promise.reject(new IsAGifError({
14972
- message: "GIF files are not yet supported",
14973
- mimeType,
14974
- sizeInBytes: contentLength,
14975
- fileName: name
14976
- }));
14977
- }
14978
15089
  if (fileType.type === "pdf") {
14979
15090
  return Promise.reject(new IsAPdfError({
14980
15091
  message: "GIF files are not supported",
@@ -14983,7 +15094,7 @@ var initVideo = async ({ state }) => {
14983
15094
  fileName: name
14984
15095
  }));
14985
15096
  }
14986
- if (fileType.type === "bmp" || fileType.type === "jpeg" || fileType.type === "png" || fileType.type === "webp") {
15097
+ if (fileType.type === "bmp" || fileType.type === "jpeg" || fileType.type === "png" || fileType.type === "webp" || fileType.type === "gif") {
14987
15098
  return Promise.reject(new IsAnImageError({
14988
15099
  message: "Image files are not supported",
14989
15100
  imageType: fileType.type,
@@ -15156,10 +15267,10 @@ var parseLoop = async ({
15156
15267
  }
15157
15268
  }
15158
15269
  state.samplesObserved.setLastSampleObserved();
15159
- if (state.controller._internals.seekSignal.getSeek()) {
15270
+ if (state.controller._internals.seekSignal.getSeek() !== null) {
15160
15271
  Log.verbose(state.logLevel, "Reached end of samples, but there is a pending seek. Trying to seek...");
15161
15272
  await workOnSeekRequest(getWorkOnSeekRequestOptions(state));
15162
- if (state.controller._internals.seekSignal.getSeek()) {
15273
+ if (state.controller._internals.seekSignal.getSeek() !== null) {
15163
15274
  throw new Error("Reached the end of the file even though a seek was requested. This is likely a bug in the parser. You can report this at https://remotion.dev/report and we will fix it as soon as possible.");
15164
15275
  }
15165
15276
  await parseLoop({
@@ -15259,7 +15370,7 @@ var getFieldsFromCallback = ({
15259
15370
  name: Boolean(callbacks.onName),
15260
15371
  rotation: Boolean(callbacks.onRotation),
15261
15372
  size: Boolean(callbacks.onSize),
15262
- structure: Boolean(callbacks.onStructure),
15373
+ slowStructure: Boolean(callbacks.onSlowStructure),
15263
15374
  tracks: Boolean(callbacks.onTracks),
15264
15375
  unrotatedDimensions: Boolean(callbacks.onUnrotatedDimensions),
15265
15376
  videoCodec: Boolean(callbacks.onVideoCodec),
@@ -15342,7 +15453,7 @@ var emittedState = () => {
15342
15453
  name: false,
15343
15454
  rotation: false,
15344
15455
  size: false,
15345
- structure: false,
15456
+ slowStructure: false,
15346
15457
  tracks: false,
15347
15458
  videoCodec: false,
15348
15459
  unrotatedDimensions: false,
@@ -16095,7 +16206,7 @@ var webmState = ({
16095
16206
  },
16096
16207
  isInsideCluster: (offset) => {
16097
16208
  for (const cluster of clusters) {
16098
- if (offset >= cluster.start && offset <= cluster.start + cluster.size) {
16209
+ if (offset >= cluster.start && offset < cluster.start + cluster.size) {
16099
16210
  return cluster;
16100
16211
  }
16101
16212
  }
@@ -16394,7 +16505,7 @@ var callbacksState = ({
16394
16505
  const callback = audioSampleCallbacks[trackId];
16395
16506
  if (audioSample.data.length > 0) {
16396
16507
  if (callback) {
16397
- if (seekSignal.getSeek()) {
16508
+ if (seekSignal.getSeek() !== null) {
16398
16509
  Log.trace(logLevel, "Not emitting sample because seek is processing");
16399
16510
  } else {
16400
16511
  await callback(audioSample);
@@ -16412,7 +16523,7 @@ var callbacksState = ({
16412
16523
  if (videoSample.data.length > 0) {
16413
16524
  const callback = videoSampleCallbacks[trackId];
16414
16525
  if (callback) {
16415
- if (seekSignal.getSeek()) {
16526
+ if (seekSignal.getSeek() !== null) {
16416
16527
  Log.trace(logLevel, "Not emitting sample because seek is processing");
16417
16528
  } else {
16418
16529
  await callback(videoSample);
@@ -16953,7 +17064,7 @@ var internalParseMedia = async function({
16953
17064
  if (state.errored) {
16954
17065
  throw state.errored;
16955
17066
  }
16956
- if (state.controller._internals.seekSignal.getSeek()) {
17067
+ if (state.controller._internals.seekSignal.getSeek() !== null) {
16957
17068
  throw new Error("Should not finish while a seek is pending");
16958
17069
  }
16959
17070
  return state.returnValue;
@@ -17001,7 +17112,7 @@ var downloadAndParseMedia = async (options) => {
17001
17112
  onSlowKeyframes: options.onSlowKeyframes ?? null,
17002
17113
  onSlowNumberOfFrames: options.onSlowNumberOfFrames ?? null,
17003
17114
  onSlowVideoBitrate: options.onSlowVideoBitrate ?? null,
17004
- onStructure: options.onStructure ?? null,
17115
+ onSlowStructure: options.onSlowStructure ?? null,
17005
17116
  onM3uStreams: options.onM3uStreams ?? null,
17006
17117
  onTracks: options.onTracks ?? null,
17007
17118
  onUnrotatedDimensions: options.onUnrotatedDimensions ?? null,
@@ -17029,7 +17140,7 @@ var downloadAndParseMedia = async (options) => {
17029
17140
  return returnValue;
17030
17141
  };
17031
17142
  // src/version.ts
17032
- var VERSION = "4.0.297";
17143
+ var VERSION = "4.0.300";
17033
17144
 
17034
17145
  // src/index.ts
17035
17146
  var MediaParserInternals = {
@@ -17060,6 +17171,5 @@ export {
17060
17171
  MediaParserAbortError,
17061
17172
  IsAnUnsupportedFileTypeError,
17062
17173
  IsAnImageError,
17063
- IsAPdfError,
17064
- IsAGifError
17174
+ IsAPdfError
17065
17175
  };