@remotion/media-parser 4.0.270 → 4.0.271

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 (332) hide show
  1. package/dist/aac-codecprivate.js +6 -13
  2. package/dist/add-avc-profile-to-track.js +5 -9
  3. package/dist/buffer-iterator.js +8 -13
  4. package/dist/combine-uint8-arrays.js +1 -5
  5. package/dist/containers/aac/parse-aac.js +9 -13
  6. package/dist/containers/aac/types.js +1 -2
  7. package/dist/containers/avc/codec-string.js +1 -5
  8. package/dist/containers/avc/color.js +3 -9
  9. package/dist/containers/avc/create-sps-pps-data.js +5 -9
  10. package/dist/containers/avc/interpret-sps.js +7 -13
  11. package/dist/containers/avc/key.js +1 -5
  12. package/dist/containers/avc/parse-avc.js +3 -7
  13. package/dist/containers/avc/sps-and-pps.js +1 -5
  14. package/dist/containers/flac/get-block-size.js +1 -5
  15. package/dist/containers/flac/get-channel-count.js +1 -5
  16. package/dist/containers/flac/get-duration-from-flac.js +1 -5
  17. package/dist/containers/flac/get-metadata-from-flac.js +1 -5
  18. package/dist/containers/flac/get-sample-rate.js +1 -5
  19. package/dist/containers/flac/parse-flac-frame.js +14 -19
  20. package/dist/containers/flac/parse-flac.js +15 -19
  21. package/dist/containers/flac/parse-header.js +1 -5
  22. package/dist/containers/flac/parse-metadata.js +1 -5
  23. package/dist/containers/flac/parse-streaminfo.js +3 -7
  24. package/dist/containers/flac/parse-unknown-block.js +1 -5
  25. package/dist/containers/flac/types.d.ts +2 -2
  26. package/dist/containers/flac/types.js +1 -2
  27. package/dist/containers/iso-base-media/base-media-box.js +1 -2
  28. package/dist/containers/iso-base-media/base-type.js +1 -2
  29. package/dist/containers/iso-base-media/esds/decoder-specific-config.js +1 -5
  30. package/dist/containers/iso-base-media/esds/esds-descriptors.js +5 -10
  31. package/dist/containers/iso-base-media/esds/esds.js +3 -7
  32. package/dist/containers/iso-base-media/ftyp.js +1 -5
  33. package/dist/containers/iso-base-media/get-actual-number-of-channels.js +4 -8
  34. package/dist/containers/iso-base-media/get-children.js +3 -7
  35. package/dist/containers/iso-base-media/get-keyframes.js +7 -11
  36. package/dist/containers/iso-base-media/get-moov-atom.js +21 -15
  37. package/dist/containers/iso-base-media/get-sample-positions-from-track.js +20 -24
  38. package/dist/containers/iso-base-media/get-video-codec-from-iso-track.d.ts +1 -1
  39. package/dist/containers/iso-base-media/get-video-codec-from-iso-track.js +3 -7
  40. package/dist/containers/iso-base-media/make-track.js +30 -34
  41. package/dist/containers/iso-base-media/mdat/mdat.js +16 -20
  42. package/dist/containers/iso-base-media/mdhd.js +1 -5
  43. package/dist/containers/iso-base-media/meta/hdlr.js +1 -5
  44. package/dist/containers/iso-base-media/meta/ilst.js +1 -5
  45. package/dist/containers/iso-base-media/moov/moov.js +3 -7
  46. package/dist/containers/iso-base-media/mvhd.js +7 -11
  47. package/dist/containers/iso-base-media/parse-boxes.js +5 -9
  48. package/dist/containers/iso-base-media/parse-icc-profile.js +4 -8
  49. package/dist/containers/iso-base-media/process-box.js +63 -67
  50. package/dist/containers/iso-base-media/stsd/av1c.js +1 -5
  51. package/dist/containers/iso-base-media/stsd/avcc.js +1 -5
  52. package/dist/containers/iso-base-media/stsd/colr.js +3 -7
  53. package/dist/containers/iso-base-media/stsd/ctts.js +1 -5
  54. package/dist/containers/iso-base-media/stsd/hvcc.js +3 -7
  55. package/dist/containers/iso-base-media/stsd/keys.js +1 -5
  56. package/dist/containers/iso-base-media/stsd/mebx.js +3 -7
  57. package/dist/containers/iso-base-media/stsd/pasp.js +1 -5
  58. package/dist/containers/iso-base-media/stsd/samples.js +8 -13
  59. package/dist/containers/iso-base-media/stsd/stco.js +1 -5
  60. package/dist/containers/iso-base-media/stsd/stsc.js +1 -5
  61. package/dist/containers/iso-base-media/stsd/stsd.js +3 -7
  62. package/dist/containers/iso-base-media/stsd/stss.js +1 -5
  63. package/dist/containers/iso-base-media/stsd/stsz.js +1 -5
  64. package/dist/containers/iso-base-media/stsd/stts.js +1 -5
  65. package/dist/containers/iso-base-media/tfdt.js +1 -5
  66. package/dist/containers/iso-base-media/tfhd.js +1 -5
  67. package/dist/containers/iso-base-media/tkhd.js +4 -8
  68. package/dist/containers/iso-base-media/to-date.js +1 -5
  69. package/dist/containers/iso-base-media/trak/trak.js +3 -7
  70. package/dist/containers/iso-base-media/traversal.d.ts +3 -2
  71. package/dist/containers/iso-base-media/traversal.js +42 -57
  72. package/dist/containers/iso-base-media/trun.js +2 -6
  73. package/dist/containers/iso-base-media/void-box.js +1 -2
  74. package/dist/containers/m3u/after-manifest-fetch.d.ts +5 -3
  75. package/dist/containers/m3u/after-manifest-fetch.js +13 -17
  76. package/dist/containers/m3u/fetch-m3u8-stream.d.ts +5 -1
  77. package/dist/containers/m3u/fetch-m3u8-stream.js +4 -12
  78. package/dist/containers/m3u/get-chunks.d.ts +1 -0
  79. package/dist/containers/m3u/get-chunks.js +6 -6
  80. package/dist/containers/m3u/get-duration-from-m3u.js +4 -8
  81. package/dist/containers/m3u/get-playlist.js +6 -12
  82. package/dist/containers/m3u/get-streams.d.ts +11 -5
  83. package/dist/containers/m3u/get-streams.js +5 -15
  84. package/dist/containers/m3u/iterate-over-segment-files.d.ts +19 -0
  85. package/dist/containers/m3u/iterate-over-segment-files.js +106 -0
  86. package/dist/containers/m3u/parse-directive.js +10 -10
  87. package/dist/containers/m3u/parse-m3u-manifest.js +3 -7
  88. package/dist/containers/m3u/parse-m3u-media-directive.d.ts +1 -0
  89. package/dist/containers/m3u/parse-m3u-media-directive.js +7 -7
  90. package/dist/containers/m3u/parse-m3u.js +13 -13
  91. package/dist/containers/m3u/parse-m3u8-text.js +3 -7
  92. package/dist/containers/m3u/parse-stream-inf.js +2 -7
  93. package/dist/containers/m3u/return-packets.d.ts +1 -1
  94. package/dist/containers/m3u/return-packets.js +14 -5
  95. package/dist/containers/m3u/run-over-m3u.js +10 -13
  96. package/dist/containers/m3u/sample-sorter.js +4 -8
  97. package/dist/containers/m3u/select-stream.d.ts +3 -2
  98. package/dist/containers/m3u/select-stream.js +9 -13
  99. package/dist/containers/m3u/types.d.ts +1 -1
  100. package/dist/containers/m3u/types.js +1 -2
  101. package/dist/containers/mp3/get-duration.js +5 -9
  102. package/dist/containers/mp3/get-frame-length.js +2 -7
  103. package/dist/containers/mp3/get-metadata-from-mp3.d.ts +2 -2
  104. package/dist/containers/mp3/get-metadata-from-mp3.js +1 -5
  105. package/dist/containers/mp3/id3-v1.js +1 -5
  106. package/dist/containers/mp3/id3.js +1 -5
  107. package/dist/containers/mp3/parse-mp3.js +7 -11
  108. package/dist/containers/mp3/parse-mpeg-header.js +10 -14
  109. package/dist/containers/mp3/samples-per-mpeg-file.js +1 -5
  110. package/dist/containers/riff/expect-riff-box.js +11 -15
  111. package/dist/containers/riff/get-duration.js +7 -12
  112. package/dist/containers/riff/get-tracks-from-avi.js +20 -28
  113. package/dist/containers/riff/is-movi.js +1 -5
  114. package/dist/containers/riff/parse-avih.js +1 -5
  115. package/dist/containers/riff/parse-isft.js +1 -5
  116. package/dist/containers/riff/parse-list-box.js +3 -7
  117. package/dist/containers/riff/parse-movi.js +13 -18
  118. package/dist/containers/riff/parse-riff-body.js +9 -13
  119. package/dist/containers/riff/parse-riff-box.js +9 -13
  120. package/dist/containers/riff/parse-riff-header.js +1 -5
  121. package/dist/containers/riff/parse-riff.js +5 -9
  122. package/dist/containers/riff/parse-strf.js +1 -5
  123. package/dist/containers/riff/parse-strh.js +3 -7
  124. package/dist/containers/riff/parse-video-section.js +7 -11
  125. package/dist/containers/riff/riff-box.js +1 -2
  126. package/dist/containers/riff/timescale.js +1 -4
  127. package/dist/containers/riff/traversal.js +7 -15
  128. package/dist/containers/transport-stream/adts-header.js +6 -10
  129. package/dist/containers/transport-stream/boxes.js +1 -2
  130. package/dist/containers/transport-stream/discard-rest-of-packet.js +2 -7
  131. package/dist/containers/transport-stream/find-separator.js +1 -4
  132. package/dist/containers/transport-stream/get-tracks.js +7 -12
  133. package/dist/containers/transport-stream/handle-aac-packet.js +12 -16
  134. package/dist/containers/transport-stream/handle-avc-packet.js +22 -26
  135. package/dist/containers/transport-stream/next-pes-header-store.js +1 -5
  136. package/dist/containers/transport-stream/parse-packet.js +13 -17
  137. package/dist/containers/transport-stream/parse-pat.js +5 -10
  138. package/dist/containers/transport-stream/parse-pes.js +1 -5
  139. package/dist/containers/transport-stream/parse-pmt.js +3 -7
  140. package/dist/containers/transport-stream/parse-stream-packet.js +13 -17
  141. package/dist/containers/transport-stream/parse-transport-stream.js +5 -9
  142. package/dist/containers/transport-stream/process-stream-buffers.js +10 -15
  143. package/dist/containers/transport-stream/traversal.js +4 -10
  144. package/dist/containers/wav/get-duration-from-wav.js +3 -8
  145. package/dist/containers/wav/get-metadata-from-wav.d.ts +2 -2
  146. package/dist/containers/wav/get-metadata-from-wav.js +1 -5
  147. package/dist/containers/wav/parse-data.js +5 -9
  148. package/dist/containers/wav/parse-fmt.js +3 -7
  149. package/dist/containers/wav/parse-header.js +1 -5
  150. package/dist/containers/wav/parse-id3.js +1 -5
  151. package/dist/containers/wav/parse-list.js +1 -5
  152. package/dist/containers/wav/parse-video-section.js +3 -7
  153. package/dist/containers/wav/parse-wav.js +15 -19
  154. package/dist/containers/wav/types.d.ts +2 -2
  155. package/dist/containers/wav/types.js +1 -2
  156. package/dist/containers/webm/allowed-partial-segments.js +1 -4
  157. package/dist/containers/webm/av1-codec-private.js +3 -7
  158. package/dist/containers/webm/color.js +6 -10
  159. package/dist/containers/webm/description.js +6 -10
  160. package/dist/containers/webm/get-ready-tracks.js +13 -18
  161. package/dist/containers/webm/get-sample-from-block.js +12 -16
  162. package/dist/containers/webm/make-track.js +43 -48
  163. package/dist/containers/webm/parse-ebml.js +14 -19
  164. package/dist/containers/webm/parse-webm-header.js +3 -7
  165. package/dist/containers/webm/segments/all-segments.js +168 -173
  166. package/dist/containers/webm/segments/block-simple-block-flags.js +4 -8
  167. package/dist/containers/webm/segments/track-entry.js +1 -5
  168. package/dist/containers/webm/segments.js +9 -13
  169. package/dist/containers/webm/traversal.js +37 -67
  170. package/dist/convert-audio-or-video-sample.js +1 -5
  171. package/dist/download-and-parse-media.js +44 -47
  172. package/dist/emit-available-info.js +38 -38
  173. package/dist/emitter.js +1 -5
  174. package/dist/errors.d.ts +2 -17
  175. package/dist/errors.js +10 -30
  176. package/dist/esm/fetch.mjs +93 -67
  177. package/dist/esm/index.mjs +679 -175
  178. package/dist/esm/node.mjs +59 -36
  179. package/dist/esm/universal.mjs +323 -0
  180. package/dist/esm/web-file.mjs +55 -43
  181. package/dist/esm/web.mjs +257 -0
  182. package/dist/esm/worker-server-entry.mjs +13056 -0
  183. package/dist/esm/worker-server.mjs +12914 -0
  184. package/dist/esm/worker-web-entry.mjs +12969 -0
  185. package/dist/esm/worker.mjs +439 -0
  186. package/dist/fetch.js +1 -17
  187. package/dist/file-types/bmp.js +3 -7
  188. package/dist/file-types/detect-file-type.js +24 -38
  189. package/dist/file-types/index.js +22 -26
  190. package/dist/file-types/jpeg.js +4 -9
  191. package/dist/file-types/pdf.js +3 -7
  192. package/dist/file-types/png.js +4 -9
  193. package/dist/file-types/webp.js +3 -7
  194. package/dist/forward-controller.js +1 -5
  195. package/dist/get-audio-codec.js +25 -38
  196. package/dist/get-container.d.ts +3 -3
  197. package/dist/get-container.js +5 -10
  198. package/dist/get-dimensions.js +8 -13
  199. package/dist/get-duration.js +27 -34
  200. package/dist/get-fields-from-callbacks.js +1 -5
  201. package/dist/get-fps.js +24 -34
  202. package/dist/get-is-hdr.js +5 -10
  203. package/dist/get-keyframes.js +6 -11
  204. package/dist/get-location.js +4 -9
  205. package/dist/get-number-of-audio-channels.js +2 -7
  206. package/dist/get-sample-aspect-ratio.js +17 -30
  207. package/dist/get-sample-positions-from-lpcm.js +5 -9
  208. package/dist/get-sample-positions.js +1 -5
  209. package/dist/get-sample-rate.js +2 -7
  210. package/dist/get-tracks.d.ts +5 -0
  211. package/dist/get-tracks.js +37 -44
  212. package/dist/get-video-codec.js +26 -34
  213. package/dist/has-all-info.js +33 -38
  214. package/dist/index.d.ts +15 -11
  215. package/dist/index.js +34 -48
  216. package/dist/init-video.d.ts +1 -1
  217. package/dist/init-video.js +47 -20
  218. package/dist/internal-parse-media.js +36 -40
  219. package/dist/is-audio-structure.d.ts +2 -2
  220. package/dist/is-audio-structure.js +1 -5
  221. package/dist/log.js +8 -12
  222. package/dist/make-hvc1-codec-strings.js +1 -5
  223. package/dist/media-parser-controller.js +7 -11
  224. package/dist/metadata/get-metadata.d.ts +4 -4
  225. package/dist/metadata/get-metadata.js +17 -22
  226. package/dist/metadata/metadata-from-iso.d.ts +3 -3
  227. package/dist/metadata/metadata-from-iso.js +12 -17
  228. package/dist/metadata/metadata-from-matroska.d.ts +2 -2
  229. package/dist/metadata/metadata-from-matroska.js +3 -7
  230. package/dist/metadata/metadata-from-riff.d.ts +2 -2
  231. package/dist/metadata/metadata-from-riff.js +3 -7
  232. package/dist/node-writer.js +1 -17
  233. package/dist/node.js +1 -17
  234. package/dist/options.d.ts +30 -24
  235. package/dist/options.js +1 -2
  236. package/dist/parse-media-on-browser-worker.d.ts +2 -0
  237. package/dist/parse-media-on-browser-worker.js +4 -0
  238. package/dist/parse-media-on-server-worker.d.ts +2 -0
  239. package/dist/parse-media-on-server-worker.js +4 -0
  240. package/dist/parse-media-on-web-worker.d.ts +2 -0
  241. package/dist/parse-media-on-web-worker.js +4 -0
  242. package/dist/parse-media-on-worker-entry.d.ts +2 -0
  243. package/dist/parse-media-on-worker-entry.js +269 -0
  244. package/dist/parse-media-on-worker.d.ts +2 -0
  245. package/dist/parse-media-on-worker.js +4 -0
  246. package/dist/parse-media.js +10 -13
  247. package/dist/parse-result.d.ts +3 -3
  248. package/dist/parse-result.js +1 -2
  249. package/dist/pause-signal.js +1 -5
  250. package/dist/perform-seek.js +6 -10
  251. package/dist/readers/fetch/get-body-and-reader.js +1 -5
  252. package/dist/readers/fetch/resolve-url.d.ts +1 -1
  253. package/dist/readers/fetch/resolve-url.js +1 -5
  254. package/dist/readers/from-fetch.d.ts +4 -1
  255. package/dist/readers/from-fetch.js +109 -94
  256. package/dist/readers/from-node.d.ts +4 -1
  257. package/dist/readers/from-node.js +58 -41
  258. package/dist/readers/from-web-file.d.ts +4 -1
  259. package/dist/readers/from-web-file.js +55 -49
  260. package/dist/readers/reader.d.ts +5 -1
  261. package/dist/readers/reader.js +1 -2
  262. package/dist/readers/universal.d.ts +2 -0
  263. package/dist/readers/universal.js +35 -0
  264. package/dist/readers/web.d.ts +2 -0
  265. package/dist/readers/web.js +22 -0
  266. package/dist/register-track.js +9 -15
  267. package/dist/remotion-license-acknowledge.js +4 -8
  268. package/dist/run-parse-iteration.js +26 -25
  269. package/dist/samples-from-moof.js +8 -12
  270. package/dist/skip.js +1 -5
  271. package/dist/state/aac-state.js +1 -5
  272. package/dist/state/can-skip-tracks.d.ts +2 -2
  273. package/dist/state/can-skip-tracks.js +3 -8
  274. package/dist/state/emitted-fields.js +1 -5
  275. package/dist/state/flac-state.js +1 -5
  276. package/dist/state/has-tracks-section.js +3 -7
  277. package/dist/state/images.js +1 -5
  278. package/dist/state/iso-base-media/cached-sample-positions.js +8 -13
  279. package/dist/state/iso-base-media/iso-state.js +5 -9
  280. package/dist/state/iso-base-media/moov-box.js +1 -5
  281. package/dist/state/keyframes.js +1 -5
  282. package/dist/state/last-eventloop-break.js +3 -7
  283. package/dist/state/m3u-state.d.ts +3 -0
  284. package/dist/state/m3u-state.js +16 -11
  285. package/dist/state/may-skip-video-data.js +3 -7
  286. package/dist/state/mp3.js +1 -5
  287. package/dist/state/need-samples-for-fields.js +1 -5
  288. package/dist/state/parser-state.d.ts +12 -10
  289. package/dist/state/parser-state.js +36 -41
  290. package/dist/state/riff.js +1 -5
  291. package/dist/state/sample-callbacks.js +8 -12
  292. package/dist/state/slow-duration-fps.js +1 -5
  293. package/dist/state/structure.d.ts +4 -4
  294. package/dist/state/structure.js +1 -5
  295. package/dist/state/transport-stream.js +3 -7
  296. package/dist/state/video-section.js +1 -5
  297. package/dist/state/webm.js +5 -9
  298. package/dist/throttled-progress.js +1 -5
  299. package/dist/truthy.js +1 -4
  300. package/dist/universal.d.ts +1 -0
  301. package/dist/universal.js +1 -0
  302. package/dist/version.d.ts +1 -1
  303. package/dist/version.js +1 -4
  304. package/dist/web-file.js +1 -17
  305. package/dist/web.d.ts +1 -0
  306. package/dist/web.js +1 -0
  307. package/dist/webcodec-sample-types.d.ts +6 -4
  308. package/dist/webcodec-sample-types.js +1 -2
  309. package/dist/worker/forward-controller.d.ts +3 -0
  310. package/dist/worker/forward-controller.js +20 -0
  311. package/dist/worker/serialize-error.d.ts +4 -0
  312. package/dist/worker/serialize-error.js +95 -0
  313. package/dist/worker/worker-types.d.ts +243 -0
  314. package/dist/worker/worker-types.js +1 -0
  315. package/dist/worker-bun-entry.d.ts +1 -0
  316. package/dist/worker-bun-entry.js +5 -0
  317. package/dist/worker-entry.d.ts +1 -0
  318. package/dist/worker-entry.js +5 -0
  319. package/dist/worker-server-entry.d.ts +1 -0
  320. package/dist/worker-server-entry.js +5 -0
  321. package/dist/worker-server.d.ts +2 -0
  322. package/dist/worker-server.js +381 -0
  323. package/dist/worker-web-entry.d.ts +1 -0
  324. package/dist/worker-web-entry.js +5 -0
  325. package/dist/worker.d.ts +2 -0
  326. package/dist/worker.js +267 -0
  327. package/dist/writers/node.js +16 -23
  328. package/dist/writers/writer.js +1 -2
  329. package/package.json +40 -21
  330. package/fetch.js +0 -2
  331. package/test.json +0 -663
  332. package/web-file.js +0 -2
@@ -1996,17 +1996,25 @@ var parseEsds = ({
1996
1996
  };
1997
1997
 
1998
1998
  // src/containers/iso-base-media/traversal.ts
1999
- var getMoovBox = (state) => {
2000
- if (state.iso.moov.getMoovBox()) {
2001
- return state.iso.moov.getMoovBox();
2002
- }
2003
- const structure = state.getIsoStructure();
1999
+ var getMoovFromFromIsoStructure = (structure) => {
2004
2000
  const moovBox = structure.boxes.find((s) => s.type === "moov-box");
2005
2001
  if (!moovBox || moovBox.type !== "moov-box") {
2006
2002
  return null;
2007
2003
  }
2008
2004
  return moovBox;
2009
2005
  };
2006
+ var getMoovBoxFromState = (state) => {
2007
+ const got = state.iso.moov.getMoovBox();
2008
+ if (got) {
2009
+ return got;
2010
+ }
2011
+ const a = state.mp4HeaderSegment;
2012
+ if (a) {
2013
+ return getMoovFromFromIsoStructure(a);
2014
+ }
2015
+ const structure = state.getIsoStructure();
2016
+ return getMoovFromFromIsoStructure(structure);
2017
+ };
2010
2018
  var getMoofBoxes = (main) => {
2011
2019
  const moofBoxes = main.filter((s) => s.type === "regular-box" && s.boxType === "moof");
2012
2020
  return moofBoxes;
@@ -2270,7 +2278,7 @@ var getFpsFromMp4TrakBox = (trakBox) => {
2270
2278
  });
2271
2279
  };
2272
2280
  var getFpsFromIsoMaseMedia = (state) => {
2273
- const moovBox = getMoovBox(state);
2281
+ const moovBox = getMoovBoxFromState(state);
2274
2282
  if (!moovBox) {
2275
2283
  return null;
2276
2284
  }
@@ -3189,7 +3197,7 @@ var matroskaHasTracks = (state) => {
3189
3197
 
3190
3198
  // src/get-tracks.ts
3191
3199
  var isoBaseMediaHasTracks = (state) => {
3192
- return Boolean(getMoovBox(state));
3200
+ return Boolean(getMoovBoxFromState(state));
3193
3201
  };
3194
3202
  var getHasTracks = (state) => {
3195
3203
  const structure = state.getStructure();
@@ -3244,18 +3252,10 @@ var getCategorizedTracksFromMatroska = (state) => {
3244
3252
  otherTracks
3245
3253
  };
3246
3254
  };
3247
- var getTracksFromIsoBaseMedia = (state) => {
3255
+ var getTracksFromMoovBox = (moovBox) => {
3248
3256
  const videoTracks = [];
3249
3257
  const audioTracks = [];
3250
3258
  const otherTracks = [];
3251
- const moovBox = getMoovBox(state);
3252
- if (!moovBox) {
3253
- return {
3254
- videoTracks,
3255
- audioTracks,
3256
- otherTracks
3257
- };
3258
- }
3259
3259
  const tracks2 = getTraks(moovBox);
3260
3260
  for (const trakBox of tracks2) {
3261
3261
  const track = makeBaseMediaTrack(trakBox);
@@ -3276,6 +3276,17 @@ var getTracksFromIsoBaseMedia = (state) => {
3276
3276
  otherTracks
3277
3277
  };
3278
3278
  };
3279
+ var getTracksFromIsoBaseMedia = (state) => {
3280
+ const moovBox = getMoovBoxFromState(state);
3281
+ if (!moovBox) {
3282
+ return {
3283
+ videoTracks: [],
3284
+ audioTracks: [],
3285
+ otherTracks: []
3286
+ };
3287
+ }
3288
+ return getTracksFromMoovBox(moovBox);
3289
+ };
3279
3290
  var defaultGetTracks = (parserState) => {
3280
3291
  const tracks2 = parserState.callbacks.tracks.getTracks();
3281
3292
  if (tracks2.length === 0) {
@@ -4727,7 +4738,7 @@ var parseTrun = ({
4727
4738
  const sampleDuration = flags & 256 ? iterator.getUint32() : null;
4728
4739
  const sampleSize = flags & 512 ? iterator.getUint32() : null;
4729
4740
  const sampleFlags = flags & 1024 ? iterator.getUint32() : null;
4730
- const sampleCompositionTimeOffset = flags & 2048 ? version === 0 ? iterator.getUint32() : iterator.getInt32Le() : null;
4741
+ const sampleCompositionTimeOffset = flags & 2048 ? version === 0 ? iterator.getUint32() : iterator.getInt32() : null;
4731
4742
  samples.push({
4732
4743
  sampleDuration,
4733
4744
  sampleSize,
@@ -5812,7 +5823,11 @@ var isIndependentSegments = (structure) => {
5812
5823
  }
5813
5824
  return structure.boxes.some((box) => box.type === "m3u-independent-segments" || box.type === "m3u-stream-info");
5814
5825
  };
5815
- var getM3uStreams = (structure, originalSrc) => {
5826
+ var getM3uStreams = ({
5827
+ structure,
5828
+ originalSrc,
5829
+ readerInterface
5830
+ }) => {
5816
5831
  if (structure === null || structure.type !== "m3u") {
5817
5832
  return null;
5818
5833
  }
@@ -5837,13 +5852,13 @@ var getM3uStreams = (structure, originalSrc) => {
5837
5852
  groupId: audioTrack.groupId,
5838
5853
  language: audioTrack.language,
5839
5854
  name: audioTrack.name,
5840
- url: originalSrc && originalSrc.startsWith("http") ? new URL(audioTrack.uri, originalSrc).href : audioTrack.uri,
5855
+ src: readerInterface.createAdjacentFileSource(audioTrack.uri, originalSrc),
5841
5856
  id: associatedPlaylists.length
5842
5857
  });
5843
5858
  }
5844
5859
  }
5845
5860
  boxes.push({
5846
- url: originalSrc && originalSrc.startsWith("http") ? new URL(next.value, originalSrc).href : next.value,
5861
+ src: readerInterface.createAdjacentFileSource(next.value, originalSrc),
5847
5862
  averageBandwidth: str.averageBandwidth,
5848
5863
  bandwidth: str.bandwidth,
5849
5864
  codecs: str.codecs,
@@ -6097,7 +6112,7 @@ var getSamplesFromTraf = (trafSegment, moofOffset) => {
6097
6112
  const samplePosition = {
6098
6113
  offset: offset + (moofOffset ?? 0) + (dataOffset ?? 0),
6099
6114
  dts,
6100
- cts: dts,
6115
+ cts: dts + (sample.sampleCompositionTimeOffset ?? 0),
6101
6116
  duration: duration2,
6102
6117
  isKeyframe: keyframe,
6103
6118
  size,
@@ -6376,7 +6391,7 @@ var getDurationFromMatroska = (segments) => {
6376
6391
  };
6377
6392
  var isoHasDuration = (parserState) => {
6378
6393
  const structure = parserState.getIsoStructure();
6379
- const moovBox = getMoovBox(parserState);
6394
+ const moovBox = getMoovBoxFromState(parserState);
6380
6395
  if (!moovBox) {
6381
6396
  return false;
6382
6397
  }
@@ -6397,7 +6412,7 @@ var isoHasDuration = (parserState) => {
6397
6412
  };
6398
6413
  var getDurationFromIsoBaseMedia = (parserState) => {
6399
6414
  const structure = parserState.getIsoStructure();
6400
- const moovBox = getMoovBox(parserState);
6415
+ const moovBox = getMoovBoxFromState(parserState);
6401
6416
  if (!moovBox) {
6402
6417
  return null;
6403
6418
  }
@@ -6639,7 +6654,7 @@ var parseIsoMetaBox = (meta, trackId) => {
6639
6654
  return entries;
6640
6655
  };
6641
6656
  var getMetadataFromIsoBase = (state) => {
6642
- const moov = getMoovBox(state);
6657
+ const moov = getMoovBoxFromState(state);
6643
6658
  if (!moov) {
6644
6659
  return [];
6645
6660
  }
@@ -7173,7 +7188,11 @@ var emitAvailableInfo = async ({
7173
7188
  }
7174
7189
  if (key === "m3uStreams") {
7175
7190
  if (!emittedFields.m3uStreams && hasInfo.m3uStreams) {
7176
- const streams = getM3uStreams(state.getStructureOrNull(), typeof state.src === "string" ? state.src : null);
7191
+ const streams = getM3uStreams({
7192
+ structure: state.getStructureOrNull(),
7193
+ originalSrc: state.src,
7194
+ readerInterface: state.readerInterface
7195
+ });
7177
7196
  await callbacks.onM3uStreams?.(streams);
7178
7197
  if (fieldsInReturnValue.m3uStreams) {
7179
7198
  returnValue.m3uStreams = streams;
@@ -7418,6 +7437,7 @@ class IsAGifError extends Error {
7418
7437
  fileName
7419
7438
  }) {
7420
7439
  super(message);
7440
+ this.name = "IsAGifError";
7421
7441
  this.fileName = "IsAGifError";
7422
7442
  this.mimeType = mimeType;
7423
7443
  this.sizeInBytes = sizeInBytes;
@@ -7497,30 +7517,6 @@ class IsAnUnsupportedFileTypeError extends Error {
7497
7517
  }
7498
7518
  }
7499
7519
 
7500
- class IsAnUnsupportedAudioTypeError extends Error {
7501
- mimeType;
7502
- sizeInBytes;
7503
- fileName;
7504
- audioType;
7505
- constructor({
7506
- message,
7507
- mimeType,
7508
- sizeInBytes,
7509
- fileName,
7510
- audioType
7511
- }) {
7512
- super(message);
7513
- this.name = "IsAnUnsupportedAudioTypeError";
7514
- this.mimeType = mimeType;
7515
- this.sizeInBytes = sizeInBytes;
7516
- this.fileName = fileName;
7517
- this.audioType = audioType;
7518
- if (Error.captureStackTrace) {
7519
- Error.captureStackTrace(this, IsAnUnsupportedAudioTypeError);
7520
- }
7521
- }
7522
- }
7523
-
7524
7520
  class MediaParserAbortError extends Error {
7525
7521
  constructor(message) {
7526
7522
  super(message);
@@ -7529,7 +7525,7 @@ class MediaParserAbortError extends Error {
7529
7525
  }
7530
7526
  }
7531
7527
  var hasBeenAborted = (error) => {
7532
- return error instanceof MediaParserAbortError;
7528
+ return error instanceof MediaParserAbortError || error.name === "MediaParserAbortError";
7533
7529
  };
7534
7530
 
7535
7531
  // src/pause-signal.ts
@@ -8307,21 +8303,6 @@ var keyframesState = () => {
8307
8303
  };
8308
8304
  };
8309
8305
 
8310
- // src/state/last-eventloop-break.ts
8311
- var eventLoopState = (logLevel) => {
8312
- let lastEventLoopBreak = Date.now();
8313
- const eventLoopBreakIfNeeded = async () => {
8314
- if (Date.now() - lastEventLoopBreak > 2000) {
8315
- await new Promise((resolve) => {
8316
- setTimeout(() => resolve(), 50);
8317
- });
8318
- Log.verbose(logLevel, "10ms event loop break");
8319
- lastEventLoopBreak = Date.now();
8320
- }
8321
- };
8322
- return { eventLoopBreakIfNeeded };
8323
- };
8324
-
8325
8306
  // src/containers/m3u/sample-sorter.ts
8326
8307
  var sampleSorter = ({
8327
8308
  logLevel,
@@ -8400,16 +8381,23 @@ var m3uState = (logLevel) => {
8400
8381
  if (!selectedMainPlaylist) {
8401
8382
  throw new Error("No main playlist selected");
8402
8383
  }
8403
- const playlistUrl = selectedMainPlaylist.type === "initial-url" ? selectedMainPlaylist.url : selectedMainPlaylist.stream.url;
8384
+ const playlistUrl = selectedMainPlaylist.type === "initial-url" ? selectedMainPlaylist.url : selectedMainPlaylist.stream.src;
8404
8385
  return playlistUrl;
8405
8386
  };
8406
8387
  const getSelectedPlaylists = () => {
8407
8388
  return [
8408
8389
  getMainPlaylistUrl(),
8409
- ...(associatedPlaylists ?? []).map((p) => p.url)
8390
+ ...(associatedPlaylists ?? []).map((p) => p.src)
8410
8391
  ];
8411
8392
  };
8412
8393
  const getAllChunksProcessedForPlaylist = (src) => allChunksProcessed[src];
8394
+ const mp4HeaderSegments = {};
8395
+ const setMp4HeaderSegment = (playlistUrl, structure) => {
8396
+ mp4HeaderSegments[playlistUrl] = structure;
8397
+ };
8398
+ const getMp4HeaderSegment = (playlistUrl) => {
8399
+ return mp4HeaderSegments[playlistUrl];
8400
+ };
8413
8401
  return {
8414
8402
  setSelectedMainPlaylist: (stream) => {
8415
8403
  selectedMainPlaylist = stream;
@@ -8486,7 +8474,9 @@ var m3uState = (logLevel) => {
8486
8474
  },
8487
8475
  getAssociatedPlaylists: () => associatedPlaylists,
8488
8476
  getSelectedPlaylists,
8489
- sampleSorter: sampleSorter({ logLevel, getAllChunksProcessedForPlaylist })
8477
+ sampleSorter: sampleSorter({ logLevel, getAllChunksProcessedForPlaylist }),
8478
+ setMp4HeaderSegment,
8479
+ getMp4HeaderSegment
8490
8480
  };
8491
8481
  };
8492
8482
 
@@ -9035,7 +9025,8 @@ var makeParserState = ({
9035
9025
  readerInterface,
9036
9026
  onDiscardedData,
9037
9027
  selectM3uStreamFn,
9038
- selectM3uAssociatedPlaylistsFn
9028
+ selectM3uAssociatedPlaylistsFn,
9029
+ mp4HeaderSegment
9039
9030
  }) => {
9040
9031
  let skippedBytes = 0;
9041
9032
  const iterator = getArrayBufferIterator(new Uint8Array([]), contentLength);
@@ -9096,12 +9087,12 @@ var makeParserState = ({
9096
9087
  iterator,
9097
9088
  controller,
9098
9089
  mode,
9099
- eventLoop: eventLoopState(logLevel),
9100
9090
  src,
9101
9091
  readerInterface,
9102
9092
  discardReadBytes,
9103
9093
  selectM3uStreamFn,
9104
- selectM3uAssociatedPlaylistsFn
9094
+ selectM3uAssociatedPlaylistsFn,
9095
+ mp4HeaderSegment
9105
9096
  };
9106
9097
  };
9107
9098
 
@@ -9110,6 +9101,14 @@ var getMoovAtom = async ({
9110
9101
  endOfMdat,
9111
9102
  state
9112
9103
  }) => {
9104
+ const headerSegment = state.mp4HeaderSegment;
9105
+ if (headerSegment) {
9106
+ const segment = getMoovFromFromIsoStructure(headerSegment);
9107
+ if (!segment) {
9108
+ throw new Error("No moov box found in header segment");
9109
+ }
9110
+ return segment;
9111
+ }
9113
9112
  const start = Date.now();
9114
9113
  Log.verbose(state.logLevel, "Starting second fetch to get moov atom");
9115
9114
  const { reader } = await state.readerInterface.read({
@@ -9139,7 +9138,8 @@ var getMoovAtom = async ({
9139
9138
  src: state.src,
9140
9139
  onDiscardedData: null,
9141
9140
  selectM3uStreamFn: state.selectM3uStreamFn,
9142
- selectM3uAssociatedPlaylistsFn: state.selectM3uAssociatedPlaylistsFn
9141
+ selectM3uAssociatedPlaylistsFn: state.selectM3uAssociatedPlaylistsFn,
9142
+ mp4HeaderSegment: state.mp4HeaderSegment
9143
9143
  });
9144
9144
  while (true) {
9145
9145
  const result = await reader.reader.read();
@@ -9308,7 +9308,7 @@ var parseStreamInf = (str) => {
9308
9308
  };
9309
9309
 
9310
9310
  // src/containers/m3u/parse-m3u-media-directive.ts
9311
- var parseM3uMediaDirective = (str) => {
9311
+ var parseM3uKeyValue = (str) => {
9312
9312
  const quotes = splitRespectingQuotes(str);
9313
9313
  const map = {};
9314
9314
  for (const quote of quotes) {
@@ -9321,6 +9321,10 @@ var parseM3uMediaDirective = (str) => {
9321
9321
  const actualValue = value?.startsWith('"') && value?.endsWith('"') ? value.slice(1, -1) : value;
9322
9322
  map[key] = actualValue;
9323
9323
  }
9324
+ return map;
9325
+ };
9326
+ var parseM3uMediaDirective = (str) => {
9327
+ const map = parseM3uKeyValue(str);
9324
9328
  return {
9325
9329
  type: "m3u-media-info",
9326
9330
  autoselect: map.AUTOSELECT === "YES",
@@ -9420,9 +9424,13 @@ var parseM3uDirective = (str) => {
9420
9424
  if (!value) {
9421
9425
  throw new Error("#EXT-X-MAP directive must have a value");
9422
9426
  }
9427
+ const p = parseM3uKeyValue(value);
9428
+ if (!p.URI) {
9429
+ throw new Error("EXT-X-MAP directive must have a URI");
9430
+ }
9423
9431
  return {
9424
9432
  type: "m3u-map",
9425
- value: Number(value)
9433
+ value: p.URI
9426
9434
  };
9427
9435
  }
9428
9436
  throw new Error(`Unknown directive ${directive}. Value: ${value}`);
@@ -9449,12 +9457,11 @@ var parseM3u8Text = (line, boxes) => {
9449
9457
  };
9450
9458
 
9451
9459
  // src/containers/m3u/fetch-m3u8-stream.ts
9452
- var fetchM3u8Stream = async (url) => {
9453
- const res = await fetch(url);
9454
- if (!res.ok) {
9455
- throw new Error(`Failed to fetch ${url} (HTTP code: ${res.status})`);
9456
- }
9457
- const text = await res.text();
9460
+ var fetchM3u8Stream = async ({
9461
+ url,
9462
+ readerInterface
9463
+ }) => {
9464
+ const text = await readerInterface.readWholeAsText(url);
9458
9465
  const lines = text.split(`
9459
9466
  `);
9460
9467
  const boxes = [];
@@ -9477,14 +9484,17 @@ var selectAssociatedPlaylists = async ({
9477
9484
  throw new Error("Expected an array of associated playlists");
9478
9485
  }
9479
9486
  for (const stream of streams) {
9480
- if (!playlists.find((playlist) => playlist.url === stream.url)) {
9487
+ if (!playlists.find((playlist) => playlist.src === stream.src)) {
9481
9488
  throw new Error(`The associated playlist ${JSON.stringify(streams)} cannot be selected because it was not in the list of selectable playlists`);
9482
9489
  }
9483
9490
  }
9484
9491
  return streams;
9485
9492
  };
9486
9493
  var defaultSelectM3uAssociatedPlaylists = ({ associatedPlaylists }) => {
9487
- return Promise.resolve(associatedPlaylists.filter((playlist) => playlist.default));
9494
+ if (associatedPlaylists.length === 1) {
9495
+ return associatedPlaylists;
9496
+ }
9497
+ return associatedPlaylists.filter((playlist) => playlist.default);
9488
9498
  };
9489
9499
  var selectStream = async ({
9490
9500
  streams,
@@ -9511,7 +9521,8 @@ var afterManifestFetch = async ({
9511
9521
  src,
9512
9522
  selectM3uStreamFn,
9513
9523
  logLevel,
9514
- selectAssociatedPlaylists: selectAssociatedPlaylistsFn
9524
+ selectAssociatedPlaylistsFn,
9525
+ readerInterface
9515
9526
  }) => {
9516
9527
  const independentSegments = isIndependentSegments(structure);
9517
9528
  if (!independentSegments) {
@@ -9524,7 +9535,7 @@ var afterManifestFetch = async ({
9524
9535
  });
9525
9536
  return m3uState2.setReadyToIterateOverM3u();
9526
9537
  }
9527
- const streams = getM3uStreams(structure, src);
9538
+ const streams = getM3uStreams({ structure, originalSrc: src, readerInterface });
9528
9539
  if (streams === null) {
9529
9540
  throw new Error("No streams found");
9530
9541
  }
@@ -9542,12 +9553,12 @@ var afterManifestFetch = async ({
9542
9553
  });
9543
9554
  m3uState2.setAssociatedPlaylists(associatedPlaylists);
9544
9555
  const playlistUrls = [
9545
- selectedPlaylist.url,
9546
- ...associatedPlaylists.map((p) => p.url)
9556
+ selectedPlaylist.src,
9557
+ ...associatedPlaylists.map((p) => p.src)
9547
9558
  ];
9548
9559
  const struc = await Promise.all(playlistUrls.map(async (url) => {
9549
9560
  Log.verbose(logLevel, `Fetching playlist ${url}`);
9550
- const boxes = await fetchM3u8Stream(url);
9561
+ const boxes = await fetchM3u8Stream({ url, readerInterface });
9551
9562
  return {
9552
9563
  type: "m3u-playlist",
9553
9564
  boxes,
@@ -9676,89 +9687,178 @@ function parseContentRange(input) {
9676
9687
  return range2;
9677
9688
  }
9678
9689
  var validateContentRangeAndDetectIfSupported = ({
9679
- actualRange,
9690
+ requestedRange,
9680
9691
  parsedContentRange,
9681
9692
  statusCode
9682
9693
  }) => {
9683
9694
  if (statusCode === 206) {
9684
9695
  return { supportsContentRange: true };
9685
9696
  }
9686
- if (typeof actualRange === "number" && parsedContentRange?.start !== actualRange) {
9687
- if (actualRange === 0) {
9697
+ if (typeof requestedRange === "number" && parsedContentRange?.start !== requestedRange) {
9698
+ if (requestedRange === 0) {
9688
9699
  return { supportsContentRange: false };
9689
9700
  }
9690
- throw new Error(`Range header (${actualRange}) does not match content-range header (${parsedContentRange?.start})`);
9701
+ throw new Error(`Range header (${requestedRange}) does not match content-range header (${parsedContentRange?.start})`);
9691
9702
  }
9692
- if (actualRange !== null && typeof actualRange !== "number" && (parsedContentRange?.start !== actualRange[0] || parsedContentRange?.end !== actualRange[1])) {
9693
- throw new Error(`Range header (${actualRange}) does not match content-range header (${parsedContentRange?.start})`);
9703
+ if (requestedRange !== null && typeof requestedRange !== "number" && (parsedContentRange?.start !== requestedRange[0] || parsedContentRange?.end !== requestedRange[1])) {
9704
+ throw new Error(`Range header (${requestedRange}) does not match content-range header (${parsedContentRange?.start})`);
9694
9705
  }
9695
9706
  return { supportsContentRange: true };
9696
9707
  };
9697
- var fetchReader = {
9698
- read: async ({ src, range: range2, controller }) => {
9699
- if (typeof src !== "string") {
9700
- throw new Error("src must be a string when using `fetchReader`");
9701
- }
9702
- const resolvedUrl = resolveUrl(src);
9703
- const resolvedUrlString = resolvedUrl.toString();
9704
- if (!resolvedUrlString.startsWith("https://") && !resolvedUrlString.startsWith("blob:") && !resolvedUrlString.startsWith("http://")) {
9705
- return Promise.reject(new Error(`${resolvedUrlString} is not a URL - needs to start with http:// or https:// or blob:. If you want to read a local file, pass \`reader: nodeReader\` to parseMedia().`));
9706
- }
9707
- const ownController = new AbortController;
9708
- const cache = typeof navigator !== "undefined" && navigator.userAgent.includes("Cloudflare-Workers") ? undefined : "no-store";
9709
- const actualRange = range2 === null ? 0 : range2;
9710
- const asString = typeof resolvedUrl === "string" ? resolvedUrl : resolvedUrl.pathname;
9711
- const requestWithoutRange = asString.endsWith(".m3u8");
9712
- const canLiveWithoutContentLength = asString.endsWith(".m3u8") || asString.endsWith(".ts");
9713
- const headers = actualRange === 0 && requestWithoutRange ? {} : typeof actualRange === "number" ? {
9714
- Range: `bytes=${actualRange}-`
9715
- } : {
9716
- Range: `bytes=${`${actualRange[0]}-${actualRange[1]}`}`
9717
- };
9718
- const res = await fetch(resolvedUrl, {
9719
- headers,
9720
- signal: ownController.signal,
9721
- cache
9722
- });
9723
- const contentRange = res.headers.get("content-range");
9724
- const parsedContentRange = contentRange ? parseContentRange(contentRange) : null;
9725
- const { supportsContentRange } = validateContentRangeAndDetectIfSupported({
9726
- actualRange,
9727
- parsedContentRange,
9728
- statusCode: res.status
9729
- });
9708
+ var fetchReadContent = async ({
9709
+ src,
9710
+ range: range2,
9711
+ controller
9712
+ }) => {
9713
+ if (typeof src !== "string" && src instanceof URL === false) {
9714
+ throw new Error("src must be a string when using `fetchReader`");
9715
+ }
9716
+ const resolvedUrl = resolveUrl(src);
9717
+ const resolvedUrlString = resolvedUrl.toString();
9718
+ if (!resolvedUrlString.startsWith("https://") && !resolvedUrlString.startsWith("blob:") && !resolvedUrlString.startsWith("http://")) {
9719
+ return Promise.reject(new Error(`${resolvedUrlString} is not a URL - needs to start with http:// or https:// or blob:. If you want to read a local file, pass \`reader: nodeReader\` to parseMedia().`));
9720
+ }
9721
+ const ownController = new AbortController;
9722
+ const cache = typeof navigator !== "undefined" && navigator.userAgent.includes("Cloudflare-Workers") ? undefined : "no-store";
9723
+ const requestedRange = range2 === null ? 0 : range2;
9724
+ const asString = typeof resolvedUrl === "string" ? resolvedUrl : resolvedUrl.pathname;
9725
+ const requestWithoutRange = asString.endsWith(".m3u8");
9726
+ const canLiveWithoutContentLength = asString.endsWith(".m3u8") || asString.endsWith(".ts");
9727
+ const headers = requestedRange === 0 && requestWithoutRange ? {} : typeof requestedRange === "number" ? {
9728
+ Range: `bytes=${requestedRange}-`
9729
+ } : {
9730
+ Range: `bytes=${`${requestedRange[0]}-${requestedRange[1]}`}`
9731
+ };
9732
+ const res = await fetch(resolvedUrl, {
9733
+ headers,
9734
+ signal: ownController.signal,
9735
+ cache
9736
+ });
9737
+ const contentRange = res.headers.get("content-range");
9738
+ const parsedContentRange = contentRange ? parseContentRange(contentRange) : null;
9739
+ const { supportsContentRange } = validateContentRangeAndDetectIfSupported({
9740
+ requestedRange,
9741
+ parsedContentRange,
9742
+ statusCode: res.status
9743
+ });
9744
+ controller._internals.signal.addEventListener("abort", () => {
9745
+ ownController.abort(new MediaParserAbortError("Aborted by user"));
9746
+ }, { once: true });
9747
+ if (res.status.toString().startsWith("4") || res.status.toString().startsWith("5")) {
9748
+ throw new Error(`Server returned status code ${res.status} for ${src} and range ${requestedRange}`);
9749
+ }
9750
+ const contentDisposition = res.headers.get("content-disposition");
9751
+ const name = contentDisposition?.match(/filename="([^"]+)"/)?.[1];
9752
+ const fallbackName = src.toString().split("/").pop();
9753
+ const { contentLength, needsContentRange, reader } = await getLengthAndReader({
9754
+ canLiveWithoutContentLength,
9755
+ res,
9756
+ ownController,
9757
+ requestedWithoutRange: requestWithoutRange
9758
+ });
9759
+ if (controller) {
9730
9760
  controller._internals.signal.addEventListener("abort", () => {
9731
- ownController.abort(new MediaParserAbortError("Aborted by user"));
9761
+ reader.reader.cancel().catch(() => {
9762
+ });
9763
+ }, { once: true });
9764
+ }
9765
+ return {
9766
+ reader,
9767
+ contentLength,
9768
+ contentType: res.headers.get("content-type"),
9769
+ name: name ?? fallbackName,
9770
+ supportsContentRange,
9771
+ needsContentRange
9772
+ };
9773
+ };
9774
+ var fetchReadWholeAsText = async (src) => {
9775
+ if (typeof src !== "string" && src instanceof URL === false) {
9776
+ throw new Error("src must be a string when using `fetchReader`");
9777
+ }
9778
+ const res = await fetch(src);
9779
+ if (!res.ok) {
9780
+ throw new Error(`Failed to fetch ${src} (HTTP code: ${res.status})`);
9781
+ }
9782
+ return res.text();
9783
+ };
9784
+ var fetchCreateAdjacentFileSource = (relativePath, src) => {
9785
+ if (typeof src !== "string" && src instanceof URL === false) {
9786
+ throw new Error("src must be a string or URL when using `fetchReader`");
9787
+ }
9788
+ return new URL(relativePath, src).toString();
9789
+ };
9790
+
9791
+ // src/readers/from-web-file.ts
9792
+ var webFileReadContent = ({ src, range: range2, controller }) => {
9793
+ if (typeof src === "string" || src instanceof URL) {
9794
+ throw new Error("`inputTypeFileReader` only supports `File` objects");
9795
+ }
9796
+ const part = range2 === null ? src : typeof range2 === "number" ? src.slice(range2) : src.slice(range2[0], range2[1]);
9797
+ const reader = new FileReader;
9798
+ reader.readAsArrayBuffer(src);
9799
+ const ownController = new AbortController;
9800
+ if (ownController) {
9801
+ ownController.signal.addEventListener("abort", () => {
9802
+ reader.abort();
9803
+ }, { once: true });
9804
+ }
9805
+ if (controller) {
9806
+ controller._internals.signal.addEventListener("abort", () => {
9807
+ ownController.abort();
9732
9808
  }, { once: true });
9733
- if (res.status.toString().startsWith("4") || res.status.toString().startsWith("5")) {
9734
- throw new Error(`Server returned status code ${res.status} for ${src} and range ${actualRange}`);
9735
- }
9736
- const contentDisposition = res.headers.get("content-disposition");
9737
- const name = contentDisposition?.match(/filename="([^"]+)"/)?.[1];
9738
- const fallbackName = src.split("/").pop();
9739
- const { contentLength, needsContentRange, reader } = await getLengthAndReader({
9740
- canLiveWithoutContentLength,
9741
- res,
9742
- ownController,
9743
- requestedWithoutRange: requestWithoutRange
9744
- });
9745
- if (controller) {
9746
- controller._internals.signal.addEventListener("abort", () => {
9747
- reader.reader.cancel().catch(() => {
9748
- });
9749
- }, { once: true });
9750
- }
9751
- return {
9752
- reader,
9753
- contentLength,
9754
- contentType: res.headers.get("content-type"),
9755
- name: name ?? fallbackName,
9756
- supportsContentRange,
9757
- needsContentRange
9758
- };
9759
9809
  }
9810
+ return new Promise((resolve, reject) => {
9811
+ reader.onload = () => {
9812
+ const stream = part.stream();
9813
+ const streamReader = stream.getReader();
9814
+ resolve({
9815
+ reader: {
9816
+ reader: streamReader,
9817
+ abort() {
9818
+ streamReader.cancel();
9819
+ ownController.abort();
9820
+ }
9821
+ },
9822
+ contentLength: src.size,
9823
+ name: src.name,
9824
+ supportsContentRange: true,
9825
+ contentType: src.type,
9826
+ needsContentRange: true
9827
+ });
9828
+ };
9829
+ reader.onerror = () => {
9830
+ reject(reader.error);
9831
+ };
9832
+ });
9833
+ };
9834
+ var webFileReadWholeAsText = () => {
9835
+ throw new Error("`webFileReader` cannot read auxiliary files.");
9836
+ };
9837
+ var webFileCreateAdjacentFileSource = () => {
9838
+ throw new Error("`webFileReader` cannot create adjacent file sources.");
9760
9839
  };
9761
9840
 
9841
+ // src/readers/web.ts
9842
+ var webReader = {
9843
+ read: (params) => {
9844
+ if (params.src instanceof Blob) {
9845
+ return webFileReadContent(params);
9846
+ }
9847
+ return fetchReadContent(params);
9848
+ },
9849
+ createAdjacentFileSource: (relativePath, src) => {
9850
+ if (src instanceof Blob) {
9851
+ return webFileCreateAdjacentFileSource(relativePath, src);
9852
+ }
9853
+ return fetchCreateAdjacentFileSource(relativePath, src);
9854
+ },
9855
+ readWholeAsText: (src) => {
9856
+ if (src instanceof Blob) {
9857
+ return webFileReadWholeAsText(src);
9858
+ }
9859
+ return fetchReadWholeAsText(src);
9860
+ }
9861
+ };
9762
9862
  // src/parse-media.ts
9763
9863
  var parseMedia = (options) => {
9764
9864
  return internalParseMedia({
@@ -9796,10 +9896,11 @@ var parseMedia = (options) => {
9796
9896
  onVideoCodec: options.onVideoCodec ?? null,
9797
9897
  onVideoTrack: options.onVideoTrack ?? null,
9798
9898
  progressIntervalInMs: options.progressIntervalInMs ?? null,
9799
- reader: options.reader ?? fetchReader,
9899
+ reader: options.reader ?? webReader,
9800
9900
  controller: options.controller ?? undefined,
9801
9901
  selectM3uStream: options.selectM3uStream ?? defaultSelectM3uStreamFn,
9802
9902
  selectM3uAssociatedPlaylists: options.selectM3uAssociatedPlaylists ?? defaultSelectM3uAssociatedPlaylists,
9903
+ mp4HeaderSegment: options.mp4HeaderSegment ?? null,
9803
9904
  src: options.src,
9804
9905
  mode: "query",
9805
9906
  onDiscardedData: null,
@@ -9814,21 +9915,25 @@ var getChunks = (playlist) => {
9814
9915
  const chunks = [];
9815
9916
  for (let i = 0;i < playlist.boxes.length; i++) {
9816
9917
  const box = playlist.boxes[i];
9918
+ if (box.type === "m3u-map") {
9919
+ chunks.push({ duration: 0, url: box.value, isHeader: true });
9920
+ continue;
9921
+ }
9817
9922
  if (box.type === "m3u-extinf") {
9818
9923
  const nextBox = playlist.boxes[i + 1];
9819
9924
  i++;
9820
9925
  if (nextBox.type !== "m3u-text-value") {
9821
9926
  throw new Error("Expected m3u-text-value");
9822
9927
  }
9823
- chunks.push({ duration: box.value, url: nextBox.value });
9928
+ chunks.push({ duration: box.value, url: nextBox.value, isHeader: false });
9824
9929
  }
9825
9930
  continue;
9826
9931
  }
9827
9932
  return chunks;
9828
9933
  };
9829
9934
 
9830
- // src/containers/m3u/return-packets.ts
9831
- var iteratorOverTsFiles = async ({
9935
+ // src/containers/m3u/iterate-over-segment-files.ts
9936
+ var iteratorOverSegmentFiles = async ({
9832
9937
  structure,
9833
9938
  onVideoTrack,
9834
9939
  m3uState: m3uState2,
@@ -9837,7 +9942,8 @@ var iteratorOverTsFiles = async ({
9837
9942
  playlistUrl,
9838
9943
  logLevel,
9839
9944
  parentController,
9840
- onInitialProgress
9945
+ onInitialProgress,
9946
+ readerInterface
9841
9947
  }) => {
9842
9948
  const playlist = getPlaylist(structure, playlistUrl);
9843
9949
  const chunks = getChunks(playlist);
@@ -9866,9 +9972,10 @@ var iteratorOverTsFiles = async ({
9866
9972
  for (const chunk of chunks) {
9867
9973
  const isLastChunk = chunk === chunks[chunks.length - 1];
9868
9974
  await childController._internals.checkForAbortAndPause();
9869
- const src = new URL(chunk.url, playlistUrl).toString();
9975
+ const src = readerInterface.createAdjacentFileSource(chunk.url, playlistUrl);
9870
9976
  try {
9871
- await parseMedia({
9977
+ const mp4HeaderSegment = m3uState2.getMp4HeaderSegment(playlistUrl);
9978
+ const data = await parseMedia({
9872
9979
  src,
9873
9980
  acknowledgeRemotionLicense: true,
9874
9981
  logLevel,
@@ -9878,6 +9985,7 @@ var iteratorOverTsFiles = async ({
9878
9985
  childController.pause();
9879
9986
  resolver(makeContinuationFn());
9880
9987
  },
9988
+ fields: chunk.isHeader ? { structure: true } : undefined,
9881
9989
  onTracks: () => {
9882
9990
  if (!m3uState2.hasEmittedDoneWithTracks(playlistUrl)) {
9883
9991
  m3uState2.setHasEmittedDoneWithTracks(playlistUrl);
@@ -9914,8 +10022,16 @@ var iteratorOverTsFiles = async ({
9914
10022
  };
9915
10023
  }
9916
10024
  return callbackOrFalse;
9917
- }
10025
+ },
10026
+ reader: readerInterface,
10027
+ mp4HeaderSegment
9918
10028
  });
10029
+ if (chunk.isHeader) {
10030
+ if (data.structure.type !== "iso-base-media") {
10031
+ throw new Error("Expected an mp4 file");
10032
+ }
10033
+ m3uState2.setMp4HeaderSegment(playlistUrl, data.structure);
10034
+ }
9919
10035
  } catch (e) {
9920
10036
  rejector(e);
9921
10037
  throw e;
@@ -9948,7 +10064,7 @@ var runOverM3u = async ({
9948
10064
  }
9949
10065
  Log.trace(logLevel, "Starting new M3U parsing process for", playlistUrl);
9950
10066
  return new Promise((resolve, reject) => {
9951
- const run = iteratorOverTsFiles({
10067
+ const run = iteratorOverSegmentFiles({
9952
10068
  playlistUrl,
9953
10069
  structure,
9954
10070
  onInitialProgress: (newRun) => {
@@ -10009,7 +10125,8 @@ var runOverM3u = async ({
10009
10125
  };
10010
10126
  },
10011
10127
  m3uState: state.m3u,
10012
- parentController: state.controller
10128
+ parentController: state.controller,
10129
+ readerInterface: state.readerInterface
10013
10130
  });
10014
10131
  run.catch((err) => {
10015
10132
  reject(err);
@@ -10032,13 +10149,17 @@ var parseM3u = async ({ state }) => {
10032
10149
  return null;
10033
10150
  }
10034
10151
  if (state.m3u.hasFinishedManifest()) {
10152
+ if (typeof state.src !== "string" && !(state.src instanceof URL)) {
10153
+ throw new Error("Expected src to be a string");
10154
+ }
10035
10155
  await afterManifestFetch({
10036
10156
  structure,
10037
10157
  m3uState: state.m3u,
10038
- src: typeof state.src === "string" ? state.src : null,
10158
+ src: state.src.toString(),
10039
10159
  selectM3uStreamFn: state.selectM3uStreamFn,
10040
10160
  logLevel: state.logLevel,
10041
- selectAssociatedPlaylists: state.selectM3uAssociatedPlaylistsFn
10161
+ selectAssociatedPlaylistsFn: state.selectM3uAssociatedPlaylistsFn,
10162
+ readerInterface: state.readerInterface
10042
10163
  });
10043
10164
  return null;
10044
10165
  }
@@ -11924,7 +12045,7 @@ var parseWebm = async (state) => {
11924
12045
  };
11925
12046
 
11926
12047
  // src/init-video.ts
11927
- var initVideo = ({
12048
+ var initVideo = async ({
11928
12049
  state,
11929
12050
  mimeType,
11930
12051
  name,
@@ -11939,6 +12060,34 @@ var initVideo = ({
11939
12060
  });
11940
12061
  return;
11941
12062
  }
12063
+ if (state.mp4HeaderSegment) {
12064
+ Log.verbose(state.logLevel, "Detected ISO Base Media segment");
12065
+ const moovAtom = getMoovFromFromIsoStructure(state.mp4HeaderSegment);
12066
+ if (!moovAtom) {
12067
+ throw new Error("No moov box found");
12068
+ }
12069
+ const tracks2 = getTracksFromMoovBox(moovAtom);
12070
+ for (const track of tracks2.videoTracks) {
12071
+ await registerVideoTrack({
12072
+ state,
12073
+ track,
12074
+ container: "mp4"
12075
+ });
12076
+ }
12077
+ for (const track of tracks2.audioTracks) {
12078
+ await registerAudioTrack({
12079
+ state,
12080
+ track,
12081
+ container: "mp4"
12082
+ });
12083
+ }
12084
+ state.callbacks.tracks.setIsDone(state.logLevel);
12085
+ state.setStructure({
12086
+ type: "iso-base-media",
12087
+ boxes: []
12088
+ });
12089
+ return;
12090
+ }
11942
12091
  if (fileType.type === "iso-base-media") {
11943
12092
  Log.verbose(state.logLevel, "Detected ISO Base Media container");
11944
12093
  state.setStructure({
@@ -12058,7 +12207,12 @@ var runParseIteration = async ({
12058
12207
  return Promise.reject(new Error("no bytes"));
12059
12208
  }
12060
12209
  if (structure === null) {
12061
- await initVideo({ state, mimeType, name, contentLength });
12210
+ await initVideo({
12211
+ state,
12212
+ mimeType,
12213
+ name,
12214
+ contentLength
12215
+ });
12062
12216
  return null;
12063
12217
  }
12064
12218
  if (structure.type === "riff") {
@@ -12165,6 +12319,7 @@ var internalParseMedia = async function({
12165
12319
  apiName,
12166
12320
  selectM3uStream: selectM3uStreamFn,
12167
12321
  selectM3uAssociatedPlaylists: selectM3uAssociatedPlaylistsFn,
12322
+ mp4HeaderSegment,
12168
12323
  ...more
12169
12324
  }) {
12170
12325
  warnIfRemotionLicenseNotAcknowledged({
@@ -12177,7 +12332,7 @@ var internalParseMedia = async function({
12177
12332
  fields: fieldsInReturnValue,
12178
12333
  callbacks: more
12179
12334
  });
12180
- Log.verbose(logLevel, `Reading ${typeof src === "string" ? src : src.name}`);
12335
+ Log.verbose(logLevel, `Reading ${typeof src === "string" ? src : src instanceof URL ? src.toString() : src.name}`);
12181
12336
  const {
12182
12337
  reader: readerInstance,
12183
12338
  contentLength,
@@ -12217,7 +12372,8 @@ var internalParseMedia = async function({
12217
12372
  src,
12218
12373
  onDiscardedData,
12219
12374
  selectM3uStreamFn,
12220
- selectM3uAssociatedPlaylistsFn
12375
+ selectM3uAssociatedPlaylistsFn,
12376
+ mp4HeaderSegment
12221
12377
  });
12222
12378
  const { iterator } = state;
12223
12379
  let currentReader = readerInstance;
@@ -12294,7 +12450,6 @@ var internalParseMedia = async function({
12294
12450
  if (iterationWithThisOffset > 0 || !hasBigBuffer) {
12295
12451
  await fetchMoreData();
12296
12452
  }
12297
- await state.eventLoop.eventLoopBreakIfNeeded();
12298
12453
  timeReadingData += Date.now() - readStart;
12299
12454
  throttledState.update?.(() => ({
12300
12455
  bytes: iterator.counter.getOffset(),
@@ -12386,6 +12541,353 @@ var internalParseMedia = async function({
12386
12541
  }
12387
12542
  return returnValue;
12388
12543
  };
12544
+ // src/worker/serialize-error.ts
12545
+ var deserializeError = (error) => {
12546
+ switch (error.errorName) {
12547
+ case "IsAGifError":
12548
+ return new IsAGifError({
12549
+ fileName: error.fileName,
12550
+ mimeType: error.mimeType,
12551
+ sizeInBytes: error.sizeInBytes,
12552
+ message: error.errorMessage
12553
+ });
12554
+ case "IsAnImageError":
12555
+ return new IsAnImageError({
12556
+ dimensions: error.dimensions,
12557
+ fileName: error.fileName,
12558
+ imageType: error.imageType,
12559
+ mimeType: error.mimeType,
12560
+ sizeInBytes: error.sizeInBytes,
12561
+ message: error.errorMessage
12562
+ });
12563
+ case "IsAPdfError":
12564
+ return new IsAPdfError({
12565
+ fileName: error.fileName,
12566
+ mimeType: error.mimeType,
12567
+ sizeInBytes: error.sizeInBytes,
12568
+ message: error.errorMessage
12569
+ });
12570
+ case "IsAnUnsupportedFileTypeError":
12571
+ return new IsAnUnsupportedFileTypeError({
12572
+ fileName: error.fileName,
12573
+ mimeType: error.mimeType,
12574
+ sizeInBytes: error.sizeInBytes,
12575
+ message: error.errorMessage
12576
+ });
12577
+ case "MediaParserAbortError":
12578
+ return new MediaParserAbortError(error.errorMessage);
12579
+ default:
12580
+ return new Error(error.errorMessage);
12581
+ }
12582
+ };
12583
+
12584
+ // src/parse-media-on-worker-entry.ts
12585
+ var convertToWorkerPayload = (payload) => {
12586
+ const {
12587
+ onAudioCodec,
12588
+ onContainer,
12589
+ onDimensions,
12590
+ onUnrotatedDimensions,
12591
+ onVideoCodec,
12592
+ onFps,
12593
+ onAudioTrack,
12594
+ onDurationInSeconds,
12595
+ onImages,
12596
+ onInternalStats,
12597
+ onIsHdr,
12598
+ onKeyframes,
12599
+ onLocation,
12600
+ onM3uStreams,
12601
+ onMetadata,
12602
+ onMimeType,
12603
+ onName,
12604
+ onNumberOfAudioChannels,
12605
+ onParseProgress,
12606
+ onRotation,
12607
+ onSampleRate,
12608
+ onSlowAudioBitrate,
12609
+ onSize,
12610
+ onSlowDurationInSeconds,
12611
+ onSlowFps,
12612
+ onSlowKeyframes,
12613
+ onSlowNumberOfFrames,
12614
+ onSlowVideoBitrate,
12615
+ onStructure,
12616
+ onTracks,
12617
+ onVideoTrack,
12618
+ selectM3uStream,
12619
+ selectM3uAssociatedPlaylists,
12620
+ src,
12621
+ ...others
12622
+ } = payload;
12623
+ return {
12624
+ type: "request-worker",
12625
+ payload: others,
12626
+ postAudioCodec: Boolean(onAudioCodec),
12627
+ postContainer: Boolean(onContainer),
12628
+ postDimensions: Boolean(onDimensions),
12629
+ postDurationInSeconds: Boolean(onDurationInSeconds),
12630
+ postFps: Boolean(onFps),
12631
+ postImages: Boolean(onImages),
12632
+ postInternalStats: Boolean(onInternalStats),
12633
+ postIsHdr: Boolean(onIsHdr),
12634
+ postKeyframes: Boolean(onKeyframes),
12635
+ postLocation: Boolean(onLocation),
12636
+ postM3uStreams: Boolean(onM3uStreams),
12637
+ postMetadata: Boolean(onMetadata),
12638
+ postMimeType: Boolean(onMimeType),
12639
+ postName: Boolean(onName),
12640
+ postNumberOfAudioChannels: Boolean(onNumberOfAudioChannels),
12641
+ postRotation: Boolean(onRotation),
12642
+ postSampleRate: Boolean(onSampleRate),
12643
+ postSlowAudioBitrate: Boolean(onSlowAudioBitrate),
12644
+ postSlowDurationInSeconds: Boolean(onSlowDurationInSeconds),
12645
+ postSlowFps: Boolean(onSlowFps),
12646
+ postSlowKeyframes: Boolean(onSlowKeyframes),
12647
+ postSlowNumberOfFrames: Boolean(onSlowNumberOfFrames),
12648
+ postSlowVideoBitrate: Boolean(onSlowVideoBitrate),
12649
+ postStructure: Boolean(onStructure),
12650
+ postTracks: Boolean(onTracks),
12651
+ postUnrotatedDimensions: Boolean(onUnrotatedDimensions),
12652
+ postVideoCodec: Boolean(onVideoCodec),
12653
+ postSize: Boolean(onSize),
12654
+ postParseProgress: Boolean(onParseProgress),
12655
+ postM3uStreamSelection: Boolean(selectM3uStream),
12656
+ postM3uAssociatedPlaylistsSelection: Boolean(selectM3uAssociatedPlaylists),
12657
+ postOnAudioTrack: Boolean(onAudioTrack),
12658
+ postOnVideoTrack: Boolean(onVideoTrack),
12659
+ src
12660
+ };
12661
+ };
12662
+ var post = (worker, payload) => {
12663
+ worker.postMessage(payload);
12664
+ };
12665
+ var parseMediaOnWorkerImplementation = async ({ controller, reader, ...params }, workerUrlEntry, apiName) => {
12666
+ if (typeof Worker === "undefined") {
12667
+ throw new Error('"Worker" is not available. Cannot call workerClient()');
12668
+ }
12669
+ if (reader) {
12670
+ throw new Error(`\`reader\` should not be provided to \`${apiName}\`. If you want to use it in the browser, use parseMediaOnWorker(). If you also want to read files from the file system, use parseMediaOnServerWorker().`);
12671
+ }
12672
+ const worker = new Worker(workerUrlEntry);
12673
+ post(worker, convertToWorkerPayload(params));
12674
+ const { promise, resolve, reject } = Promise.withResolvers();
12675
+ const onAbort = () => {
12676
+ post(worker, { type: "request-abort" });
12677
+ };
12678
+ const onResume = () => {
12679
+ post(worker, { type: "request-resume" });
12680
+ };
12681
+ const onPause = () => {
12682
+ post(worker, { type: "request-pause" });
12683
+ };
12684
+ const callbacks = {};
12685
+ function onMessage(message) {
12686
+ const data = message.data;
12687
+ if (data.type === "response-done") {
12688
+ resolve(data.payload);
12689
+ }
12690
+ if (data.type === "response-error") {
12691
+ cleanup();
12692
+ reject(deserializeError(data));
12693
+ }
12694
+ if (data.type === "response-on-callback-request") {
12695
+ Promise.resolve().then(async () => {
12696
+ if (data.payload.callbackType === "audio-codec") {
12697
+ await params.onAudioCodec?.(data.payload.value);
12698
+ return { payloadType: "void" };
12699
+ }
12700
+ if (data.payload.callbackType === "container") {
12701
+ await params.onContainer?.(data.payload.value);
12702
+ return { payloadType: "void" };
12703
+ }
12704
+ if (data.payload.callbackType === "dimensions") {
12705
+ await params.onDimensions?.(data.payload.value);
12706
+ return { payloadType: "void" };
12707
+ }
12708
+ if (data.payload.callbackType === "unrotated-dimensions") {
12709
+ await params.onUnrotatedDimensions?.(data.payload.value);
12710
+ return { payloadType: "void" };
12711
+ }
12712
+ if (data.payload.callbackType === "video-codec") {
12713
+ await params.onVideoCodec?.(data.payload.value);
12714
+ return { payloadType: "void" };
12715
+ }
12716
+ if (data.payload.callbackType === "tracks") {
12717
+ await params.onTracks?.(data.payload.value);
12718
+ return { payloadType: "void" };
12719
+ }
12720
+ if (data.payload.callbackType === "rotation") {
12721
+ await params.onRotation?.(data.payload.value);
12722
+ return { payloadType: "void" };
12723
+ }
12724
+ if (data.payload.callbackType === "sample-rate") {
12725
+ await params.onSampleRate?.(data.payload.value);
12726
+ return { payloadType: "void" };
12727
+ }
12728
+ if (data.payload.callbackType === "slow-audio-bitrate") {
12729
+ await params.onSlowAudioBitrate?.(data.payload.value);
12730
+ return { payloadType: "void" };
12731
+ }
12732
+ if (data.payload.callbackType === "slow-duration-in-seconds") {
12733
+ await params.onSlowDurationInSeconds?.(data.payload.value);
12734
+ return { payloadType: "void" };
12735
+ }
12736
+ if (data.payload.callbackType === "slow-fps") {
12737
+ await params.onSlowFps?.(data.payload.value);
12738
+ return { payloadType: "void" };
12739
+ }
12740
+ if (data.payload.callbackType === "slow-keyframes") {
12741
+ await params.onSlowKeyframes?.(data.payload.value);
12742
+ return { payloadType: "void" };
12743
+ }
12744
+ if (data.payload.callbackType === "slow-number-of-frames") {
12745
+ await params.onSlowNumberOfFrames?.(data.payload.value);
12746
+ return { payloadType: "void" };
12747
+ }
12748
+ if (data.payload.callbackType === "slow-video-bitrate") {
12749
+ await params.onSlowVideoBitrate?.(data.payload.value);
12750
+ return { payloadType: "void" };
12751
+ }
12752
+ if (data.payload.callbackType === "structure") {
12753
+ await params.onStructure?.(data.payload.value);
12754
+ return { payloadType: "void" };
12755
+ }
12756
+ if (data.payload.callbackType === "fps") {
12757
+ await params.onFps?.(data.payload.value);
12758
+ return { payloadType: "void" };
12759
+ }
12760
+ if (data.payload.callbackType === "images") {
12761
+ await params.onImages?.(data.payload.value);
12762
+ return { payloadType: "void" };
12763
+ }
12764
+ if (data.payload.callbackType === "internal-stats") {
12765
+ await params.onInternalStats?.(data.payload.value);
12766
+ return { payloadType: "void" };
12767
+ }
12768
+ if (data.payload.callbackType === "is-hdr") {
12769
+ await params.onIsHdr?.(data.payload.value);
12770
+ return { payloadType: "void" };
12771
+ }
12772
+ if (data.payload.callbackType === "keyframes") {
12773
+ await params.onKeyframes?.(data.payload.value);
12774
+ return { payloadType: "void" };
12775
+ }
12776
+ if (data.payload.callbackType === "location") {
12777
+ await params.onLocation?.(data.payload.value);
12778
+ return { payloadType: "void" };
12779
+ }
12780
+ if (data.payload.callbackType === "m3u-streams") {
12781
+ await params.onM3uStreams?.(data.payload.value);
12782
+ return { payloadType: "void" };
12783
+ }
12784
+ if (data.payload.callbackType === "metadata") {
12785
+ await params.onMetadata?.(data.payload.value);
12786
+ return { payloadType: "void" };
12787
+ }
12788
+ if (data.payload.callbackType === "mime-type") {
12789
+ await params.onMimeType?.(data.payload.value);
12790
+ return { payloadType: "void" };
12791
+ }
12792
+ if (data.payload.callbackType === "name") {
12793
+ await params.onName?.(data.payload.value);
12794
+ return { payloadType: "void" };
12795
+ }
12796
+ if (data.payload.callbackType === "number-of-audio-channels") {
12797
+ await params.onNumberOfAudioChannels?.(data.payload.value);
12798
+ return { payloadType: "void" };
12799
+ }
12800
+ if (data.payload.callbackType === "size") {
12801
+ await params.onSize?.(data.payload.value);
12802
+ return { payloadType: "void" };
12803
+ }
12804
+ if (data.payload.callbackType === "duration-in-seconds") {
12805
+ await params.onDurationInSeconds?.(data.payload.value);
12806
+ return { payloadType: "void" };
12807
+ }
12808
+ if (data.payload.callbackType === "parse-progress") {
12809
+ await params.onParseProgress?.(data.payload.value);
12810
+ return { payloadType: "void" };
12811
+ }
12812
+ if (data.payload.callbackType === "m3u-stream-selection") {
12813
+ const selection = await params.selectM3uStream(data.payload.value);
12814
+ return { payloadType: "m3u-stream-selection", value: selection };
12815
+ }
12816
+ if (data.payload.callbackType === "m3u-associated-playlists-selection") {
12817
+ const selection = await params.selectM3uAssociatedPlaylists(data.payload.value);
12818
+ return {
12819
+ payloadType: "m3u-associated-playlists-selection",
12820
+ value: selection
12821
+ };
12822
+ }
12823
+ if (data.payload.callbackType === "on-audio-track") {
12824
+ const possibleCallback = await params.onAudioTrack?.(data.payload.value);
12825
+ if (possibleCallback) {
12826
+ callbacks[data.payload.value.track.trackId] = possibleCallback;
12827
+ }
12828
+ return {
12829
+ payloadType: "on-audio-track-response",
12830
+ registeredCallback: Boolean(possibleCallback)
12831
+ };
12832
+ }
12833
+ if (data.payload.callbackType === "on-video-track") {
12834
+ const possibleCallback = await params.onVideoTrack?.(data.payload.value);
12835
+ if (possibleCallback) {
12836
+ callbacks[data.payload.value.track.trackId] = possibleCallback;
12837
+ }
12838
+ return {
12839
+ payloadType: "on-video-track-response",
12840
+ registeredCallback: Boolean(possibleCallback)
12841
+ };
12842
+ }
12843
+ if (data.payload.callbackType === "on-audio-video-sample") {
12844
+ const callback = callbacks[data.payload.trackId];
12845
+ if (!callback) {
12846
+ throw new Error(`No callback registered for track ${data.payload.trackId}`);
12847
+ }
12848
+ await callback(data.payload.value);
12849
+ return { payloadType: "void" };
12850
+ }
12851
+ throw new Error(`Unknown callback type: ${data.payload}`);
12852
+ }).then((payload) => {
12853
+ post(worker, {
12854
+ type: "acknowledge-callback",
12855
+ nonce: data.nonce,
12856
+ ...payload
12857
+ });
12858
+ }).catch((err) => {
12859
+ reject(err);
12860
+ post(worker, {
12861
+ type: "signal-error-in-callback",
12862
+ nonce: data.nonce
12863
+ });
12864
+ });
12865
+ }
12866
+ }
12867
+ worker.addEventListener("message", onMessage);
12868
+ controller?.addEventListener("abort", onAbort);
12869
+ controller?.addEventListener("resume", onResume);
12870
+ controller?.addEventListener("pause", onPause);
12871
+ function cleanup() {
12872
+ worker.removeEventListener("message", onMessage);
12873
+ controller?.removeEventListener("abort", onAbort);
12874
+ controller?.removeEventListener("resume", onResume);
12875
+ controller?.removeEventListener("pause", onPause);
12876
+ worker.terminate();
12877
+ }
12878
+ const val = await promise;
12879
+ cleanup();
12880
+ return val;
12881
+ };
12882
+
12883
+ // src/parse-media-on-server-worker.ts
12884
+ var parseMediaOnServerWorker = (params) => {
12885
+ return parseMediaOnWorkerImplementation(params, new URL("./worker-server-entry", import.meta.url), "parseMediaOnServerWorker");
12886
+ };
12887
+ // src/parse-media-on-web-worker.ts
12888
+ var parseMediaOnWebWorker = (params) => {
12889
+ return parseMediaOnWorkerImplementation(params, new URL("./worker-web-entry", import.meta.url), "parseMediaOnWebWorker");
12890
+ };
12389
12891
  // src/download-and-parse-media.ts
12390
12892
  var downloadAndParseMedia = async (options) => {
12391
12893
  const logLevel = options.logLevel ?? "info";
@@ -12399,11 +12901,12 @@ var downloadAndParseMedia = async (options) => {
12399
12901
  logLevel,
12400
12902
  mode: "download",
12401
12903
  onAudioCodec: options.onAudioCodec ?? null,
12402
- onAudioTrack: null,
12904
+ onAudioTrack: options.onAudioTrack ?? null,
12403
12905
  onContainer: options.onContainer ?? null,
12404
12906
  onDimensions: options.onDimensions ?? null,
12405
12907
  selectM3uStream: options.selectM3uStream ?? defaultSelectM3uStreamFn,
12406
12908
  selectM3uAssociatedPlaylists: options.selectM3uAssociatedPlaylists ?? defaultSelectM3uAssociatedPlaylists,
12909
+ mp4HeaderSegment: options.mp4HeaderSegment ?? null,
12407
12910
  onDiscardedData: async (data) => {
12408
12911
  await content.write(data);
12409
12912
  },
@@ -12433,9 +12936,9 @@ var downloadAndParseMedia = async (options) => {
12433
12936
  onTracks: options.onTracks ?? null,
12434
12937
  onUnrotatedDimensions: options.onUnrotatedDimensions ?? null,
12435
12938
  onVideoCodec: options.onVideoCodec ?? null,
12436
- onVideoTrack: null,
12939
+ onVideoTrack: options.onVideoTrack ?? null,
12437
12940
  progressIntervalInMs: options.progressIntervalInMs ?? null,
12438
- reader: options.reader ?? fetchReader,
12941
+ reader: options.reader ?? webReader,
12439
12942
  controller: options.controller ?? undefined,
12440
12943
  src: options.src,
12441
12944
  onError: async (err) => {
@@ -12454,7 +12957,7 @@ var downloadAndParseMedia = async (options) => {
12454
12957
  return returnValue;
12455
12958
  };
12456
12959
  // src/version.ts
12457
- var VERSION = "4.0.270";
12960
+ var VERSION = "4.0.271";
12458
12961
 
12459
12962
  // src/index.ts
12460
12963
  var MediaParserInternals = {
@@ -12473,6 +12976,8 @@ var MediaParserInternals = {
12473
12976
  internalParseMedia
12474
12977
  };
12475
12978
  export {
12979
+ parseMediaOnWebWorker,
12980
+ parseMediaOnServerWorker,
12476
12981
  parseMedia,
12477
12982
  mediaParserController,
12478
12983
  hasBeenAborted,
@@ -12483,7 +12988,6 @@ export {
12483
12988
  MediaParserInternals,
12484
12989
  MediaParserAbortError,
12485
12990
  IsAnUnsupportedFileTypeError,
12486
- IsAnUnsupportedAudioTypeError,
12487
12991
  IsAnImageError,
12488
12992
  IsAPdfError,
12489
12993
  IsAGifError