@remotion/media-parser 4.0.270 → 4.0.272
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.
- package/dist/aac-codecprivate.js +6 -13
- package/dist/add-avc-profile-to-track.js +5 -9
- package/dist/buffer-iterator.js +8 -13
- package/dist/combine-uint8-arrays.js +1 -5
- package/dist/containers/aac/parse-aac.js +9 -13
- package/dist/containers/aac/types.js +1 -2
- package/dist/containers/avc/codec-string.js +1 -5
- package/dist/containers/avc/color.js +3 -9
- package/dist/containers/avc/create-sps-pps-data.js +5 -9
- package/dist/containers/avc/interpret-sps.js +7 -13
- package/dist/containers/avc/key.js +1 -5
- package/dist/containers/avc/parse-avc.js +3 -7
- package/dist/containers/avc/sps-and-pps.js +1 -5
- package/dist/containers/flac/get-block-size.js +1 -5
- package/dist/containers/flac/get-channel-count.d.ts +1 -1
- package/dist/containers/flac/get-channel-count.js +1 -5
- package/dist/containers/flac/get-duration-from-flac.js +1 -5
- package/dist/containers/flac/get-metadata-from-flac.d.ts +1 -1
- package/dist/containers/flac/get-metadata-from-flac.js +1 -5
- package/dist/containers/flac/get-sample-rate.js +1 -5
- package/dist/containers/flac/parse-flac-frame.js +14 -19
- package/dist/containers/flac/parse-flac.js +15 -19
- package/dist/containers/flac/parse-header.js +1 -5
- package/dist/containers/flac/parse-metadata.js +1 -5
- package/dist/containers/flac/parse-streaminfo.js +3 -7
- package/dist/containers/flac/parse-unknown-block.js +1 -5
- package/dist/containers/flac/types.d.ts +2 -2
- package/dist/containers/flac/types.js +1 -2
- package/dist/containers/iso-base-media/base-media-box.js +1 -2
- package/dist/containers/iso-base-media/base-type.js +1 -2
- package/dist/containers/iso-base-media/esds/decoder-specific-config.js +1 -5
- package/dist/containers/iso-base-media/esds/esds-descriptors.js +5 -10
- package/dist/containers/iso-base-media/esds/esds.js +3 -7
- package/dist/containers/iso-base-media/ftyp.js +1 -5
- package/dist/containers/iso-base-media/get-actual-number-of-channels.js +4 -8
- package/dist/containers/iso-base-media/get-children.js +3 -7
- package/dist/containers/iso-base-media/get-keyframes.js +7 -11
- package/dist/containers/iso-base-media/get-moov-atom.js +21 -15
- package/dist/containers/iso-base-media/get-sample-positions-from-track.js +20 -24
- package/dist/containers/iso-base-media/get-video-codec-from-iso-track.d.ts +1 -1
- package/dist/containers/iso-base-media/get-video-codec-from-iso-track.js +3 -7
- package/dist/containers/iso-base-media/make-track.js +30 -34
- package/dist/containers/iso-base-media/mdat/mdat.js +16 -20
- package/dist/containers/iso-base-media/mdhd.js +1 -5
- package/dist/containers/iso-base-media/meta/hdlr.js +1 -5
- package/dist/containers/iso-base-media/meta/ilst.js +1 -5
- package/dist/containers/iso-base-media/moov/moov.js +3 -7
- package/dist/containers/iso-base-media/mvhd.js +7 -11
- package/dist/containers/iso-base-media/parse-boxes.js +5 -9
- package/dist/containers/iso-base-media/parse-icc-profile.js +4 -8
- package/dist/containers/iso-base-media/process-box.js +63 -67
- package/dist/containers/iso-base-media/stsd/av1c.js +1 -5
- package/dist/containers/iso-base-media/stsd/avcc.js +1 -5
- package/dist/containers/iso-base-media/stsd/colr.js +3 -7
- package/dist/containers/iso-base-media/stsd/ctts.js +1 -5
- package/dist/containers/iso-base-media/stsd/hvcc.js +3 -7
- package/dist/containers/iso-base-media/stsd/keys.js +1 -5
- package/dist/containers/iso-base-media/stsd/mebx.js +3 -7
- package/dist/containers/iso-base-media/stsd/pasp.js +1 -5
- package/dist/containers/iso-base-media/stsd/samples.js +8 -13
- package/dist/containers/iso-base-media/stsd/stco.js +1 -5
- package/dist/containers/iso-base-media/stsd/stsc.js +1 -5
- package/dist/containers/iso-base-media/stsd/stsd.js +3 -7
- package/dist/containers/iso-base-media/stsd/stss.js +1 -5
- package/dist/containers/iso-base-media/stsd/stsz.js +1 -5
- package/dist/containers/iso-base-media/stsd/stts.js +1 -5
- package/dist/containers/iso-base-media/tfdt.js +1 -5
- package/dist/containers/iso-base-media/tfhd.js +1 -5
- package/dist/containers/iso-base-media/tkhd.js +4 -8
- package/dist/containers/iso-base-media/to-date.js +1 -5
- package/dist/containers/iso-base-media/trak/trak.js +3 -7
- package/dist/containers/iso-base-media/traversal.d.ts +3 -2
- package/dist/containers/iso-base-media/traversal.js +42 -57
- package/dist/containers/iso-base-media/trun.js +2 -6
- package/dist/containers/iso-base-media/void-box.js +1 -2
- package/dist/containers/m3u/after-manifest-fetch.d.ts +5 -3
- package/dist/containers/m3u/after-manifest-fetch.js +13 -17
- package/dist/containers/m3u/fetch-m3u8-stream.d.ts +5 -1
- package/dist/containers/m3u/fetch-m3u8-stream.js +4 -12
- package/dist/containers/m3u/get-chunks.d.ts +1 -0
- package/dist/containers/m3u/get-chunks.js +6 -6
- package/dist/containers/m3u/get-duration-from-m3u.js +4 -8
- package/dist/containers/m3u/get-playlist.js +6 -12
- package/dist/containers/m3u/get-streams.d.ts +11 -5
- package/dist/containers/m3u/get-streams.js +5 -15
- package/dist/containers/m3u/iterate-over-segment-files.d.ts +19 -0
- package/dist/containers/m3u/iterate-over-segment-files.js +110 -0
- package/dist/containers/m3u/parse-directive.js +24 -10
- package/dist/containers/m3u/parse-m3u-manifest.js +3 -7
- package/dist/containers/m3u/parse-m3u-media-directive.d.ts +1 -0
- package/dist/containers/m3u/parse-m3u-media-directive.js +7 -7
- package/dist/containers/m3u/parse-m3u.js +13 -13
- package/dist/containers/m3u/parse-m3u8-text.js +3 -7
- package/dist/containers/m3u/parse-stream-inf.js +2 -7
- package/dist/containers/m3u/return-packets.d.ts +1 -1
- package/dist/containers/m3u/return-packets.js +14 -5
- package/dist/containers/m3u/run-over-m3u.js +68 -57
- package/dist/containers/m3u/sample-sorter.d.ts +2 -0
- package/dist/containers/m3u/sample-sorter.js +17 -9
- package/dist/containers/m3u/select-stream.d.ts +3 -2
- package/dist/containers/m3u/select-stream.js +9 -13
- package/dist/containers/m3u/types.d.ts +9 -2
- package/dist/containers/m3u/types.js +1 -2
- package/dist/containers/mp3/get-duration.js +5 -9
- package/dist/containers/mp3/get-frame-length.js +2 -7
- package/dist/containers/mp3/get-metadata-from-mp3.d.ts +2 -2
- package/dist/containers/mp3/get-metadata-from-mp3.js +1 -5
- package/dist/containers/mp3/id3-v1.js +1 -5
- package/dist/containers/mp3/id3.js +1 -5
- package/dist/containers/mp3/parse-mp3.js +7 -11
- package/dist/containers/mp3/parse-mpeg-header.js +10 -14
- package/dist/containers/mp3/samples-per-mpeg-file.js +1 -5
- package/dist/containers/riff/expect-riff-box.js +11 -15
- package/dist/containers/riff/get-duration.js +7 -12
- package/dist/containers/riff/get-tracks-from-avi.js +20 -28
- package/dist/containers/riff/is-movi.js +1 -5
- package/dist/containers/riff/parse-avih.js +1 -5
- package/dist/containers/riff/parse-isft.js +1 -5
- package/dist/containers/riff/parse-list-box.js +3 -7
- package/dist/containers/riff/parse-movi.js +13 -18
- package/dist/containers/riff/parse-riff-body.js +9 -13
- package/dist/containers/riff/parse-riff-box.js +9 -13
- package/dist/containers/riff/parse-riff-header.js +1 -5
- package/dist/containers/riff/parse-riff.js +5 -9
- package/dist/containers/riff/parse-strf.js +1 -5
- package/dist/containers/riff/parse-strh.js +3 -7
- package/dist/containers/riff/parse-video-section.js +7 -11
- package/dist/containers/riff/riff-box.js +1 -2
- package/dist/containers/riff/timescale.js +1 -4
- package/dist/containers/riff/traversal.js +7 -15
- package/dist/containers/transport-stream/adts-header.js +6 -10
- package/dist/containers/transport-stream/boxes.js +1 -2
- package/dist/containers/transport-stream/discard-rest-of-packet.js +2 -7
- package/dist/containers/transport-stream/find-separator.js +1 -4
- package/dist/containers/transport-stream/get-tracks.d.ts +2 -0
- package/dist/containers/transport-stream/get-tracks.js +13 -14
- package/dist/containers/transport-stream/handle-aac-packet.js +12 -16
- package/dist/containers/transport-stream/handle-avc-packet.js +22 -26
- package/dist/containers/transport-stream/next-pes-header-store.js +1 -5
- package/dist/containers/transport-stream/parse-packet.js +13 -17
- package/dist/containers/transport-stream/parse-pat.js +5 -10
- package/dist/containers/transport-stream/parse-pes.js +1 -5
- package/dist/containers/transport-stream/parse-pmt.js +8 -12
- package/dist/containers/transport-stream/parse-stream-packet.js +13 -17
- package/dist/containers/transport-stream/parse-transport-stream.js +5 -9
- package/dist/containers/transport-stream/process-stream-buffers.js +12 -16
- package/dist/containers/transport-stream/traversal.js +4 -10
- package/dist/containers/wav/get-duration-from-wav.js +3 -8
- package/dist/containers/wav/get-metadata-from-wav.d.ts +2 -2
- package/dist/containers/wav/get-metadata-from-wav.js +1 -5
- package/dist/containers/wav/parse-data.js +5 -9
- package/dist/containers/wav/parse-fmt.js +3 -7
- package/dist/containers/wav/parse-header.js +1 -5
- package/dist/containers/wav/parse-id3.js +1 -5
- package/dist/containers/wav/parse-list.js +1 -5
- package/dist/containers/wav/parse-video-section.js +3 -7
- package/dist/containers/wav/parse-wav.js +15 -19
- package/dist/containers/wav/types.d.ts +2 -2
- package/dist/containers/wav/types.js +1 -2
- package/dist/containers/webm/allowed-partial-segments.js +1 -4
- package/dist/containers/webm/av1-codec-private.js +3 -7
- package/dist/containers/webm/color.js +6 -10
- package/dist/containers/webm/description.js +6 -10
- package/dist/containers/webm/get-ready-tracks.js +13 -18
- package/dist/containers/webm/get-sample-from-block.js +12 -16
- package/dist/containers/webm/make-track.js +43 -48
- package/dist/containers/webm/parse-ebml.js +14 -19
- package/dist/containers/webm/parse-webm-header.js +3 -7
- package/dist/containers/webm/segments/all-segments.js +168 -173
- package/dist/containers/webm/segments/block-simple-block-flags.js +4 -8
- package/dist/containers/webm/segments/track-entry.js +1 -5
- package/dist/containers/webm/segments.js +9 -13
- package/dist/containers/webm/traversal.js +37 -67
- package/dist/convert-audio-or-video-sample.js +1 -5
- package/dist/download-and-parse-media.js +44 -47
- package/dist/emit-available-info.js +38 -38
- package/dist/emitter.js +1 -5
- package/dist/errors.d.ts +2 -17
- package/dist/errors.js +10 -30
- package/dist/esm/fetch.mjs +93 -67
- package/dist/esm/index.mjs +742 -194
- package/dist/esm/node.mjs +59 -36
- package/dist/esm/universal.mjs +323 -0
- package/dist/esm/web-file.mjs +55 -43
- package/dist/esm/web.mjs +257 -0
- package/dist/esm/worker-server-entry.mjs +13100 -0
- package/dist/esm/worker-server.mjs +12914 -0
- package/dist/esm/worker-web-entry.mjs +13013 -0
- package/dist/esm/worker.mjs +439 -0
- package/dist/fetch.js +1 -17
- package/dist/file-types/bmp.js +3 -7
- package/dist/file-types/detect-file-type.js +24 -38
- package/dist/file-types/index.js +22 -26
- package/dist/file-types/jpeg.js +4 -9
- package/dist/file-types/pdf.js +3 -7
- package/dist/file-types/png.js +4 -9
- package/dist/file-types/webp.js +3 -7
- package/dist/forward-controller.js +1 -5
- package/dist/get-audio-codec.js +25 -38
- package/dist/get-container.d.ts +3 -3
- package/dist/get-container.js +5 -10
- package/dist/get-dimensions.js +8 -13
- package/dist/get-duration.js +27 -34
- package/dist/get-fields-from-callbacks.js +1 -5
- package/dist/get-fps.js +24 -34
- package/dist/get-is-hdr.js +5 -10
- package/dist/get-keyframes.js +6 -11
- package/dist/get-location.js +4 -9
- package/dist/get-number-of-audio-channels.js +2 -7
- package/dist/get-sample-aspect-ratio.js +17 -30
- package/dist/get-sample-positions-from-lpcm.js +5 -9
- package/dist/get-sample-positions.js +1 -5
- package/dist/get-sample-rate.js +2 -7
- package/dist/get-tracks.d.ts +5 -0
- package/dist/get-tracks.js +37 -44
- package/dist/get-video-codec.js +26 -34
- package/dist/has-all-info.js +33 -38
- package/dist/index.d.ts +18 -11
- package/dist/index.js +34 -48
- package/dist/init-video.d.ts +1 -1
- package/dist/init-video.js +47 -20
- package/dist/internal-parse-media.js +36 -40
- package/dist/is-audio-structure.d.ts +2 -2
- package/dist/is-audio-structure.js +1 -5
- package/dist/log.js +8 -12
- package/dist/make-hvc1-codec-strings.js +1 -5
- package/dist/media-parser-controller.js +7 -11
- package/dist/metadata/get-metadata.d.ts +4 -4
- package/dist/metadata/get-metadata.js +17 -22
- package/dist/metadata/metadata-from-iso.d.ts +3 -3
- package/dist/metadata/metadata-from-iso.js +12 -17
- package/dist/metadata/metadata-from-matroska.d.ts +2 -2
- package/dist/metadata/metadata-from-matroska.js +3 -7
- package/dist/metadata/metadata-from-riff.d.ts +2 -2
- package/dist/metadata/metadata-from-riff.js +3 -7
- package/dist/node-writer.js +1 -17
- package/dist/node.js +1 -17
- package/dist/options.d.ts +30 -24
- package/dist/options.js +1 -2
- package/dist/parse-media-on-browser-worker.d.ts +2 -0
- package/dist/parse-media-on-browser-worker.js +4 -0
- package/dist/parse-media-on-server-worker.d.ts +2 -0
- package/dist/parse-media-on-server-worker.js +4 -0
- package/dist/parse-media-on-web-worker.d.ts +2 -0
- package/dist/parse-media-on-web-worker.js +4 -0
- package/dist/parse-media-on-worker-entry.d.ts +2 -0
- package/dist/parse-media-on-worker-entry.js +269 -0
- package/dist/parse-media-on-worker.d.ts +2 -0
- package/dist/parse-media-on-worker.js +4 -0
- package/dist/parse-media.js +10 -13
- package/dist/parse-result.d.ts +3 -3
- package/dist/parse-result.js +1 -2
- package/dist/pause-signal.js +1 -5
- package/dist/perform-seek.js +6 -10
- package/dist/readers/fetch/get-body-and-reader.js +1 -5
- package/dist/readers/fetch/resolve-url.d.ts +1 -1
- package/dist/readers/fetch/resolve-url.js +1 -5
- package/dist/readers/from-fetch.d.ts +4 -1
- package/dist/readers/from-fetch.js +109 -94
- package/dist/readers/from-node.d.ts +4 -1
- package/dist/readers/from-node.js +58 -41
- package/dist/readers/from-web-file.d.ts +4 -1
- package/dist/readers/from-web-file.js +55 -49
- package/dist/readers/reader.d.ts +5 -1
- package/dist/readers/reader.js +1 -2
- package/dist/readers/universal.d.ts +2 -0
- package/dist/readers/universal.js +35 -0
- package/dist/readers/web.d.ts +2 -0
- package/dist/readers/web.js +22 -0
- package/dist/register-track.js +9 -15
- package/dist/remotion-license-acknowledge.js +4 -8
- package/dist/run-parse-iteration.js +26 -25
- package/dist/samples-from-moof.js +8 -12
- package/dist/skip.js +1 -5
- package/dist/state/aac-state.js +1 -5
- package/dist/state/can-skip-tracks.d.ts +2 -2
- package/dist/state/can-skip-tracks.js +3 -8
- package/dist/state/emitted-fields.js +1 -5
- package/dist/state/flac-state.js +1 -5
- package/dist/state/has-tracks-section.d.ts +2 -2
- package/dist/state/has-tracks-section.js +6 -8
- package/dist/state/images.js +1 -5
- package/dist/state/iso-base-media/cached-sample-positions.js +8 -13
- package/dist/state/iso-base-media/iso-state.js +5 -9
- package/dist/state/iso-base-media/moov-box.js +1 -5
- package/dist/state/keyframes.js +1 -5
- package/dist/state/last-eventloop-break.js +3 -7
- package/dist/state/m3u-state.d.ts +6 -0
- package/dist/state/m3u-state.js +20 -12
- package/dist/state/may-skip-video-data.js +3 -7
- package/dist/state/mp3.js +1 -5
- package/dist/state/need-samples-for-fields.js +1 -5
- package/dist/state/parser-state.d.ts +15 -10
- package/dist/state/parser-state.js +37 -41
- package/dist/state/riff.js +1 -5
- package/dist/state/sample-callbacks.d.ts +3 -2
- package/dist/state/sample-callbacks.js +8 -12
- package/dist/state/slow-duration-fps.js +1 -5
- package/dist/state/structure.d.ts +4 -4
- package/dist/state/structure.js +1 -5
- package/dist/state/transport-stream.js +3 -7
- package/dist/state/video-section.js +1 -5
- package/dist/state/webm.js +5 -9
- package/dist/throttled-progress.js +1 -5
- package/dist/truthy.js +1 -4
- package/dist/universal.d.ts +1 -0
- package/dist/universal.js +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -4
- package/dist/web-file.js +1 -17
- package/dist/web.d.ts +1 -0
- package/dist/web.js +1 -0
- package/dist/webcodec-sample-types.d.ts +6 -4
- package/dist/webcodec-sample-types.js +1 -2
- package/dist/worker/forward-controller.d.ts +3 -0
- package/dist/worker/forward-controller.js +20 -0
- package/dist/worker/serialize-error.d.ts +4 -0
- package/dist/worker/serialize-error.js +95 -0
- package/dist/worker/worker-types.d.ts +243 -0
- package/dist/worker/worker-types.js +1 -0
- package/dist/worker-bun-entry.d.ts +1 -0
- package/dist/worker-bun-entry.js +5 -0
- package/dist/worker-entry.d.ts +1 -0
- package/dist/worker-entry.js +5 -0
- package/dist/worker-server-entry.d.ts +1 -0
- package/dist/worker-server-entry.js +5 -0
- package/dist/worker-server.d.ts +2 -0
- package/dist/worker-server.js +381 -0
- package/dist/worker-web-entry.d.ts +1 -0
- package/dist/worker-web-entry.js +5 -0
- package/dist/worker.d.ts +2 -0
- package/dist/worker.js +267 -0
- package/dist/writers/node.js +16 -23
- package/dist/writers/writer.js +1 -2
- package/package.json +40 -21
- package/fetch.js +0 -2
- package/test.json +0 -663
- package/web-file.js +0 -2
package/dist/esm/index.mjs
CHANGED
|
@@ -1996,17 +1996,25 @@ var parseEsds = ({
|
|
|
1996
1996
|
};
|
|
1997
1997
|
|
|
1998
1998
|
// src/containers/iso-base-media/traversal.ts
|
|
1999
|
-
var
|
|
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 =
|
|
2281
|
+
const moovBox = getMoovBoxFromState(state);
|
|
2274
2282
|
if (!moovBox) {
|
|
2275
2283
|
return null;
|
|
2276
2284
|
}
|
|
@@ -2471,14 +2479,17 @@ var getStreamForId = (structure, packetIdentifier) => {
|
|
|
2471
2479
|
};
|
|
2472
2480
|
|
|
2473
2481
|
// src/containers/transport-stream/get-tracks.ts
|
|
2482
|
+
var filterStreamsBySupportedTypes = (streams) => {
|
|
2483
|
+
return streams.filter((stream) => stream.streamType === 27 || stream.streamType === 15);
|
|
2484
|
+
};
|
|
2474
2485
|
var getTracksFromTransportStream = (parserState) => {
|
|
2475
2486
|
const structure = parserState.getTsStructure();
|
|
2476
2487
|
const programMapTable = findProgramMapTableOrThrow(structure);
|
|
2477
2488
|
const parserTracks = parserState.callbacks.tracks.getTracks();
|
|
2478
|
-
const mapped = programMapTable.streams.map((stream) => {
|
|
2489
|
+
const mapped = filterStreamsBySupportedTypes(programMapTable.streams).map((stream) => {
|
|
2479
2490
|
return parserTracks.find((track) => track.trackId === stream.pid);
|
|
2480
2491
|
}).filter(truthy);
|
|
2481
|
-
if (mapped.length !== programMapTable.streams.length) {
|
|
2492
|
+
if (mapped.length !== filterStreamsBySupportedTypes(programMapTable.streams).length) {
|
|
2482
2493
|
throw new Error("Not all tracks found");
|
|
2483
2494
|
}
|
|
2484
2495
|
return {
|
|
@@ -3189,7 +3200,7 @@ var matroskaHasTracks = (state) => {
|
|
|
3189
3200
|
|
|
3190
3201
|
// src/get-tracks.ts
|
|
3191
3202
|
var isoBaseMediaHasTracks = (state) => {
|
|
3192
|
-
return Boolean(
|
|
3203
|
+
return Boolean(getMoovBoxFromState(state));
|
|
3193
3204
|
};
|
|
3194
3205
|
var getHasTracks = (state) => {
|
|
3195
3206
|
const structure = state.getStructure();
|
|
@@ -3244,18 +3255,10 @@ var getCategorizedTracksFromMatroska = (state) => {
|
|
|
3244
3255
|
otherTracks
|
|
3245
3256
|
};
|
|
3246
3257
|
};
|
|
3247
|
-
var
|
|
3258
|
+
var getTracksFromMoovBox = (moovBox) => {
|
|
3248
3259
|
const videoTracks = [];
|
|
3249
3260
|
const audioTracks = [];
|
|
3250
3261
|
const otherTracks = [];
|
|
3251
|
-
const moovBox = getMoovBox(state);
|
|
3252
|
-
if (!moovBox) {
|
|
3253
|
-
return {
|
|
3254
|
-
videoTracks,
|
|
3255
|
-
audioTracks,
|
|
3256
|
-
otherTracks
|
|
3257
|
-
};
|
|
3258
|
-
}
|
|
3259
3262
|
const tracks2 = getTraks(moovBox);
|
|
3260
3263
|
for (const trakBox of tracks2) {
|
|
3261
3264
|
const track = makeBaseMediaTrack(trakBox);
|
|
@@ -3276,6 +3279,17 @@ var getTracksFromIsoBaseMedia = (state) => {
|
|
|
3276
3279
|
otherTracks
|
|
3277
3280
|
};
|
|
3278
3281
|
};
|
|
3282
|
+
var getTracksFromIsoBaseMedia = (state) => {
|
|
3283
|
+
const moovBox = getMoovBoxFromState(state);
|
|
3284
|
+
if (!moovBox) {
|
|
3285
|
+
return {
|
|
3286
|
+
videoTracks: [],
|
|
3287
|
+
audioTracks: [],
|
|
3288
|
+
otherTracks: []
|
|
3289
|
+
};
|
|
3290
|
+
}
|
|
3291
|
+
return getTracksFromMoovBox(moovBox);
|
|
3292
|
+
};
|
|
3279
3293
|
var defaultGetTracks = (parserState) => {
|
|
3280
3294
|
const tracks2 = parserState.callbacks.tracks.getTracks();
|
|
3281
3295
|
if (tracks2.length === 0) {
|
|
@@ -4727,7 +4741,7 @@ var parseTrun = ({
|
|
|
4727
4741
|
const sampleDuration = flags & 256 ? iterator.getUint32() : null;
|
|
4728
4742
|
const sampleSize = flags & 512 ? iterator.getUint32() : null;
|
|
4729
4743
|
const sampleFlags = flags & 1024 ? iterator.getUint32() : null;
|
|
4730
|
-
const sampleCompositionTimeOffset = flags & 2048 ? version === 0 ? iterator.getUint32() : iterator.
|
|
4744
|
+
const sampleCompositionTimeOffset = flags & 2048 ? version === 0 ? iterator.getUint32() : iterator.getInt32() : null;
|
|
4731
4745
|
samples.push({
|
|
4732
4746
|
sampleDuration,
|
|
4733
4747
|
sampleSize,
|
|
@@ -5812,7 +5826,11 @@ var isIndependentSegments = (structure) => {
|
|
|
5812
5826
|
}
|
|
5813
5827
|
return structure.boxes.some((box) => box.type === "m3u-independent-segments" || box.type === "m3u-stream-info");
|
|
5814
5828
|
};
|
|
5815
|
-
var getM3uStreams = (
|
|
5829
|
+
var getM3uStreams = ({
|
|
5830
|
+
structure,
|
|
5831
|
+
originalSrc,
|
|
5832
|
+
readerInterface
|
|
5833
|
+
}) => {
|
|
5816
5834
|
if (structure === null || structure.type !== "m3u") {
|
|
5817
5835
|
return null;
|
|
5818
5836
|
}
|
|
@@ -5837,13 +5855,13 @@ var getM3uStreams = (structure, originalSrc) => {
|
|
|
5837
5855
|
groupId: audioTrack.groupId,
|
|
5838
5856
|
language: audioTrack.language,
|
|
5839
5857
|
name: audioTrack.name,
|
|
5840
|
-
|
|
5858
|
+
src: readerInterface.createAdjacentFileSource(audioTrack.uri, originalSrc),
|
|
5841
5859
|
id: associatedPlaylists.length
|
|
5842
5860
|
});
|
|
5843
5861
|
}
|
|
5844
5862
|
}
|
|
5845
5863
|
boxes.push({
|
|
5846
|
-
|
|
5864
|
+
src: readerInterface.createAdjacentFileSource(next.value, originalSrc),
|
|
5847
5865
|
averageBandwidth: str.averageBandwidth,
|
|
5848
5866
|
bandwidth: str.bandwidth,
|
|
5849
5867
|
codecs: str.codecs,
|
|
@@ -6097,7 +6115,7 @@ var getSamplesFromTraf = (trafSegment, moofOffset) => {
|
|
|
6097
6115
|
const samplePosition = {
|
|
6098
6116
|
offset: offset + (moofOffset ?? 0) + (dataOffset ?? 0),
|
|
6099
6117
|
dts,
|
|
6100
|
-
cts: dts,
|
|
6118
|
+
cts: dts + (sample.sampleCompositionTimeOffset ?? 0),
|
|
6101
6119
|
duration: duration2,
|
|
6102
6120
|
isKeyframe: keyframe,
|
|
6103
6121
|
size,
|
|
@@ -6376,7 +6394,7 @@ var getDurationFromMatroska = (segments) => {
|
|
|
6376
6394
|
};
|
|
6377
6395
|
var isoHasDuration = (parserState) => {
|
|
6378
6396
|
const structure = parserState.getIsoStructure();
|
|
6379
|
-
const moovBox =
|
|
6397
|
+
const moovBox = getMoovBoxFromState(parserState);
|
|
6380
6398
|
if (!moovBox) {
|
|
6381
6399
|
return false;
|
|
6382
6400
|
}
|
|
@@ -6397,7 +6415,7 @@ var isoHasDuration = (parserState) => {
|
|
|
6397
6415
|
};
|
|
6398
6416
|
var getDurationFromIsoBaseMedia = (parserState) => {
|
|
6399
6417
|
const structure = parserState.getIsoStructure();
|
|
6400
|
-
const moovBox =
|
|
6418
|
+
const moovBox = getMoovBoxFromState(parserState);
|
|
6401
6419
|
if (!moovBox) {
|
|
6402
6420
|
return null;
|
|
6403
6421
|
}
|
|
@@ -6639,7 +6657,7 @@ var parseIsoMetaBox = (meta, trackId) => {
|
|
|
6639
6657
|
return entries;
|
|
6640
6658
|
};
|
|
6641
6659
|
var getMetadataFromIsoBase = (state) => {
|
|
6642
|
-
const moov =
|
|
6660
|
+
const moov = getMoovBoxFromState(state);
|
|
6643
6661
|
if (!moov) {
|
|
6644
6662
|
return [];
|
|
6645
6663
|
}
|
|
@@ -7173,7 +7191,11 @@ var emitAvailableInfo = async ({
|
|
|
7173
7191
|
}
|
|
7174
7192
|
if (key === "m3uStreams") {
|
|
7175
7193
|
if (!emittedFields.m3uStreams && hasInfo.m3uStreams) {
|
|
7176
|
-
const streams = getM3uStreams(
|
|
7194
|
+
const streams = getM3uStreams({
|
|
7195
|
+
structure: state.getStructureOrNull(),
|
|
7196
|
+
originalSrc: state.src,
|
|
7197
|
+
readerInterface: state.readerInterface
|
|
7198
|
+
});
|
|
7177
7199
|
await callbacks.onM3uStreams?.(streams);
|
|
7178
7200
|
if (fieldsInReturnValue.m3uStreams) {
|
|
7179
7201
|
returnValue.m3uStreams = streams;
|
|
@@ -7418,6 +7440,7 @@ class IsAGifError extends Error {
|
|
|
7418
7440
|
fileName
|
|
7419
7441
|
}) {
|
|
7420
7442
|
super(message);
|
|
7443
|
+
this.name = "IsAGifError";
|
|
7421
7444
|
this.fileName = "IsAGifError";
|
|
7422
7445
|
this.mimeType = mimeType;
|
|
7423
7446
|
this.sizeInBytes = sizeInBytes;
|
|
@@ -7497,30 +7520,6 @@ class IsAnUnsupportedFileTypeError extends Error {
|
|
|
7497
7520
|
}
|
|
7498
7521
|
}
|
|
7499
7522
|
|
|
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
7523
|
class MediaParserAbortError extends Error {
|
|
7525
7524
|
constructor(message) {
|
|
7526
7525
|
super(message);
|
|
@@ -7529,7 +7528,7 @@ class MediaParserAbortError extends Error {
|
|
|
7529
7528
|
}
|
|
7530
7529
|
}
|
|
7531
7530
|
var hasBeenAborted = (error) => {
|
|
7532
|
-
return error instanceof MediaParserAbortError;
|
|
7531
|
+
return error instanceof MediaParserAbortError || error.name === "MediaParserAbortError";
|
|
7533
7532
|
};
|
|
7534
7533
|
|
|
7535
7534
|
// src/pause-signal.ts
|
|
@@ -8307,21 +8306,6 @@ var keyframesState = () => {
|
|
|
8307
8306
|
};
|
|
8308
8307
|
};
|
|
8309
8308
|
|
|
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
8309
|
// src/containers/m3u/sample-sorter.ts
|
|
8326
8310
|
var sampleSorter = ({
|
|
8327
8311
|
logLevel,
|
|
@@ -8341,6 +8325,12 @@ var sampleSorter = ({
|
|
|
8341
8325
|
addAudioStreamToConsider: (src, callback) => {
|
|
8342
8326
|
audioCallbacks[src] = callback;
|
|
8343
8327
|
},
|
|
8328
|
+
hasAudioStreamToConsider: (src) => {
|
|
8329
|
+
return Boolean(audioCallbacks[src]);
|
|
8330
|
+
},
|
|
8331
|
+
hasVideoStreamToConsider: (src) => {
|
|
8332
|
+
return Boolean(videoCallbacks[src]);
|
|
8333
|
+
},
|
|
8344
8334
|
addAudioSample: async (src, sample) => {
|
|
8345
8335
|
const callback = audioCallbacks[src];
|
|
8346
8336
|
if (!callback) {
|
|
@@ -8352,13 +8342,16 @@ var sampleSorter = ({
|
|
|
8352
8342
|
addVideoSample: async (src, sample) => {
|
|
8353
8343
|
const callback = videoCallbacks[src];
|
|
8354
8344
|
if (!callback) {
|
|
8355
|
-
throw new Error("No callback found for
|
|
8345
|
+
throw new Error("No callback found for video sample.");
|
|
8356
8346
|
}
|
|
8357
8347
|
latestSample[src] = sample.dts;
|
|
8358
8348
|
await callback(sample);
|
|
8359
8349
|
},
|
|
8360
8350
|
getNextStreamToRun: (streams) => {
|
|
8361
8351
|
for (const stream of streams) {
|
|
8352
|
+
if (getAllChunksProcessedForPlaylist(stream)) {
|
|
8353
|
+
continue;
|
|
8354
|
+
}
|
|
8362
8355
|
if (!streamsWithTracks.includes(stream)) {
|
|
8363
8356
|
Log.trace(logLevel, `Did not yet detect track of ${stream}, working on that`);
|
|
8364
8357
|
return stream;
|
|
@@ -8374,6 +8367,9 @@ var sampleSorter = ({
|
|
|
8374
8367
|
}
|
|
8375
8368
|
}
|
|
8376
8369
|
for (const stream of streams) {
|
|
8370
|
+
if (getAllChunksProcessedForPlaylist(stream)) {
|
|
8371
|
+
continue;
|
|
8372
|
+
}
|
|
8377
8373
|
if ((latestSample[stream] ?? 0) === smallestDts) {
|
|
8378
8374
|
Log.trace(logLevel, `Working on ${stream} because it has the smallest DTS`);
|
|
8379
8375
|
return stream;
|
|
@@ -8400,16 +8396,23 @@ var m3uState = (logLevel) => {
|
|
|
8400
8396
|
if (!selectedMainPlaylist) {
|
|
8401
8397
|
throw new Error("No main playlist selected");
|
|
8402
8398
|
}
|
|
8403
|
-
const playlistUrl = selectedMainPlaylist.type === "initial-url" ? selectedMainPlaylist.url : selectedMainPlaylist.stream.
|
|
8399
|
+
const playlistUrl = selectedMainPlaylist.type === "initial-url" ? selectedMainPlaylist.url : selectedMainPlaylist.stream.src;
|
|
8404
8400
|
return playlistUrl;
|
|
8405
8401
|
};
|
|
8406
8402
|
const getSelectedPlaylists = () => {
|
|
8407
8403
|
return [
|
|
8408
8404
|
getMainPlaylistUrl(),
|
|
8409
|
-
...(associatedPlaylists ?? []).map((p) => p.
|
|
8405
|
+
...(associatedPlaylists ?? []).map((p) => p.src)
|
|
8410
8406
|
];
|
|
8411
8407
|
};
|
|
8412
8408
|
const getAllChunksProcessedForPlaylist = (src) => allChunksProcessed[src];
|
|
8409
|
+
const mp4HeaderSegments = {};
|
|
8410
|
+
const setMp4HeaderSegment = (playlistUrl, structure) => {
|
|
8411
|
+
mp4HeaderSegments[playlistUrl] = structure;
|
|
8412
|
+
};
|
|
8413
|
+
const getMp4HeaderSegment = (playlistUrl) => {
|
|
8414
|
+
return mp4HeaderSegments[playlistUrl];
|
|
8415
|
+
};
|
|
8413
8416
|
return {
|
|
8414
8417
|
setSelectedMainPlaylist: (stream) => {
|
|
8415
8418
|
selectedMainPlaylist = stream;
|
|
@@ -8438,7 +8441,7 @@ var m3uState = (logLevel) => {
|
|
|
8438
8441
|
setHasEmittedDoneWithTracks: (src) => {
|
|
8439
8442
|
hasEmittedDoneWithTracks[src] = true;
|
|
8440
8443
|
},
|
|
8441
|
-
hasEmittedDoneWithTracks: (src) => hasEmittedDoneWithTracks[src],
|
|
8444
|
+
hasEmittedDoneWithTracks: (src) => hasEmittedDoneWithTracks[src] !== undefined,
|
|
8442
8445
|
setReadyToIterateOverM3u: () => {
|
|
8443
8446
|
readyToIterateOverM3u = true;
|
|
8444
8447
|
},
|
|
@@ -8470,6 +8473,9 @@ var m3uState = (logLevel) => {
|
|
|
8470
8473
|
const selectedPlaylists = getSelectedPlaylists();
|
|
8471
8474
|
return selectedPlaylists.every((url) => tracksDone[url]);
|
|
8472
8475
|
},
|
|
8476
|
+
getTrackDone: (playlistUrl) => {
|
|
8477
|
+
return tracksDone[playlistUrl];
|
|
8478
|
+
},
|
|
8473
8479
|
getM3uStreamRun: (playlistUrl) => m3uStreamRuns[playlistUrl] ?? null,
|
|
8474
8480
|
abortM3UStreamRuns: () => {
|
|
8475
8481
|
const values = Object.values(m3uStreamRuns);
|
|
@@ -8486,7 +8492,9 @@ var m3uState = (logLevel) => {
|
|
|
8486
8492
|
},
|
|
8487
8493
|
getAssociatedPlaylists: () => associatedPlaylists,
|
|
8488
8494
|
getSelectedPlaylists,
|
|
8489
|
-
sampleSorter: sampleSorter({ logLevel, getAllChunksProcessedForPlaylist })
|
|
8495
|
+
sampleSorter: sampleSorter({ logLevel, getAllChunksProcessedForPlaylist }),
|
|
8496
|
+
setMp4HeaderSegment,
|
|
8497
|
+
getMp4HeaderSegment
|
|
8490
8498
|
};
|
|
8491
8499
|
};
|
|
8492
8500
|
|
|
@@ -8574,7 +8582,7 @@ var makeCanSkipTracksState = ({
|
|
|
8574
8582
|
};
|
|
8575
8583
|
|
|
8576
8584
|
// src/state/has-tracks-section.ts
|
|
8577
|
-
var makeTracksSectionState = (canSkipTracksState) => {
|
|
8585
|
+
var makeTracksSectionState = (canSkipTracksState, src) => {
|
|
8578
8586
|
const tracks2 = [];
|
|
8579
8587
|
let doneWithTracks = false;
|
|
8580
8588
|
return {
|
|
@@ -8599,7 +8607,7 @@ var makeTracksSectionState = (canSkipTracksState) => {
|
|
|
8599
8607
|
return;
|
|
8600
8608
|
}
|
|
8601
8609
|
if (!doneWithTracks) {
|
|
8602
|
-
throw new Error("Error in Media Parser: End of parsing has been reached, but no tracks have been found");
|
|
8610
|
+
throw new Error("Error in Media Parser: End of parsing of " + src + " has been reached, but no tracks have been found ");
|
|
8603
8611
|
}
|
|
8604
8612
|
}
|
|
8605
8613
|
};
|
|
@@ -8614,7 +8622,8 @@ var sampleCallback = ({
|
|
|
8614
8622
|
keyframes,
|
|
8615
8623
|
emittedFields,
|
|
8616
8624
|
slowDurationAndFpsState,
|
|
8617
|
-
structure
|
|
8625
|
+
structure,
|
|
8626
|
+
src
|
|
8618
8627
|
}) => {
|
|
8619
8628
|
const videoSampleCallbacks = {};
|
|
8620
8629
|
const audioSampleCallbacks = {};
|
|
@@ -8626,7 +8635,7 @@ var sampleCallback = ({
|
|
|
8626
8635
|
hasVideoTrackHandlers,
|
|
8627
8636
|
structure
|
|
8628
8637
|
});
|
|
8629
|
-
const tracksState = makeTracksSectionState(canSkipTracksState);
|
|
8638
|
+
const tracksState = makeTracksSectionState(canSkipTracksState, src);
|
|
8630
8639
|
const samplesForTrack = {};
|
|
8631
8640
|
return {
|
|
8632
8641
|
registerVideoSampleCallback: async (id, callback) => {
|
|
@@ -9035,7 +9044,8 @@ var makeParserState = ({
|
|
|
9035
9044
|
readerInterface,
|
|
9036
9045
|
onDiscardedData,
|
|
9037
9046
|
selectM3uStreamFn,
|
|
9038
|
-
selectM3uAssociatedPlaylistsFn
|
|
9047
|
+
selectM3uAssociatedPlaylistsFn,
|
|
9048
|
+
mp4HeaderSegment
|
|
9039
9049
|
}) => {
|
|
9040
9050
|
let skippedBytes = 0;
|
|
9041
9051
|
const iterator = getArrayBufferIterator(new Uint8Array([]), contentLength);
|
|
@@ -9074,7 +9084,8 @@ var makeParserState = ({
|
|
|
9074
9084
|
keyframes,
|
|
9075
9085
|
emittedFields,
|
|
9076
9086
|
slowDurationAndFpsState: slowDurationAndFps,
|
|
9077
|
-
structure
|
|
9087
|
+
structure,
|
|
9088
|
+
src
|
|
9078
9089
|
}),
|
|
9079
9090
|
getInternalStats: () => ({
|
|
9080
9091
|
skippedBytes,
|
|
@@ -9096,12 +9107,12 @@ var makeParserState = ({
|
|
|
9096
9107
|
iterator,
|
|
9097
9108
|
controller,
|
|
9098
9109
|
mode,
|
|
9099
|
-
eventLoop: eventLoopState(logLevel),
|
|
9100
9110
|
src,
|
|
9101
9111
|
readerInterface,
|
|
9102
9112
|
discardReadBytes,
|
|
9103
9113
|
selectM3uStreamFn,
|
|
9104
|
-
selectM3uAssociatedPlaylistsFn
|
|
9114
|
+
selectM3uAssociatedPlaylistsFn,
|
|
9115
|
+
mp4HeaderSegment
|
|
9105
9116
|
};
|
|
9106
9117
|
};
|
|
9107
9118
|
|
|
@@ -9110,6 +9121,14 @@ var getMoovAtom = async ({
|
|
|
9110
9121
|
endOfMdat,
|
|
9111
9122
|
state
|
|
9112
9123
|
}) => {
|
|
9124
|
+
const headerSegment = state.mp4HeaderSegment;
|
|
9125
|
+
if (headerSegment) {
|
|
9126
|
+
const segment = getMoovFromFromIsoStructure(headerSegment);
|
|
9127
|
+
if (!segment) {
|
|
9128
|
+
throw new Error("No moov box found in header segment");
|
|
9129
|
+
}
|
|
9130
|
+
return segment;
|
|
9131
|
+
}
|
|
9113
9132
|
const start = Date.now();
|
|
9114
9133
|
Log.verbose(state.logLevel, "Starting second fetch to get moov atom");
|
|
9115
9134
|
const { reader } = await state.readerInterface.read({
|
|
@@ -9139,7 +9158,8 @@ var getMoovAtom = async ({
|
|
|
9139
9158
|
src: state.src,
|
|
9140
9159
|
onDiscardedData: null,
|
|
9141
9160
|
selectM3uStreamFn: state.selectM3uStreamFn,
|
|
9142
|
-
selectM3uAssociatedPlaylistsFn: state.selectM3uAssociatedPlaylistsFn
|
|
9161
|
+
selectM3uAssociatedPlaylistsFn: state.selectM3uAssociatedPlaylistsFn,
|
|
9162
|
+
mp4HeaderSegment: state.mp4HeaderSegment
|
|
9143
9163
|
});
|
|
9144
9164
|
while (true) {
|
|
9145
9165
|
const result = await reader.reader.read();
|
|
@@ -9308,7 +9328,7 @@ var parseStreamInf = (str) => {
|
|
|
9308
9328
|
};
|
|
9309
9329
|
|
|
9310
9330
|
// src/containers/m3u/parse-m3u-media-directive.ts
|
|
9311
|
-
var
|
|
9331
|
+
var parseM3uKeyValue = (str) => {
|
|
9312
9332
|
const quotes = splitRespectingQuotes(str);
|
|
9313
9333
|
const map = {};
|
|
9314
9334
|
for (const quote of quotes) {
|
|
@@ -9321,6 +9341,10 @@ var parseM3uMediaDirective = (str) => {
|
|
|
9321
9341
|
const actualValue = value?.startsWith('"') && value?.endsWith('"') ? value.slice(1, -1) : value;
|
|
9322
9342
|
map[key] = actualValue;
|
|
9323
9343
|
}
|
|
9344
|
+
return map;
|
|
9345
|
+
};
|
|
9346
|
+
var parseM3uMediaDirective = (str) => {
|
|
9347
|
+
const map = parseM3uKeyValue(str);
|
|
9324
9348
|
return {
|
|
9325
9349
|
type: "m3u-media-info",
|
|
9326
9350
|
autoselect: map.AUTOSELECT === "YES",
|
|
@@ -9416,13 +9440,31 @@ var parseM3uDirective = (str) => {
|
|
|
9416
9440
|
const res = parseStreamInf(value);
|
|
9417
9441
|
return res;
|
|
9418
9442
|
}
|
|
9443
|
+
if (directive === "#EXT-X-I-FRAME-STREAM-INF") {
|
|
9444
|
+
return {
|
|
9445
|
+
type: "m3u-i-frame-stream-info"
|
|
9446
|
+
};
|
|
9447
|
+
}
|
|
9448
|
+
if (directive === "#EXT-X-ALLOW-CACHE") {
|
|
9449
|
+
if (!value) {
|
|
9450
|
+
throw new Error("#EXT-X-ALLOW-CACHE directive must have a value");
|
|
9451
|
+
}
|
|
9452
|
+
return {
|
|
9453
|
+
type: "m3u-allow-cache",
|
|
9454
|
+
allowsCache: value === "YES"
|
|
9455
|
+
};
|
|
9456
|
+
}
|
|
9419
9457
|
if (directive === "#EXT-X-MAP") {
|
|
9420
9458
|
if (!value) {
|
|
9421
9459
|
throw new Error("#EXT-X-MAP directive must have a value");
|
|
9422
9460
|
}
|
|
9461
|
+
const p = parseM3uKeyValue(value);
|
|
9462
|
+
if (!p.URI) {
|
|
9463
|
+
throw new Error("EXT-X-MAP directive must have a URI");
|
|
9464
|
+
}
|
|
9423
9465
|
return {
|
|
9424
9466
|
type: "m3u-map",
|
|
9425
|
-
value:
|
|
9467
|
+
value: p.URI
|
|
9426
9468
|
};
|
|
9427
9469
|
}
|
|
9428
9470
|
throw new Error(`Unknown directive ${directive}. Value: ${value}`);
|
|
@@ -9449,12 +9491,11 @@ var parseM3u8Text = (line, boxes) => {
|
|
|
9449
9491
|
};
|
|
9450
9492
|
|
|
9451
9493
|
// src/containers/m3u/fetch-m3u8-stream.ts
|
|
9452
|
-
var fetchM3u8Stream = async (
|
|
9453
|
-
|
|
9454
|
-
|
|
9455
|
-
|
|
9456
|
-
|
|
9457
|
-
const text = await res.text();
|
|
9494
|
+
var fetchM3u8Stream = async ({
|
|
9495
|
+
url,
|
|
9496
|
+
readerInterface
|
|
9497
|
+
}) => {
|
|
9498
|
+
const text = await readerInterface.readWholeAsText(url);
|
|
9458
9499
|
const lines = text.split(`
|
|
9459
9500
|
`);
|
|
9460
9501
|
const boxes = [];
|
|
@@ -9477,14 +9518,17 @@ var selectAssociatedPlaylists = async ({
|
|
|
9477
9518
|
throw new Error("Expected an array of associated playlists");
|
|
9478
9519
|
}
|
|
9479
9520
|
for (const stream of streams) {
|
|
9480
|
-
if (!playlists.find((playlist) => playlist.
|
|
9521
|
+
if (!playlists.find((playlist) => playlist.src === stream.src)) {
|
|
9481
9522
|
throw new Error(`The associated playlist ${JSON.stringify(streams)} cannot be selected because it was not in the list of selectable playlists`);
|
|
9482
9523
|
}
|
|
9483
9524
|
}
|
|
9484
9525
|
return streams;
|
|
9485
9526
|
};
|
|
9486
9527
|
var defaultSelectM3uAssociatedPlaylists = ({ associatedPlaylists }) => {
|
|
9487
|
-
|
|
9528
|
+
if (associatedPlaylists.length === 1) {
|
|
9529
|
+
return associatedPlaylists;
|
|
9530
|
+
}
|
|
9531
|
+
return associatedPlaylists.filter((playlist) => playlist.default);
|
|
9488
9532
|
};
|
|
9489
9533
|
var selectStream = async ({
|
|
9490
9534
|
streams,
|
|
@@ -9511,7 +9555,8 @@ var afterManifestFetch = async ({
|
|
|
9511
9555
|
src,
|
|
9512
9556
|
selectM3uStreamFn,
|
|
9513
9557
|
logLevel,
|
|
9514
|
-
|
|
9558
|
+
selectAssociatedPlaylistsFn,
|
|
9559
|
+
readerInterface
|
|
9515
9560
|
}) => {
|
|
9516
9561
|
const independentSegments = isIndependentSegments(structure);
|
|
9517
9562
|
if (!independentSegments) {
|
|
@@ -9524,7 +9569,7 @@ var afterManifestFetch = async ({
|
|
|
9524
9569
|
});
|
|
9525
9570
|
return m3uState2.setReadyToIterateOverM3u();
|
|
9526
9571
|
}
|
|
9527
|
-
const streams = getM3uStreams(structure, src);
|
|
9572
|
+
const streams = getM3uStreams({ structure, originalSrc: src, readerInterface });
|
|
9528
9573
|
if (streams === null) {
|
|
9529
9574
|
throw new Error("No streams found");
|
|
9530
9575
|
}
|
|
@@ -9542,12 +9587,12 @@ var afterManifestFetch = async ({
|
|
|
9542
9587
|
});
|
|
9543
9588
|
m3uState2.setAssociatedPlaylists(associatedPlaylists);
|
|
9544
9589
|
const playlistUrls = [
|
|
9545
|
-
selectedPlaylist.
|
|
9546
|
-
...associatedPlaylists.map((p) => p.
|
|
9590
|
+
selectedPlaylist.src,
|
|
9591
|
+
...associatedPlaylists.map((p) => p.src)
|
|
9547
9592
|
];
|
|
9548
9593
|
const struc = await Promise.all(playlistUrls.map(async (url) => {
|
|
9549
9594
|
Log.verbose(logLevel, `Fetching playlist ${url}`);
|
|
9550
|
-
const boxes = await fetchM3u8Stream(url);
|
|
9595
|
+
const boxes = await fetchM3u8Stream({ url, readerInterface });
|
|
9551
9596
|
return {
|
|
9552
9597
|
type: "m3u-playlist",
|
|
9553
9598
|
boxes,
|
|
@@ -9676,89 +9721,178 @@ function parseContentRange(input) {
|
|
|
9676
9721
|
return range2;
|
|
9677
9722
|
}
|
|
9678
9723
|
var validateContentRangeAndDetectIfSupported = ({
|
|
9679
|
-
|
|
9724
|
+
requestedRange,
|
|
9680
9725
|
parsedContentRange,
|
|
9681
9726
|
statusCode
|
|
9682
9727
|
}) => {
|
|
9683
9728
|
if (statusCode === 206) {
|
|
9684
9729
|
return { supportsContentRange: true };
|
|
9685
9730
|
}
|
|
9686
|
-
if (typeof
|
|
9687
|
-
if (
|
|
9731
|
+
if (typeof requestedRange === "number" && parsedContentRange?.start !== requestedRange) {
|
|
9732
|
+
if (requestedRange === 0) {
|
|
9688
9733
|
return { supportsContentRange: false };
|
|
9689
9734
|
}
|
|
9690
|
-
throw new Error(`Range header (${
|
|
9735
|
+
throw new Error(`Range header (${requestedRange}) does not match content-range header (${parsedContentRange?.start})`);
|
|
9691
9736
|
}
|
|
9692
|
-
if (
|
|
9693
|
-
throw new Error(`Range header (${
|
|
9737
|
+
if (requestedRange !== null && typeof requestedRange !== "number" && (parsedContentRange?.start !== requestedRange[0] || parsedContentRange?.end !== requestedRange[1])) {
|
|
9738
|
+
throw new Error(`Range header (${requestedRange}) does not match content-range header (${parsedContentRange?.start})`);
|
|
9694
9739
|
}
|
|
9695
9740
|
return { supportsContentRange: true };
|
|
9696
9741
|
};
|
|
9697
|
-
var
|
|
9698
|
-
|
|
9699
|
-
|
|
9700
|
-
|
|
9701
|
-
|
|
9702
|
-
|
|
9703
|
-
|
|
9704
|
-
|
|
9705
|
-
|
|
9706
|
-
|
|
9707
|
-
|
|
9708
|
-
|
|
9709
|
-
|
|
9710
|
-
|
|
9711
|
-
|
|
9712
|
-
|
|
9713
|
-
|
|
9714
|
-
|
|
9715
|
-
|
|
9716
|
-
|
|
9717
|
-
}
|
|
9718
|
-
|
|
9719
|
-
|
|
9720
|
-
|
|
9721
|
-
|
|
9722
|
-
|
|
9723
|
-
|
|
9724
|
-
|
|
9725
|
-
|
|
9726
|
-
|
|
9727
|
-
|
|
9728
|
-
|
|
9729
|
-
|
|
9742
|
+
var fetchReadContent = async ({
|
|
9743
|
+
src,
|
|
9744
|
+
range: range2,
|
|
9745
|
+
controller
|
|
9746
|
+
}) => {
|
|
9747
|
+
if (typeof src !== "string" && src instanceof URL === false) {
|
|
9748
|
+
throw new Error("src must be a string when using `fetchReader`");
|
|
9749
|
+
}
|
|
9750
|
+
const resolvedUrl = resolveUrl(src);
|
|
9751
|
+
const resolvedUrlString = resolvedUrl.toString();
|
|
9752
|
+
if (!resolvedUrlString.startsWith("https://") && !resolvedUrlString.startsWith("blob:") && !resolvedUrlString.startsWith("http://")) {
|
|
9753
|
+
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().`));
|
|
9754
|
+
}
|
|
9755
|
+
const ownController = new AbortController;
|
|
9756
|
+
const cache = typeof navigator !== "undefined" && navigator.userAgent.includes("Cloudflare-Workers") ? undefined : "no-store";
|
|
9757
|
+
const requestedRange = range2 === null ? 0 : range2;
|
|
9758
|
+
const asString = typeof resolvedUrl === "string" ? resolvedUrl : resolvedUrl.pathname;
|
|
9759
|
+
const requestWithoutRange = asString.endsWith(".m3u8");
|
|
9760
|
+
const canLiveWithoutContentLength = asString.endsWith(".m3u8") || asString.endsWith(".ts");
|
|
9761
|
+
const headers = requestedRange === 0 && requestWithoutRange ? {} : typeof requestedRange === "number" ? {
|
|
9762
|
+
Range: `bytes=${requestedRange}-`
|
|
9763
|
+
} : {
|
|
9764
|
+
Range: `bytes=${`${requestedRange[0]}-${requestedRange[1]}`}`
|
|
9765
|
+
};
|
|
9766
|
+
const res = await fetch(resolvedUrl, {
|
|
9767
|
+
headers,
|
|
9768
|
+
signal: ownController.signal,
|
|
9769
|
+
cache
|
|
9770
|
+
});
|
|
9771
|
+
const contentRange = res.headers.get("content-range");
|
|
9772
|
+
const parsedContentRange = contentRange ? parseContentRange(contentRange) : null;
|
|
9773
|
+
const { supportsContentRange } = validateContentRangeAndDetectIfSupported({
|
|
9774
|
+
requestedRange,
|
|
9775
|
+
parsedContentRange,
|
|
9776
|
+
statusCode: res.status
|
|
9777
|
+
});
|
|
9778
|
+
controller._internals.signal.addEventListener("abort", () => {
|
|
9779
|
+
ownController.abort(new MediaParserAbortError("Aborted by user"));
|
|
9780
|
+
}, { once: true });
|
|
9781
|
+
if (res.status.toString().startsWith("4") || res.status.toString().startsWith("5")) {
|
|
9782
|
+
throw new Error(`Server returned status code ${res.status} for ${src} and range ${requestedRange}`);
|
|
9783
|
+
}
|
|
9784
|
+
const contentDisposition = res.headers.get("content-disposition");
|
|
9785
|
+
const name = contentDisposition?.match(/filename="([^"]+)"/)?.[1];
|
|
9786
|
+
const fallbackName = src.toString().split("/").pop();
|
|
9787
|
+
const { contentLength, needsContentRange, reader } = await getLengthAndReader({
|
|
9788
|
+
canLiveWithoutContentLength,
|
|
9789
|
+
res,
|
|
9790
|
+
ownController,
|
|
9791
|
+
requestedWithoutRange: requestWithoutRange
|
|
9792
|
+
});
|
|
9793
|
+
if (controller) {
|
|
9730
9794
|
controller._internals.signal.addEventListener("abort", () => {
|
|
9731
|
-
|
|
9795
|
+
reader.reader.cancel().catch(() => {
|
|
9796
|
+
});
|
|
9732
9797
|
}, { 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
9798
|
}
|
|
9799
|
+
return {
|
|
9800
|
+
reader,
|
|
9801
|
+
contentLength,
|
|
9802
|
+
contentType: res.headers.get("content-type"),
|
|
9803
|
+
name: name ?? fallbackName,
|
|
9804
|
+
supportsContentRange,
|
|
9805
|
+
needsContentRange
|
|
9806
|
+
};
|
|
9807
|
+
};
|
|
9808
|
+
var fetchReadWholeAsText = async (src) => {
|
|
9809
|
+
if (typeof src !== "string" && src instanceof URL === false) {
|
|
9810
|
+
throw new Error("src must be a string when using `fetchReader`");
|
|
9811
|
+
}
|
|
9812
|
+
const res = await fetch(src);
|
|
9813
|
+
if (!res.ok) {
|
|
9814
|
+
throw new Error(`Failed to fetch ${src} (HTTP code: ${res.status})`);
|
|
9815
|
+
}
|
|
9816
|
+
return res.text();
|
|
9817
|
+
};
|
|
9818
|
+
var fetchCreateAdjacentFileSource = (relativePath, src) => {
|
|
9819
|
+
if (typeof src !== "string" && src instanceof URL === false) {
|
|
9820
|
+
throw new Error("src must be a string or URL when using `fetchReader`");
|
|
9821
|
+
}
|
|
9822
|
+
return new URL(relativePath, src).toString();
|
|
9823
|
+
};
|
|
9824
|
+
|
|
9825
|
+
// src/readers/from-web-file.ts
|
|
9826
|
+
var webFileReadContent = ({ src, range: range2, controller }) => {
|
|
9827
|
+
if (typeof src === "string" || src instanceof URL) {
|
|
9828
|
+
throw new Error("`inputTypeFileReader` only supports `File` objects");
|
|
9829
|
+
}
|
|
9830
|
+
const part = range2 === null ? src : typeof range2 === "number" ? src.slice(range2) : src.slice(range2[0], range2[1]);
|
|
9831
|
+
const reader = new FileReader;
|
|
9832
|
+
reader.readAsArrayBuffer(src);
|
|
9833
|
+
const ownController = new AbortController;
|
|
9834
|
+
if (ownController) {
|
|
9835
|
+
ownController.signal.addEventListener("abort", () => {
|
|
9836
|
+
reader.abort();
|
|
9837
|
+
}, { once: true });
|
|
9838
|
+
}
|
|
9839
|
+
if (controller) {
|
|
9840
|
+
controller._internals.signal.addEventListener("abort", () => {
|
|
9841
|
+
ownController.abort();
|
|
9842
|
+
}, { once: true });
|
|
9843
|
+
}
|
|
9844
|
+
return new Promise((resolve, reject) => {
|
|
9845
|
+
reader.onload = () => {
|
|
9846
|
+
const stream = part.stream();
|
|
9847
|
+
const streamReader = stream.getReader();
|
|
9848
|
+
resolve({
|
|
9849
|
+
reader: {
|
|
9850
|
+
reader: streamReader,
|
|
9851
|
+
abort() {
|
|
9852
|
+
streamReader.cancel();
|
|
9853
|
+
ownController.abort();
|
|
9854
|
+
}
|
|
9855
|
+
},
|
|
9856
|
+
contentLength: src.size,
|
|
9857
|
+
name: src.name,
|
|
9858
|
+
supportsContentRange: true,
|
|
9859
|
+
contentType: src.type,
|
|
9860
|
+
needsContentRange: true
|
|
9861
|
+
});
|
|
9862
|
+
};
|
|
9863
|
+
reader.onerror = () => {
|
|
9864
|
+
reject(reader.error);
|
|
9865
|
+
};
|
|
9866
|
+
});
|
|
9867
|
+
};
|
|
9868
|
+
var webFileReadWholeAsText = () => {
|
|
9869
|
+
throw new Error("`webFileReader` cannot read auxiliary files.");
|
|
9870
|
+
};
|
|
9871
|
+
var webFileCreateAdjacentFileSource = () => {
|
|
9872
|
+
throw new Error("`webFileReader` cannot create adjacent file sources.");
|
|
9760
9873
|
};
|
|
9761
9874
|
|
|
9875
|
+
// src/readers/web.ts
|
|
9876
|
+
var webReader = {
|
|
9877
|
+
read: (params) => {
|
|
9878
|
+
if (params.src instanceof Blob) {
|
|
9879
|
+
return webFileReadContent(params);
|
|
9880
|
+
}
|
|
9881
|
+
return fetchReadContent(params);
|
|
9882
|
+
},
|
|
9883
|
+
createAdjacentFileSource: (relativePath, src) => {
|
|
9884
|
+
if (src instanceof Blob) {
|
|
9885
|
+
return webFileCreateAdjacentFileSource(relativePath, src);
|
|
9886
|
+
}
|
|
9887
|
+
return fetchCreateAdjacentFileSource(relativePath, src);
|
|
9888
|
+
},
|
|
9889
|
+
readWholeAsText: (src) => {
|
|
9890
|
+
if (src instanceof Blob) {
|
|
9891
|
+
return webFileReadWholeAsText(src);
|
|
9892
|
+
}
|
|
9893
|
+
return fetchReadWholeAsText(src);
|
|
9894
|
+
}
|
|
9895
|
+
};
|
|
9762
9896
|
// src/parse-media.ts
|
|
9763
9897
|
var parseMedia = (options) => {
|
|
9764
9898
|
return internalParseMedia({
|
|
@@ -9796,10 +9930,11 @@ var parseMedia = (options) => {
|
|
|
9796
9930
|
onVideoCodec: options.onVideoCodec ?? null,
|
|
9797
9931
|
onVideoTrack: options.onVideoTrack ?? null,
|
|
9798
9932
|
progressIntervalInMs: options.progressIntervalInMs ?? null,
|
|
9799
|
-
reader: options.reader ??
|
|
9933
|
+
reader: options.reader ?? webReader,
|
|
9800
9934
|
controller: options.controller ?? undefined,
|
|
9801
9935
|
selectM3uStream: options.selectM3uStream ?? defaultSelectM3uStreamFn,
|
|
9802
9936
|
selectM3uAssociatedPlaylists: options.selectM3uAssociatedPlaylists ?? defaultSelectM3uAssociatedPlaylists,
|
|
9937
|
+
mp4HeaderSegment: options.mp4HeaderSegment ?? null,
|
|
9803
9938
|
src: options.src,
|
|
9804
9939
|
mode: "query",
|
|
9805
9940
|
onDiscardedData: null,
|
|
@@ -9814,21 +9949,25 @@ var getChunks = (playlist) => {
|
|
|
9814
9949
|
const chunks = [];
|
|
9815
9950
|
for (let i = 0;i < playlist.boxes.length; i++) {
|
|
9816
9951
|
const box = playlist.boxes[i];
|
|
9952
|
+
if (box.type === "m3u-map") {
|
|
9953
|
+
chunks.push({ duration: 0, url: box.value, isHeader: true });
|
|
9954
|
+
continue;
|
|
9955
|
+
}
|
|
9817
9956
|
if (box.type === "m3u-extinf") {
|
|
9818
9957
|
const nextBox = playlist.boxes[i + 1];
|
|
9819
9958
|
i++;
|
|
9820
9959
|
if (nextBox.type !== "m3u-text-value") {
|
|
9821
9960
|
throw new Error("Expected m3u-text-value");
|
|
9822
9961
|
}
|
|
9823
|
-
chunks.push({ duration: box.value, url: nextBox.value });
|
|
9962
|
+
chunks.push({ duration: box.value, url: nextBox.value, isHeader: false });
|
|
9824
9963
|
}
|
|
9825
9964
|
continue;
|
|
9826
9965
|
}
|
|
9827
9966
|
return chunks;
|
|
9828
9967
|
};
|
|
9829
9968
|
|
|
9830
|
-
// src/containers/m3u/
|
|
9831
|
-
var
|
|
9969
|
+
// src/containers/m3u/iterate-over-segment-files.ts
|
|
9970
|
+
var iteratorOverSegmentFiles = async ({
|
|
9832
9971
|
structure,
|
|
9833
9972
|
onVideoTrack,
|
|
9834
9973
|
m3uState: m3uState2,
|
|
@@ -9837,7 +9976,8 @@ var iteratorOverTsFiles = async ({
|
|
|
9837
9976
|
playlistUrl,
|
|
9838
9977
|
logLevel,
|
|
9839
9978
|
parentController,
|
|
9840
|
-
onInitialProgress
|
|
9979
|
+
onInitialProgress,
|
|
9980
|
+
readerInterface
|
|
9841
9981
|
}) => {
|
|
9842
9982
|
const playlist = getPlaylist(structure, playlistUrl);
|
|
9843
9983
|
const chunks = getChunks(playlist);
|
|
@@ -9866,9 +10006,10 @@ var iteratorOverTsFiles = async ({
|
|
|
9866
10006
|
for (const chunk of chunks) {
|
|
9867
10007
|
const isLastChunk = chunk === chunks[chunks.length - 1];
|
|
9868
10008
|
await childController._internals.checkForAbortAndPause();
|
|
9869
|
-
const src =
|
|
10009
|
+
const src = readerInterface.createAdjacentFileSource(chunk.url, playlistUrl);
|
|
9870
10010
|
try {
|
|
9871
|
-
|
|
10011
|
+
const mp4HeaderSegment = m3uState2.getMp4HeaderSegment(playlistUrl);
|
|
10012
|
+
const data = await parseMedia({
|
|
9872
10013
|
src,
|
|
9873
10014
|
acknowledgeRemotionLicense: true,
|
|
9874
10015
|
logLevel,
|
|
@@ -9878,6 +10019,7 @@ var iteratorOverTsFiles = async ({
|
|
|
9878
10019
|
childController.pause();
|
|
9879
10020
|
resolver(makeContinuationFn());
|
|
9880
10021
|
},
|
|
10022
|
+
fields: chunk.isHeader ? { structure: true } : undefined,
|
|
9881
10023
|
onTracks: () => {
|
|
9882
10024
|
if (!m3uState2.hasEmittedDoneWithTracks(playlistUrl)) {
|
|
9883
10025
|
m3uState2.setHasEmittedDoneWithTracks(playlistUrl);
|
|
@@ -9885,7 +10027,7 @@ var iteratorOverTsFiles = async ({
|
|
|
9885
10027
|
return null;
|
|
9886
10028
|
}
|
|
9887
10029
|
},
|
|
9888
|
-
onAudioTrack: async ({ track }) => {
|
|
10030
|
+
onAudioTrack: onAudioTrack === null ? null : async ({ track }) => {
|
|
9889
10031
|
const callbackOrFalse = m3uState2.hasEmittedAudioTrack(playlistUrl);
|
|
9890
10032
|
if (callbackOrFalse === false) {
|
|
9891
10033
|
const callback = await onAudioTrack(track);
|
|
@@ -9900,7 +10042,7 @@ var iteratorOverTsFiles = async ({
|
|
|
9900
10042
|
}
|
|
9901
10043
|
return callbackOrFalse;
|
|
9902
10044
|
},
|
|
9903
|
-
onVideoTrack: async ({ track }) => {
|
|
10045
|
+
onVideoTrack: onVideoTrack === null ? null : async ({ track }) => {
|
|
9904
10046
|
const callbackOrFalse = m3uState2.hasEmittedVideoTrack(playlistUrl);
|
|
9905
10047
|
if (callbackOrFalse === false) {
|
|
9906
10048
|
const callback = await onVideoTrack(track);
|
|
@@ -9914,8 +10056,16 @@ var iteratorOverTsFiles = async ({
|
|
|
9914
10056
|
};
|
|
9915
10057
|
}
|
|
9916
10058
|
return callbackOrFalse;
|
|
9917
|
-
}
|
|
10059
|
+
},
|
|
10060
|
+
reader: readerInterface,
|
|
10061
|
+
mp4HeaderSegment
|
|
9918
10062
|
});
|
|
10063
|
+
if (chunk.isHeader) {
|
|
10064
|
+
if (data.structure.type !== "iso-base-media") {
|
|
10065
|
+
throw new Error("Expected an mp4 file");
|
|
10066
|
+
}
|
|
10067
|
+
m3uState2.setMp4HeaderSegment(playlistUrl, data.structure);
|
|
10068
|
+
}
|
|
9919
10069
|
} catch (e) {
|
|
9920
10070
|
rejector(e);
|
|
9921
10071
|
throw e;
|
|
@@ -9936,6 +10086,16 @@ var runOverM3u = async ({
|
|
|
9936
10086
|
playlistUrl,
|
|
9937
10087
|
logLevel
|
|
9938
10088
|
}) => {
|
|
10089
|
+
const tracksDone = state.m3u.getTrackDone(playlistUrl);
|
|
10090
|
+
const hasAudioStreamToConsider = state.m3u.sampleSorter.hasAudioStreamToConsider(playlistUrl);
|
|
10091
|
+
const hasVideoStreamToConsider = state.m3u.sampleSorter.hasVideoStreamToConsider(playlistUrl);
|
|
10092
|
+
const audioDone = !hasAudioStreamToConsider && tracksDone;
|
|
10093
|
+
const videoDone = !hasVideoStreamToConsider && tracksDone;
|
|
10094
|
+
const bothDone = audioDone && videoDone;
|
|
10095
|
+
if (bothDone) {
|
|
10096
|
+
state.m3u.setAllChunksProcessed(playlistUrl);
|
|
10097
|
+
return;
|
|
10098
|
+
}
|
|
9939
10099
|
const existingRun = state.m3u.getM3uStreamRun(playlistUrl);
|
|
9940
10100
|
if (existingRun) {
|
|
9941
10101
|
Log.trace(logLevel, "Existing M3U parsing process found for", playlistUrl);
|
|
@@ -9948,7 +10108,7 @@ var runOverM3u = async ({
|
|
|
9948
10108
|
}
|
|
9949
10109
|
Log.trace(logLevel, "Starting new M3U parsing process for", playlistUrl);
|
|
9950
10110
|
return new Promise((resolve, reject) => {
|
|
9951
|
-
const run =
|
|
10111
|
+
const run = iteratorOverSegmentFiles({
|
|
9952
10112
|
playlistUrl,
|
|
9953
10113
|
structure,
|
|
9954
10114
|
onInitialProgress: (newRun) => {
|
|
@@ -9962,7 +10122,7 @@ var runOverM3u = async ({
|
|
|
9962
10122
|
state.callbacks.tracks.setIsDone(state.logLevel);
|
|
9963
10123
|
}
|
|
9964
10124
|
},
|
|
9965
|
-
onAudioTrack: async (track) => {
|
|
10125
|
+
onAudioTrack: audioDone ? null : async (track) => {
|
|
9966
10126
|
const existingTracks = state.callbacks.tracks.getTracks();
|
|
9967
10127
|
let { trackId } = track;
|
|
9968
10128
|
while (existingTracks.find((t) => t.trackId === trackId)) {
|
|
@@ -9985,7 +10145,7 @@ var runOverM3u = async ({
|
|
|
9985
10145
|
await state.m3u.sampleSorter.addAudioSample(playlistUrl, sample);
|
|
9986
10146
|
};
|
|
9987
10147
|
},
|
|
9988
|
-
onVideoTrack: async (track) => {
|
|
10148
|
+
onVideoTrack: videoDone ? null : async (track) => {
|
|
9989
10149
|
const existingTracks = state.callbacks.tracks.getTracks();
|
|
9990
10150
|
let { trackId } = track;
|
|
9991
10151
|
while (existingTracks.find((t) => t.trackId === trackId)) {
|
|
@@ -10009,7 +10169,8 @@ var runOverM3u = async ({
|
|
|
10009
10169
|
};
|
|
10010
10170
|
},
|
|
10011
10171
|
m3uState: state.m3u,
|
|
10012
|
-
parentController: state.controller
|
|
10172
|
+
parentController: state.controller,
|
|
10173
|
+
readerInterface: state.readerInterface
|
|
10013
10174
|
});
|
|
10014
10175
|
run.catch((err) => {
|
|
10015
10176
|
reject(err);
|
|
@@ -10032,13 +10193,17 @@ var parseM3u = async ({ state }) => {
|
|
|
10032
10193
|
return null;
|
|
10033
10194
|
}
|
|
10034
10195
|
if (state.m3u.hasFinishedManifest()) {
|
|
10196
|
+
if (typeof state.src !== "string" && !(state.src instanceof URL)) {
|
|
10197
|
+
throw new Error("Expected src to be a string");
|
|
10198
|
+
}
|
|
10035
10199
|
await afterManifestFetch({
|
|
10036
10200
|
structure,
|
|
10037
10201
|
m3uState: state.m3u,
|
|
10038
|
-
src:
|
|
10202
|
+
src: state.src.toString(),
|
|
10039
10203
|
selectM3uStreamFn: state.selectM3uStreamFn,
|
|
10040
10204
|
logLevel: state.logLevel,
|
|
10041
|
-
|
|
10205
|
+
selectAssociatedPlaylistsFn: state.selectM3uAssociatedPlaylistsFn,
|
|
10206
|
+
readerInterface: state.readerInterface
|
|
10042
10207
|
});
|
|
10043
10208
|
return null;
|
|
10044
10209
|
}
|
|
@@ -11054,11 +11219,12 @@ var parsePmtTable = ({
|
|
|
11054
11219
|
const sectionNumber = iterator.getBits(8);
|
|
11055
11220
|
const lastSectionNumber = iterator.getBits(8);
|
|
11056
11221
|
const tables = [];
|
|
11222
|
+
iterator.getBits(3);
|
|
11223
|
+
iterator.getBits(13);
|
|
11224
|
+
iterator.getBits(4);
|
|
11225
|
+
const programInfoLength = iterator.getBits(12);
|
|
11226
|
+
iterator.getBits(programInfoLength * 8);
|
|
11057
11227
|
for (let i = sectionNumber;i <= lastSectionNumber; i++) {
|
|
11058
|
-
iterator.getBits(3);
|
|
11059
|
-
iterator.getBits(13);
|
|
11060
|
-
iterator.getBits(4);
|
|
11061
|
-
const programInfoLength = iterator.getBits(12);
|
|
11062
11228
|
const streams = [];
|
|
11063
11229
|
while (true) {
|
|
11064
11230
|
const streamType = iterator.getBits(8);
|
|
@@ -11068,7 +11234,6 @@ var parsePmtTable = ({
|
|
|
11068
11234
|
const esInfoLength = iterator.getBits(12);
|
|
11069
11235
|
iterator.getBits(esInfoLength * 8);
|
|
11070
11236
|
streams.push({ streamType, pid: elementaryPid });
|
|
11071
|
-
iterator.getBits(programInfoLength * 8);
|
|
11072
11237
|
const remaining = sectionLength - (iterator.counter.getOffset() - start);
|
|
11073
11238
|
if (remaining <= 4) {
|
|
11074
11239
|
break;
|
|
@@ -11355,7 +11520,7 @@ var processStreamBuffer = async ({
|
|
|
11355
11520
|
if (!state.callbacks.tracks.hasAllTracks()) {
|
|
11356
11521
|
const tracksRegistered = state.callbacks.tracks.getTracks().length;
|
|
11357
11522
|
const { streams } = findProgramMapTableOrThrow(structure);
|
|
11358
|
-
if (streams.length === tracksRegistered) {
|
|
11523
|
+
if (filterStreamsBySupportedTypes(streams).length === tracksRegistered) {
|
|
11359
11524
|
state.callbacks.tracks.setIsDone(state.logLevel);
|
|
11360
11525
|
}
|
|
11361
11526
|
}
|
|
@@ -11924,7 +12089,7 @@ var parseWebm = async (state) => {
|
|
|
11924
12089
|
};
|
|
11925
12090
|
|
|
11926
12091
|
// src/init-video.ts
|
|
11927
|
-
var initVideo = ({
|
|
12092
|
+
var initVideo = async ({
|
|
11928
12093
|
state,
|
|
11929
12094
|
mimeType,
|
|
11930
12095
|
name,
|
|
@@ -11939,6 +12104,34 @@ var initVideo = ({
|
|
|
11939
12104
|
});
|
|
11940
12105
|
return;
|
|
11941
12106
|
}
|
|
12107
|
+
if (state.mp4HeaderSegment) {
|
|
12108
|
+
Log.verbose(state.logLevel, "Detected ISO Base Media segment");
|
|
12109
|
+
const moovAtom = getMoovFromFromIsoStructure(state.mp4HeaderSegment);
|
|
12110
|
+
if (!moovAtom) {
|
|
12111
|
+
throw new Error("No moov box found");
|
|
12112
|
+
}
|
|
12113
|
+
const tracks2 = getTracksFromMoovBox(moovAtom);
|
|
12114
|
+
for (const track of tracks2.videoTracks) {
|
|
12115
|
+
await registerVideoTrack({
|
|
12116
|
+
state,
|
|
12117
|
+
track,
|
|
12118
|
+
container: "mp4"
|
|
12119
|
+
});
|
|
12120
|
+
}
|
|
12121
|
+
for (const track of tracks2.audioTracks) {
|
|
12122
|
+
await registerAudioTrack({
|
|
12123
|
+
state,
|
|
12124
|
+
track,
|
|
12125
|
+
container: "mp4"
|
|
12126
|
+
});
|
|
12127
|
+
}
|
|
12128
|
+
state.callbacks.tracks.setIsDone(state.logLevel);
|
|
12129
|
+
state.setStructure({
|
|
12130
|
+
type: "iso-base-media",
|
|
12131
|
+
boxes: []
|
|
12132
|
+
});
|
|
12133
|
+
return;
|
|
12134
|
+
}
|
|
11942
12135
|
if (fileType.type === "iso-base-media") {
|
|
11943
12136
|
Log.verbose(state.logLevel, "Detected ISO Base Media container");
|
|
11944
12137
|
state.setStructure({
|
|
@@ -12058,7 +12251,12 @@ var runParseIteration = async ({
|
|
|
12058
12251
|
return Promise.reject(new Error("no bytes"));
|
|
12059
12252
|
}
|
|
12060
12253
|
if (structure === null) {
|
|
12061
|
-
await initVideo({
|
|
12254
|
+
await initVideo({
|
|
12255
|
+
state,
|
|
12256
|
+
mimeType,
|
|
12257
|
+
name,
|
|
12258
|
+
contentLength
|
|
12259
|
+
});
|
|
12062
12260
|
return null;
|
|
12063
12261
|
}
|
|
12064
12262
|
if (structure.type === "riff") {
|
|
@@ -12165,6 +12363,7 @@ var internalParseMedia = async function({
|
|
|
12165
12363
|
apiName,
|
|
12166
12364
|
selectM3uStream: selectM3uStreamFn,
|
|
12167
12365
|
selectM3uAssociatedPlaylists: selectM3uAssociatedPlaylistsFn,
|
|
12366
|
+
mp4HeaderSegment,
|
|
12168
12367
|
...more
|
|
12169
12368
|
}) {
|
|
12170
12369
|
warnIfRemotionLicenseNotAcknowledged({
|
|
@@ -12177,7 +12376,7 @@ var internalParseMedia = async function({
|
|
|
12177
12376
|
fields: fieldsInReturnValue,
|
|
12178
12377
|
callbacks: more
|
|
12179
12378
|
});
|
|
12180
|
-
Log.verbose(logLevel, `Reading ${typeof src === "string" ? src : src.name}`);
|
|
12379
|
+
Log.verbose(logLevel, `Reading ${typeof src === "string" ? src : src instanceof URL ? src.toString() : src.name}`);
|
|
12181
12380
|
const {
|
|
12182
12381
|
reader: readerInstance,
|
|
12183
12382
|
contentLength,
|
|
@@ -12217,7 +12416,8 @@ var internalParseMedia = async function({
|
|
|
12217
12416
|
src,
|
|
12218
12417
|
onDiscardedData,
|
|
12219
12418
|
selectM3uStreamFn,
|
|
12220
|
-
selectM3uAssociatedPlaylistsFn
|
|
12419
|
+
selectM3uAssociatedPlaylistsFn,
|
|
12420
|
+
mp4HeaderSegment
|
|
12221
12421
|
});
|
|
12222
12422
|
const { iterator } = state;
|
|
12223
12423
|
let currentReader = readerInstance;
|
|
@@ -12294,7 +12494,6 @@ var internalParseMedia = async function({
|
|
|
12294
12494
|
if (iterationWithThisOffset > 0 || !hasBigBuffer) {
|
|
12295
12495
|
await fetchMoreData();
|
|
12296
12496
|
}
|
|
12297
|
-
await state.eventLoop.eventLoopBreakIfNeeded();
|
|
12298
12497
|
timeReadingData += Date.now() - readStart;
|
|
12299
12498
|
throttledState.update?.(() => ({
|
|
12300
12499
|
bytes: iterator.counter.getOffset(),
|
|
@@ -12386,6 +12585,353 @@ var internalParseMedia = async function({
|
|
|
12386
12585
|
}
|
|
12387
12586
|
return returnValue;
|
|
12388
12587
|
};
|
|
12588
|
+
// src/worker/serialize-error.ts
|
|
12589
|
+
var deserializeError = (error) => {
|
|
12590
|
+
switch (error.errorName) {
|
|
12591
|
+
case "IsAGifError":
|
|
12592
|
+
return new IsAGifError({
|
|
12593
|
+
fileName: error.fileName,
|
|
12594
|
+
mimeType: error.mimeType,
|
|
12595
|
+
sizeInBytes: error.sizeInBytes,
|
|
12596
|
+
message: error.errorMessage
|
|
12597
|
+
});
|
|
12598
|
+
case "IsAnImageError":
|
|
12599
|
+
return new IsAnImageError({
|
|
12600
|
+
dimensions: error.dimensions,
|
|
12601
|
+
fileName: error.fileName,
|
|
12602
|
+
imageType: error.imageType,
|
|
12603
|
+
mimeType: error.mimeType,
|
|
12604
|
+
sizeInBytes: error.sizeInBytes,
|
|
12605
|
+
message: error.errorMessage
|
|
12606
|
+
});
|
|
12607
|
+
case "IsAPdfError":
|
|
12608
|
+
return new IsAPdfError({
|
|
12609
|
+
fileName: error.fileName,
|
|
12610
|
+
mimeType: error.mimeType,
|
|
12611
|
+
sizeInBytes: error.sizeInBytes,
|
|
12612
|
+
message: error.errorMessage
|
|
12613
|
+
});
|
|
12614
|
+
case "IsAnUnsupportedFileTypeError":
|
|
12615
|
+
return new IsAnUnsupportedFileTypeError({
|
|
12616
|
+
fileName: error.fileName,
|
|
12617
|
+
mimeType: error.mimeType,
|
|
12618
|
+
sizeInBytes: error.sizeInBytes,
|
|
12619
|
+
message: error.errorMessage
|
|
12620
|
+
});
|
|
12621
|
+
case "MediaParserAbortError":
|
|
12622
|
+
return new MediaParserAbortError(error.errorMessage);
|
|
12623
|
+
default:
|
|
12624
|
+
return new Error(error.errorMessage);
|
|
12625
|
+
}
|
|
12626
|
+
};
|
|
12627
|
+
|
|
12628
|
+
// src/parse-media-on-worker-entry.ts
|
|
12629
|
+
var convertToWorkerPayload = (payload) => {
|
|
12630
|
+
const {
|
|
12631
|
+
onAudioCodec,
|
|
12632
|
+
onContainer,
|
|
12633
|
+
onDimensions,
|
|
12634
|
+
onUnrotatedDimensions,
|
|
12635
|
+
onVideoCodec,
|
|
12636
|
+
onFps,
|
|
12637
|
+
onAudioTrack,
|
|
12638
|
+
onDurationInSeconds,
|
|
12639
|
+
onImages,
|
|
12640
|
+
onInternalStats,
|
|
12641
|
+
onIsHdr,
|
|
12642
|
+
onKeyframes,
|
|
12643
|
+
onLocation,
|
|
12644
|
+
onM3uStreams,
|
|
12645
|
+
onMetadata,
|
|
12646
|
+
onMimeType,
|
|
12647
|
+
onName,
|
|
12648
|
+
onNumberOfAudioChannels,
|
|
12649
|
+
onParseProgress,
|
|
12650
|
+
onRotation,
|
|
12651
|
+
onSampleRate,
|
|
12652
|
+
onSlowAudioBitrate,
|
|
12653
|
+
onSize,
|
|
12654
|
+
onSlowDurationInSeconds,
|
|
12655
|
+
onSlowFps,
|
|
12656
|
+
onSlowKeyframes,
|
|
12657
|
+
onSlowNumberOfFrames,
|
|
12658
|
+
onSlowVideoBitrate,
|
|
12659
|
+
onStructure,
|
|
12660
|
+
onTracks,
|
|
12661
|
+
onVideoTrack,
|
|
12662
|
+
selectM3uStream,
|
|
12663
|
+
selectM3uAssociatedPlaylists,
|
|
12664
|
+
src,
|
|
12665
|
+
...others
|
|
12666
|
+
} = payload;
|
|
12667
|
+
return {
|
|
12668
|
+
type: "request-worker",
|
|
12669
|
+
payload: others,
|
|
12670
|
+
postAudioCodec: Boolean(onAudioCodec),
|
|
12671
|
+
postContainer: Boolean(onContainer),
|
|
12672
|
+
postDimensions: Boolean(onDimensions),
|
|
12673
|
+
postDurationInSeconds: Boolean(onDurationInSeconds),
|
|
12674
|
+
postFps: Boolean(onFps),
|
|
12675
|
+
postImages: Boolean(onImages),
|
|
12676
|
+
postInternalStats: Boolean(onInternalStats),
|
|
12677
|
+
postIsHdr: Boolean(onIsHdr),
|
|
12678
|
+
postKeyframes: Boolean(onKeyframes),
|
|
12679
|
+
postLocation: Boolean(onLocation),
|
|
12680
|
+
postM3uStreams: Boolean(onM3uStreams),
|
|
12681
|
+
postMetadata: Boolean(onMetadata),
|
|
12682
|
+
postMimeType: Boolean(onMimeType),
|
|
12683
|
+
postName: Boolean(onName),
|
|
12684
|
+
postNumberOfAudioChannels: Boolean(onNumberOfAudioChannels),
|
|
12685
|
+
postRotation: Boolean(onRotation),
|
|
12686
|
+
postSampleRate: Boolean(onSampleRate),
|
|
12687
|
+
postSlowAudioBitrate: Boolean(onSlowAudioBitrate),
|
|
12688
|
+
postSlowDurationInSeconds: Boolean(onSlowDurationInSeconds),
|
|
12689
|
+
postSlowFps: Boolean(onSlowFps),
|
|
12690
|
+
postSlowKeyframes: Boolean(onSlowKeyframes),
|
|
12691
|
+
postSlowNumberOfFrames: Boolean(onSlowNumberOfFrames),
|
|
12692
|
+
postSlowVideoBitrate: Boolean(onSlowVideoBitrate),
|
|
12693
|
+
postStructure: Boolean(onStructure),
|
|
12694
|
+
postTracks: Boolean(onTracks),
|
|
12695
|
+
postUnrotatedDimensions: Boolean(onUnrotatedDimensions),
|
|
12696
|
+
postVideoCodec: Boolean(onVideoCodec),
|
|
12697
|
+
postSize: Boolean(onSize),
|
|
12698
|
+
postParseProgress: Boolean(onParseProgress),
|
|
12699
|
+
postM3uStreamSelection: Boolean(selectM3uStream),
|
|
12700
|
+
postM3uAssociatedPlaylistsSelection: Boolean(selectM3uAssociatedPlaylists),
|
|
12701
|
+
postOnAudioTrack: Boolean(onAudioTrack),
|
|
12702
|
+
postOnVideoTrack: Boolean(onVideoTrack),
|
|
12703
|
+
src
|
|
12704
|
+
};
|
|
12705
|
+
};
|
|
12706
|
+
var post = (worker, payload) => {
|
|
12707
|
+
worker.postMessage(payload);
|
|
12708
|
+
};
|
|
12709
|
+
var parseMediaOnWorkerImplementation = async ({ controller, reader, ...params }, workerUrlEntry, apiName) => {
|
|
12710
|
+
if (typeof Worker === "undefined") {
|
|
12711
|
+
throw new Error('"Worker" is not available. Cannot call workerClient()');
|
|
12712
|
+
}
|
|
12713
|
+
if (reader) {
|
|
12714
|
+
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().`);
|
|
12715
|
+
}
|
|
12716
|
+
const worker = new Worker(workerUrlEntry);
|
|
12717
|
+
post(worker, convertToWorkerPayload(params));
|
|
12718
|
+
const { promise, resolve, reject } = Promise.withResolvers();
|
|
12719
|
+
const onAbort = () => {
|
|
12720
|
+
post(worker, { type: "request-abort" });
|
|
12721
|
+
};
|
|
12722
|
+
const onResume = () => {
|
|
12723
|
+
post(worker, { type: "request-resume" });
|
|
12724
|
+
};
|
|
12725
|
+
const onPause = () => {
|
|
12726
|
+
post(worker, { type: "request-pause" });
|
|
12727
|
+
};
|
|
12728
|
+
const callbacks = {};
|
|
12729
|
+
function onMessage(message) {
|
|
12730
|
+
const data = message.data;
|
|
12731
|
+
if (data.type === "response-done") {
|
|
12732
|
+
resolve(data.payload);
|
|
12733
|
+
}
|
|
12734
|
+
if (data.type === "response-error") {
|
|
12735
|
+
cleanup();
|
|
12736
|
+
reject(deserializeError(data));
|
|
12737
|
+
}
|
|
12738
|
+
if (data.type === "response-on-callback-request") {
|
|
12739
|
+
Promise.resolve().then(async () => {
|
|
12740
|
+
if (data.payload.callbackType === "audio-codec") {
|
|
12741
|
+
await params.onAudioCodec?.(data.payload.value);
|
|
12742
|
+
return { payloadType: "void" };
|
|
12743
|
+
}
|
|
12744
|
+
if (data.payload.callbackType === "container") {
|
|
12745
|
+
await params.onContainer?.(data.payload.value);
|
|
12746
|
+
return { payloadType: "void" };
|
|
12747
|
+
}
|
|
12748
|
+
if (data.payload.callbackType === "dimensions") {
|
|
12749
|
+
await params.onDimensions?.(data.payload.value);
|
|
12750
|
+
return { payloadType: "void" };
|
|
12751
|
+
}
|
|
12752
|
+
if (data.payload.callbackType === "unrotated-dimensions") {
|
|
12753
|
+
await params.onUnrotatedDimensions?.(data.payload.value);
|
|
12754
|
+
return { payloadType: "void" };
|
|
12755
|
+
}
|
|
12756
|
+
if (data.payload.callbackType === "video-codec") {
|
|
12757
|
+
await params.onVideoCodec?.(data.payload.value);
|
|
12758
|
+
return { payloadType: "void" };
|
|
12759
|
+
}
|
|
12760
|
+
if (data.payload.callbackType === "tracks") {
|
|
12761
|
+
await params.onTracks?.(data.payload.value);
|
|
12762
|
+
return { payloadType: "void" };
|
|
12763
|
+
}
|
|
12764
|
+
if (data.payload.callbackType === "rotation") {
|
|
12765
|
+
await params.onRotation?.(data.payload.value);
|
|
12766
|
+
return { payloadType: "void" };
|
|
12767
|
+
}
|
|
12768
|
+
if (data.payload.callbackType === "sample-rate") {
|
|
12769
|
+
await params.onSampleRate?.(data.payload.value);
|
|
12770
|
+
return { payloadType: "void" };
|
|
12771
|
+
}
|
|
12772
|
+
if (data.payload.callbackType === "slow-audio-bitrate") {
|
|
12773
|
+
await params.onSlowAudioBitrate?.(data.payload.value);
|
|
12774
|
+
return { payloadType: "void" };
|
|
12775
|
+
}
|
|
12776
|
+
if (data.payload.callbackType === "slow-duration-in-seconds") {
|
|
12777
|
+
await params.onSlowDurationInSeconds?.(data.payload.value);
|
|
12778
|
+
return { payloadType: "void" };
|
|
12779
|
+
}
|
|
12780
|
+
if (data.payload.callbackType === "slow-fps") {
|
|
12781
|
+
await params.onSlowFps?.(data.payload.value);
|
|
12782
|
+
return { payloadType: "void" };
|
|
12783
|
+
}
|
|
12784
|
+
if (data.payload.callbackType === "slow-keyframes") {
|
|
12785
|
+
await params.onSlowKeyframes?.(data.payload.value);
|
|
12786
|
+
return { payloadType: "void" };
|
|
12787
|
+
}
|
|
12788
|
+
if (data.payload.callbackType === "slow-number-of-frames") {
|
|
12789
|
+
await params.onSlowNumberOfFrames?.(data.payload.value);
|
|
12790
|
+
return { payloadType: "void" };
|
|
12791
|
+
}
|
|
12792
|
+
if (data.payload.callbackType === "slow-video-bitrate") {
|
|
12793
|
+
await params.onSlowVideoBitrate?.(data.payload.value);
|
|
12794
|
+
return { payloadType: "void" };
|
|
12795
|
+
}
|
|
12796
|
+
if (data.payload.callbackType === "structure") {
|
|
12797
|
+
await params.onStructure?.(data.payload.value);
|
|
12798
|
+
return { payloadType: "void" };
|
|
12799
|
+
}
|
|
12800
|
+
if (data.payload.callbackType === "fps") {
|
|
12801
|
+
await params.onFps?.(data.payload.value);
|
|
12802
|
+
return { payloadType: "void" };
|
|
12803
|
+
}
|
|
12804
|
+
if (data.payload.callbackType === "images") {
|
|
12805
|
+
await params.onImages?.(data.payload.value);
|
|
12806
|
+
return { payloadType: "void" };
|
|
12807
|
+
}
|
|
12808
|
+
if (data.payload.callbackType === "internal-stats") {
|
|
12809
|
+
await params.onInternalStats?.(data.payload.value);
|
|
12810
|
+
return { payloadType: "void" };
|
|
12811
|
+
}
|
|
12812
|
+
if (data.payload.callbackType === "is-hdr") {
|
|
12813
|
+
await params.onIsHdr?.(data.payload.value);
|
|
12814
|
+
return { payloadType: "void" };
|
|
12815
|
+
}
|
|
12816
|
+
if (data.payload.callbackType === "keyframes") {
|
|
12817
|
+
await params.onKeyframes?.(data.payload.value);
|
|
12818
|
+
return { payloadType: "void" };
|
|
12819
|
+
}
|
|
12820
|
+
if (data.payload.callbackType === "location") {
|
|
12821
|
+
await params.onLocation?.(data.payload.value);
|
|
12822
|
+
return { payloadType: "void" };
|
|
12823
|
+
}
|
|
12824
|
+
if (data.payload.callbackType === "m3u-streams") {
|
|
12825
|
+
await params.onM3uStreams?.(data.payload.value);
|
|
12826
|
+
return { payloadType: "void" };
|
|
12827
|
+
}
|
|
12828
|
+
if (data.payload.callbackType === "metadata") {
|
|
12829
|
+
await params.onMetadata?.(data.payload.value);
|
|
12830
|
+
return { payloadType: "void" };
|
|
12831
|
+
}
|
|
12832
|
+
if (data.payload.callbackType === "mime-type") {
|
|
12833
|
+
await params.onMimeType?.(data.payload.value);
|
|
12834
|
+
return { payloadType: "void" };
|
|
12835
|
+
}
|
|
12836
|
+
if (data.payload.callbackType === "name") {
|
|
12837
|
+
await params.onName?.(data.payload.value);
|
|
12838
|
+
return { payloadType: "void" };
|
|
12839
|
+
}
|
|
12840
|
+
if (data.payload.callbackType === "number-of-audio-channels") {
|
|
12841
|
+
await params.onNumberOfAudioChannels?.(data.payload.value);
|
|
12842
|
+
return { payloadType: "void" };
|
|
12843
|
+
}
|
|
12844
|
+
if (data.payload.callbackType === "size") {
|
|
12845
|
+
await params.onSize?.(data.payload.value);
|
|
12846
|
+
return { payloadType: "void" };
|
|
12847
|
+
}
|
|
12848
|
+
if (data.payload.callbackType === "duration-in-seconds") {
|
|
12849
|
+
await params.onDurationInSeconds?.(data.payload.value);
|
|
12850
|
+
return { payloadType: "void" };
|
|
12851
|
+
}
|
|
12852
|
+
if (data.payload.callbackType === "parse-progress") {
|
|
12853
|
+
await params.onParseProgress?.(data.payload.value);
|
|
12854
|
+
return { payloadType: "void" };
|
|
12855
|
+
}
|
|
12856
|
+
if (data.payload.callbackType === "m3u-stream-selection") {
|
|
12857
|
+
const selection = await params.selectM3uStream(data.payload.value);
|
|
12858
|
+
return { payloadType: "m3u-stream-selection", value: selection };
|
|
12859
|
+
}
|
|
12860
|
+
if (data.payload.callbackType === "m3u-associated-playlists-selection") {
|
|
12861
|
+
const selection = await params.selectM3uAssociatedPlaylists(data.payload.value);
|
|
12862
|
+
return {
|
|
12863
|
+
payloadType: "m3u-associated-playlists-selection",
|
|
12864
|
+
value: selection
|
|
12865
|
+
};
|
|
12866
|
+
}
|
|
12867
|
+
if (data.payload.callbackType === "on-audio-track") {
|
|
12868
|
+
const possibleCallback = await params.onAudioTrack?.(data.payload.value);
|
|
12869
|
+
if (possibleCallback) {
|
|
12870
|
+
callbacks[data.payload.value.track.trackId] = possibleCallback;
|
|
12871
|
+
}
|
|
12872
|
+
return {
|
|
12873
|
+
payloadType: "on-audio-track-response",
|
|
12874
|
+
registeredCallback: Boolean(possibleCallback)
|
|
12875
|
+
};
|
|
12876
|
+
}
|
|
12877
|
+
if (data.payload.callbackType === "on-video-track") {
|
|
12878
|
+
const possibleCallback = await params.onVideoTrack?.(data.payload.value);
|
|
12879
|
+
if (possibleCallback) {
|
|
12880
|
+
callbacks[data.payload.value.track.trackId] = possibleCallback;
|
|
12881
|
+
}
|
|
12882
|
+
return {
|
|
12883
|
+
payloadType: "on-video-track-response",
|
|
12884
|
+
registeredCallback: Boolean(possibleCallback)
|
|
12885
|
+
};
|
|
12886
|
+
}
|
|
12887
|
+
if (data.payload.callbackType === "on-audio-video-sample") {
|
|
12888
|
+
const callback = callbacks[data.payload.trackId];
|
|
12889
|
+
if (!callback) {
|
|
12890
|
+
throw new Error(`No callback registered for track ${data.payload.trackId}`);
|
|
12891
|
+
}
|
|
12892
|
+
await callback(data.payload.value);
|
|
12893
|
+
return { payloadType: "void" };
|
|
12894
|
+
}
|
|
12895
|
+
throw new Error(`Unknown callback type: ${data.payload}`);
|
|
12896
|
+
}).then((payload) => {
|
|
12897
|
+
post(worker, {
|
|
12898
|
+
type: "acknowledge-callback",
|
|
12899
|
+
nonce: data.nonce,
|
|
12900
|
+
...payload
|
|
12901
|
+
});
|
|
12902
|
+
}).catch((err) => {
|
|
12903
|
+
reject(err);
|
|
12904
|
+
post(worker, {
|
|
12905
|
+
type: "signal-error-in-callback",
|
|
12906
|
+
nonce: data.nonce
|
|
12907
|
+
});
|
|
12908
|
+
});
|
|
12909
|
+
}
|
|
12910
|
+
}
|
|
12911
|
+
worker.addEventListener("message", onMessage);
|
|
12912
|
+
controller?.addEventListener("abort", onAbort);
|
|
12913
|
+
controller?.addEventListener("resume", onResume);
|
|
12914
|
+
controller?.addEventListener("pause", onPause);
|
|
12915
|
+
function cleanup() {
|
|
12916
|
+
worker.removeEventListener("message", onMessage);
|
|
12917
|
+
controller?.removeEventListener("abort", onAbort);
|
|
12918
|
+
controller?.removeEventListener("resume", onResume);
|
|
12919
|
+
controller?.removeEventListener("pause", onPause);
|
|
12920
|
+
worker.terminate();
|
|
12921
|
+
}
|
|
12922
|
+
const val = await promise;
|
|
12923
|
+
cleanup();
|
|
12924
|
+
return val;
|
|
12925
|
+
};
|
|
12926
|
+
|
|
12927
|
+
// src/parse-media-on-server-worker.ts
|
|
12928
|
+
var parseMediaOnServerWorker = (params) => {
|
|
12929
|
+
return parseMediaOnWorkerImplementation(params, new URL("./worker-server-entry", import.meta.url), "parseMediaOnServerWorker");
|
|
12930
|
+
};
|
|
12931
|
+
// src/parse-media-on-web-worker.ts
|
|
12932
|
+
var parseMediaOnWebWorker = (params) => {
|
|
12933
|
+
return parseMediaOnWorkerImplementation(params, new URL("./worker-web-entry", import.meta.url), "parseMediaOnWebWorker");
|
|
12934
|
+
};
|
|
12389
12935
|
// src/download-and-parse-media.ts
|
|
12390
12936
|
var downloadAndParseMedia = async (options) => {
|
|
12391
12937
|
const logLevel = options.logLevel ?? "info";
|
|
@@ -12399,11 +12945,12 @@ var downloadAndParseMedia = async (options) => {
|
|
|
12399
12945
|
logLevel,
|
|
12400
12946
|
mode: "download",
|
|
12401
12947
|
onAudioCodec: options.onAudioCodec ?? null,
|
|
12402
|
-
onAudioTrack: null,
|
|
12948
|
+
onAudioTrack: options.onAudioTrack ?? null,
|
|
12403
12949
|
onContainer: options.onContainer ?? null,
|
|
12404
12950
|
onDimensions: options.onDimensions ?? null,
|
|
12405
12951
|
selectM3uStream: options.selectM3uStream ?? defaultSelectM3uStreamFn,
|
|
12406
12952
|
selectM3uAssociatedPlaylists: options.selectM3uAssociatedPlaylists ?? defaultSelectM3uAssociatedPlaylists,
|
|
12953
|
+
mp4HeaderSegment: options.mp4HeaderSegment ?? null,
|
|
12407
12954
|
onDiscardedData: async (data) => {
|
|
12408
12955
|
await content.write(data);
|
|
12409
12956
|
},
|
|
@@ -12433,9 +12980,9 @@ var downloadAndParseMedia = async (options) => {
|
|
|
12433
12980
|
onTracks: options.onTracks ?? null,
|
|
12434
12981
|
onUnrotatedDimensions: options.onUnrotatedDimensions ?? null,
|
|
12435
12982
|
onVideoCodec: options.onVideoCodec ?? null,
|
|
12436
|
-
onVideoTrack: null,
|
|
12983
|
+
onVideoTrack: options.onVideoTrack ?? null,
|
|
12437
12984
|
progressIntervalInMs: options.progressIntervalInMs ?? null,
|
|
12438
|
-
reader: options.reader ??
|
|
12985
|
+
reader: options.reader ?? webReader,
|
|
12439
12986
|
controller: options.controller ?? undefined,
|
|
12440
12987
|
src: options.src,
|
|
12441
12988
|
onError: async (err) => {
|
|
@@ -12454,7 +13001,7 @@ var downloadAndParseMedia = async (options) => {
|
|
|
12454
13001
|
return returnValue;
|
|
12455
13002
|
};
|
|
12456
13003
|
// src/version.ts
|
|
12457
|
-
var VERSION = "4.0.
|
|
13004
|
+
var VERSION = "4.0.272";
|
|
12458
13005
|
|
|
12459
13006
|
// src/index.ts
|
|
12460
13007
|
var MediaParserInternals = {
|
|
@@ -12473,6 +13020,8 @@ var MediaParserInternals = {
|
|
|
12473
13020
|
internalParseMedia
|
|
12474
13021
|
};
|
|
12475
13022
|
export {
|
|
13023
|
+
parseMediaOnWebWorker,
|
|
13024
|
+
parseMediaOnServerWorker,
|
|
12476
13025
|
parseMedia,
|
|
12477
13026
|
mediaParserController,
|
|
12478
13027
|
hasBeenAborted,
|
|
@@ -12483,7 +13032,6 @@ export {
|
|
|
12483
13032
|
MediaParserInternals,
|
|
12484
13033
|
MediaParserAbortError,
|
|
12485
13034
|
IsAnUnsupportedFileTypeError,
|
|
12486
|
-
IsAnUnsupportedAudioTypeError,
|
|
12487
13035
|
IsAnImageError,
|
|
12488
13036
|
IsAPdfError,
|
|
12489
13037
|
IsAGifError
|