@remotion/media-parser 4.0.289 → 4.0.291
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/containers/flac/get-channel-count.d.ts +1 -1
- package/dist/containers/iso-base-media/base-media-box.d.ts +0 -1
- package/dist/containers/iso-base-media/collect-sample-positions-from-moof-boxes.d.ts +4 -1
- package/dist/containers/iso-base-media/collect-sample-positions-from-moof-boxes.js +9 -5
- package/dist/containers/iso-base-media/find-keyframe-before-time.js +16 -11
- package/dist/containers/iso-base-media/find-track-to-seek.d.ts +14 -0
- package/dist/containers/iso-base-media/find-track-to-seek.js +39 -0
- package/dist/containers/iso-base-media/get-children.js +2 -2
- package/dist/containers/iso-base-media/get-keyframes.js +6 -1
- package/dist/containers/iso-base-media/get-mfra-seeking-box.d.ts +3 -1
- package/dist/containers/iso-base-media/get-mfra-seeking-box.js +5 -1
- package/dist/containers/iso-base-media/get-moov-atom.js +6 -3
- package/dist/containers/iso-base-media/get-sample-position-bounds.js +3 -1
- package/dist/containers/iso-base-media/get-sample-positions-from-track.js +1 -1
- package/dist/containers/iso-base-media/get-seeking-byte-from-fragmented-mp4.d.ts +14 -0
- package/dist/containers/iso-base-media/get-seeking-byte-from-fragmented-mp4.js +89 -0
- package/dist/containers/iso-base-media/get-seeking-byte.d.ts +3 -3
- package/dist/containers/iso-base-media/get-seeking-byte.js +32 -96
- package/dist/containers/iso-base-media/get-video-codec-from-iso-track.d.ts +1 -1
- package/dist/containers/iso-base-media/mdat/calculate-jump-marks.d.ts +6 -0
- package/dist/containers/iso-base-media/mdat/calculate-jump-marks.js +131 -0
- package/dist/containers/iso-base-media/mdat/mdat.d.ts +2 -2
- package/dist/containers/iso-base-media/mdat/mdat.js +18 -2
- package/dist/containers/iso-base-media/mfra/find-best-segment-from-tfra.d.ts +3 -3
- package/dist/containers/iso-base-media/mfra/find-best-segment-from-tfra.js +2 -2
- package/dist/containers/iso-base-media/mfra/get-mfra-atom.d.ts +5 -1
- package/dist/containers/iso-base-media/mfra/get-mfra-atom.js +3 -1
- package/dist/containers/iso-base-media/mfra/get-mfro-atom.d.ts +5 -1
- package/dist/containers/iso-base-media/mfra/get-mfro-atom.js +3 -1
- package/dist/containers/iso-base-media/parse-boxes.js +5 -2
- package/dist/containers/iso-base-media/process-box.d.ts +16 -5
- package/dist/containers/iso-base-media/process-box.js +206 -118
- package/dist/containers/iso-base-media/sample-positions.d.ts +25 -0
- package/dist/containers/iso-base-media/sample-positions.js +37 -0
- package/dist/containers/iso-base-media/seeking-hints.d.ts +1 -1
- package/dist/containers/iso-base-media/stsd/samples.js +1 -0
- package/dist/containers/iso-base-media/stsd/stsc.d.ts +1 -6
- package/dist/containers/iso-base-media/stsd/stsc.js +2 -5
- package/dist/containers/iso-base-media/stsd/stss.d.ts +1 -1
- package/dist/containers/iso-base-media/stsd/stss.js +2 -2
- package/dist/containers/iso-base-media/turn-sample-positions-into-array.d.ts +19 -0
- package/dist/containers/iso-base-media/turn-sample-positions-into-array.js +73 -0
- package/dist/containers/m3u/after-manifest-fetch.d.ts +5 -1
- package/dist/containers/m3u/after-manifest-fetch.js +3 -1
- package/dist/containers/m3u/first-sample-in-m3u-chunk.d.ts +13 -0
- package/dist/containers/m3u/first-sample-in-m3u-chunk.js +31 -0
- package/dist/containers/m3u/get-seeking-byte.d.ts +13 -0
- package/dist/containers/m3u/get-seeking-byte.js +32 -0
- package/dist/containers/m3u/get-streams.d.ts +1 -0
- package/dist/containers/m3u/get-streams.js +1 -0
- package/dist/containers/m3u/iterate-over-segment-files.d.ts +5 -3
- package/dist/containers/m3u/iterate-over-segment-files.js +11 -1
- package/dist/containers/m3u/parse-m3u-media-directive.js +1 -0
- package/dist/containers/m3u/parse-m3u.js +8 -0
- package/dist/containers/m3u/process-m3u-chunk.d.ts +12 -0
- package/dist/containers/m3u/process-m3u-chunk.js +274 -0
- package/dist/containers/m3u/run-over-m3u.js +7 -80
- package/dist/containers/m3u/sample-sorter.d.ts +1 -0
- package/dist/containers/m3u/sample-sorter.js +4 -1
- package/dist/containers/m3u/seek/get-chunk-to-seek-to.d.ts +5 -0
- package/dist/containers/m3u/seek/get-chunk-to-seek-to.js +14 -0
- package/dist/containers/m3u/seeking-hints.d.ts +2 -0
- package/dist/containers/m3u/seeking-hints.js +9 -0
- package/dist/containers/m3u/select-stream.d.ts +2 -1
- package/dist/containers/m3u/select-stream.js +7 -2
- package/dist/containers/m3u/types.d.ts +1 -0
- package/dist/containers/mp3/get-duration.d.ts +5 -0
- package/dist/containers/riff/seek/fetch-idx1.d.ts +3 -1
- package/dist/containers/riff/seek/fetch-idx1.js +3 -1
- package/dist/containers/transport-stream/handle-aac-packet.d.ts +2 -2
- package/dist/containers/transport-stream/handle-avc-packet.d.ts +2 -2
- package/dist/containers/transport-stream/process-audio.d.ts +2 -2
- package/dist/containers/transport-stream/process-stream-buffers.d.ts +3 -3
- package/dist/containers/transport-stream/process-video.d.ts +2 -2
- package/dist/containers/wav/get-duration-from-wav.d.ts +0 -1
- package/dist/containers/webm/get-sample-from-block.d.ts +12 -2
- package/dist/containers/webm/get-sample-from-block.js +40 -9
- package/dist/containers/webm/parse-ebml.js +28 -10
- package/dist/containers/webm/seek/fetch-web-cues.d.ts +3 -1
- package/dist/containers/webm/seek/fetch-web-cues.js +3 -1
- package/dist/containers/webm/state-for-processing.d.ts +2 -2
- package/dist/controller/media-parser-controller.d.ts +1 -1
- package/dist/controller/media-parser-controller.js +6 -2
- package/dist/controller/seek-signal.d.ts +1 -5
- package/dist/download-and-parse-media.js +1 -1
- package/dist/esm/index.mjs +1400 -611
- package/dist/esm/node.mjs +23 -3
- package/dist/esm/server-worker.mjs +8 -1
- package/dist/esm/universal.mjs +168 -15
- package/dist/esm/web.mjs +145 -13
- package/dist/esm/worker-server-entry.mjs +1467 -635
- package/dist/esm/worker-web-entry.mjs +1439 -634
- package/dist/esm/worker.mjs +8 -1
- package/dist/get-audio-codec.js +3 -0
- package/dist/get-duration.js +2 -1
- package/dist/get-fps.js +2 -1
- package/dist/get-sample-positions-from-mp4.js +10 -5
- package/dist/get-sample-positions.js +4 -4
- package/dist/get-seeking-byte.d.ts +5 -3
- package/dist/get-seeking-byte.js +19 -10
- package/dist/get-seeking-hints.d.ts +3 -3
- package/dist/get-seeking-hints.js +18 -13
- package/dist/get-tracks.d.ts +9 -1
- package/dist/get-tracks.js +13 -6
- package/dist/index.d.ts +21 -5
- package/dist/init-video.js +3 -2
- package/dist/internal-parse-media.js +13 -4
- package/dist/iterator/buffer-iterator.js +5 -3
- package/dist/metadata/metadata-from-iso.js +2 -1
- package/dist/options.d.ts +6 -1
- package/dist/parse-loop.js +22 -6
- package/dist/parse-media-on-worker-entry.js +1 -0
- package/dist/parse-media.js +1 -1
- package/dist/parse-result.d.ts +2 -2
- package/dist/perform-seek.d.ts +3 -1
- package/dist/perform-seek.js +3 -1
- package/dist/readers/fetch/get-body-and-reader.js +17 -2
- package/dist/readers/from-fetch.d.ts +17 -1
- package/dist/readers/from-fetch.js +68 -13
- package/dist/readers/from-node.js +24 -2
- package/dist/readers/from-web-file.js +3 -0
- package/dist/readers/reader.d.ts +19 -2
- package/dist/readers/universal.js +9 -0
- package/dist/readers/web.js +6 -0
- package/dist/register-track.d.ts +3 -3
- package/dist/seek-backwards.d.ts +3 -1
- package/dist/seek-backwards.js +4 -1
- package/dist/seek-forwards.d.ts +3 -1
- package/dist/seek-forwards.js +3 -1
- package/dist/seeking-hints.d.ts +4 -1
- package/dist/set-seeking-hints.js +4 -0
- package/dist/skip.d.ts +5 -0
- package/dist/skip.js +6 -1
- package/dist/state/can-skip-tracks.d.ts +1 -0
- package/dist/state/can-skip-tracks.js +10 -6
- package/dist/state/iso-base-media/cached-sample-positions.d.ts +15 -1
- package/dist/state/iso-base-media/cached-sample-positions.js +9 -4
- package/dist/state/iso-base-media/iso-state.d.ts +5 -1
- package/dist/state/iso-base-media/iso-state.js +2 -1
- package/dist/state/iso-base-media/lazy-mfra-load.d.ts +3 -1
- package/dist/state/iso-base-media/lazy-mfra-load.js +2 -1
- package/dist/state/keyframes.js +1 -0
- package/dist/state/m3u-state.d.ts +15 -4
- package/dist/state/m3u-state.js +20 -0
- package/dist/state/matroska/lazy-cues-fetch.d.ts +3 -1
- package/dist/state/matroska/lazy-cues-fetch.js +2 -1
- package/dist/state/matroska/webm.d.ts +3 -1
- package/dist/state/matroska/webm.js +2 -1
- package/dist/state/mp3.d.ts +16 -5
- package/dist/state/mp3.js +7 -5
- package/dist/state/parser-state.d.ts +31 -15
- package/dist/state/parser-state.js +19 -5
- package/dist/state/riff/lazy-idx1-fetch.d.ts +5 -3
- package/dist/state/riff/lazy-idx1-fetch.js +2 -1
- package/dist/state/riff.d.ts +5 -3
- package/dist/state/riff.js +2 -1
- package/dist/state/sample-callbacks.d.ts +3 -2
- package/dist/state/sample-callbacks.js +3 -3
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/work-on-seek-request.d.ts +6 -3
- package/dist/work-on-seek-request.js +13 -13
- package/dist/worker/forward-controller-to-worker.js +1 -1
- package/dist/worker/serialize-error.js +26 -3
- package/dist/worker/worker-types.d.ts +7 -1
- package/dist/worker-server.js +2 -2
- package/package.json +3 -3
package/dist/esm/node.mjs
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// src/readers/from-node.ts
|
|
2
2
|
import { createReadStream, promises, statSync } from "fs";
|
|
3
3
|
import { dirname, join, relative, sep } from "path";
|
|
4
|
-
import { Readable } from "stream";
|
|
5
4
|
var nodeReadContent = ({ src, range, controller }) => {
|
|
6
5
|
if (typeof src !== "string") {
|
|
7
6
|
throw new Error("src must be a string when using `nodeReader`");
|
|
@@ -16,7 +15,27 @@ var nodeReadContent = ({ src, range, controller }) => {
|
|
|
16
15
|
ownController.abort();
|
|
17
16
|
}, { once: true });
|
|
18
17
|
const stats = statSync(src);
|
|
19
|
-
|
|
18
|
+
let readerCancelled = false;
|
|
19
|
+
const reader = new ReadableStream({
|
|
20
|
+
start(c) {
|
|
21
|
+
if (readerCancelled) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
stream.on("data", (chunk) => {
|
|
25
|
+
c.enqueue(chunk);
|
|
26
|
+
});
|
|
27
|
+
stream.on("end", () => {
|
|
28
|
+
c.close();
|
|
29
|
+
});
|
|
30
|
+
stream.on("error", (err) => {
|
|
31
|
+
c.error(err);
|
|
32
|
+
});
|
|
33
|
+
},
|
|
34
|
+
cancel() {
|
|
35
|
+
readerCancelled = true;
|
|
36
|
+
stream.destroy();
|
|
37
|
+
}
|
|
38
|
+
}).getReader();
|
|
20
39
|
if (controller) {
|
|
21
40
|
controller._internals.signal.addEventListener("abort", () => {
|
|
22
41
|
reader.cancel().catch(() => {});
|
|
@@ -56,7 +75,8 @@ var nodeCreateAdjacentFileSource = (relativePath, src) => {
|
|
|
56
75
|
var nodeReader = {
|
|
57
76
|
read: nodeReadContent,
|
|
58
77
|
readWholeAsText: nodeReadWholeAsText,
|
|
59
|
-
createAdjacentFileSource: nodeCreateAdjacentFileSource
|
|
78
|
+
createAdjacentFileSource: nodeCreateAdjacentFileSource,
|
|
79
|
+
preload: () => {}
|
|
60
80
|
};
|
|
61
81
|
export {
|
|
62
82
|
nodeReader,
|
|
@@ -144,8 +144,14 @@ var deserializeError = (error) => {
|
|
|
144
144
|
});
|
|
145
145
|
case "MediaParserAbortError":
|
|
146
146
|
return new MediaParserAbortError(error.errorMessage);
|
|
147
|
-
|
|
147
|
+
case "Error":
|
|
148
|
+
return new Error(error.errorMessage);
|
|
149
|
+
case "AbortError":
|
|
148
150
|
return new Error(error.errorMessage);
|
|
151
|
+
case "NotReadableError":
|
|
152
|
+
return new Error(error.errorMessage);
|
|
153
|
+
default:
|
|
154
|
+
throw new Error(`Unknown error name: ${error}`);
|
|
149
155
|
}
|
|
150
156
|
};
|
|
151
157
|
|
|
@@ -280,6 +286,7 @@ var parseMediaOnWorkerImplementation = async ({ controller, reader, ...params },
|
|
|
280
286
|
if (data.type === "response-error") {
|
|
281
287
|
cleanup();
|
|
282
288
|
const error = deserializeError(data);
|
|
289
|
+
error.stack = data.errorStack;
|
|
283
290
|
reject(error);
|
|
284
291
|
if (data.errorName === "MediaParserAbortError") {
|
|
285
292
|
finalSeekingHints = data.seekingHints;
|
package/dist/esm/universal.mjs
CHANGED
|
@@ -7,6 +7,40 @@ class MediaParserAbortError extends Error {
|
|
|
7
7
|
}
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
+
// src/log.ts
|
|
11
|
+
var logLevels = ["trace", "verbose", "info", "warn", "error"];
|
|
12
|
+
var getNumberForLogLevel = (level) => {
|
|
13
|
+
return logLevels.indexOf(level);
|
|
14
|
+
};
|
|
15
|
+
var isEqualOrBelowLogLevel = (currentLevel, level) => {
|
|
16
|
+
return getNumberForLogLevel(currentLevel) <= getNumberForLogLevel(level);
|
|
17
|
+
};
|
|
18
|
+
var Log = {
|
|
19
|
+
trace: (logLevel, ...args) => {
|
|
20
|
+
if (isEqualOrBelowLogLevel(logLevel, "trace")) {
|
|
21
|
+
return console.log(...args);
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
verbose: (logLevel, ...args) => {
|
|
25
|
+
if (isEqualOrBelowLogLevel(logLevel, "verbose")) {
|
|
26
|
+
return console.log(...args);
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
info: (logLevel, ...args) => {
|
|
30
|
+
if (isEqualOrBelowLogLevel(logLevel, "info")) {
|
|
31
|
+
return console.log(...args);
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
warn: (logLevel, ...args) => {
|
|
35
|
+
if (isEqualOrBelowLogLevel(logLevel, "warn")) {
|
|
36
|
+
return console.warn(...args);
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
error: (...args) => {
|
|
40
|
+
return console.error(...args);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
|
|
10
44
|
// src/readers/fetch/get-body-and-reader.ts
|
|
11
45
|
var getLengthAndReader = async ({
|
|
12
46
|
canLiveWithoutContentLength,
|
|
@@ -19,10 +53,22 @@ var getLengthAndReader = async ({
|
|
|
19
53
|
if (requestedWithoutRange || canLiveWithoutContentLength && contentLength === null) {
|
|
20
54
|
const buffer = await res.arrayBuffer();
|
|
21
55
|
const encoded = new Uint8Array(buffer);
|
|
56
|
+
let streamCancelled = false;
|
|
22
57
|
const stream = new ReadableStream({
|
|
23
58
|
start(controller) {
|
|
24
|
-
|
|
25
|
-
|
|
59
|
+
if (ownController.signal.aborted) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
if (streamCancelled) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
try {
|
|
66
|
+
controller.enqueue(encoded);
|
|
67
|
+
controller.close();
|
|
68
|
+
} catch {}
|
|
69
|
+
},
|
|
70
|
+
cancel() {
|
|
71
|
+
streamCancelled = true;
|
|
26
72
|
}
|
|
27
73
|
});
|
|
28
74
|
return {
|
|
@@ -98,14 +144,11 @@ var validateContentRangeAndDetectIfSupported = ({
|
|
|
98
144
|
}
|
|
99
145
|
return { supportsContentRange: true };
|
|
100
146
|
};
|
|
101
|
-
var
|
|
102
|
-
src,
|
|
147
|
+
var makeFetchRequest = async ({
|
|
103
148
|
range,
|
|
149
|
+
src,
|
|
104
150
|
controller
|
|
105
151
|
}) => {
|
|
106
|
-
if (typeof src !== "string" && src instanceof URL === false) {
|
|
107
|
-
throw new Error("src must be a string when using `fetchReader`");
|
|
108
|
-
}
|
|
109
152
|
const resolvedUrl = resolveUrl(src);
|
|
110
153
|
const resolvedUrlString = resolvedUrl.toString();
|
|
111
154
|
if (!resolvedUrlString.startsWith("https://") && !resolvedUrlString.startsWith("blob:") && !resolvedUrlString.startsWith("http://")) {
|
|
@@ -134,21 +177,83 @@ var fetchReadContent = async ({
|
|
|
134
177
|
parsedContentRange,
|
|
135
178
|
statusCode: res.status
|
|
136
179
|
});
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
180
|
+
if (controller) {
|
|
181
|
+
controller._internals.signal.addEventListener("abort", () => {
|
|
182
|
+
ownController.abort(new MediaParserAbortError("Aborted by user"));
|
|
183
|
+
}, { once: true });
|
|
184
|
+
}
|
|
140
185
|
if (res.status.toString().startsWith("4") || res.status.toString().startsWith("5")) {
|
|
141
|
-
throw new Error(`Server returned status code ${res.status} for ${
|
|
186
|
+
throw new Error(`Server returned status code ${res.status} for ${resolvedUrl} and range ${requestedRange}`);
|
|
142
187
|
}
|
|
143
188
|
const contentDisposition = res.headers.get("content-disposition");
|
|
144
189
|
const name = contentDisposition?.match(/filename="([^"]+)"/)?.[1];
|
|
145
|
-
const fallbackName = src.toString().split("/").pop();
|
|
146
190
|
const { contentLength, needsContentRange, reader } = await getLengthAndReader({
|
|
147
191
|
canLiveWithoutContentLength,
|
|
148
192
|
res,
|
|
149
193
|
ownController,
|
|
150
194
|
requestedWithoutRange: requestWithoutRange
|
|
151
195
|
});
|
|
196
|
+
const contentType = res.headers.get("content-type");
|
|
197
|
+
return {
|
|
198
|
+
contentLength,
|
|
199
|
+
needsContentRange,
|
|
200
|
+
reader,
|
|
201
|
+
name,
|
|
202
|
+
contentType,
|
|
203
|
+
supportsContentRange
|
|
204
|
+
};
|
|
205
|
+
};
|
|
206
|
+
var cacheKey = ({
|
|
207
|
+
src,
|
|
208
|
+
range
|
|
209
|
+
}) => {
|
|
210
|
+
return `${src}-${JSON.stringify(range)}`;
|
|
211
|
+
};
|
|
212
|
+
var makeFetchRequestOrGetCached = ({
|
|
213
|
+
range,
|
|
214
|
+
src,
|
|
215
|
+
controller,
|
|
216
|
+
logLevel,
|
|
217
|
+
prefetchCache
|
|
218
|
+
}) => {
|
|
219
|
+
const key = cacheKey({ src, range });
|
|
220
|
+
const cached = prefetchCache.get(key);
|
|
221
|
+
if (cached) {
|
|
222
|
+
Log.verbose(logLevel, `Reading from preload cache for ${key}`);
|
|
223
|
+
return cached;
|
|
224
|
+
}
|
|
225
|
+
Log.verbose(logLevel, `Fetching ${key}`);
|
|
226
|
+
const result = makeFetchRequest({ range, src, controller });
|
|
227
|
+
prefetchCache.set(key, result);
|
|
228
|
+
return result;
|
|
229
|
+
};
|
|
230
|
+
var fetchReadContent = async ({
|
|
231
|
+
src,
|
|
232
|
+
range,
|
|
233
|
+
controller,
|
|
234
|
+
logLevel,
|
|
235
|
+
prefetchCache
|
|
236
|
+
}) => {
|
|
237
|
+
if (typeof src !== "string" && src instanceof URL === false) {
|
|
238
|
+
throw new Error("src must be a string when using `fetchReader`");
|
|
239
|
+
}
|
|
240
|
+
const fallbackName = src.toString().split("/").pop();
|
|
241
|
+
const {
|
|
242
|
+
reader,
|
|
243
|
+
contentLength,
|
|
244
|
+
needsContentRange,
|
|
245
|
+
name,
|
|
246
|
+
supportsContentRange,
|
|
247
|
+
contentType
|
|
248
|
+
} = await makeFetchRequestOrGetCached({
|
|
249
|
+
range,
|
|
250
|
+
src,
|
|
251
|
+
controller,
|
|
252
|
+
logLevel,
|
|
253
|
+
prefetchCache
|
|
254
|
+
});
|
|
255
|
+
const key = cacheKey({ src, range });
|
|
256
|
+
prefetchCache.delete(key);
|
|
152
257
|
if (controller) {
|
|
153
258
|
controller._internals.signal.addEventListener("abort", () => {
|
|
154
259
|
reader.reader.cancel().catch(() => {});
|
|
@@ -157,12 +262,33 @@ var fetchReadContent = async ({
|
|
|
157
262
|
return {
|
|
158
263
|
reader,
|
|
159
264
|
contentLength,
|
|
160
|
-
contentType
|
|
265
|
+
contentType,
|
|
161
266
|
name: name ?? fallbackName,
|
|
162
267
|
supportsContentRange,
|
|
163
268
|
needsContentRange
|
|
164
269
|
};
|
|
165
270
|
};
|
|
271
|
+
var fetchPreload = ({
|
|
272
|
+
src,
|
|
273
|
+
range,
|
|
274
|
+
logLevel,
|
|
275
|
+
prefetchCache
|
|
276
|
+
}) => {
|
|
277
|
+
if (typeof src !== "string" && src instanceof URL === false) {
|
|
278
|
+
throw new Error("src must be a string when using `fetchReader`");
|
|
279
|
+
}
|
|
280
|
+
const key = cacheKey({ src, range });
|
|
281
|
+
if (prefetchCache.has(key)) {
|
|
282
|
+
return prefetchCache.get(key);
|
|
283
|
+
}
|
|
284
|
+
makeFetchRequestOrGetCached({
|
|
285
|
+
range,
|
|
286
|
+
src,
|
|
287
|
+
controller: null,
|
|
288
|
+
logLevel,
|
|
289
|
+
prefetchCache
|
|
290
|
+
});
|
|
291
|
+
};
|
|
166
292
|
var fetchReadWholeAsText = async (src) => {
|
|
167
293
|
if (typeof src !== "string" && src instanceof URL === false) {
|
|
168
294
|
throw new Error("src must be a string when using `fetchReader`");
|
|
@@ -183,7 +309,6 @@ var fetchCreateAdjacentFileSource = (relativePath, src) => {
|
|
|
183
309
|
// src/readers/from-node.ts
|
|
184
310
|
import { createReadStream, promises, statSync } from "fs";
|
|
185
311
|
import { dirname, join, relative, sep } from "path";
|
|
186
|
-
import { Readable } from "stream";
|
|
187
312
|
var nodeReadContent = ({ src, range, controller }) => {
|
|
188
313
|
if (typeof src !== "string") {
|
|
189
314
|
throw new Error("src must be a string when using `nodeReader`");
|
|
@@ -198,7 +323,27 @@ var nodeReadContent = ({ src, range, controller }) => {
|
|
|
198
323
|
ownController.abort();
|
|
199
324
|
}, { once: true });
|
|
200
325
|
const stats = statSync(src);
|
|
201
|
-
|
|
326
|
+
let readerCancelled = false;
|
|
327
|
+
const reader = new ReadableStream({
|
|
328
|
+
start(c) {
|
|
329
|
+
if (readerCancelled) {
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
332
|
+
stream.on("data", (chunk) => {
|
|
333
|
+
c.enqueue(chunk);
|
|
334
|
+
});
|
|
335
|
+
stream.on("end", () => {
|
|
336
|
+
c.close();
|
|
337
|
+
});
|
|
338
|
+
stream.on("error", (err) => {
|
|
339
|
+
c.error(err);
|
|
340
|
+
});
|
|
341
|
+
},
|
|
342
|
+
cancel() {
|
|
343
|
+
readerCancelled = true;
|
|
344
|
+
stream.destroy();
|
|
345
|
+
}
|
|
346
|
+
}).getReader();
|
|
202
347
|
if (controller) {
|
|
203
348
|
controller._internals.signal.addEventListener("abort", () => {
|
|
204
349
|
reader.cancel().catch(() => {});
|
|
@@ -314,6 +459,14 @@ var universalReader = {
|
|
|
314
459
|
return fetchCreateAdjacentFileSource(relativePath, src);
|
|
315
460
|
}
|
|
316
461
|
return nodeCreateAdjacentFileSource(relativePath, src);
|
|
462
|
+
},
|
|
463
|
+
preload: ({ src, range, logLevel, prefetchCache }) => {
|
|
464
|
+
if (src instanceof Blob) {
|
|
465
|
+
return;
|
|
466
|
+
}
|
|
467
|
+
if (src.toString().startsWith("http") || src.toString().startsWith("blob:")) {
|
|
468
|
+
return fetchPreload({ range, src, logLevel, prefetchCache });
|
|
469
|
+
}
|
|
317
470
|
}
|
|
318
471
|
};
|
|
319
472
|
export {
|
package/dist/esm/web.mjs
CHANGED
|
@@ -7,6 +7,40 @@ class MediaParserAbortError extends Error {
|
|
|
7
7
|
}
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
+
// src/log.ts
|
|
11
|
+
var logLevels = ["trace", "verbose", "info", "warn", "error"];
|
|
12
|
+
var getNumberForLogLevel = (level) => {
|
|
13
|
+
return logLevels.indexOf(level);
|
|
14
|
+
};
|
|
15
|
+
var isEqualOrBelowLogLevel = (currentLevel, level) => {
|
|
16
|
+
return getNumberForLogLevel(currentLevel) <= getNumberForLogLevel(level);
|
|
17
|
+
};
|
|
18
|
+
var Log = {
|
|
19
|
+
trace: (logLevel, ...args) => {
|
|
20
|
+
if (isEqualOrBelowLogLevel(logLevel, "trace")) {
|
|
21
|
+
return console.log(...args);
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
verbose: (logLevel, ...args) => {
|
|
25
|
+
if (isEqualOrBelowLogLevel(logLevel, "verbose")) {
|
|
26
|
+
return console.log(...args);
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
info: (logLevel, ...args) => {
|
|
30
|
+
if (isEqualOrBelowLogLevel(logLevel, "info")) {
|
|
31
|
+
return console.log(...args);
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
warn: (logLevel, ...args) => {
|
|
35
|
+
if (isEqualOrBelowLogLevel(logLevel, "warn")) {
|
|
36
|
+
return console.warn(...args);
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
error: (...args) => {
|
|
40
|
+
return console.error(...args);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
|
|
10
44
|
// src/readers/fetch/get-body-and-reader.ts
|
|
11
45
|
var getLengthAndReader = async ({
|
|
12
46
|
canLiveWithoutContentLength,
|
|
@@ -19,10 +53,22 @@ var getLengthAndReader = async ({
|
|
|
19
53
|
if (requestedWithoutRange || canLiveWithoutContentLength && contentLength === null) {
|
|
20
54
|
const buffer = await res.arrayBuffer();
|
|
21
55
|
const encoded = new Uint8Array(buffer);
|
|
56
|
+
let streamCancelled = false;
|
|
22
57
|
const stream = new ReadableStream({
|
|
23
58
|
start(controller) {
|
|
24
|
-
|
|
25
|
-
|
|
59
|
+
if (ownController.signal.aborted) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
if (streamCancelled) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
try {
|
|
66
|
+
controller.enqueue(encoded);
|
|
67
|
+
controller.close();
|
|
68
|
+
} catch {}
|
|
69
|
+
},
|
|
70
|
+
cancel() {
|
|
71
|
+
streamCancelled = true;
|
|
26
72
|
}
|
|
27
73
|
});
|
|
28
74
|
return {
|
|
@@ -98,14 +144,11 @@ var validateContentRangeAndDetectIfSupported = ({
|
|
|
98
144
|
}
|
|
99
145
|
return { supportsContentRange: true };
|
|
100
146
|
};
|
|
101
|
-
var
|
|
102
|
-
src,
|
|
147
|
+
var makeFetchRequest = async ({
|
|
103
148
|
range,
|
|
149
|
+
src,
|
|
104
150
|
controller
|
|
105
151
|
}) => {
|
|
106
|
-
if (typeof src !== "string" && src instanceof URL === false) {
|
|
107
|
-
throw new Error("src must be a string when using `fetchReader`");
|
|
108
|
-
}
|
|
109
152
|
const resolvedUrl = resolveUrl(src);
|
|
110
153
|
const resolvedUrlString = resolvedUrl.toString();
|
|
111
154
|
if (!resolvedUrlString.startsWith("https://") && !resolvedUrlString.startsWith("blob:") && !resolvedUrlString.startsWith("http://")) {
|
|
@@ -134,21 +177,83 @@ var fetchReadContent = async ({
|
|
|
134
177
|
parsedContentRange,
|
|
135
178
|
statusCode: res.status
|
|
136
179
|
});
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
180
|
+
if (controller) {
|
|
181
|
+
controller._internals.signal.addEventListener("abort", () => {
|
|
182
|
+
ownController.abort(new MediaParserAbortError("Aborted by user"));
|
|
183
|
+
}, { once: true });
|
|
184
|
+
}
|
|
140
185
|
if (res.status.toString().startsWith("4") || res.status.toString().startsWith("5")) {
|
|
141
|
-
throw new Error(`Server returned status code ${res.status} for ${
|
|
186
|
+
throw new Error(`Server returned status code ${res.status} for ${resolvedUrl} and range ${requestedRange}`);
|
|
142
187
|
}
|
|
143
188
|
const contentDisposition = res.headers.get("content-disposition");
|
|
144
189
|
const name = contentDisposition?.match(/filename="([^"]+)"/)?.[1];
|
|
145
|
-
const fallbackName = src.toString().split("/").pop();
|
|
146
190
|
const { contentLength, needsContentRange, reader } = await getLengthAndReader({
|
|
147
191
|
canLiveWithoutContentLength,
|
|
148
192
|
res,
|
|
149
193
|
ownController,
|
|
150
194
|
requestedWithoutRange: requestWithoutRange
|
|
151
195
|
});
|
|
196
|
+
const contentType = res.headers.get("content-type");
|
|
197
|
+
return {
|
|
198
|
+
contentLength,
|
|
199
|
+
needsContentRange,
|
|
200
|
+
reader,
|
|
201
|
+
name,
|
|
202
|
+
contentType,
|
|
203
|
+
supportsContentRange
|
|
204
|
+
};
|
|
205
|
+
};
|
|
206
|
+
var cacheKey = ({
|
|
207
|
+
src,
|
|
208
|
+
range
|
|
209
|
+
}) => {
|
|
210
|
+
return `${src}-${JSON.stringify(range)}`;
|
|
211
|
+
};
|
|
212
|
+
var makeFetchRequestOrGetCached = ({
|
|
213
|
+
range,
|
|
214
|
+
src,
|
|
215
|
+
controller,
|
|
216
|
+
logLevel,
|
|
217
|
+
prefetchCache
|
|
218
|
+
}) => {
|
|
219
|
+
const key = cacheKey({ src, range });
|
|
220
|
+
const cached = prefetchCache.get(key);
|
|
221
|
+
if (cached) {
|
|
222
|
+
Log.verbose(logLevel, `Reading from preload cache for ${key}`);
|
|
223
|
+
return cached;
|
|
224
|
+
}
|
|
225
|
+
Log.verbose(logLevel, `Fetching ${key}`);
|
|
226
|
+
const result = makeFetchRequest({ range, src, controller });
|
|
227
|
+
prefetchCache.set(key, result);
|
|
228
|
+
return result;
|
|
229
|
+
};
|
|
230
|
+
var fetchReadContent = async ({
|
|
231
|
+
src,
|
|
232
|
+
range,
|
|
233
|
+
controller,
|
|
234
|
+
logLevel,
|
|
235
|
+
prefetchCache
|
|
236
|
+
}) => {
|
|
237
|
+
if (typeof src !== "string" && src instanceof URL === false) {
|
|
238
|
+
throw new Error("src must be a string when using `fetchReader`");
|
|
239
|
+
}
|
|
240
|
+
const fallbackName = src.toString().split("/").pop();
|
|
241
|
+
const {
|
|
242
|
+
reader,
|
|
243
|
+
contentLength,
|
|
244
|
+
needsContentRange,
|
|
245
|
+
name,
|
|
246
|
+
supportsContentRange,
|
|
247
|
+
contentType
|
|
248
|
+
} = await makeFetchRequestOrGetCached({
|
|
249
|
+
range,
|
|
250
|
+
src,
|
|
251
|
+
controller,
|
|
252
|
+
logLevel,
|
|
253
|
+
prefetchCache
|
|
254
|
+
});
|
|
255
|
+
const key = cacheKey({ src, range });
|
|
256
|
+
prefetchCache.delete(key);
|
|
152
257
|
if (controller) {
|
|
153
258
|
controller._internals.signal.addEventListener("abort", () => {
|
|
154
259
|
reader.reader.cancel().catch(() => {});
|
|
@@ -157,12 +262,33 @@ var fetchReadContent = async ({
|
|
|
157
262
|
return {
|
|
158
263
|
reader,
|
|
159
264
|
contentLength,
|
|
160
|
-
contentType
|
|
265
|
+
contentType,
|
|
161
266
|
name: name ?? fallbackName,
|
|
162
267
|
supportsContentRange,
|
|
163
268
|
needsContentRange
|
|
164
269
|
};
|
|
165
270
|
};
|
|
271
|
+
var fetchPreload = ({
|
|
272
|
+
src,
|
|
273
|
+
range,
|
|
274
|
+
logLevel,
|
|
275
|
+
prefetchCache
|
|
276
|
+
}) => {
|
|
277
|
+
if (typeof src !== "string" && src instanceof URL === false) {
|
|
278
|
+
throw new Error("src must be a string when using `fetchReader`");
|
|
279
|
+
}
|
|
280
|
+
const key = cacheKey({ src, range });
|
|
281
|
+
if (prefetchCache.has(key)) {
|
|
282
|
+
return prefetchCache.get(key);
|
|
283
|
+
}
|
|
284
|
+
makeFetchRequestOrGetCached({
|
|
285
|
+
range,
|
|
286
|
+
src,
|
|
287
|
+
controller: null,
|
|
288
|
+
logLevel,
|
|
289
|
+
prefetchCache
|
|
290
|
+
});
|
|
291
|
+
};
|
|
166
292
|
var fetchReadWholeAsText = async (src) => {
|
|
167
293
|
if (typeof src !== "string" && src instanceof URL === false) {
|
|
168
294
|
throw new Error("src must be a string when using `fetchReader`");
|
|
@@ -249,6 +375,12 @@ var webReader = {
|
|
|
249
375
|
return webFileReadWholeAsText(src);
|
|
250
376
|
}
|
|
251
377
|
return fetchReadWholeAsText(src);
|
|
378
|
+
},
|
|
379
|
+
preload: ({ range, src, logLevel, prefetchCache }) => {
|
|
380
|
+
if (src instanceof Blob) {
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
383
|
+
return fetchPreload({ range, src, logLevel, prefetchCache });
|
|
252
384
|
}
|
|
253
385
|
};
|
|
254
386
|
export {
|