@remotion/media-parser 4.0.311 → 4.0.313
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/aac/get-seeking-byte.js +5 -1
- package/dist/containers/flac/get-seeking-byte.d.ts +2 -1
- package/dist/containers/flac/get-seeking-byte.js +1 -1
- package/dist/containers/iso-base-media/base-media-box.d.ts +3 -2
- package/dist/containers/iso-base-media/collect-sample-positions-from-moof-boxes.d.ts +3 -1
- package/dist/containers/iso-base-media/collect-sample-positions-from-moof-boxes.js +2 -1
- package/dist/containers/iso-base-media/find-keyframe-before-time.d.ts +1 -1
- package/dist/containers/iso-base-media/find-keyframe-before-time.js +1 -1
- package/dist/containers/iso-base-media/find-track-to-seek.js +2 -0
- package/dist/containers/iso-base-media/get-keyframes.js +1 -0
- package/dist/containers/iso-base-media/get-sample-positions-from-track.d.ts +3 -1
- package/dist/containers/iso-base-media/get-sample-positions-from-track.js +2 -1
- package/dist/containers/iso-base-media/get-seeking-byte-from-fragmented-mp4.js +4 -1
- package/dist/containers/iso-base-media/get-seeking-byte.js +3 -1
- package/dist/containers/iso-base-media/moov/mvhd.d.ts +30 -0
- package/dist/containers/iso-base-media/moov/mvhd.js +65 -0
- package/dist/containers/iso-base-media/moov/trex.d.ts +16 -0
- package/dist/containers/iso-base-media/moov/trex.js +27 -0
- package/dist/containers/iso-base-media/process-box.js +10 -1
- package/dist/containers/iso-base-media/tkhd.d.ts +1 -1
- package/dist/containers/iso-base-media/traversal.d.ts +4 -1
- package/dist/containers/iso-base-media/traversal.js +18 -1
- package/dist/containers/m3u/get-seeking-byte.js +2 -0
- package/dist/containers/mp3/get-seeking-byte.js +4 -1
- package/dist/containers/riff/get-seeking-byte.js +3 -0
- package/dist/containers/wav/get-seeking-byte.js +1 -0
- package/dist/containers/wav/parse-list.js +4 -3
- package/dist/containers/webm/seek/get-seeking-byte.js +21 -6
- package/dist/controller/media-parser-controller.d.ts +3 -0
- package/dist/controller/media-parser-controller.js +15 -0
- package/dist/esm/index.mjs +327 -156
- package/dist/esm/server-worker.mjs +17 -0
- package/dist/esm/worker-server-entry.mjs +341 -155
- package/dist/esm/worker-web-entry.mjs +341 -155
- package/dist/esm/worker.mjs +28 -0
- package/dist/get-duration.js +1 -0
- package/dist/get-seeking-byte.js +13 -2
- package/dist/index.cjs +54 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.js +1 -1
- package/dist/internal-parse-media.js +25 -0
- package/dist/iterator/buffer-iterator.d.ts +1 -1
- package/dist/iterator/buffer-manager.d.ts +1 -1
- package/dist/iterator/buffer-manager.js +19 -5
- package/dist/parse-media-on-worker-entry.js +17 -0
- package/dist/samples-from-moof.d.ts +3 -1
- package/dist/samples-from-moof.js +15 -12
- package/dist/state/iso-base-media/cached-sample-positions.js +1 -0
- package/dist/state/iso-base-media/lazy-mfra-load.js +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/webcodec-sample-types.d.ts +2 -2
- package/dist/work-on-seek-request.d.ts +22 -0
- package/dist/work-on-seek-request.js +3 -2
- package/dist/worker/forward-controller-to-worker.js +18 -0
- package/dist/worker/worker-types.d.ts +13 -2
- package/package.json +3 -3
package/dist/esm/worker.mjs
CHANGED
|
@@ -243,6 +243,14 @@ var parseMediaOnWorkerImplementation = async ({ controller, reader, ...params },
|
|
|
243
243
|
seekingHintPromises.push(prom);
|
|
244
244
|
return prom.promise;
|
|
245
245
|
});
|
|
246
|
+
const simulateSeekPromises = {};
|
|
247
|
+
controller?._internals.attachSimulateSeekResolution((seek) => {
|
|
248
|
+
const prom = withResolvers();
|
|
249
|
+
const nonce = String(Math.random());
|
|
250
|
+
post(worker, { type: "request-simulate-seek", payload: seek, nonce });
|
|
251
|
+
simulateSeekPromises[nonce] = prom;
|
|
252
|
+
return prom.promise;
|
|
253
|
+
});
|
|
246
254
|
const callbacks = {};
|
|
247
255
|
function onMessage(message) {
|
|
248
256
|
const data = message.data;
|
|
@@ -462,6 +470,15 @@ var parseMediaOnWorkerImplementation = async ({ controller, reader, ...params },
|
|
|
462
470
|
firstPromise.resolve(data.payload);
|
|
463
471
|
return;
|
|
464
472
|
}
|
|
473
|
+
if (data.type === "response-simulate-seek") {
|
|
474
|
+
const prom = simulateSeekPromises[data.nonce];
|
|
475
|
+
if (!prom) {
|
|
476
|
+
throw new Error("No simulate seek promise found");
|
|
477
|
+
}
|
|
478
|
+
prom.resolve(data.payload);
|
|
479
|
+
delete simulateSeekPromises[data.nonce];
|
|
480
|
+
return;
|
|
481
|
+
}
|
|
465
482
|
throw new Error(`Unknown response type: ${JSON.stringify(data)}`);
|
|
466
483
|
}
|
|
467
484
|
worker.addEventListener("message", onMessage);
|
|
@@ -489,6 +506,17 @@ var parseMediaOnWebWorker = (params) => {
|
|
|
489
506
|
if (typeof Worker === "undefined") {
|
|
490
507
|
throw new Error('"Worker" is not available. Cannot call parseMediaOnWebWorker()');
|
|
491
508
|
}
|
|
509
|
+
if (import.meta.url.includes(".vite/deps")) {
|
|
510
|
+
const err = [
|
|
511
|
+
"Detected Vite pre-bundling, which will break the worker.",
|
|
512
|
+
"Please add the following to your vite.config.js:",
|
|
513
|
+
" optimizeDeps: {",
|
|
514
|
+
' exclude: ["@remotion/media-parser/worker"]',
|
|
515
|
+
" }"
|
|
516
|
+
].join(`
|
|
517
|
+
`);
|
|
518
|
+
throw new Error(err);
|
|
519
|
+
}
|
|
492
520
|
const worker = new Worker(new URL("./worker-web-entry.mjs", import.meta.url));
|
|
493
521
|
return parseMediaOnWorkerImplementation(params, worker, "parseMediaOnWebWorker");
|
|
494
522
|
};
|
package/dist/get-duration.js
CHANGED
|
@@ -82,6 +82,7 @@ const getDurationFromIsoBaseMedia = (parserState) => {
|
|
|
82
82
|
trakBox,
|
|
83
83
|
moofBoxes,
|
|
84
84
|
moofComplete: (0, are_samples_complete_1.areSamplesComplete)({ moofBoxes, tfraBoxes }),
|
|
85
|
+
trexBoxes: (0, traversal_1.getTrexBoxes)(moovBox),
|
|
85
86
|
});
|
|
86
87
|
if (!isComplete) {
|
|
87
88
|
return null;
|
package/dist/get-seeking-byte.js
CHANGED
|
@@ -7,6 +7,7 @@ const get_seeking_byte_3 = require("./containers/iso-base-media/get-seeking-byte
|
|
|
7
7
|
const get_seeking_byte_4 = require("./containers/m3u/get-seeking-byte");
|
|
8
8
|
const get_seeking_byte_5 = require("./containers/mp3/get-seeking-byte");
|
|
9
9
|
const get_seeking_byte_6 = require("./containers/riff/get-seeking-byte");
|
|
10
|
+
const handle_avc_packet_1 = require("./containers/transport-stream/handle-avc-packet");
|
|
10
11
|
const get_seeking_byte_7 = require("./containers/wav/get-seeking-byte");
|
|
11
12
|
const get_seeking_byte_8 = require("./containers/webm/seek/get-seeking-byte");
|
|
12
13
|
const observed_pes_header_1 = require("./state/transport-stream/observed-pes-header");
|
|
@@ -46,7 +47,8 @@ const getSeekingByte = ({ info, time, logLevel, currentPosition, isoState, trans
|
|
|
46
47
|
if (byte) {
|
|
47
48
|
return Promise.resolve({
|
|
48
49
|
type: 'do-seek',
|
|
49
|
-
byte,
|
|
50
|
+
byte: byte.offset,
|
|
51
|
+
timeInSeconds: byte.timeInSeconds,
|
|
50
52
|
});
|
|
51
53
|
}
|
|
52
54
|
return Promise.resolve({
|
|
@@ -59,11 +61,20 @@ const getSeekingByte = ({ info, time, logLevel, currentPosition, isoState, trans
|
|
|
59
61
|
timeInSeconds: time,
|
|
60
62
|
ptsStartOffset: info.ptsStartOffset,
|
|
61
63
|
});
|
|
62
|
-
|
|
64
|
+
if (!lastKeyframeBeforeTimeInSeconds) {
|
|
65
|
+
transportStream.resetBeforeSeek();
|
|
66
|
+
return Promise.resolve({
|
|
67
|
+
type: 'do-seek',
|
|
68
|
+
byte: 0,
|
|
69
|
+
timeInSeconds: 0,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
const byte = lastKeyframeBeforeTimeInSeconds.offset;
|
|
63
73
|
transportStream.resetBeforeSeek();
|
|
64
74
|
return Promise.resolve({
|
|
65
75
|
type: 'do-seek',
|
|
66
76
|
byte,
|
|
77
|
+
timeInSeconds: Math.min(lastKeyframeBeforeTimeInSeconds.pts, (_a = lastKeyframeBeforeTimeInSeconds.dts) !== null && _a !== void 0 ? _a : Infinity) / handle_avc_packet_1.MPEG_TIMESCALE,
|
|
67
78
|
});
|
|
68
79
|
}
|
|
69
80
|
if (info.type === 'riff-seeking-hints') {
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WEBCODECS_TIMESCALE = exports.VERSION = exports.mediaParserController = exports.defaultSelectM3uStreamFn = exports.defaultSelectM3uAssociatedPlaylists = exports.MediaParserInternals = exports.downloadAndParseMedia = exports.MediaParserAbortError = exports.IsAPdfError = exports.IsAnUnsupportedFileTypeError = exports.IsAnImageError = exports.hasBeenAborted = exports.parseMedia = void 0;
|
|
4
|
+
const aac_codecprivate_1 = require("./aac-codecprivate");
|
|
5
|
+
const ftyp_1 = require("./containers/iso-base-media/ftyp");
|
|
6
|
+
const mvhd_1 = require("./containers/iso-base-media/mvhd");
|
|
7
|
+
const samples_1 = require("./containers/iso-base-media/stsd/samples");
|
|
8
|
+
const stsd_1 = require("./containers/iso-base-media/stsd/stsd");
|
|
9
|
+
const tkhd_1 = require("./containers/iso-base-media/tkhd");
|
|
10
|
+
const parse_ebml_1 = require("./containers/webm/parse-ebml");
|
|
11
|
+
const all_segments_1 = require("./containers/webm/segments/all-segments");
|
|
12
|
+
const internal_parse_media_1 = require("./internal-parse-media");
|
|
13
|
+
const buffer_iterator_1 = require("./iterator/buffer-iterator");
|
|
14
|
+
const log_1 = require("./log");
|
|
15
|
+
const need_samples_for_fields_1 = require("./state/need-samples-for-fields");
|
|
16
|
+
const parser_state_1 = require("./state/parser-state");
|
|
17
|
+
var parse_media_1 = require("./parse-media");
|
|
18
|
+
Object.defineProperty(exports, "parseMedia", { enumerable: true, get: function () { return parse_media_1.parseMedia; } });
|
|
19
|
+
var errors_1 = require("./errors");
|
|
20
|
+
Object.defineProperty(exports, "hasBeenAborted", { enumerable: true, get: function () { return errors_1.hasBeenAborted; } });
|
|
21
|
+
Object.defineProperty(exports, "IsAnImageError", { enumerable: true, get: function () { return errors_1.IsAnImageError; } });
|
|
22
|
+
Object.defineProperty(exports, "IsAnUnsupportedFileTypeError", { enumerable: true, get: function () { return errors_1.IsAnUnsupportedFileTypeError; } });
|
|
23
|
+
Object.defineProperty(exports, "IsAPdfError", { enumerable: true, get: function () { return errors_1.IsAPdfError; } });
|
|
24
|
+
Object.defineProperty(exports, "MediaParserAbortError", { enumerable: true, get: function () { return errors_1.MediaParserAbortError; } });
|
|
25
|
+
var download_and_parse_media_1 = require("./download-and-parse-media");
|
|
26
|
+
Object.defineProperty(exports, "downloadAndParseMedia", { enumerable: true, get: function () { return download_and_parse_media_1.downloadAndParseMedia; } });
|
|
27
|
+
/**
|
|
28
|
+
* @deprecated Dont use these yet.
|
|
29
|
+
*/
|
|
30
|
+
exports.MediaParserInternals = {
|
|
31
|
+
Log: log_1.Log,
|
|
32
|
+
createAacCodecPrivate: aac_codecprivate_1.createAacCodecPrivate,
|
|
33
|
+
matroskaElements: all_segments_1.matroskaElements,
|
|
34
|
+
ebmlMap: all_segments_1.ebmlMap,
|
|
35
|
+
parseTkhd: tkhd_1.parseTkhd,
|
|
36
|
+
getArrayBufferIterator: buffer_iterator_1.getArrayBufferIterator,
|
|
37
|
+
parseStsd: stsd_1.parseStsd,
|
|
38
|
+
makeParserState: parser_state_1.makeParserState,
|
|
39
|
+
processSample: samples_1.processIsoFormatBox,
|
|
40
|
+
parseFtyp: ftyp_1.parseFtyp,
|
|
41
|
+
parseEbml: parse_ebml_1.parseEbml,
|
|
42
|
+
parseMvhd: mvhd_1.parseMvhd,
|
|
43
|
+
internalParseMedia: internal_parse_media_1.internalParseMedia,
|
|
44
|
+
fieldsNeedSamplesMap: need_samples_for_fields_1.fieldsNeedSamplesMap,
|
|
45
|
+
};
|
|
46
|
+
var select_stream_1 = require("./containers/m3u/select-stream");
|
|
47
|
+
Object.defineProperty(exports, "defaultSelectM3uAssociatedPlaylists", { enumerable: true, get: function () { return select_stream_1.defaultSelectM3uAssociatedPlaylists; } });
|
|
48
|
+
Object.defineProperty(exports, "defaultSelectM3uStreamFn", { enumerable: true, get: function () { return select_stream_1.defaultSelectM3uStreamFn; } });
|
|
49
|
+
var media_parser_controller_1 = require("./controller/media-parser-controller");
|
|
50
|
+
Object.defineProperty(exports, "mediaParserController", { enumerable: true, get: function () { return media_parser_controller_1.mediaParserController; } });
|
|
51
|
+
var version_1 = require("./version");
|
|
52
|
+
Object.defineProperty(exports, "VERSION", { enumerable: true, get: function () { return version_1.VERSION; } });
|
|
53
|
+
var webcodecs_timescale_1 = require("./webcodecs-timescale");
|
|
54
|
+
Object.defineProperty(exports, "WEBCODECS_TIMESCALE", { enumerable: true, get: function () { return webcodecs_timescale_1.WEBCODECS_TIMESCALE; } });
|
package/dist/index.d.ts
CHANGED
|
@@ -669,7 +669,7 @@ export declare const MediaParserInternals: {
|
|
|
669
669
|
offset: number;
|
|
670
670
|
size: number;
|
|
671
671
|
}) => import("./containers/iso-base-media/tkhd").TkhdBox;
|
|
672
|
-
getArrayBufferIterator: (initialData: Uint8Array, maxBytes: number
|
|
672
|
+
getArrayBufferIterator: (initialData: Uint8Array, maxBytes: number) => {
|
|
673
673
|
startReadingBits: () => void;
|
|
674
674
|
stopReadingBits: () => void;
|
|
675
675
|
skipTo: (offset: number) => void;
|
|
@@ -1265,7 +1265,7 @@ export declare const MediaParserInternals: {
|
|
|
1265
1265
|
iterator: import("./iterator/buffer-iterator").BufferIterator;
|
|
1266
1266
|
offset: number;
|
|
1267
1267
|
size: number;
|
|
1268
|
-
}) => import("./containers/iso-base-media/mvhd").MvhdBox;
|
|
1268
|
+
}) => import("./containers/iso-base-media/moov/mvhd").MvhdBox;
|
|
1269
1269
|
internalParseMedia: import("./options").InternalParseMedia;
|
|
1270
1270
|
fieldsNeedSamplesMap: Record<keyof import("./fields").AllOptions<import("./fields").ParseMediaFields>, boolean>;
|
|
1271
1271
|
};
|
|
@@ -1275,6 +1275,7 @@ export { defaultSelectM3uAssociatedPlaylists, defaultSelectM3uStreamFn, SelectM3
|
|
|
1275
1275
|
export { mediaParserController, MediaParserController, } from './controller/media-parser-controller';
|
|
1276
1276
|
export { VERSION } from './version';
|
|
1277
1277
|
export { WEBCODECS_TIMESCALE } from './webcodecs-timescale';
|
|
1278
|
+
export type { SeekResolution } from './work-on-seek-request';
|
|
1278
1279
|
export type { MediaParserSampleAspectRatio } from './get-tracks';
|
|
1279
1280
|
/**
|
|
1280
1281
|
* @deprecated Dont use these yet.
|
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.WEBCODECS_TIMESCALE = exports.VERSION = exports.mediaParserController = exports.defaultSelectM3uStreamFn = exports.defaultSelectM3uAssociatedPlaylists = exports.MediaParserInternals = exports.downloadAndParseMedia = exports.MediaParserAbortError = exports.IsAPdfError = exports.IsAnUnsupportedFileTypeError = exports.IsAnImageError = exports.hasBeenAborted = exports.parseMedia = void 0;
|
|
4
4
|
const aac_codecprivate_1 = require("./aac-codecprivate");
|
|
5
5
|
const ftyp_1 = require("./containers/iso-base-media/ftyp");
|
|
6
|
-
const mvhd_1 = require("./containers/iso-base-media/mvhd");
|
|
6
|
+
const mvhd_1 = require("./containers/iso-base-media/moov/mvhd");
|
|
7
7
|
const samples_1 = require("./containers/iso-base-media/stsd/samples");
|
|
8
8
|
const stsd_1 = require("./containers/iso-base-media/stsd/stsd");
|
|
9
9
|
const tkhd_1 = require("./containers/iso-base-media/tkhd");
|
|
@@ -11,6 +11,7 @@ const remotion_license_acknowledge_1 = require("./remotion-license-acknowledge")
|
|
|
11
11
|
const set_seeking_hints_1 = require("./set-seeking-hints");
|
|
12
12
|
const parser_state_1 = require("./state/parser-state");
|
|
13
13
|
const throttled_progress_1 = require("./throttled-progress");
|
|
14
|
+
const work_on_seek_request_1 = require("./work-on-seek-request");
|
|
14
15
|
const internalParseMedia = async function ({ src, fields: _fieldsInReturnValue, reader: readerInterface, onAudioTrack, onVideoTrack, controller = (0, media_parser_controller_1.mediaParserController)(), logLevel, onParseProgress: onParseProgressDoNotCallDirectly, progressIntervalInMs, mode, onDiscardedData, onError, acknowledgeRemotionLicense, apiName, selectM3uStream: selectM3uStreamFn, selectM3uAssociatedPlaylists: selectM3uAssociatedPlaylistsFn, m3uPlaylistContext, makeSamplesStartAtZero, seekingHints, ...more }) {
|
|
15
16
|
var _a;
|
|
16
17
|
if (!src) {
|
|
@@ -82,6 +83,30 @@ const internalParseMedia = async function ({ src, fields: _fieldsInReturnValue,
|
|
|
82
83
|
contentLength: state.contentLength,
|
|
83
84
|
aacState: state.aac,
|
|
84
85
|
})));
|
|
86
|
+
controller._internals.attachSimulateSeekResolution((seek) => {
|
|
87
|
+
const { aacState, avcState, flacState, isoState, iterator, keyframes, m3uState, mediaSection, mp3State, riffState, samplesObserved, structureState, tracksState, transportStream, webmState, } = (0, work_on_seek_request_1.getWorkOnSeekRequestOptions)(state);
|
|
88
|
+
return (0, work_on_seek_request_1.turnSeekIntoByte)({
|
|
89
|
+
aacState,
|
|
90
|
+
seek,
|
|
91
|
+
avcState,
|
|
92
|
+
contentLength,
|
|
93
|
+
flacState,
|
|
94
|
+
isoState,
|
|
95
|
+
iterator,
|
|
96
|
+
keyframes,
|
|
97
|
+
logLevel,
|
|
98
|
+
m3uPlaylistContext,
|
|
99
|
+
m3uState,
|
|
100
|
+
mediaSectionState: mediaSection,
|
|
101
|
+
mp3State,
|
|
102
|
+
riffState,
|
|
103
|
+
samplesObserved,
|
|
104
|
+
structureState,
|
|
105
|
+
tracksState,
|
|
106
|
+
transportStream,
|
|
107
|
+
webmState,
|
|
108
|
+
});
|
|
109
|
+
});
|
|
85
110
|
if (!hasAudioTrackHandlers &&
|
|
86
111
|
!hasVideoTrackHandlers &&
|
|
87
112
|
Object.values(state.fields).every((v) => !v) &&
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const getArrayBufferIterator: (initialData: Uint8Array, maxBytes: number
|
|
1
|
+
export declare const getArrayBufferIterator: (initialData: Uint8Array, maxBytes: number) => {
|
|
2
2
|
startReadingBits: () => void;
|
|
3
3
|
stopReadingBits: () => void;
|
|
4
4
|
skipTo: (offset: number) => void;
|
|
@@ -2,7 +2,7 @@ import type { ParseMediaMode } from '../options';
|
|
|
2
2
|
import type { OffsetCounter } from './offset-counter';
|
|
3
3
|
export declare const bufferManager: ({ initialData, maxBytes, counter, }: {
|
|
4
4
|
initialData: Uint8Array;
|
|
5
|
-
maxBytes: number
|
|
5
|
+
maxBytes: number;
|
|
6
6
|
counter: OffsetCounter;
|
|
7
7
|
}) => {
|
|
8
8
|
view: DataView<ArrayBuffer>;
|
|
@@ -1,12 +1,26 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.bufferManager = void 0;
|
|
4
|
+
const makeBufferWithMaxBytes = (initialData, maxBytes) => {
|
|
5
|
+
const maxByteLength = Math.min(maxBytes, 2 ** 31);
|
|
6
|
+
try {
|
|
7
|
+
const buf = new ArrayBuffer(initialData.byteLength, {
|
|
8
|
+
maxByteLength,
|
|
9
|
+
});
|
|
10
|
+
return buf;
|
|
11
|
+
}
|
|
12
|
+
catch (e) {
|
|
13
|
+
// Cloudflare Workers have a limit of 128MB max array buffer size
|
|
14
|
+
if (e instanceof RangeError && maxBytes > 2 ** 27) {
|
|
15
|
+
return new ArrayBuffer(initialData.byteLength, {
|
|
16
|
+
maxByteLength: 2 ** 27,
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
throw e;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
4
22
|
const bufferManager = ({ initialData, maxBytes, counter, }) => {
|
|
5
|
-
const buf =
|
|
6
|
-
maxByteLength: maxBytes === null
|
|
7
|
-
? initialData.byteLength
|
|
8
|
-
: Math.min(maxBytes, 2 ** 31),
|
|
9
|
-
});
|
|
23
|
+
const buf = makeBufferWithMaxBytes(initialData, maxBytes);
|
|
10
24
|
if (!buf.resize) {
|
|
11
25
|
throw new Error('`ArrayBuffer.resize` is not supported in this Runtime. On the server: Use at least Node.js 20 or Bun. In the browser: Chrome 111, Edge 111, Safari 16.4, Firefox 128, Opera 111');
|
|
12
26
|
}
|
|
@@ -84,6 +84,14 @@ const parseMediaOnWorkerImplementation = async ({ controller, reader, ...params
|
|
|
84
84
|
seekingHintPromises.push(prom);
|
|
85
85
|
return prom.promise;
|
|
86
86
|
});
|
|
87
|
+
const simulateSeekPromises = {};
|
|
88
|
+
controller === null || controller === void 0 ? void 0 : controller._internals.attachSimulateSeekResolution((seek) => {
|
|
89
|
+
const prom = (0, with_resolvers_1.withResolvers)();
|
|
90
|
+
const nonce = String(Math.random());
|
|
91
|
+
post(worker, { type: 'request-simulate-seek', payload: seek, nonce });
|
|
92
|
+
simulateSeekPromises[nonce] = prom;
|
|
93
|
+
return prom.promise;
|
|
94
|
+
});
|
|
87
95
|
const callbacks = {};
|
|
88
96
|
function onMessage(message) {
|
|
89
97
|
const data = message.data;
|
|
@@ -313,6 +321,15 @@ const parseMediaOnWorkerImplementation = async ({ controller, reader, ...params
|
|
|
313
321
|
firstPromise.resolve(data.payload);
|
|
314
322
|
return;
|
|
315
323
|
}
|
|
324
|
+
if (data.type === 'response-simulate-seek') {
|
|
325
|
+
const prom = simulateSeekPromises[data.nonce];
|
|
326
|
+
if (!prom) {
|
|
327
|
+
throw new Error('No simulate seek promise found');
|
|
328
|
+
}
|
|
329
|
+
prom.resolve(data.payload);
|
|
330
|
+
delete simulateSeekPromises[data.nonce];
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
316
333
|
throw new Error(`Unknown response type: ${JSON.stringify(data)}`);
|
|
317
334
|
}
|
|
318
335
|
worker.addEventListener('message', onMessage);
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import type { TrexBox } from './containers/iso-base-media/moov/trex';
|
|
1
2
|
import type { SamplePosition } from './get-sample-positions';
|
|
2
3
|
import type { MoofBox } from './state/iso-base-media/precomputed-moof';
|
|
3
|
-
export declare const getSamplesFromMoof: ({ moofBox, trackId, }: {
|
|
4
|
+
export declare const getSamplesFromMoof: ({ moofBox, trackId, trexBoxes, }: {
|
|
4
5
|
moofBox: MoofBox;
|
|
5
6
|
trackId: number;
|
|
7
|
+
trexBoxes: TrexBox[];
|
|
6
8
|
}) => SamplePosition[];
|
|
@@ -2,15 +2,18 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getSamplesFromMoof = void 0;
|
|
4
4
|
const traversal_1 = require("./containers/iso-base-media/traversal");
|
|
5
|
-
const getSamplesFromTraf = (trafSegment, moofOffset) => {
|
|
6
|
-
var _a, _b, _c, _d, _e, _f
|
|
5
|
+
const getSamplesFromTraf = (trafSegment, moofOffset, trexBoxes) => {
|
|
6
|
+
var _a, _b, _c, _d, _e, _f;
|
|
7
7
|
if (trafSegment.type !== 'regular-box' || trafSegment.boxType !== 'traf') {
|
|
8
8
|
throw new Error('Expected traf-box');
|
|
9
9
|
}
|
|
10
10
|
const tfhdBox = (0, traversal_1.getTfhdBox)(trafSegment);
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
const
|
|
11
|
+
const trexBox = (_a = trexBoxes.find((t) => t.trackId === (tfhdBox === null || tfhdBox === void 0 ? void 0 : tfhdBox.trackId))) !== null && _a !== void 0 ? _a : null;
|
|
12
|
+
// intentional || instead of ?? to allow for 0, doesn't make sense for duration or size
|
|
13
|
+
const defaultTrackSampleDuration = (tfhdBox === null || tfhdBox === void 0 ? void 0 : tfhdBox.defaultSampleDuration) || (trexBox === null || trexBox === void 0 ? void 0 : trexBox.defaultSampleDuration) || null;
|
|
14
|
+
const defaultTrackSampleSize = (tfhdBox === null || tfhdBox === void 0 ? void 0 : tfhdBox.defaultSampleSize) || (trexBox === null || trexBox === void 0 ? void 0 : trexBox.defaultSampleSize) || null;
|
|
15
|
+
// but flags may just be 0 :)
|
|
16
|
+
const defaultTrackSampleFlags = (_c = (_b = tfhdBox === null || tfhdBox === void 0 ? void 0 : tfhdBox.defaultSampleFlags) !== null && _b !== void 0 ? _b : trexBox === null || trexBox === void 0 ? void 0 : trexBox.defaultSampleFlags) !== null && _c !== void 0 ? _c : null;
|
|
14
17
|
const tfdtBox = (0, traversal_1.getTfdtBox)(trafSegment);
|
|
15
18
|
const trunBoxes = (0, traversal_1.getTrunBoxes)(trafSegment);
|
|
16
19
|
let time = 0;
|
|
@@ -25,11 +28,11 @@ const getSamplesFromTraf = (trafSegment, moofOffset) => {
|
|
|
25
28
|
}
|
|
26
29
|
for (const sample of trunBox.samples) {
|
|
27
30
|
i++;
|
|
28
|
-
const duration =
|
|
31
|
+
const duration = sample.sampleDuration || defaultTrackSampleDuration;
|
|
29
32
|
if (duration === null) {
|
|
30
33
|
throw new Error('Expected duration');
|
|
31
34
|
}
|
|
32
|
-
const size = (
|
|
35
|
+
const size = (_d = sample.sampleSize) !== null && _d !== void 0 ? _d : defaultTrackSampleSize;
|
|
33
36
|
if (size === null) {
|
|
34
37
|
throw new Error('Expected size');
|
|
35
38
|
}
|
|
@@ -38,16 +41,16 @@ const getSamplesFromTraf = (trafSegment, moofOffset) => {
|
|
|
38
41
|
? sample.sampleFlags
|
|
39
42
|
: isFirstSample && trunBox.firstSampleFlags !== null
|
|
40
43
|
? trunBox.firstSampleFlags
|
|
41
|
-
:
|
|
44
|
+
: defaultTrackSampleFlags;
|
|
42
45
|
if (sampleFlags === null) {
|
|
43
46
|
throw new Error('Expected sample flags');
|
|
44
47
|
}
|
|
45
48
|
const keyframe = !((sampleFlags >> 16) & 0x1);
|
|
46
|
-
const dts = time + ((
|
|
49
|
+
const dts = time + ((_e = tfdtBox === null || tfdtBox === void 0 ? void 0 : tfdtBox.baseMediaDecodeTime) !== null && _e !== void 0 ? _e : 0);
|
|
47
50
|
const samplePosition = {
|
|
48
51
|
offset: offset + (moofOffset !== null && moofOffset !== void 0 ? moofOffset : 0) + (dataOffset !== null && dataOffset !== void 0 ? dataOffset : 0),
|
|
49
52
|
decodingTimestamp: dts,
|
|
50
|
-
timestamp: dts + ((
|
|
53
|
+
timestamp: dts + ((_f = sample.sampleCompositionTimeOffset) !== null && _f !== void 0 ? _f : 0),
|
|
51
54
|
duration,
|
|
52
55
|
isKeyframe: keyframe,
|
|
53
56
|
size,
|
|
@@ -62,13 +65,13 @@ const getSamplesFromTraf = (trafSegment, moofOffset) => {
|
|
|
62
65
|
}
|
|
63
66
|
return samples;
|
|
64
67
|
};
|
|
65
|
-
const getSamplesFromMoof = ({ moofBox, trackId, }) => {
|
|
68
|
+
const getSamplesFromMoof = ({ moofBox, trackId, trexBoxes, }) => {
|
|
66
69
|
const mapped = moofBox.trafBoxes.map((traf) => {
|
|
67
70
|
const tfhdBox = (0, traversal_1.getTfhdBox)(traf);
|
|
68
71
|
if (!tfhdBox || tfhdBox.trackId !== trackId) {
|
|
69
72
|
return [];
|
|
70
73
|
}
|
|
71
|
-
return getSamplesFromTraf(traf, moofBox.offset);
|
|
74
|
+
return getSamplesFromTraf(traf, moofBox.offset, trexBoxes);
|
|
72
75
|
});
|
|
73
76
|
return mapped.flat(1);
|
|
74
77
|
};
|
|
@@ -37,6 +37,7 @@ const calculateFlatSamples = ({ state, mediaSectionStart, }) => {
|
|
|
37
37
|
trakBox,
|
|
38
38
|
moofBoxes: relevantMoofBox ? [relevantMoofBox] : [],
|
|
39
39
|
moofComplete,
|
|
40
|
+
trexBoxes: (0, traversal_1.getTrexBoxes)(moov),
|
|
40
41
|
});
|
|
41
42
|
return samplePositions.map((samplePosition) => {
|
|
42
43
|
return {
|
|
@@ -19,7 +19,7 @@ const lazyMfraLoad = ({ contentLength, controller, readerInterface, src, logLeve
|
|
|
19
19
|
logLevel,
|
|
20
20
|
prefetchCache,
|
|
21
21
|
}).then((boxes) => {
|
|
22
|
-
log_1.Log.verbose(logLevel, 'Lazily found mfra atom.');
|
|
22
|
+
log_1.Log.verbose(logLevel, boxes ? 'Lazily found mfra atom.' : 'No mfra atom found.');
|
|
23
23
|
result = boxes;
|
|
24
24
|
return boxes;
|
|
25
25
|
});
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const VERSION = "4.0.
|
|
1
|
+
export declare const VERSION = "4.0.313";
|
package/dist/version.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { MediaParserAudioTrack, MediaParserVideoTrack } from './get-tracks';
|
|
2
2
|
import type { MediaParserContainer } from './options';
|
|
3
|
-
export type MediaParserOnAudioSample = (sample: MediaParserAudioSample) => void | Promise<void> |
|
|
4
|
-
export type MediaParserOnVideoSample = (sample: MediaParserVideoSample) => void | Promise<void> |
|
|
3
|
+
export type MediaParserOnAudioSample = (sample: MediaParserAudioSample) => void | Promise<OnTrackDoneCallback | void> | Promise<void> | OnTrackDoneCallback;
|
|
4
|
+
export type MediaParserOnVideoSample = (sample: MediaParserVideoSample) => void | Promise<OnTrackDoneCallback | void> | Promise<void> | OnTrackDoneCallback;
|
|
5
5
|
export type OnTrackDoneCallback = () => void | Promise<void>;
|
|
6
6
|
export type MediaParserOnAudioTrackParams = {
|
|
7
7
|
track: MediaParserAudioTrack;
|
|
@@ -22,6 +22,27 @@ import type { SeekInfiniteLoop } from './state/seek-infinite-loop';
|
|
|
22
22
|
import type { StructureState } from './state/structure';
|
|
23
23
|
import type { TransportStreamState } from './state/transport-stream/transport-stream';
|
|
24
24
|
import { type MediaSectionState } from './state/video-section';
|
|
25
|
+
export declare const turnSeekIntoByte: ({ seek, mediaSectionState, logLevel, iterator, structureState, m3uPlaylistContext, isoState, transportStream, tracksState, webmState, keyframes, flacState, samplesObserved, riffState, mp3State, contentLength, aacState, m3uState, avcState, }: {
|
|
26
|
+
seek: number;
|
|
27
|
+
mediaSectionState: MediaSectionState;
|
|
28
|
+
logLevel: MediaParserLogLevel;
|
|
29
|
+
iterator: BufferIterator;
|
|
30
|
+
structureState: StructureState;
|
|
31
|
+
m3uPlaylistContext: M3uPlaylistContext | null;
|
|
32
|
+
isoState: IsoBaseMediaState;
|
|
33
|
+
transportStream: TransportStreamState;
|
|
34
|
+
tracksState: TracksState;
|
|
35
|
+
webmState: WebmState;
|
|
36
|
+
keyframes: KeyframesState;
|
|
37
|
+
flacState: FlacState;
|
|
38
|
+
samplesObserved: SamplesObservedState;
|
|
39
|
+
riffState: RiffState;
|
|
40
|
+
mp3State: Mp3State;
|
|
41
|
+
aacState: AacState;
|
|
42
|
+
contentLength: number;
|
|
43
|
+
m3uState: M3uState;
|
|
44
|
+
avcState: AvcState;
|
|
45
|
+
}) => Promise<SeekResolution>;
|
|
25
46
|
export type WorkOnSeekRequestOptions = {
|
|
26
47
|
logLevel: MediaParserLogLevel;
|
|
27
48
|
controller: MediaParserController;
|
|
@@ -63,4 +84,5 @@ export type SeekResolution = {
|
|
|
63
84
|
} | {
|
|
64
85
|
type: 'do-seek';
|
|
65
86
|
byte: number;
|
|
87
|
+
timeInSeconds: number;
|
|
66
88
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.workOnSeekRequest = exports.getWorkOnSeekRequestOptions = void 0;
|
|
3
|
+
exports.workOnSeekRequest = exports.getWorkOnSeekRequestOptions = exports.turnSeekIntoByte = void 0;
|
|
4
4
|
const get_seeking_byte_1 = require("./get-seeking-byte");
|
|
5
5
|
const get_seeking_hints_1 = require("./get-seeking-hints");
|
|
6
6
|
const log_1 = require("./log");
|
|
@@ -55,6 +55,7 @@ const turnSeekIntoByte = async ({ seek, mediaSectionState, logLevel, iterator, s
|
|
|
55
55
|
});
|
|
56
56
|
return seekingByte;
|
|
57
57
|
};
|
|
58
|
+
exports.turnSeekIntoByte = turnSeekIntoByte;
|
|
58
59
|
const getWorkOnSeekRequestOptions = (state) => {
|
|
59
60
|
return {
|
|
60
61
|
logLevel: state.logLevel,
|
|
@@ -94,7 +95,7 @@ const workOnSeekRequest = async (options) => {
|
|
|
94
95
|
return;
|
|
95
96
|
}
|
|
96
97
|
log_1.Log.trace(logLevel, `Has seek request for ${src}: ${JSON.stringify(seek)}`);
|
|
97
|
-
const resolution = await turnSeekIntoByte({
|
|
98
|
+
const resolution = await (0, exports.turnSeekIntoByte)({
|
|
98
99
|
seek,
|
|
99
100
|
mediaSectionState: mediaSection,
|
|
100
101
|
logLevel,
|
|
@@ -29,6 +29,24 @@ const forwardMediaParserControllerToWorker = (controller) => {
|
|
|
29
29
|
});
|
|
30
30
|
return;
|
|
31
31
|
}
|
|
32
|
+
if (message.type === 'request-simulate-seek') {
|
|
33
|
+
controller
|
|
34
|
+
.simulateSeek(message.payload)
|
|
35
|
+
.then((resolution) => {
|
|
36
|
+
postMessage({
|
|
37
|
+
type: 'response-simulate-seek',
|
|
38
|
+
nonce: message.nonce,
|
|
39
|
+
payload: resolution,
|
|
40
|
+
});
|
|
41
|
+
})
|
|
42
|
+
.catch((err) => {
|
|
43
|
+
postMessage({
|
|
44
|
+
type: 'response-error',
|
|
45
|
+
payload: err,
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
32
50
|
if (message.type === 'request-resume') {
|
|
33
51
|
controller.resume();
|
|
34
52
|
return;
|
|
@@ -12,6 +12,7 @@ import type { SeekingHints } from '../seeking-hints';
|
|
|
12
12
|
import type { MediaParserEmbeddedImage } from '../state/images';
|
|
13
13
|
import type { InternalStats } from '../state/parser-state';
|
|
14
14
|
import type { MediaParserAudioSample, MediaParserOnAudioTrackParams, MediaParserOnVideoTrackParams, MediaParserVideoSample } from '../webcodec-sample-types';
|
|
15
|
+
import type { SeekResolution } from '../work-on-seek-request';
|
|
15
16
|
export type ParseMediaOnWorkerPayload = {
|
|
16
17
|
type: 'request-worker';
|
|
17
18
|
src: ParseMediaSrc;
|
|
@@ -63,6 +64,11 @@ type RequestResume = {
|
|
|
63
64
|
type RequestGetSeekingHints = {
|
|
64
65
|
type: 'request-get-seeking-hints';
|
|
65
66
|
};
|
|
67
|
+
type RequestSimulateSeek = {
|
|
68
|
+
type: 'request-simulate-seek';
|
|
69
|
+
payload: number;
|
|
70
|
+
nonce: string;
|
|
71
|
+
};
|
|
66
72
|
type RequestAbort = {
|
|
67
73
|
type: 'request-abort';
|
|
68
74
|
};
|
|
@@ -75,6 +81,11 @@ type ResponseGetSeekingHints = {
|
|
|
75
81
|
type: 'response-get-seeking-hints';
|
|
76
82
|
payload: SeekingHints;
|
|
77
83
|
};
|
|
84
|
+
type ResponseSimulateSeek = {
|
|
85
|
+
type: 'response-simulate-seek';
|
|
86
|
+
nonce: string;
|
|
87
|
+
payload: SeekResolution;
|
|
88
|
+
};
|
|
78
89
|
type BaseError = {
|
|
79
90
|
errorStack: string;
|
|
80
91
|
errorMessage: string;
|
|
@@ -261,6 +272,6 @@ export type SignalErrorInCallback = {
|
|
|
261
272
|
type: 'signal-error-in-callback';
|
|
262
273
|
nonce: string;
|
|
263
274
|
};
|
|
264
|
-
export type WorkerRequestPayload = ParseMediaOnWorkerPayload | RequestResume | RequestPause | RequestAbort | RequestSeek | RequestGetSeekingHints | AcknowledgeCallback | SignalErrorInCallback;
|
|
265
|
-
export type WorkerResponsePayload = ResponseDone | ResponseError | ResponseOnCallbackRequest | ResponseGetSeekingHints;
|
|
275
|
+
export type WorkerRequestPayload = ParseMediaOnWorkerPayload | RequestResume | RequestPause | RequestAbort | RequestSeek | RequestGetSeekingHints | RequestSimulateSeek | AcknowledgeCallback | SignalErrorInCallback;
|
|
276
|
+
export type WorkerResponsePayload = ResponseDone | ResponseError | ResponseOnCallbackRequest | ResponseGetSeekingHints | ResponseSimulateSeek;
|
|
266
277
|
export {};
|
package/package.json
CHANGED
|
@@ -3,15 +3,15 @@
|
|
|
3
3
|
"url": "https://github.com/remotion-dev/remotion/tree/main/packages/media-parser"
|
|
4
4
|
},
|
|
5
5
|
"name": "@remotion/media-parser",
|
|
6
|
-
"version": "4.0.
|
|
6
|
+
"version": "4.0.313",
|
|
7
7
|
"main": "dist/index.js",
|
|
8
8
|
"sideEffects": false,
|
|
9
9
|
"devDependencies": {
|
|
10
10
|
"@types/wicg-file-system-access": "2023.10.5",
|
|
11
11
|
"eslint": "9.19.0",
|
|
12
12
|
"@types/bun": "1.2.8",
|
|
13
|
-
"@remotion/example-videos": "4.0.
|
|
14
|
-
"@remotion/eslint-config-internal": "4.0.
|
|
13
|
+
"@remotion/example-videos": "4.0.313",
|
|
14
|
+
"@remotion/eslint-config-internal": "4.0.313"
|
|
15
15
|
},
|
|
16
16
|
"publishConfig": {
|
|
17
17
|
"access": "public"
|