@remotion/media-parser 4.0.286 → 4.0.287

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 (225) hide show
  1. package/dist/containers/flac/get-channel-count.d.ts +1 -1
  2. package/dist/containers/iso-base-media/collect-sample-positions-from-moof-boxes.d.ts +2 -2
  3. package/dist/containers/iso-base-media/collect-sample-positions-from-moof-boxes.js +6 -3
  4. package/dist/containers/iso-base-media/get-keyframes.js +1 -1
  5. package/dist/containers/iso-base-media/get-sample-positions-from-track.d.ts +2 -2
  6. package/dist/containers/iso-base-media/get-seeking-byte.d.ts +15 -0
  7. package/dist/containers/iso-base-media/{get-seeking-from-mp4.js → get-seeking-byte.js} +16 -2
  8. package/dist/containers/iso-base-media/mdat/mdat.js +6 -3
  9. package/dist/containers/iso-base-media/process-box.js +5 -3
  10. package/dist/containers/iso-base-media/{get-seeking-info-from-mp4.d.ts → seeking-hints.d.ts} +8 -3
  11. package/dist/containers/iso-base-media/seeking-hints.js +52 -0
  12. package/dist/containers/iso-base-media/traversal.d.ts +4 -2
  13. package/dist/containers/iso-base-media/traversal.js +6 -5
  14. package/dist/containers/m3u/iterate-over-segment-files.js +23 -20
  15. package/dist/containers/riff/parse-video-section.js +1 -1
  16. package/dist/containers/transport-stream/handle-aac-packet.js +4 -1
  17. package/dist/containers/transport-stream/handle-avc-packet.js +4 -1
  18. package/dist/containers/transport-stream/seeking-hints.d.ts +9 -0
  19. package/dist/containers/transport-stream/seeking-hints.js +26 -0
  20. package/dist/containers/wav/get-seeking-byte.d.ts +2 -2
  21. package/dist/containers/wav/get-seeking-byte.js +2 -2
  22. package/dist/containers/wav/seeking-hints.d.ts +12 -0
  23. package/dist/containers/wav/seeking-hints.js +25 -0
  24. package/dist/containers/webm/seek/get-seeking-byte.d.ts +3 -5
  25. package/dist/containers/webm/seek/get-seeking-byte.js +5 -5
  26. package/dist/containers/webm/seek/seeking-hints.d.ts +10 -0
  27. package/dist/containers/webm/seek/seeking-hints.js +28 -0
  28. package/dist/controller/media-parser-controller.d.ts +3 -0
  29. package/dist/controller/media-parser-controller.js +15 -0
  30. package/dist/download-and-parse-media.js +2 -1
  31. package/dist/emit-available-info.js +1 -1
  32. package/dist/esm/index.mjs +430 -197
  33. package/dist/esm/node-writer.mjs +1 -2
  34. package/dist/esm/node.mjs +1 -2
  35. package/dist/esm/server-worker.mjs +46 -1
  36. package/dist/esm/universal.mjs +2 -4
  37. package/dist/esm/web.mjs +1 -2
  38. package/dist/esm/worker-server-entry.mjs +466 -204
  39. package/dist/esm/worker-web-entry.mjs +465 -202
  40. package/dist/esm/worker.mjs +46 -1
  41. package/dist/{forward-controller.d.ts → forward-controller-pause-resume-abort.d.ts} +1 -1
  42. package/dist/{forward-controller.js → forward-controller-pause-resume-abort.js} +3 -3
  43. package/dist/get-audio-codec.js +2 -2
  44. package/dist/get-dimensions.js +1 -1
  45. package/dist/get-duration.js +3 -2
  46. package/dist/get-fps.js +1 -0
  47. package/dist/get-is-hdr.js +2 -2
  48. package/dist/get-keyframes.js +1 -1
  49. package/dist/get-seeking-byte.d.ts +7 -5
  50. package/dist/get-seeking-byte.js +13 -12
  51. package/dist/{get-seeking-info.d.ts → get-seeking-hints.d.ts} +7 -3
  52. package/dist/get-seeking-hints.js +35 -0
  53. package/dist/get-tracks.d.ts +4 -4
  54. package/dist/get-tracks.js +8 -6
  55. package/dist/get-video-codec.js +2 -2
  56. package/dist/has-all-info.js +1 -1
  57. package/dist/index.d.ts +31 -3
  58. package/dist/internal-parse-media.js +16 -1
  59. package/dist/iterator/buffer-iterator.js +3 -4
  60. package/dist/metadata/metadata-from-iso.js +1 -0
  61. package/dist/options.d.ts +2 -0
  62. package/dist/parse-media-on-worker-entry.js +51 -1
  63. package/dist/parse-media.js +2 -1
  64. package/dist/samples-from-moof.d.ts +2 -2
  65. package/dist/samples-from-moof.js +5 -8
  66. package/dist/seeking-hints.d.ts +39 -0
  67. package/dist/set-seeking-hints.d.ts +6 -0
  68. package/dist/set-seeking-hints.js +27 -0
  69. package/dist/state/has-tracks-section.js +3 -1
  70. package/dist/state/iso-base-media/cached-sample-positions.js +1 -1
  71. package/dist/state/iso-base-media/iso-state.d.ts +18 -2
  72. package/dist/state/iso-base-media/iso-state.js +4 -0
  73. package/dist/state/iso-base-media/lazy-mfra-load.d.ts +3 -0
  74. package/dist/state/iso-base-media/lazy-mfra-load.js +13 -0
  75. package/dist/state/iso-base-media/moov-box.d.ts +7 -2
  76. package/dist/state/iso-base-media/moov-box.js +1 -1
  77. package/dist/state/iso-base-media/precomputed-moof.d.ts +11 -0
  78. package/dist/state/iso-base-media/precomputed-moof.js +28 -0
  79. package/dist/state/iso-base-media/precomputed-tfra.d.ts +6 -0
  80. package/dist/state/iso-base-media/precomputed-tfra.js +17 -0
  81. package/dist/state/keyframes.d.ts +2 -0
  82. package/dist/state/keyframes.js +17 -9
  83. package/dist/state/matroska/lazy-cues-fetch.d.ts +7 -1
  84. package/dist/state/matroska/lazy-cues-fetch.js +21 -0
  85. package/dist/state/matroska/webm.d.ts +7 -0
  86. package/dist/state/matroska/webm.js +9 -1
  87. package/dist/state/parser-state.d.ts +31 -3
  88. package/dist/state/samples-observed/slow-duration-fps.js +0 -3
  89. package/dist/state/transport-stream/observed-pes-header.d.ts +2 -0
  90. package/dist/state/transport-stream/observed-pes-header.js +22 -12
  91. package/dist/state/transport-stream/pts-start-offset.d.ts +4 -1
  92. package/dist/state/transport-stream/pts-start-offset.js +1 -1
  93. package/dist/state/transport-stream/transport-stream.d.ts +5 -1
  94. package/dist/version.d.ts +1 -1
  95. package/dist/version.js +1 -1
  96. package/dist/with-resolvers.d.ts +5 -0
  97. package/dist/work-on-seek-request.js +8 -5
  98. package/dist/worker/{forward-controller.js → forward-controller-to-worker.js} +17 -0
  99. package/dist/worker/serialize-error.d.ts +6 -1
  100. package/dist/worker/serialize-error.js +2 -1
  101. package/dist/worker/worker-types.d.ts +12 -2
  102. package/dist/worker-server.js +16 -5
  103. package/package.json +3 -3
  104. package/dist/containers/iso-base-media/get-mfra-atom.d.ts +0 -9
  105. package/dist/containers/iso-base-media/get-mfra-atom.js +0 -12
  106. package/dist/containers/iso-base-media/get-seeking-from-mp4.d.ts +0 -11
  107. package/dist/containers/iso-base-media/get-seeking-info-from-mp4.js +0 -25
  108. package/dist/containers/iso-base-media/mfra/mfra.d.ts +0 -2
  109. package/dist/containers/iso-base-media/mfra/mfra.js +0 -11
  110. package/dist/containers/transport-stream/get-seeking-info.d.ts +0 -4
  111. package/dist/containers/transport-stream/get-seeking-info.js +0 -17
  112. package/dist/containers/transport-stream/next-pes-header-store.d.ts +0 -6
  113. package/dist/containers/transport-stream/next-pes-header-store.js +0 -18
  114. package/dist/containers/transport-stream/start-offset.d.ts +0 -4
  115. package/dist/containers/transport-stream/start-offset.js +0 -13
  116. package/dist/containers/wav/get-seeking-info.d.ts +0 -7
  117. package/dist/containers/wav/get-seeking-info.js +0 -20
  118. package/dist/containers/wav/parse-video-section.d.ts +0 -5
  119. package/dist/containers/wav/parse-video-section.js +0 -41
  120. package/dist/containers/webm/cues/fetch-web-cues.d.ts +0 -12
  121. package/dist/containers/webm/cues/fetch-web-cues.js +0 -32
  122. package/dist/containers/webm/cues/format-cues.d.ts +0 -8
  123. package/dist/containers/webm/cues/format-cues.js +0 -41
  124. package/dist/containers/webm/cues/get-seeking-byte.d.ts +0 -14
  125. package/dist/containers/webm/cues/get-seeking-byte.js +0 -91
  126. package/dist/containers/webm/fetch-web-cues.d.ts +0 -12
  127. package/dist/containers/webm/fetch-web-cues.js +0 -29
  128. package/dist/containers/webm/get-seeking-byte.d.ts +0 -14
  129. package/dist/containers/webm/get-seeking-byte.js +0 -91
  130. package/dist/containers/webm/get-seeking-info.d.ts +0 -3
  131. package/dist/containers/webm/get-seeking-info.js +0 -17
  132. package/dist/containers/webm/seek/get-seeking-info.d.ts +0 -3
  133. package/dist/containers/webm/seek/get-seeking-info.js +0 -17
  134. package/dist/emitter.d.ts +0 -33
  135. package/dist/emitter.js +0 -65
  136. package/dist/get-sample-positions-from-lpcm.d.ts +0 -3
  137. package/dist/get-sample-positions-from-lpcm.js +0 -46
  138. package/dist/get-seeking-info.js +0 -35
  139. package/dist/media-parser-controller.d.ts +0 -21
  140. package/dist/media-parser-controller.js +0 -38
  141. package/dist/pause-signal.d.ts +0 -11
  142. package/dist/pause-signal.js +0 -38
  143. package/dist/readers/state/aac-state.d.ts +0 -13
  144. package/dist/readers/state/aac-state.js +0 -17
  145. package/dist/readers/state/can-skip-tracks.d.ts +0 -16
  146. package/dist/readers/state/can-skip-tracks.js +0 -60
  147. package/dist/readers/state/current-reader.d.ts +0 -6
  148. package/dist/readers/state/current-reader.js +0 -13
  149. package/dist/readers/state/emitted-fields.d.ts +0 -1
  150. package/dist/readers/state/emitted-fields.js +0 -37
  151. package/dist/readers/state/flac-state.d.ts +0 -4
  152. package/dist/readers/state/flac-state.js +0 -13
  153. package/dist/readers/state/has-tracks-section.d.ts +0 -14
  154. package/dist/readers/state/has-tracks-section.js +0 -37
  155. package/dist/readers/state/images.d.ts +0 -9
  156. package/dist/readers/state/images.js +0 -14
  157. package/dist/readers/state/iso-base-media/cached-sample-positions.d.ts +0 -12
  158. package/dist/readers/state/iso-base-media/cached-sample-positions.js +0 -46
  159. package/dist/readers/state/iso-base-media/iso-state.d.ts +0 -24
  160. package/dist/readers/state/iso-base-media/iso-state.js +0 -20
  161. package/dist/readers/state/iso-base-media/lazy-mfra-load.d.ts +0 -13
  162. package/dist/readers/state/iso-base-media/lazy-mfra-load.js +0 -29
  163. package/dist/readers/state/iso-base-media/moov-box.d.ts +0 -5
  164. package/dist/readers/state/iso-base-media/moov-box.js +0 -13
  165. package/dist/readers/state/keyframes.d.ts +0 -6
  166. package/dist/readers/state/keyframes.js +0 -15
  167. package/dist/readers/state/m3u-state.d.ts +0 -44
  168. package/dist/readers/state/m3u-state.js +0 -124
  169. package/dist/readers/state/may-skip-video-data.d.ts +0 -4
  170. package/dist/readers/state/may-skip-video-data.js +0 -18
  171. package/dist/readers/state/mp3.d.ts +0 -15
  172. package/dist/readers/state/mp3.js +0 -19
  173. package/dist/readers/state/need-samples-for-fields.d.ts +0 -6
  174. package/dist/readers/state/need-samples-for-fields.js +0 -39
  175. package/dist/readers/state/parser-state.d.ts +0 -252
  176. package/dist/readers/state/parser-state.js +0 -124
  177. package/dist/readers/state/riff.d.ts +0 -10
  178. package/dist/readers/state/riff.js +0 -32
  179. package/dist/readers/state/sample-callbacks.d.ts +0 -44
  180. package/dist/readers/state/sample-callbacks.js +0 -118
  181. package/dist/readers/state/seek-infinite-loop.d.ts +0 -5
  182. package/dist/readers/state/seek-infinite-loop.js +0 -22
  183. package/dist/readers/state/slow-duration-fps.d.ts +0 -11
  184. package/dist/readers/state/slow-duration-fps.js +0 -86
  185. package/dist/readers/state/structure.d.ts +0 -15
  186. package/dist/readers/state/structure.js +0 -78
  187. package/dist/readers/state/timings.d.ts +0 -8
  188. package/dist/readers/state/timings.js +0 -13
  189. package/dist/readers/state/transport-stream/last-emitted-sample.d.ts +0 -6
  190. package/dist/readers/state/transport-stream/last-emitted-sample.js +0 -16
  191. package/dist/readers/state/transport-stream/next-pes-header-store.d.ts +0 -6
  192. package/dist/readers/state/transport-stream/next-pes-header-store.js +0 -18
  193. package/dist/readers/state/transport-stream/start-offset.d.ts +0 -4
  194. package/dist/readers/state/transport-stream/start-offset.js +0 -13
  195. package/dist/readers/state/transport-stream/transport-stream.d.ts +0 -19
  196. package/dist/readers/state/transport-stream/transport-stream.js +0 -25
  197. package/dist/readers/state/video-section.d.ts +0 -33
  198. package/dist/readers/state/video-section.js +0 -65
  199. package/dist/readers/state/webm.d.ts +0 -28
  200. package/dist/readers/state/webm.js +0 -109
  201. package/dist/seek-signal.d.ts +0 -19
  202. package/dist/seek-signal.js +0 -24
  203. package/dist/seeking-info.d.ts +0 -31
  204. package/dist/server-worker.module.d.ts +0 -2
  205. package/dist/server-worker.module.js +0 -12
  206. package/dist/state/matroska/lazy-seek-fetch.d.ts +0 -1
  207. package/dist/state/matroska/lazy-seek-fetch.js +0 -5
  208. package/dist/state/matroska.d.ts +0 -0
  209. package/dist/state/matroska.js +0 -1
  210. package/dist/state/slow-duration-fps.d.ts +0 -11
  211. package/dist/state/slow-duration-fps.js +0 -86
  212. package/dist/state/transport-stream/start-offset.d.ts +0 -5
  213. package/dist/state/transport-stream/start-offset.js +0 -13
  214. package/dist/state/transport-stream.d.ts +0 -8
  215. package/dist/state/transport-stream.js +0 -11
  216. package/dist/state/uml.d.ts +0 -32
  217. package/dist/state/uml.js +0 -52
  218. package/dist/state/webm.d.ts +0 -30
  219. package/dist/state/webm.js +0 -109
  220. package/dist/state/work-on-seek-request-options.d.ts +0 -3
  221. package/dist/state/work-on-seek-request-options.js +0 -26
  222. package/dist/worker.module.d.ts +0 -4
  223. package/dist/worker.module.js +0 -12
  224. /package/dist/{seeking-info.js → seeking-hints.js} +0 -0
  225. /package/dist/worker/{forward-controller.d.ts → forward-controller-to-worker.d.ts} +0 -0
@@ -242,8 +242,7 @@ var fetchReadContent = async ({
242
242
  });
243
243
  if (controller) {
244
244
  controller._internals.signal.addEventListener("abort", () => {
245
- reader.reader.cancel().catch(() => {
246
- });
245
+ reader.reader.cancel().catch(() => {});
247
246
  }, { once: true });
248
247
  }
249
248
  return {
@@ -537,6 +536,19 @@ var mediaParserController = () => {
537
536
  }
538
537
  await pauseSignal.waitUntilResume();
539
538
  };
539
+ let seekingHintResolution = null;
540
+ const getSeekingHints = () => {
541
+ if (!seekingHintResolution) {
542
+ throw new Error("The mediaParserController() was not yet used in a parseMedia() call");
543
+ }
544
+ return seekingHintResolution();
545
+ };
546
+ const attachSeekingHintResolution = (callback) => {
547
+ if (seekingHintResolution) {
548
+ throw new Error("The mediaParserController() was used in multiple parseMedia() calls. Create a separate controller for each call.");
549
+ }
550
+ seekingHintResolution = callback;
551
+ };
540
552
  return {
541
553
  abort: (reason) => {
542
554
  abortController.abort(reason);
@@ -547,12 +559,14 @@ var mediaParserController = () => {
547
559
  resume: pauseSignal.resume,
548
560
  addEventListener: emitter.addEventListener,
549
561
  removeEventListener: emitter.removeEventListener,
562
+ getSeekingHints,
550
563
  _internals: {
551
564
  signal: abortController.signal,
552
565
  checkForAbortAndPause,
553
566
  seekSignal,
554
567
  markAsReadyToEmitEvents: emitter.markAsReady,
555
- performedSeeksSignal
568
+ performedSeeksSignal,
569
+ attachSeekingHintResolution
556
570
  }
557
571
  };
558
572
  };
@@ -634,6 +648,29 @@ var m3uHasStreams = (state) => {
634
648
  return state.m3u.hasFinishedManifest();
635
649
  };
636
650
 
651
+ // src/state/iso-base-media/precomputed-moof.ts
652
+ var precomputedMoofState = () => {
653
+ let moofBoxes = [];
654
+ return {
655
+ getMoofBoxes: () => moofBoxes,
656
+ setMoofBoxes: (boxes) => {
657
+ moofBoxes = boxes;
658
+ }
659
+ };
660
+ };
661
+ var toMoofBox = (box) => {
662
+ if (box.type !== "regular-box") {
663
+ throw new Error("expected regular bpx");
664
+ }
665
+ return {
666
+ offset: box.offset,
667
+ trafBoxes: box.children.filter((c) => c.type === "regular-box" && c.boxType === "traf")
668
+ };
669
+ };
670
+ var deduplicateMoofBoxesByOffset = (moofBoxes) => {
671
+ return moofBoxes.filter((m, i, arr) => i === arr.findIndex((t) => t.offset === m.offset));
672
+ };
673
+
637
674
  // src/containers/iso-base-media/traversal.ts
638
675
  var getMoovFromFromIsoStructure = (structure) => {
639
676
  const moovBox = structure.boxes.find((s) => s.type === "moov-box");
@@ -645,11 +682,12 @@ var getMoovFromFromIsoStructure = (structure) => {
645
682
  var getMoovBoxFromState = ({
646
683
  structureState,
647
684
  isoState,
648
- mp4HeaderSegment
685
+ mp4HeaderSegment,
686
+ mayUsePrecomputed
649
687
  }) => {
650
- const got = isoState.moov.getMoovBox();
651
- if (got) {
652
- return got;
688
+ const got = isoState.moov.getMoovBoxAndPrecomputed();
689
+ if (got && (mayUsePrecomputed || !got.precomputed)) {
690
+ return got.moovBox;
653
691
  }
654
692
  if (mp4HeaderSegment) {
655
693
  return getMoovFromFromIsoStructure(mp4HeaderSegment);
@@ -659,7 +697,7 @@ var getMoovBoxFromState = ({
659
697
  };
660
698
  var getMoofBoxes = (main) => {
661
699
  const moofBoxes = main.filter((s) => s.type === "regular-box" && s.boxType === "moof");
662
- return moofBoxes;
700
+ return moofBoxes.map((m) => toMoofBox(m));
663
701
  };
664
702
  var getMvhdBox = (moovBox) => {
665
703
  const mvHdBox = moovBox.children.find((s) => s.type === "mvhd-box");
@@ -931,7 +969,8 @@ var getFpsFromIsoMaseMedia = (state) => {
931
969
  const moovBox = getMoovBoxFromState({
932
970
  structureState: state.structure,
933
971
  isoState: state.iso,
934
- mp4HeaderSegment: state.mp4HeaderSegment
972
+ mp4HeaderSegment: state.mp4HeaderSegment,
973
+ mayUsePrecomputed: true
935
974
  });
936
975
  if (!moovBox) {
937
976
  return null;
@@ -2089,6 +2128,40 @@ var detectFileType = (data) => {
2089
2128
  return { type: "unknown" };
2090
2129
  };
2091
2130
 
2131
+ // src/log.ts
2132
+ var logLevels = ["trace", "verbose", "info", "warn", "error"];
2133
+ var getNumberForLogLevel = (level) => {
2134
+ return logLevels.indexOf(level);
2135
+ };
2136
+ var isEqualOrBelowLogLevel = (currentLevel, level) => {
2137
+ return getNumberForLogLevel(currentLevel) <= getNumberForLogLevel(level);
2138
+ };
2139
+ var Log = {
2140
+ trace: (logLevel, ...args) => {
2141
+ if (isEqualOrBelowLogLevel(logLevel, "trace")) {
2142
+ return console.log(...args);
2143
+ }
2144
+ },
2145
+ verbose: (logLevel, ...args) => {
2146
+ if (isEqualOrBelowLogLevel(logLevel, "verbose")) {
2147
+ return console.log(...args);
2148
+ }
2149
+ },
2150
+ info: (logLevel, ...args) => {
2151
+ if (isEqualOrBelowLogLevel(logLevel, "info")) {
2152
+ return console.log(...args);
2153
+ }
2154
+ },
2155
+ warn: (logLevel, ...args) => {
2156
+ if (isEqualOrBelowLogLevel(logLevel, "warn")) {
2157
+ return console.warn(...args);
2158
+ }
2159
+ },
2160
+ error: (...args) => {
2161
+ return console.error(...args);
2162
+ }
2163
+ };
2164
+
2092
2165
  // src/iterator/buffer-manager.ts
2093
2166
  var bufferManager = ({
2094
2167
  initialData,
@@ -2292,8 +2365,7 @@ var getArrayBufferIterator = (initialData, maxBytes) => {
2292
2365
  };
2293
2366
  const getPaddedFourByteNumber = () => {
2294
2367
  let lastInt = 128;
2295
- while (lastInt = getUint8(), lastInt === 128) {
2296
- }
2368
+ while (lastInt = getUint8(), lastInt === 128) {}
2297
2369
  return lastInt;
2298
2370
  };
2299
2371
  const getUint32 = () => {
@@ -2361,11 +2433,11 @@ var getArrayBufferIterator = (initialData, maxBytes) => {
2361
2433
  return (1 << zerosCount) - 1 + suffix;
2362
2434
  };
2363
2435
  const peekB = (length) => {
2364
- console.log([...getSlice(length)].map((b) => b.toString(16).padStart(2, "0")));
2436
+ Log.info("info", [...getSlice(length)].map((b) => b.toString(16).padStart(2, "0")));
2365
2437
  counter.decrement(length);
2366
2438
  };
2367
2439
  const peekD = (length) => {
2368
- console.log([...getSlice(length)].map((b) => b));
2440
+ Log.info("info", [...getSlice(length)].map((b) => b.toString(16).padStart(2, "0")));
2369
2441
  counter.decrement(length);
2370
2442
  };
2371
2443
  const leb128 = () => {
@@ -2702,11 +2774,11 @@ var parseAv1PrivateData = (data, colrAtom) => {
2702
2774
 
2703
2775
  // src/get-video-codec.ts
2704
2776
  var getVideoCodec = (state) => {
2705
- const track = getTracks(state);
2777
+ const track = getTracks(state, true);
2706
2778
  return track.videoTracks[0]?.codecWithoutConfig ?? null;
2707
2779
  };
2708
2780
  var hasVideoCodec = (state) => {
2709
- return getHasTracks(state);
2781
+ return getHasTracks(state, true);
2710
2782
  };
2711
2783
  var getVideoPrivateData = (trakBox) => {
2712
2784
  const videoSample = getStsdVideoConfig(trakBox);
@@ -3951,14 +4023,15 @@ var matroskaHasTracks = ({
3951
4023
  };
3952
4024
 
3953
4025
  // src/get-tracks.ts
3954
- var isoBaseMediaHasTracks = (state) => {
4026
+ var isoBaseMediaHasTracks = (state, mayUsePrecomputed) => {
3955
4027
  return Boolean(getMoovBoxFromState({
3956
4028
  structureState: state.structure,
3957
4029
  isoState: state.iso,
3958
- mp4HeaderSegment: state.mp4HeaderSegment
4030
+ mp4HeaderSegment: state.mp4HeaderSegment,
4031
+ mayUsePrecomputed
3959
4032
  }));
3960
4033
  };
3961
- var getHasTracks = (state) => {
4034
+ var getHasTracks = (state, mayUsePrecomputed) => {
3962
4035
  const structure = state.structure.getStructure();
3963
4036
  if (structure.type === "matroska") {
3964
4037
  return matroskaHasTracks({
@@ -3967,7 +4040,7 @@ var getHasTracks = (state) => {
3967
4040
  });
3968
4041
  }
3969
4042
  if (structure.type === "iso-base-media") {
3970
- return isoBaseMediaHasTracks(state);
4043
+ return isoBaseMediaHasTracks(state, mayUsePrecomputed);
3971
4044
  }
3972
4045
  if (structure.type === "riff") {
3973
4046
  return hasAllTracksFromAvi(state);
@@ -4039,11 +4112,12 @@ var getTracksFromMoovBox = (moovBox) => {
4039
4112
  otherTracks
4040
4113
  };
4041
4114
  };
4042
- var getTracksFromIsoBaseMedia = (state) => {
4115
+ var getTracksFromIsoBaseMedia = (state, mayUsePrecomputed) => {
4043
4116
  const moovBox = getMoovBoxFromState({
4044
4117
  structureState: state.structure,
4045
4118
  isoState: state.iso,
4046
- mp4HeaderSegment: state.mp4HeaderSegment
4119
+ mp4HeaderSegment: state.mp4HeaderSegment,
4120
+ mayUsePrecomputed
4047
4121
  });
4048
4122
  if (!moovBox) {
4049
4123
  return {
@@ -4065,13 +4139,13 @@ var defaultGetTracks = (parserState) => {
4065
4139
  videoTracks: tracks2.filter((t) => t.type === "video")
4066
4140
  };
4067
4141
  };
4068
- var getTracks = (state) => {
4142
+ var getTracks = (state, mayUsePrecomputed) => {
4069
4143
  const structure = state.structure.getStructure();
4070
4144
  if (structure.type === "matroska") {
4071
4145
  return getCategorizedTracksFromMatroska(state);
4072
4146
  }
4073
4147
  if (structure.type === "iso-base-media") {
4074
- return getTracksFromIsoBaseMedia(state);
4148
+ return getTracksFromIsoBaseMedia(state, mayUsePrecomputed);
4075
4149
  }
4076
4150
  if (structure.type === "riff") {
4077
4151
  return getTracksFromAvi(structure, state);
@@ -4087,7 +4161,7 @@ var getTracks = (state) => {
4087
4161
 
4088
4162
  // src/get-audio-codec.ts
4089
4163
  var getAudioCodec = (parserState) => {
4090
- const tracks2 = getTracks(parserState);
4164
+ const tracks2 = getTracks(parserState, true);
4091
4165
  const allTracks = tracks2.audioTracks.length + tracks2.otherTracks.length + tracks2.videoTracks.length;
4092
4166
  if (allTracks === 0) {
4093
4167
  throw new Error("No tracks yet");
@@ -4102,7 +4176,7 @@ var getAudioCodec = (parserState) => {
4102
4176
  return null;
4103
4177
  };
4104
4178
  var hasAudioCodec = (state) => {
4105
- return getHasTracks(state);
4179
+ return getHasTracks(state, true);
4106
4180
  };
4107
4181
  var getCodecSpecificatorFromEsdsBox = ({
4108
4182
  child
@@ -4338,7 +4412,7 @@ var getDimensions = (state) => {
4338
4412
  if (structure && isAudioStructure(structure)) {
4339
4413
  return null;
4340
4414
  }
4341
- const { videoTracks } = getTracks(state);
4415
+ const { videoTracks } = getTracks(state, true);
4342
4416
  if (!videoTracks.length) {
4343
4417
  return null;
4344
4418
  }
@@ -4431,13 +4505,12 @@ var getSamplesFromMoof = ({
4431
4505
  moofBox,
4432
4506
  trackId
4433
4507
  }) => {
4434
- if (moofBox.type !== "regular-box") {
4435
- throw new Error("Expected moof-box");
4436
- }
4437
- const trafs = moofBox.children.filter((c) => c.type === "regular-box" && c.boxType === "traf");
4438
- const mapped = trafs.map((traf) => {
4508
+ const mapped = moofBox.trafBoxes.map((traf) => {
4439
4509
  const tfhdBox = getTfhdBox(traf);
4440
- return tfhdBox?.trackId === trackId ? getSamplesFromTraf(traf, moofBox.offset) : [];
4510
+ if (!tfhdBox || tfhdBox.trackId !== trackId) {
4511
+ return [];
4512
+ }
4513
+ return getSamplesFromTraf(traf, moofBox.offset);
4441
4514
  });
4442
4515
  return mapped.flat(1);
4443
4516
  };
@@ -4449,10 +4522,13 @@ var collectSamplePositionsFromMoofBoxes = ({
4449
4522
  tkhdBox
4450
4523
  }) => {
4451
4524
  const isComplete = tfraBoxes.length > 0 && tfraBoxes.every((t) => t.entries.length === moofBoxes.length);
4452
- const samplePositions_ = moofBoxes.map((m) => {
4453
- return getSamplesFromMoof({ moofBox: m, trackId: tkhdBox.trackId });
4525
+ const samplePositions = moofBoxes.map((m) => {
4526
+ return getSamplesFromMoof({
4527
+ moofBox: m,
4528
+ trackId: tkhdBox.trackId
4529
+ });
4454
4530
  });
4455
- return { samplePositions: samplePositions_, isComplete };
4531
+ return { samplePositions, isComplete };
4456
4532
  };
4457
4533
 
4458
4534
  // src/get-sample-positions.ts
@@ -4820,7 +4896,8 @@ var getDurationFromIsoBaseMedia = (parserState) => {
4820
4896
  const moovBox = getMoovBoxFromState({
4821
4897
  structureState: parserState.structure,
4822
4898
  isoState: parserState.iso,
4823
- mp4HeaderSegment: parserState.mp4HeaderSegment
4899
+ mp4HeaderSegment: parserState.mp4HeaderSegment,
4900
+ mayUsePrecomputed: true
4824
4901
  });
4825
4902
  if (!moovBox) {
4826
4903
  return null;
@@ -4837,7 +4914,7 @@ var getDurationFromIsoBaseMedia = (parserState) => {
4837
4914
  if (mvhdBox.durationInSeconds > 0) {
4838
4915
  return mvhdBox.durationInSeconds;
4839
4916
  }
4840
- const tracks2 = getTracks(parserState);
4917
+ const tracks2 = getTracks(parserState, true);
4841
4918
  const allTracks = [
4842
4919
  ...tracks2.videoTracks,
4843
4920
  ...tracks2.audioTracks,
@@ -4901,7 +4978,7 @@ var hasDuration = (parserState) => {
4901
4978
  if (structure === null) {
4902
4979
  return false;
4903
4980
  }
4904
- return getHasTracks(parserState);
4981
+ return getHasTracks(parserState, true);
4905
4982
  };
4906
4983
  var hasSlowDuration = (parserState) => {
4907
4984
  try {
@@ -4916,16 +4993,16 @@ var isVideoTrackHdr = (track) => {
4916
4993
  return track.color.matrixCoefficients === "bt2020" && track.color.transferCharacteristics === "arib-std-b67" && track.color.primaries === "bt2020";
4917
4994
  };
4918
4995
  var getIsHdr = (state) => {
4919
- const { videoTracks } = getTracks(state);
4996
+ const { videoTracks } = getTracks(state, true);
4920
4997
  return videoTracks.some((track) => isVideoTrackHdr(track));
4921
4998
  };
4922
4999
  var hasHdr = (state) => {
4923
- return getHasTracks(state);
5000
+ return getHasTracks(state, true);
4924
5001
  };
4925
5002
 
4926
5003
  // src/containers/iso-base-media/get-keyframes.ts
4927
5004
  var getKeyframesFromIsoBaseMedia = (state) => {
4928
- const { videoTracks } = getTracksFromIsoBaseMedia(state);
5005
+ const { videoTracks } = getTracksFromIsoBaseMedia(state, true);
4929
5006
  const structure = state.structure.getIsoStructure();
4930
5007
  const moofBoxes = getMoofBoxes(structure.boxes);
4931
5008
  const tfraBoxes = getTfraBoxes(structure);
@@ -4966,7 +5043,7 @@ var getKeyframes = (state) => {
4966
5043
  var hasKeyframes = (parserState) => {
4967
5044
  const structure = parserState.structure.getStructure();
4968
5045
  if (structure.type === "iso-base-media") {
4969
- return getHasTracks(parserState);
5046
+ return getHasTracks(parserState, true);
4970
5047
  }
4971
5048
  return true;
4972
5049
  };
@@ -5079,7 +5156,8 @@ var getMetadataFromIsoBase = (state) => {
5079
5156
  const moov = getMoovBoxFromState({
5080
5157
  structureState: state.structure,
5081
5158
  isoState: state.iso,
5082
- mp4HeaderSegment: state.mp4HeaderSegment
5159
+ mp4HeaderSegment: state.mp4HeaderSegment,
5160
+ mayUsePrecomputed: true
5083
5161
  });
5084
5162
  if (!moov) {
5085
5163
  return [];
@@ -5290,40 +5368,6 @@ var hasSampleRate = (state) => {
5290
5368
  return state.callbacks.tracks.hasAllTracks();
5291
5369
  };
5292
5370
 
5293
- // src/log.ts
5294
- var logLevels = ["trace", "verbose", "info", "warn", "error"];
5295
- var getNumberForLogLevel = (level) => {
5296
- return logLevels.indexOf(level);
5297
- };
5298
- var isEqualOrBelowLogLevel = (currentLevel, level) => {
5299
- return getNumberForLogLevel(currentLevel) <= getNumberForLogLevel(level);
5300
- };
5301
- var Log = {
5302
- trace: (logLevel, ...args) => {
5303
- if (isEqualOrBelowLogLevel(logLevel, "trace")) {
5304
- return console.log(...args);
5305
- }
5306
- },
5307
- verbose: (logLevel, ...args) => {
5308
- if (isEqualOrBelowLogLevel(logLevel, "verbose")) {
5309
- return console.log(...args);
5310
- }
5311
- },
5312
- info: (logLevel, ...args) => {
5313
- if (isEqualOrBelowLogLevel(logLevel, "info")) {
5314
- return console.log(...args);
5315
- }
5316
- },
5317
- warn: (logLevel, ...args) => {
5318
- if (isEqualOrBelowLogLevel(logLevel, "warn")) {
5319
- return console.warn(...args);
5320
- }
5321
- },
5322
- error: (...args) => {
5323
- return console.error(...args);
5324
- }
5325
- };
5326
-
5327
5371
  // src/state/video-section.ts
5328
5372
  var isByteInMediaSection = ({
5329
5373
  position,
@@ -5466,13 +5510,15 @@ var findBestSegmentFromTfra = ({
5466
5510
  };
5467
5511
  };
5468
5512
 
5469
- // src/containers/iso-base-media/get-seeking-from-mp4.ts
5513
+ // src/containers/iso-base-media/get-seeking-byte.ts
5470
5514
  var getSeekingByteFromIsoBaseMedia = async ({
5471
5515
  info,
5472
5516
  time,
5473
5517
  logLevel,
5474
5518
  currentPosition,
5475
- isoState
5519
+ isoState,
5520
+ mp4HeaderSegment,
5521
+ structure
5476
5522
  }) => {
5477
5523
  const tracks2 = getTracksFromMoovBox(info.moovBox);
5478
5524
  const allTracks = [
@@ -5480,6 +5526,18 @@ var getSeekingByteFromIsoBaseMedia = async ({
5480
5526
  ...tracks2.audioTracks,
5481
5527
  ...tracks2.otherTracks
5482
5528
  ];
5529
+ const hasMoov = Boolean(getMoovBoxFromState({
5530
+ mp4HeaderSegment,
5531
+ structureState: structure,
5532
+ isoState,
5533
+ mayUsePrecomputed: false
5534
+ }));
5535
+ if (!hasMoov) {
5536
+ Log.trace(logLevel, "No moov box found, must wait");
5537
+ return {
5538
+ type: "valid-but-must-wait"
5539
+ };
5540
+ }
5483
5541
  const firstVideoTrack = allTracks.find((t) => t.type === "video");
5484
5542
  if (!firstVideoTrack) {
5485
5543
  throw new Error("No video track found");
@@ -5515,7 +5573,7 @@ var getSeekingByteFromIsoBaseMedia = async ({
5515
5573
  }
5516
5574
  }
5517
5575
  }
5518
- const atom = await isoState.mfra.triggerLoad();
5576
+ const atom = await (info.mfraAlreadyLoaded ? Promise.resolve(info.mfraAlreadyLoaded) : isoState.mfra.triggerLoad());
5519
5577
  if (atom) {
5520
5578
  const moofOffset = findBestSegmentFromTfra({
5521
5579
  mfra: atom,
@@ -5586,12 +5644,12 @@ var getSeekingByteFromWav = ({
5586
5644
  time
5587
5645
  }) => {
5588
5646
  const bytesPerSecond = info.sampleRate * info.blockAlign;
5589
- const durationInSeconds = info.mediaSections.size / bytesPerSecond;
5647
+ const durationInSeconds = info.mediaSection.size / bytesPerSecond;
5590
5648
  const timeRoundedDown = Math.floor(Math.min(time, durationInSeconds - 0.0000001) * WAVE_SAMPLES_PER_SECOND) / WAVE_SAMPLES_PER_SECOND;
5591
5649
  const byteOffset = bytesPerSecond * timeRoundedDown;
5592
5650
  return Promise.resolve({
5593
5651
  type: "do-seek",
5594
- byte: byteOffset + info.mediaSections.start
5652
+ byte: byteOffset + info.mediaSection.start
5595
5653
  });
5596
5654
  };
5597
5655
 
@@ -5652,8 +5710,7 @@ var getSeekingByteFromMatroska = async ({
5652
5710
  webmState,
5653
5711
  info,
5654
5712
  logLevel,
5655
- mediaSection,
5656
- keyframes
5713
+ mediaSection
5657
5714
  }) => {
5658
5715
  if (!info.track) {
5659
5716
  Log.trace(logLevel, "No video track found, cannot seek yet");
@@ -5661,9 +5718,9 @@ var getSeekingByteFromMatroska = async ({
5661
5718
  type: "valid-but-must-wait"
5662
5719
  };
5663
5720
  }
5664
- const cuesResponse = await webmState.cues.getLoadedCues();
5721
+ const cuesResponse = info.loadedCues ?? await webmState.cues.getLoadedCues();
5665
5722
  const byteFromObservedKeyframe = findKeyframeBeforeTime2({
5666
- keyframes: keyframes.getKeyframes(),
5723
+ keyframes: info.keyframes,
5667
5724
  time
5668
5725
  });
5669
5726
  const byteFromCues = getByteFromCues({
@@ -6114,7 +6171,10 @@ var handleAvcPacket = async ({
6114
6171
  const dimensions = getDimensionsFromSps(spsAndPps.sps.spsData);
6115
6172
  const sampleAspectRatio = getSampleAspectRatioFromSps(spsAndPps.sps.spsData);
6116
6173
  const startOffset = makeSamplesStartAtZero ? Math.min(streamBuffer.pesHeader.pts, streamBuffer.pesHeader.dts ?? Infinity) : 0;
6117
- transportStream.startOffset.setOffset(programId, startOffset);
6174
+ transportStream.startOffset.setOffset({
6175
+ trackId: programId,
6176
+ newOffset: startOffset
6177
+ });
6118
6178
  const track = {
6119
6179
  m3uStreamFormat: null,
6120
6180
  rotation: 0,
@@ -6178,20 +6238,30 @@ var handleAvcPacket = async ({
6178
6238
  var makeObservedPesHeader = () => {
6179
6239
  const pesHeaders = [];
6180
6240
  const confirmedAsKeyframe = [];
6241
+ const addPesHeader = (pesHeader) => {
6242
+ if (pesHeaders.find((p) => p.offset === pesHeader.offset)) {
6243
+ return;
6244
+ }
6245
+ pesHeaders.push(pesHeader);
6246
+ };
6247
+ const markPtsAsKeyframe = (pts) => {
6248
+ confirmedAsKeyframe.push(pts);
6249
+ };
6250
+ const getPesKeyframeHeaders = () => {
6251
+ return pesHeaders.filter((p) => confirmedAsKeyframe.includes(p.pts));
6252
+ };
6253
+ const setPesKeyframesFromSeekingHints = (hints) => {
6254
+ for (const pesHeader of hints.observedPesHeaders) {
6255
+ addPesHeader(pesHeader);
6256
+ markPtsAsKeyframe(pesHeader.pts);
6257
+ }
6258
+ };
6181
6259
  const state = {
6182
6260
  pesHeaders,
6183
- addPesHeader: (pesHeader) => {
6184
- if (pesHeaders.find((p) => p.offset === pesHeader.offset)) {
6185
- return;
6186
- }
6187
- pesHeaders.push(pesHeader);
6188
- },
6189
- markPtsAsKeyframe: (pts) => {
6190
- confirmedAsKeyframe.push(pts);
6191
- },
6192
- getPesKeyframeHeaders: () => {
6193
- return pesHeaders.filter((p) => confirmedAsKeyframe.includes(p.pts));
6194
- }
6261
+ addPesHeader,
6262
+ markPtsAsKeyframe,
6263
+ getPesKeyframeHeaders,
6264
+ setPesKeyframesFromSeekingHints
6195
6265
  };
6196
6266
  return state;
6197
6267
  };
@@ -6213,34 +6283,36 @@ var getSeekingByte = ({
6213
6283
  transportStream,
6214
6284
  webmState,
6215
6285
  mediaSection,
6216
- keyframes
6286
+ mp4HeaderSegment,
6287
+ structure
6217
6288
  }) => {
6218
- if (info.type === "iso-base-media-seeking-info") {
6289
+ if (info.type === "iso-base-media-seeking-hints") {
6219
6290
  return getSeekingByteFromIsoBaseMedia({
6220
6291
  info,
6221
6292
  time,
6222
6293
  logLevel,
6223
6294
  currentPosition,
6224
- isoState
6295
+ isoState,
6296
+ mp4HeaderSegment,
6297
+ structure
6225
6298
  });
6226
6299
  }
6227
- if (info.type === "wav-seeking-info") {
6300
+ if (info.type === "wav-seeking-hints") {
6228
6301
  return getSeekingByteFromWav({
6229
6302
  info,
6230
6303
  time
6231
6304
  });
6232
6305
  }
6233
- if (info.type === "webm-seeking-info") {
6306
+ if (info.type === "webm-seeking-hints") {
6234
6307
  return getSeekingByteFromMatroska({
6235
6308
  info,
6236
6309
  time,
6237
6310
  webmState,
6238
6311
  logLevel,
6239
- mediaSection,
6240
- keyframes
6312
+ mediaSection
6241
6313
  });
6242
6314
  }
6243
- if (info.type === "transport-stream-seeking-info") {
6315
+ if (info.type === "transport-stream-seeking-hints") {
6244
6316
  const lastKeyframeBeforeTimeInSeconds = getLastKeyFrameBeforeTimeInSeconds({
6245
6317
  observedPesHeaders: info.observedPesHeaders,
6246
6318
  timeInSeconds: time,
@@ -6256,8 +6328,22 @@ var getSeekingByte = ({
6256
6328
  throw new Error(`Unknown seeking info type: ${info}`);
6257
6329
  };
6258
6330
 
6259
- // src/containers/iso-base-media/get-seeking-info-from-mp4.ts
6260
- var getSeekingInfoFromMp4 = ({
6331
+ // src/state/iso-base-media/precomputed-tfra.ts
6332
+ var precomputedTfraState = () => {
6333
+ let tfraBoxes = [];
6334
+ return {
6335
+ getTfraBoxes: () => tfraBoxes,
6336
+ setTfraBoxes: (boxes) => {
6337
+ tfraBoxes = boxes;
6338
+ }
6339
+ };
6340
+ };
6341
+ var deduplicateTfraBoxesByOffset = (tfraBoxes) => {
6342
+ return tfraBoxes.filter((m, i, arr) => i === arr.findIndex((t) => t.offset === m.offset));
6343
+ };
6344
+
6345
+ // src/containers/iso-base-media/seeking-hints.ts
6346
+ var getSeekingHintsFromMp4 = ({
6261
6347
  structureState,
6262
6348
  isoState,
6263
6349
  mp4HeaderSegment,
@@ -6267,37 +6353,65 @@ var getSeekingInfoFromMp4 = ({
6267
6353
  const moovAtom = getMoovBoxFromState({
6268
6354
  isoState,
6269
6355
  mp4HeaderSegment,
6270
- structureState
6356
+ structureState,
6357
+ mayUsePrecomputed: true
6271
6358
  });
6272
- const moofBoxes = getMoofBoxes(structure.boxes);
6273
- const tfraBoxes = getTfraBoxes(structure);
6359
+ const moofBoxes = deduplicateMoofBoxesByOffset([
6360
+ ...isoState.moof.getMoofBoxes(),
6361
+ ...getMoofBoxes(structure.boxes)
6362
+ ]);
6363
+ const tfraBoxes = deduplicateTfraBoxesByOffset([
6364
+ ...isoState.tfra.getTfraBoxes(),
6365
+ ...getTfraBoxes(structure)
6366
+ ]);
6274
6367
  if (!moovAtom) {
6275
6368
  return null;
6276
6369
  }
6277
6370
  return {
6278
- type: "iso-base-media-seeking-info",
6371
+ type: "iso-base-media-seeking-hints",
6279
6372
  moovBox: moovAtom,
6280
6373
  moofBoxes,
6281
6374
  tfraBoxes,
6282
- mediaSections: mediaSectionState2.getMediaSections()
6375
+ mediaSections: mediaSectionState2.getMediaSections(),
6376
+ mfraAlreadyLoaded: isoState.mfra.getIfAlreadyLoaded()
6283
6377
  };
6284
6378
  };
6379
+ var setSeekingHintsForMp4 = ({
6380
+ hints,
6381
+ state
6382
+ }) => {
6383
+ state.iso.moov.setMoovBox({
6384
+ moovBox: hints.moovBox,
6385
+ precomputed: true
6386
+ });
6387
+ };
6285
6388
 
6286
- // src/containers/transport-stream/get-seeking-info.ts
6287
- var getSeekingInfoFromTransportStream = (transportStream, tracksState) => {
6389
+ // src/containers/transport-stream/seeking-hints.ts
6390
+ var getSeekingHintsFromTransportStream = (transportStream, tracksState) => {
6288
6391
  const firstVideoTrack = tracksState.getTracks().find((t) => t.type === "video");
6289
6392
  if (!firstVideoTrack) {
6290
- throw new Error("No video track found");
6393
+ return null;
6291
6394
  }
6292
6395
  return {
6293
- type: "transport-stream-seeking-info",
6396
+ type: "transport-stream-seeking-hints",
6294
6397
  observedPesHeaders: transportStream.observedPesHeaders.getPesKeyframeHeaders(),
6295
- ptsStartOffset: transportStream.startOffset.getOffset(firstVideoTrack.trackId)
6398
+ ptsStartOffset: transportStream.startOffset.getOffset(firstVideoTrack.trackId),
6399
+ firstVideoTrackId: firstVideoTrack.trackId
6296
6400
  };
6297
6401
  };
6402
+ var setSeekingHintsForTransportStream = ({
6403
+ hints,
6404
+ state
6405
+ }) => {
6406
+ state.transportStream.observedPesHeaders.setPesKeyframesFromSeekingHints(hints);
6407
+ state.transportStream.startOffset.setOffset({
6408
+ trackId: hints.firstVideoTrackId,
6409
+ newOffset: hints.ptsStartOffset
6410
+ });
6411
+ };
6298
6412
 
6299
- // src/containers/wav/get-seeking-info.ts
6300
- var getSeekingInfoFromWav = ({
6413
+ // src/containers/wav/seeking-hints.ts
6414
+ var getSeekingHintsFromWav = ({
6301
6415
  structure,
6302
6416
  mediaSectionState: mediaSectionState2
6303
6417
  }) => {
@@ -6310,41 +6424,62 @@ var getSeekingInfoFromWav = ({
6310
6424
  return null;
6311
6425
  }
6312
6426
  return {
6313
- type: "wav-seeking-info",
6427
+ type: "wav-seeking-hints",
6314
6428
  sampleRate: fmtBox.sampleRate,
6315
6429
  blockAlign: fmtBox.blockAlign,
6316
- mediaSections: mediaSection[0]
6430
+ mediaSection: mediaSection[0]
6317
6431
  };
6318
6432
  };
6433
+ var setSeekingHintsForWav = ({
6434
+ hints,
6435
+ state
6436
+ }) => {
6437
+ state.mediaSection.addMediaSection(hints.mediaSection);
6438
+ };
6319
6439
 
6320
- // src/containers/webm/seek/get-seeking-info.ts
6321
- var getSeekingInfoFromMatroska = (tracksState) => {
6440
+ // src/containers/webm/seek/seeking-hints.ts
6441
+ var getSeekingHintsFromMatroska = (tracksState, keyframesState, webmState) => {
6322
6442
  const tracks2 = tracksState.getTracks();
6323
6443
  const firstVideoTrack = tracks2.find((track) => track.type === "video");
6444
+ const keyframes = keyframesState.getKeyframes();
6445
+ const loadedCues = webmState.cues.getIfAlreadyLoaded();
6324
6446
  return {
6325
- type: "webm-seeking-info",
6447
+ type: "webm-seeking-hints",
6326
6448
  track: firstVideoTrack ? {
6327
6449
  timescale: firstVideoTrack.timescale,
6328
6450
  trackId: firstVideoTrack.trackId
6329
- } : null
6451
+ } : null,
6452
+ keyframes,
6453
+ loadedCues,
6454
+ timestampMap: webmState.getTimeStampMapForSeekingHints()
6330
6455
  };
6331
6456
  };
6457
+ var setSeekingHintsForWebm = ({
6458
+ hints,
6459
+ state
6460
+ }) => {
6461
+ state.webm.cues.setFromSeekingHints(hints);
6462
+ state.keyframes.setFromSeekingHints(hints);
6463
+ state.webm.setTimeStampMapForSeekingHints(hints.timestampMap);
6464
+ };
6332
6465
 
6333
- // src/get-seeking-info.ts
6334
- var getSeekingInfo = ({
6466
+ // src/get-seeking-hints.ts
6467
+ var getSeekingHints = ({
6335
6468
  structureState,
6336
6469
  mp4HeaderSegment,
6337
6470
  mediaSectionState: mediaSectionState2,
6338
6471
  isoState,
6339
6472
  transportStream,
6340
- tracksState
6473
+ tracksState,
6474
+ keyframesState,
6475
+ webmState
6341
6476
  }) => {
6342
6477
  const structure = structureState.getStructureOrNull();
6343
6478
  if (!structure) {
6344
6479
  return null;
6345
6480
  }
6346
6481
  if (structure.type === "iso-base-media") {
6347
- return getSeekingInfoFromMp4({
6482
+ return getSeekingHintsFromMp4({
6348
6483
  structureState,
6349
6484
  isoState,
6350
6485
  mp4HeaderSegment,
@@ -6352,16 +6487,16 @@ var getSeekingInfo = ({
6352
6487
  });
6353
6488
  }
6354
6489
  if (structure.type === "wav") {
6355
- return getSeekingInfoFromWav({
6490
+ return getSeekingHintsFromWav({
6356
6491
  structure,
6357
6492
  mediaSectionState: mediaSectionState2
6358
6493
  });
6359
6494
  }
6360
6495
  if (structure.type === "matroska") {
6361
- return getSeekingInfoFromMatroska(tracksState);
6496
+ return getSeekingHintsFromMatroska(tracksState, keyframesState, webmState);
6362
6497
  }
6363
6498
  if (structure.type === "transport-stream") {
6364
- return getSeekingInfoFromTransportStream(transportStream, tracksState);
6499
+ return getSeekingHintsFromTransportStream(transportStream, tracksState);
6365
6500
  }
6366
6501
  throw new Error(`Seeking is not supported for this format: ${structure.type}`);
6367
6502
  };
@@ -6590,22 +6725,24 @@ var turnSeekIntoByte = async ({
6590
6725
  if (seek2.timeInSeconds < 0) {
6591
6726
  throw new Error(`Cannot seek to a negative time: ${JSON.stringify(seek2)}`);
6592
6727
  }
6593
- const seekingInfo = getSeekingInfo({
6728
+ const seekingHints = getSeekingHints({
6594
6729
  structureState,
6595
6730
  mp4HeaderSegment,
6596
6731
  mediaSectionState: mediaSectionState2,
6597
6732
  isoState,
6598
6733
  transportStream,
6599
- tracksState
6734
+ tracksState,
6735
+ keyframesState: keyframes,
6736
+ webmState
6600
6737
  });
6601
- if (!seekingInfo) {
6738
+ if (!seekingHints) {
6602
6739
  Log.trace(logLevel, "No seeking info, cannot seek yet");
6603
6740
  return {
6604
6741
  type: "valid-but-must-wait"
6605
6742
  };
6606
6743
  }
6607
6744
  const seekingByte = await getSeekingByte({
6608
- info: seekingInfo,
6745
+ info: seekingHints,
6609
6746
  time: seek2.timeInSeconds,
6610
6747
  logLevel,
6611
6748
  currentPosition: iterator.counter.getOffset(),
@@ -6613,7 +6750,8 @@ var turnSeekIntoByte = async ({
6613
6750
  transportStream,
6614
6751
  webmState,
6615
6752
  mediaSection: mediaSectionState2,
6616
- keyframes
6753
+ mp4HeaderSegment,
6754
+ structure: structureState
6617
6755
  });
6618
6756
  return seekingByte;
6619
6757
  }
@@ -6889,7 +7027,7 @@ var emitAvailableInfo = async ({
6889
7027
  }
6890
7028
  if (key === "tracks") {
6891
7029
  if (!emittedFields.tracks && hasInfo.tracks) {
6892
- const { videoTracks, audioTracks } = getTracks(state);
7030
+ const { videoTracks, audioTracks } = getTracks(state, true);
6893
7031
  await callbackFunctions.onTracks?.({ videoTracks, audioTracks });
6894
7032
  if (fieldsInReturnValue.tracks) {
6895
7033
  returnValue.tracks = { videoTracks, audioTracks };
@@ -7131,7 +7269,7 @@ var getAvailableInfo = ({
7131
7269
  return Boolean(structure && hasAudioCodec(state));
7132
7270
  }
7133
7271
  if (key === "tracks") {
7134
- return Boolean(structure && getHasTracks(state));
7272
+ return Boolean(structure && getHasTracks(state, true));
7135
7273
  }
7136
7274
  if (key === "keyframes") {
7137
7275
  return Boolean(structure && hasKeyframes(state));
@@ -7766,7 +7904,7 @@ var parseFlac = ({
7766
7904
 
7767
7905
  // src/state/iso-base-media/cached-sample-positions.ts
7768
7906
  var calculateFlatSamples = (state) => {
7769
- const tracks2 = getTracks(state);
7907
+ const tracks2 = getTracks(state, true);
7770
7908
  const allTracks = [
7771
7909
  ...tracks2.videoTracks,
7772
7910
  ...tracks2.audioTracks,
@@ -7859,7 +7997,9 @@ var makeTracksSectionState = (canSkipTracksState, src) => {
7859
7997
  addTrack: (track) => {
7860
7998
  tracks2.push(track);
7861
7999
  },
7862
- getTracks: () => tracks2,
8000
+ getTracks: () => {
8001
+ return tracks2;
8002
+ },
7863
8003
  ensureHasTracksAtEnd: (fields) => {
7864
8004
  if (canSkipTracksState.canSkipTracks()) {
7865
8005
  return;
@@ -9620,7 +9760,7 @@ var processBox = async ({
9620
9760
  iterator.discard(boxSize - 8);
9621
9761
  return null;
9622
9762
  }
9623
- if (isoState && isoState.moov.getMoovBox()) {
9763
+ if (isoState && isoState.moov.getMoovBoxAndPrecomputed() && !isoState.moov.getMoovBoxAndPrecomputed()?.precomputed) {
9624
9764
  Log.verbose(logLevel, "Moov box already parsed, skipping");
9625
9765
  iterator.discard(boxSize - 8);
9626
9766
  return null;
@@ -9849,13 +9989,16 @@ var parseMdatSection = async (state) => {
9849
9989
  if (maySkipVideoData({ state })) {
9850
9990
  return makeSkip(endOfMdat);
9851
9991
  }
9852
- const alreadyHas = getHasTracks(state);
9853
- if (!alreadyHas) {
9992
+ const alreadyHasMoov = getHasTracks(state, true);
9993
+ if (!alreadyHasMoov) {
9854
9994
  const moov = await getMoovAtom({
9855
9995
  endOfMdat,
9856
9996
  state
9857
9997
  });
9858
- state.iso.moov.setMoovBox(moov);
9998
+ state.iso.moov.setMoovBox({
9999
+ moovBox: moov,
10000
+ precomputed: false
10001
+ });
9859
10002
  state.callbacks.tracks.setIsDone(state.logLevel);
9860
10003
  state.structure.getIsoStructure().boxes.push(moov);
9861
10004
  return parseMdatSection(state);
@@ -10258,8 +10401,8 @@ var parseM3uManifest = ({
10258
10401
  return Promise.resolve(null);
10259
10402
  };
10260
10403
 
10261
- // src/forward-controller.ts
10262
- var forwardMediaParserController = ({
10404
+ // src/forward-controller-pause-resume-abort.ts
10405
+ var forwardMediaParserControllerPauseResume = ({
10263
10406
  parentController,
10264
10407
  childController
10265
10408
  }) => {
@@ -10331,7 +10474,8 @@ var parseMedia = (options) => {
10331
10474
  onError: () => ({ action: "fail" }),
10332
10475
  acknowledgeRemotionLicense: Boolean(options.acknowledgeRemotionLicense),
10333
10476
  apiName: "parseMedia()",
10334
- makeSamplesStartAtZero: options.makeSamplesStartAtZero ?? true
10477
+ makeSamplesStartAtZero: options.makeSamplesStartAtZero ?? true,
10478
+ seekingHints: options.seekingHints ?? null
10335
10479
  });
10336
10480
  };
10337
10481
 
@@ -10373,28 +10517,29 @@ var iteratorOverSegmentFiles = async ({
10373
10517
  const playlist = getPlaylist(structure, playlistUrl);
10374
10518
  const chunks = getChunks(playlist);
10375
10519
  let resolver = onInitialProgress;
10376
- let rejector = (_e) => {
10377
- };
10378
- const childController = mediaParserController();
10379
- const forwarded = forwardMediaParserController({
10380
- childController,
10381
- parentController
10382
- });
10383
- const makeContinuationFn = () => {
10384
- return {
10385
- continue() {
10386
- const { promise, reject, resolve } = withResolvers();
10387
- resolver = resolve;
10388
- rejector = reject;
10389
- childController.resume();
10390
- return promise;
10391
- },
10392
- abort() {
10393
- childController.abort();
10394
- }
10395
- };
10396
- };
10520
+ let rejector = (_e) => {};
10397
10521
  for (const chunk of chunks) {
10522
+ resolver = onInitialProgress;
10523
+ rejector = (_e) => {};
10524
+ const childController = mediaParserController();
10525
+ const forwarded = forwardMediaParserControllerPauseResume({
10526
+ childController,
10527
+ parentController
10528
+ });
10529
+ const makeContinuationFn = () => {
10530
+ return {
10531
+ continue() {
10532
+ const { promise, reject, resolve } = withResolvers();
10533
+ resolver = resolve;
10534
+ rejector = reject;
10535
+ childController.resume();
10536
+ return promise;
10537
+ },
10538
+ abort() {
10539
+ childController.abort();
10540
+ }
10541
+ };
10542
+ };
10398
10543
  const isLastChunk = chunk === chunks[chunks.length - 1];
10399
10544
  await childController._internals.checkForAbortAndPause();
10400
10545
  const src = readerInterface.createAdjacentFileSource(chunk.url, playlistUrl);
@@ -11428,7 +11573,7 @@ var parseMediaSection = async (state) => {
11428
11573
  await parseMovi({
11429
11574
  state
11430
11575
  });
11431
- const tracks2 = getTracks(state);
11576
+ const tracks2 = getTracks(state, false);
11432
11577
  if (!tracks2.videoTracks.some((t) => t.codec === TO_BE_OVERRIDDEN_LATER) && !state.callbacks.tracks.getIsDone()) {
11433
11578
  state.callbacks.tracks.setIsDone(state.logLevel);
11434
11579
  }
@@ -11799,7 +11944,10 @@ var handleAacPacket = async ({
11799
11944
  });
11800
11945
  if (!isTrackRegistered) {
11801
11946
  const startOffset = makeSamplesStartAtZero ? Math.min(streamBuffer.pesHeader.pts, streamBuffer.pesHeader.dts ?? Infinity) : 0;
11802
- transportStream.startOffset.setOffset(programId, startOffset);
11947
+ transportStream.startOffset.setOffset({
11948
+ trackId: programId,
11949
+ newOffset: startOffset
11950
+ });
11803
11951
  const track = {
11804
11952
  type: "audio",
11805
11953
  codecPrivate: codecPrivate2,
@@ -13312,6 +13460,30 @@ var warnIfRemotionLicenseNotAcknowledged = ({
13312
13460
  Log.warn(logLevel, `Pass \`acknowledgeRemotionLicense: true\` to \`${apiName}\` function to make this message disappear.`);
13313
13461
  };
13314
13462
 
13463
+ // src/set-seeking-hints.ts
13464
+ var setSeekingHints = ({
13465
+ hints,
13466
+ state
13467
+ }) => {
13468
+ if (hints.type === "iso-base-media-seeking-hints") {
13469
+ setSeekingHintsForMp4({ hints, state });
13470
+ return;
13471
+ }
13472
+ if (hints.type === "wav-seeking-hints") {
13473
+ setSeekingHintsForWav({ hints, state });
13474
+ return;
13475
+ }
13476
+ if (hints.type === "transport-stream-seeking-hints") {
13477
+ setSeekingHintsForTransportStream({ hints, state });
13478
+ return;
13479
+ }
13480
+ if (hints.type === "webm-seeking-hints") {
13481
+ setSeekingHintsForWebm({ hints, state });
13482
+ return;
13483
+ }
13484
+ throw new Error(`Unknown seeking hints type: ${hints}`);
13485
+ };
13486
+
13315
13487
  // src/get-fields-from-callbacks.ts
13316
13488
  var getFieldsFromCallback = ({
13317
13489
  fields,
@@ -13542,6 +13714,7 @@ var lazyMfraLoad = ({
13542
13714
  logLevel
13543
13715
  }) => {
13544
13716
  let prom = null;
13717
+ let result = null;
13545
13718
  const triggerLoad = () => {
13546
13719
  if (prom) {
13547
13720
  return prom;
@@ -13555,12 +13728,24 @@ var lazyMfraLoad = ({
13555
13728
  logLevel
13556
13729
  }).then((boxes) => {
13557
13730
  Log.verbose(logLevel, "Lazily found mfra atom.");
13731
+ result = boxes;
13558
13732
  return boxes;
13559
13733
  });
13560
13734
  return prom;
13561
13735
  };
13736
+ const getIfAlreadyLoaded = () => {
13737
+ if (result) {
13738
+ return result;
13739
+ }
13740
+ return null;
13741
+ };
13742
+ const setFromSeekingHints = (hints) => {
13743
+ result = hints.mfraAlreadyLoaded;
13744
+ };
13562
13745
  return {
13563
- triggerLoad
13746
+ triggerLoad,
13747
+ getIfAlreadyLoaded,
13748
+ setFromSeekingHints
13564
13749
  };
13565
13750
  };
13566
13751
 
@@ -13571,7 +13756,7 @@ var moovState = () => {
13571
13756
  setMoovBox: (moov) => {
13572
13757
  moovBox = moov;
13573
13758
  },
13574
- getMoovBox: () => moovBox
13759
+ getMoovBoxAndPrecomputed: () => moovBox
13575
13760
  };
13576
13761
  };
13577
13762
 
@@ -13592,23 +13777,33 @@ var isoBaseMediaState = ({
13592
13777
  readerInterface,
13593
13778
  src,
13594
13779
  logLevel
13595
- })
13780
+ }),
13781
+ moof: precomputedMoofState(),
13782
+ tfra: precomputedTfraState()
13596
13783
  };
13597
13784
  };
13598
13785
 
13599
13786
  // src/state/keyframes.ts
13600
13787
  var keyframesState = () => {
13601
13788
  const keyframes = [];
13602
- return {
13603
- addKeyframe: (keyframe) => {
13604
- if (keyframes.find((k) => k.positionInBytes === keyframe.positionInBytes)) {
13605
- return;
13606
- }
13607
- keyframes.push(keyframe);
13608
- },
13609
- getKeyframes: () => {
13610
- return keyframes;
13789
+ const addKeyframe = (keyframe) => {
13790
+ if (keyframes.find((k) => k.positionInBytes === keyframe.positionInBytes)) {
13791
+ return;
13611
13792
  }
13793
+ keyframes.push(keyframe);
13794
+ };
13795
+ const getKeyframes2 = () => {
13796
+ return keyframes;
13797
+ };
13798
+ const setFromSeekingHints = (hints) => {
13799
+ for (const keyframe of hints.keyframes) {
13800
+ addKeyframe(keyframe);
13801
+ }
13802
+ };
13803
+ return {
13804
+ addKeyframe,
13805
+ getKeyframes: getKeyframes2,
13806
+ setFromSeekingHints
13612
13807
  };
13613
13808
  };
13614
13809
 
@@ -13885,6 +14080,7 @@ var lazyCuesFetch = ({
13885
14080
  }) => {
13886
14081
  let prom = null;
13887
14082
  let sOffset = null;
14083
+ let result = null;
13888
14084
  const triggerLoad = (position, segmentOffset) => {
13889
14085
  if (prom) {
13890
14086
  return prom;
@@ -13902,6 +14098,7 @@ var lazyCuesFetch = ({
13902
14098
  src
13903
14099
  }).then((cues) => {
13904
14100
  Log.verbose(logLevel, "Cues loaded");
14101
+ result = cues;
13905
14102
  return cues;
13906
14103
  });
13907
14104
  return prom;
@@ -13922,9 +14119,27 @@ var lazyCuesFetch = ({
13922
14119
  segmentOffset: sOffset
13923
14120
  };
13924
14121
  };
14122
+ const getIfAlreadyLoaded = () => {
14123
+ if (result) {
14124
+ if (!sOffset) {
14125
+ throw new Error("Segment offset not set");
14126
+ }
14127
+ return {
14128
+ cues: result,
14129
+ segmentOffset: sOffset
14130
+ };
14131
+ }
14132
+ return null;
14133
+ };
14134
+ const setFromSeekingHints = (hints) => {
14135
+ result = hints.loadedCues?.cues ?? null;
14136
+ sOffset = hints.loadedCues?.segmentOffset ?? null;
14137
+ };
13925
14138
  return {
13926
14139
  triggerLoad,
13927
- getLoadedCues
14140
+ getLoadedCues,
14141
+ getIfAlreadyLoaded,
14142
+ setFromSeekingHints
13928
14143
  };
13929
14144
  };
13930
14145
 
@@ -13954,7 +14169,7 @@ var webmState = ({
13954
14169
  trackTimescale: trackTimescale?.value ?? null
13955
14170
  };
13956
14171
  };
13957
- const timestampMap = new Map;
14172
+ let timestampMap = new Map;
13958
14173
  const getTimestampOffsetForByteOffset = (byteOffset) => {
13959
14174
  const entries = Array.from(timestampMap.entries());
13960
14175
  const sortedByByteOffset = entries.sort((a, b) => {
@@ -13996,12 +14211,20 @@ var webmState = ({
13996
14211
  readerInterface,
13997
14212
  src
13998
14213
  });
14214
+ const getTimeStampMapForSeekingHints = () => {
14215
+ return timestampMap;
14216
+ };
14217
+ const setTimeStampMapForSeekingHints = (newTimestampMap) => {
14218
+ timestampMap = newTimestampMap;
14219
+ };
13999
14220
  return {
14000
14221
  cues,
14001
14222
  onTrackEntrySegment,
14002
14223
  getTrackInfoByNumber: (id) => trackEntries[id],
14003
14224
  setTimestampOffset,
14004
14225
  getTimestampOffsetForByteOffset,
14226
+ getTimeStampMapForSeekingHints,
14227
+ setTimeStampMapForSeekingHints,
14005
14228
  getTimescale,
14006
14229
  setTimescale,
14007
14230
  addSegment: (seg) => {
@@ -14231,9 +14454,6 @@ var samplesObservedState = () => {
14231
14454
  const timeBetweenSamplesAudio = startingTimestampDifferenceAudio / (audioSamples.size - 1);
14232
14455
  audioDuration = timeBetweenSamplesAudio * audioSamples.size;
14233
14456
  }
14234
- if (videoDuration === null && audioDuration === null) {
14235
- throw new Error("No samples");
14236
- }
14237
14457
  return Math.max(videoDuration ?? 0, audioDuration ?? 0);
14238
14458
  };
14239
14459
  const addVideoSample = (videoSample) => {
@@ -14365,7 +14585,7 @@ var ptsStartOffsetStore = () => {
14365
14585
  const offsets = {};
14366
14586
  return {
14367
14587
  getOffset: (trackId) => offsets[trackId] || 0,
14368
- setOffset: (trackId, newOffset) => {
14588
+ setOffset: ({ newOffset, trackId }) => {
14369
14589
  offsets[trackId] = newOffset;
14370
14590
  }
14371
14591
  };
@@ -14526,8 +14746,7 @@ var throttledStateUpdate = ({
14526
14746
  return {
14527
14747
  get: () => currentState,
14528
14748
  update: null,
14529
- stopAndGetLastProgress: () => {
14530
- }
14749
+ stopAndGetLastProgress: () => {}
14531
14750
  };
14532
14751
  }
14533
14752
  let lastUpdated = null;
@@ -14538,8 +14757,7 @@ var throttledStateUpdate = ({
14538
14757
  updateFn(currentState);
14539
14758
  lastUpdated = currentState;
14540
14759
  };
14541
- let cleanup = () => {
14542
- };
14760
+ let cleanup = () => {};
14543
14761
  if (everyMilliseconds > 0) {
14544
14762
  const interval = setInterval(() => {
14545
14763
  callUpdateIfChanged();
@@ -14590,6 +14808,7 @@ var internalParseMedia = async function({
14590
14808
  selectM3uAssociatedPlaylists: selectM3uAssociatedPlaylistsFn,
14591
14809
  mp4HeaderSegment,
14592
14810
  makeSamplesStartAtZero,
14811
+ seekingHints,
14593
14812
  ...more
14594
14813
  }) {
14595
14814
  controller._internals.markAsReadyToEmitEvents();
@@ -14638,6 +14857,19 @@ var internalParseMedia = async function({
14638
14857
  initialReaderInstance: readerInstance,
14639
14858
  makeSamplesStartAtZero
14640
14859
  });
14860
+ if (seekingHints) {
14861
+ setSeekingHints({ hints: seekingHints, state });
14862
+ }
14863
+ controller._internals.attachSeekingHintResolution(() => Promise.resolve(getSeekingHints({
14864
+ tracksState: state.callbacks.tracks,
14865
+ keyframesState: state.keyframes,
14866
+ webmState: state.webm,
14867
+ structureState: state.structure,
14868
+ mp4HeaderSegment: state.mp4HeaderSegment,
14869
+ mediaSectionState: state.mediaSection,
14870
+ isoState: state.iso,
14871
+ transportStream: state.transportStream
14872
+ })));
14641
14873
  if (!hasAudioTrackHandlers && !hasVideoTrackHandlers && Object.values(state.fields).every((v) => !v) && mode === "query") {
14642
14874
  Log.warn(logLevel, new Error("Warning - No `fields` and no `on*` callbacks were passed to `parseMedia()`. Specify the data you would like to retrieve."));
14643
14875
  }
@@ -14665,7 +14897,7 @@ var internalParseMedia = async function({
14665
14897
  return state.returnValue;
14666
14898
  };
14667
14899
 
14668
- // src/worker/forward-controller.ts
14900
+ // src/worker/forward-controller-to-worker.ts
14669
14901
  var forwardMediaParserControllerToWorker = (controller) => {
14670
14902
  return (message) => {
14671
14903
  if (message.type === "request-pause") {
@@ -14676,6 +14908,20 @@ var forwardMediaParserControllerToWorker = (controller) => {
14676
14908
  controller._experimentalSeek(message.payload);
14677
14909
  return;
14678
14910
  }
14911
+ if (message.type === "request-get-seeking-hints") {
14912
+ controller.getSeekingHints().then((hints) => {
14913
+ postMessage({
14914
+ type: "response-get-seeking-hints",
14915
+ payload: hints
14916
+ });
14917
+ }).catch((error) => {
14918
+ postMessage({
14919
+ type: "response-error",
14920
+ payload: error
14921
+ });
14922
+ });
14923
+ return;
14924
+ }
14679
14925
  if (message.type === "request-resume") {
14680
14926
  controller.resume();
14681
14927
  return;
@@ -14691,7 +14937,11 @@ var forwardMediaParserControllerToWorker = (controller) => {
14691
14937
  };
14692
14938
 
14693
14939
  // src/worker/serialize-error.ts
14694
- var serializeError = (error, logLevel) => {
14940
+ var serializeError = ({
14941
+ error,
14942
+ logLevel,
14943
+ seekingHints
14944
+ }) => {
14695
14945
  if (error instanceof IsAGifError) {
14696
14946
  return {
14697
14947
  type: "response-error",
@@ -14732,7 +14982,8 @@ var serializeError = (error, logLevel) => {
14732
14982
  type: "response-error",
14733
14983
  errorName: "MediaParserAbortError",
14734
14984
  errorMessage: error.message,
14735
- errorStack: error.stack ?? ""
14985
+ errorStack: error.stack ?? "",
14986
+ seekingHints
14736
14987
  };
14737
14988
  }
14738
14989
  if (error.name !== "Error") {
@@ -14784,7 +15035,9 @@ var startParsing = async (message, reader) => {
14784
15035
  acknowledgeRemotionLicense,
14785
15036
  logLevel: userLogLevel,
14786
15037
  progressIntervalInMs,
14787
- mp4HeaderSegment
15038
+ mp4HeaderSegment,
15039
+ seekingHints,
15040
+ makeSamplesStartAtZero
14788
15041
  } = payload;
14789
15042
  const {
14790
15043
  postAudioCodec,
@@ -15068,14 +15321,24 @@ var startParsing = async (message, reader) => {
15068
15321
  };
15069
15322
  } : null,
15070
15323
  onDiscardedData: null,
15071
- makeSamplesStartAtZero: true
15324
+ makeSamplesStartAtZero: makeSamplesStartAtZero ?? true,
15325
+ seekingHints: seekingHints ?? null
15072
15326
  });
15073
15327
  post({
15074
15328
  type: "response-done",
15075
- payload: ret
15329
+ payload: ret,
15330
+ seekingHints: await controller.getSeekingHints()
15076
15331
  });
15077
15332
  } catch (e) {
15078
- post(serializeError(e, logLevel));
15333
+ let seekingHintsRes = null;
15334
+ try {
15335
+ seekingHintsRes = await controller.getSeekingHints();
15336
+ } catch {}
15337
+ post(serializeError({
15338
+ error: e,
15339
+ logLevel,
15340
+ seekingHints: seekingHintsRes
15341
+ }));
15079
15342
  }
15080
15343
  };
15081
15344
  var onMessageForWorker = forwardMediaParserControllerToWorker(controller);