@remotion/media-parser 4.0.293 → 4.0.294
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/iso-base-media/are-samples-complete.d.ts +6 -0
- package/dist/containers/iso-base-media/are-samples-complete.js +11 -0
- package/dist/containers/iso-base-media/collect-sample-positions-from-moof-boxes.d.ts +2 -3
- package/dist/containers/iso-base-media/collect-sample-positions-from-moof-boxes.js +1 -3
- package/dist/containers/iso-base-media/find-track-to-seek.js +9 -2
- package/dist/containers/iso-base-media/get-keyframes.js +6 -2
- package/dist/containers/iso-base-media/get-sample-positions-from-track.d.ts +2 -3
- package/dist/containers/iso-base-media/get-sample-positions-from-track.js +4 -4
- package/dist/containers/iso-base-media/get-seeking-byte-from-fragmented-mp4.js +6 -1
- package/dist/containers/iso-base-media/mdat/mdat.js +18 -1
- package/dist/containers/iso-base-media/process-box.js +7 -7
- package/dist/containers/iso-base-media/seeking-hints.js +1 -1
- package/dist/containers/iso-base-media/traversal.d.ts +2 -1
- package/dist/containers/iso-base-media/traversal.js +8 -4
- package/dist/emit-available-info.js +26 -26
- package/dist/esm/index.mjs +160 -88
- package/dist/esm/node.mjs +7 -4
- package/dist/esm/universal.mjs +29 -37
- package/dist/esm/web.mjs +22 -33
- package/dist/esm/worker-server-entry.mjs +166 -91
- package/dist/esm/worker-web-entry.mjs +159 -87
- package/dist/get-duration.js +15 -3
- package/dist/has-all-info.js +2 -1
- package/dist/index.d.ts +1 -1
- package/dist/readers/fetch/get-body-and-reader.js +3 -1
- package/dist/readers/from-node.js +7 -3
- package/dist/readers/from-web-file.js +20 -32
- package/dist/readers/reader.d.ts +1 -1
- package/dist/seek-backwards.js +1 -0
- package/dist/seek-forwards.js +1 -0
- package/dist/state/iso-base-media/cached-sample-positions.d.ts +5 -2
- package/dist/state/iso-base-media/cached-sample-positions.js +17 -7
- package/dist/state/iso-base-media/iso-state.d.ts +1 -1
- package/dist/state/iso-base-media/last-moof-box.d.ts +2 -0
- package/dist/state/iso-base-media/last-moof-box.js +21 -0
- package/dist/state/iso-base-media/precomputed-moof.d.ts +1 -0
- package/dist/state/iso-base-media/precomputed-moof.js +1 -0
- package/dist/state/parser-state.d.ts +1 -1
- package/dist/state/parser-state.js +2 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +3 -3
package/dist/esm/web.mjs
CHANGED
|
@@ -75,8 +75,9 @@ var getLengthAndReader = async ({
|
|
|
75
75
|
contentLength: encoded.byteLength,
|
|
76
76
|
reader: {
|
|
77
77
|
reader: stream.getReader(),
|
|
78
|
-
abort() {
|
|
78
|
+
abort: () => {
|
|
79
79
|
ownController.abort();
|
|
80
|
+
return Promise.resolve();
|
|
80
81
|
}
|
|
81
82
|
},
|
|
82
83
|
needsContentRange: false
|
|
@@ -91,6 +92,7 @@ var getLengthAndReader = async ({
|
|
|
91
92
|
reader,
|
|
92
93
|
abort: () => {
|
|
93
94
|
ownController.abort();
|
|
95
|
+
return Promise.resolve();
|
|
94
96
|
}
|
|
95
97
|
},
|
|
96
98
|
contentLength,
|
|
@@ -311,42 +313,29 @@ var webFileReadContent = ({ src, range, controller }) => {
|
|
|
311
313
|
if (typeof src === "string" || src instanceof URL) {
|
|
312
314
|
throw new Error("`inputTypeFileReader` only supports `File` objects");
|
|
313
315
|
}
|
|
314
|
-
const part = range === null ? src : typeof range === "number" ? src.slice(range) : src.slice(range[0], range[1]);
|
|
315
|
-
const
|
|
316
|
-
|
|
317
|
-
const ownController = new AbortController;
|
|
318
|
-
if (ownController) {
|
|
319
|
-
ownController.signal.addEventListener("abort", () => {
|
|
320
|
-
reader.abort();
|
|
321
|
-
}, { once: true });
|
|
322
|
-
}
|
|
316
|
+
const part = range === null ? src : typeof range === "number" ? src.slice(range) : src.slice(range[0], range[1] + 1);
|
|
317
|
+
const stream = part.stream();
|
|
318
|
+
const streamReader = stream.getReader();
|
|
323
319
|
if (controller) {
|
|
324
320
|
controller._internals.signal.addEventListener("abort", () => {
|
|
325
|
-
|
|
321
|
+
streamReader.cancel();
|
|
326
322
|
}, { once: true });
|
|
327
323
|
}
|
|
328
|
-
return
|
|
329
|
-
reader
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
contentType: src.type,
|
|
344
|
-
needsContentRange: true
|
|
345
|
-
});
|
|
346
|
-
};
|
|
347
|
-
reader.onerror = () => {
|
|
348
|
-
reject(reader.error);
|
|
349
|
-
};
|
|
324
|
+
return Promise.resolve({
|
|
325
|
+
reader: {
|
|
326
|
+
reader: streamReader,
|
|
327
|
+
async abort() {
|
|
328
|
+
try {
|
|
329
|
+
await streamReader.cancel();
|
|
330
|
+
} catch {}
|
|
331
|
+
return Promise.resolve();
|
|
332
|
+
}
|
|
333
|
+
},
|
|
334
|
+
contentLength: src.size,
|
|
335
|
+
name: src instanceof File ? src.name : src.toString(),
|
|
336
|
+
supportsContentRange: true,
|
|
337
|
+
contentType: src.type,
|
|
338
|
+
needsContentRange: true
|
|
350
339
|
});
|
|
351
340
|
};
|
|
352
341
|
var webFileReadWholeAsText = () => {
|
|
@@ -166,8 +166,9 @@ var getLengthAndReader = async ({
|
|
|
166
166
|
contentLength: encoded.byteLength,
|
|
167
167
|
reader: {
|
|
168
168
|
reader: stream.getReader(),
|
|
169
|
-
abort() {
|
|
169
|
+
abort: () => {
|
|
170
170
|
ownController.abort();
|
|
171
|
+
return Promise.resolve();
|
|
171
172
|
}
|
|
172
173
|
},
|
|
173
174
|
needsContentRange: false
|
|
@@ -182,6 +183,7 @@ var getLengthAndReader = async ({
|
|
|
182
183
|
reader,
|
|
183
184
|
abort: () => {
|
|
184
185
|
ownController.abort();
|
|
186
|
+
return Promise.resolve();
|
|
185
187
|
}
|
|
186
188
|
},
|
|
187
189
|
contentLength,
|
|
@@ -407,8 +409,7 @@ var nodeReadContent = ({ src, range, controller }) => {
|
|
|
407
409
|
const ownController = new AbortController;
|
|
408
410
|
const stream = createReadStream(src, {
|
|
409
411
|
start: range === null ? 0 : typeof range === "number" ? range : range[0],
|
|
410
|
-
end: range === null ? Infinity : typeof range === "number" ? Infinity : range[1]
|
|
411
|
-
signal: ownController.signal
|
|
412
|
+
end: range === null ? Infinity : typeof range === "number" ? Infinity : range[1]
|
|
412
413
|
});
|
|
413
414
|
controller._internals.signal.addEventListener("abort", () => {
|
|
414
415
|
ownController.abort();
|
|
@@ -443,8 +444,12 @@ var nodeReadContent = ({ src, range, controller }) => {
|
|
|
443
444
|
return Promise.resolve({
|
|
444
445
|
reader: {
|
|
445
446
|
reader,
|
|
446
|
-
abort: () => {
|
|
447
|
-
|
|
447
|
+
abort: async () => {
|
|
448
|
+
try {
|
|
449
|
+
stream.destroy();
|
|
450
|
+
ownController.abort();
|
|
451
|
+
await reader.cancel();
|
|
452
|
+
} catch {}
|
|
448
453
|
}
|
|
449
454
|
},
|
|
450
455
|
contentLength: stats.size,
|
|
@@ -477,42 +482,29 @@ var webFileReadContent = ({ src, range, controller }) => {
|
|
|
477
482
|
if (typeof src === "string" || src instanceof URL) {
|
|
478
483
|
throw new Error("`inputTypeFileReader` only supports `File` objects");
|
|
479
484
|
}
|
|
480
|
-
const part = range === null ? src : typeof range === "number" ? src.slice(range) : src.slice(range[0], range[1]);
|
|
481
|
-
const
|
|
482
|
-
|
|
483
|
-
const ownController = new AbortController;
|
|
484
|
-
if (ownController) {
|
|
485
|
-
ownController.signal.addEventListener("abort", () => {
|
|
486
|
-
reader.abort();
|
|
487
|
-
}, { once: true });
|
|
488
|
-
}
|
|
485
|
+
const part = range === null ? src : typeof range === "number" ? src.slice(range) : src.slice(range[0], range[1] + 1);
|
|
486
|
+
const stream = part.stream();
|
|
487
|
+
const streamReader = stream.getReader();
|
|
489
488
|
if (controller) {
|
|
490
489
|
controller._internals.signal.addEventListener("abort", () => {
|
|
491
|
-
|
|
490
|
+
streamReader.cancel();
|
|
492
491
|
}, { once: true });
|
|
493
492
|
}
|
|
494
|
-
return
|
|
495
|
-
reader
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
contentType: src.type,
|
|
510
|
-
needsContentRange: true
|
|
511
|
-
});
|
|
512
|
-
};
|
|
513
|
-
reader.onerror = () => {
|
|
514
|
-
reject(reader.error);
|
|
515
|
-
};
|
|
493
|
+
return Promise.resolve({
|
|
494
|
+
reader: {
|
|
495
|
+
reader: streamReader,
|
|
496
|
+
async abort() {
|
|
497
|
+
try {
|
|
498
|
+
await streamReader.cancel();
|
|
499
|
+
} catch {}
|
|
500
|
+
return Promise.resolve();
|
|
501
|
+
}
|
|
502
|
+
},
|
|
503
|
+
contentLength: src.size,
|
|
504
|
+
name: src instanceof File ? src.name : src.toString(),
|
|
505
|
+
supportsContentRange: true,
|
|
506
|
+
contentType: src.type,
|
|
507
|
+
needsContentRange: true
|
|
516
508
|
});
|
|
517
509
|
};
|
|
518
510
|
var webFileReadWholeAsText = () => {
|
|
@@ -892,7 +884,8 @@ var toMoofBox = (box) => {
|
|
|
892
884
|
}
|
|
893
885
|
return {
|
|
894
886
|
offset: box.offset,
|
|
895
|
-
trafBoxes: box.children.filter((c) => c.type === "regular-box" && c.boxType === "traf")
|
|
887
|
+
trafBoxes: box.children.filter((c) => c.type === "regular-box" && c.boxType === "traf"),
|
|
888
|
+
size: box.boxSize
|
|
896
889
|
};
|
|
897
890
|
};
|
|
898
891
|
var deduplicateMoofBoxesByOffset = (moofBoxes) => {
|
|
@@ -1066,13 +1059,16 @@ var getTrunBoxes = (segment) => {
|
|
|
1066
1059
|
const trunBoxes = segment.children.filter((c) => c.type === "trun-box");
|
|
1067
1060
|
return trunBoxes;
|
|
1068
1061
|
};
|
|
1062
|
+
var getTfraBoxesFromMfraBoxChildren = (mfraBoxChildren) => {
|
|
1063
|
+
const tfraBoxes = mfraBoxChildren.filter((b) => b.type === "tfra-box");
|
|
1064
|
+
return tfraBoxes;
|
|
1065
|
+
};
|
|
1069
1066
|
var getTfraBoxes = (structure) => {
|
|
1070
|
-
const mfraBox = structure.
|
|
1067
|
+
const mfraBox = structure.find((b) => b.type === "regular-box" && b.boxType === "mfra");
|
|
1071
1068
|
if (!mfraBox) {
|
|
1072
1069
|
return [];
|
|
1073
1070
|
}
|
|
1074
|
-
|
|
1075
|
-
return tfraBoxes;
|
|
1071
|
+
return getTfraBoxesFromMfraBoxChildren(mfraBox.children);
|
|
1076
1072
|
};
|
|
1077
1073
|
|
|
1078
1074
|
// src/containers/riff/traversal.ts
|
|
@@ -4664,6 +4660,17 @@ var getDurationFromFlac = (parserState) => {
|
|
|
4664
4660
|
return streaminfo.totalSamples / streaminfo.sampleRate;
|
|
4665
4661
|
};
|
|
4666
4662
|
|
|
4663
|
+
// src/containers/iso-base-media/are-samples-complete.ts
|
|
4664
|
+
var areSamplesComplete = ({
|
|
4665
|
+
moofBoxes,
|
|
4666
|
+
tfraBoxes
|
|
4667
|
+
}) => {
|
|
4668
|
+
if (moofBoxes.length === 0) {
|
|
4669
|
+
return true;
|
|
4670
|
+
}
|
|
4671
|
+
return tfraBoxes.length > 0 && tfraBoxes.every((t) => t.entries.length === moofBoxes.length);
|
|
4672
|
+
};
|
|
4673
|
+
|
|
4667
4674
|
// src/samples-from-moof.ts
|
|
4668
4675
|
var getSamplesFromTraf = (trafSegment, moofOffset) => {
|
|
4669
4676
|
if (trafSegment.type !== "regular-box" || trafSegment.boxType !== "traf") {
|
|
@@ -4737,10 +4744,9 @@ var getSamplesFromMoof = ({
|
|
|
4737
4744
|
// src/containers/iso-base-media/collect-sample-positions-from-moof-boxes.ts
|
|
4738
4745
|
var collectSamplePositionsFromMoofBoxes = ({
|
|
4739
4746
|
moofBoxes,
|
|
4740
|
-
|
|
4741
|
-
|
|
4747
|
+
tkhdBox,
|
|
4748
|
+
isComplete
|
|
4742
4749
|
}) => {
|
|
4743
|
-
const isComplete = tfraBoxes.length > 0 && tfraBoxes.every((t) => t.entries.length === moofBoxes.length);
|
|
4744
4750
|
const samplePositions = moofBoxes.map((m, index) => {
|
|
4745
4751
|
const isLastFragment = index === moofBoxes.length - 1 && isComplete;
|
|
4746
4752
|
return {
|
|
@@ -4920,21 +4926,21 @@ var collectSamplePositionsFromTrak = (trakBox) => {
|
|
|
4920
4926
|
var getSamplePositionsFromTrack = ({
|
|
4921
4927
|
trakBox,
|
|
4922
4928
|
moofBoxes,
|
|
4923
|
-
|
|
4929
|
+
moofComplete
|
|
4924
4930
|
}) => {
|
|
4925
4931
|
const tkhdBox = getTkhdBox(trakBox);
|
|
4926
4932
|
if (!tkhdBox) {
|
|
4927
4933
|
throw new Error("Expected tkhd box in trak box");
|
|
4928
4934
|
}
|
|
4929
4935
|
if (moofBoxes.length > 0) {
|
|
4930
|
-
const {
|
|
4936
|
+
const { samplePositions } = collectSamplePositionsFromMoofBoxes({
|
|
4931
4937
|
moofBoxes,
|
|
4932
|
-
|
|
4933
|
-
|
|
4938
|
+
tkhdBox,
|
|
4939
|
+
isComplete: moofComplete
|
|
4934
4940
|
});
|
|
4935
4941
|
return {
|
|
4936
4942
|
samplePositions: samplePositions.map((s) => s.samples).flat(1),
|
|
4937
|
-
isComplete
|
|
4943
|
+
isComplete: moofComplete
|
|
4938
4944
|
};
|
|
4939
4945
|
}
|
|
4940
4946
|
return {
|
|
@@ -5137,6 +5143,20 @@ var getDurationFromWav = (state) => {
|
|
|
5137
5143
|
return durationInSeconds;
|
|
5138
5144
|
};
|
|
5139
5145
|
|
|
5146
|
+
// src/state/iso-base-media/precomputed-tfra.ts
|
|
5147
|
+
var precomputedTfraState = () => {
|
|
5148
|
+
let tfraBoxes = [];
|
|
5149
|
+
return {
|
|
5150
|
+
getTfraBoxes: () => tfraBoxes,
|
|
5151
|
+
setTfraBoxes: (boxes) => {
|
|
5152
|
+
tfraBoxes = boxes;
|
|
5153
|
+
}
|
|
5154
|
+
};
|
|
5155
|
+
};
|
|
5156
|
+
var deduplicateTfraBoxesByOffset = (tfraBoxes) => {
|
|
5157
|
+
return tfraBoxes.filter((m, i, arr) => i === arr.findIndex((t) => t.offset === m.offset));
|
|
5158
|
+
};
|
|
5159
|
+
|
|
5140
5160
|
// src/get-duration.ts
|
|
5141
5161
|
var getDurationFromMatroska = (segments) => {
|
|
5142
5162
|
const mainSegment = segments.find((s) => s.type === "Segment");
|
|
@@ -5174,7 +5194,14 @@ var getDurationFromIsoBaseMedia = (parserState) => {
|
|
|
5174
5194
|
return null;
|
|
5175
5195
|
}
|
|
5176
5196
|
const moofBoxes = getMoofBoxes(structure.boxes);
|
|
5177
|
-
const
|
|
5197
|
+
const mfra = parserState.iso.mfra.getIfAlreadyLoaded();
|
|
5198
|
+
const tfraBoxes = deduplicateTfraBoxesByOffset([
|
|
5199
|
+
...mfra ? getTfraBoxesFromMfraBoxChildren(mfra) : [],
|
|
5200
|
+
...getTfraBoxes(structure.boxes)
|
|
5201
|
+
]);
|
|
5202
|
+
if (!areSamplesComplete({ moofBoxes, tfraBoxes })) {
|
|
5203
|
+
return null;
|
|
5204
|
+
}
|
|
5178
5205
|
const mvhdBox = getMvhdBox(moovBox);
|
|
5179
5206
|
if (!mvhdBox) {
|
|
5180
5207
|
return null;
|
|
@@ -5196,7 +5223,7 @@ var getDurationFromIsoBaseMedia = (parserState) => {
|
|
|
5196
5223
|
const { samplePositions, isComplete } = getSamplePositionsFromTrack({
|
|
5197
5224
|
trakBox: t.trakBox,
|
|
5198
5225
|
moofBoxes,
|
|
5199
|
-
tfraBoxes
|
|
5226
|
+
moofComplete: areSamplesComplete({ moofBoxes, tfraBoxes })
|
|
5200
5227
|
});
|
|
5201
5228
|
if (!isComplete) {
|
|
5202
5229
|
return null;
|
|
@@ -5253,7 +5280,10 @@ var hasDuration = (parserState) => {
|
|
|
5253
5280
|
};
|
|
5254
5281
|
var hasSlowDuration = (parserState) => {
|
|
5255
5282
|
try {
|
|
5256
|
-
|
|
5283
|
+
if (!hasDuration(parserState)) {
|
|
5284
|
+
return false;
|
|
5285
|
+
}
|
|
5286
|
+
return getDuration(parserState) !== null;
|
|
5257
5287
|
} catch {
|
|
5258
5288
|
return false;
|
|
5259
5289
|
}
|
|
@@ -5281,13 +5311,16 @@ var getKeyframesFromIsoBaseMedia = (state) => {
|
|
|
5281
5311
|
});
|
|
5282
5312
|
const structure = state.structure.getIsoStructure();
|
|
5283
5313
|
const moofBoxes = getMoofBoxes(structure.boxes);
|
|
5284
|
-
const tfraBoxes = getTfraBoxes(structure);
|
|
5314
|
+
const tfraBoxes = getTfraBoxes(structure.boxes);
|
|
5285
5315
|
const allSamples = videoTracks.map((t) => {
|
|
5286
5316
|
const { timescale: ts } = t;
|
|
5287
5317
|
const { samplePositions, isComplete } = getSamplePositionsFromTrack({
|
|
5288
5318
|
trakBox: t.trakBox,
|
|
5289
5319
|
moofBoxes,
|
|
5290
|
-
|
|
5320
|
+
moofComplete: areSamplesComplete({
|
|
5321
|
+
moofBoxes,
|
|
5322
|
+
tfraBoxes
|
|
5323
|
+
})
|
|
5291
5324
|
});
|
|
5292
5325
|
if (!isComplete) {
|
|
5293
5326
|
return [];
|
|
@@ -5740,7 +5773,10 @@ var findAnyTrackWithSamplePositions = (allTracks, struc) => {
|
|
|
5740
5773
|
const { samplePositions } = getSamplePositionsFromTrack({
|
|
5741
5774
|
trakBox: track.trakBox,
|
|
5742
5775
|
moofBoxes: getMoofBoxes(struc.boxes),
|
|
5743
|
-
|
|
5776
|
+
moofComplete: areSamplesComplete({
|
|
5777
|
+
moofBoxes: getMoofBoxes(struc.boxes),
|
|
5778
|
+
tfraBoxes: getTfraBoxes(struc.boxes)
|
|
5779
|
+
})
|
|
5744
5780
|
});
|
|
5745
5781
|
if (samplePositions.length === 0) {
|
|
5746
5782
|
continue;
|
|
@@ -5759,7 +5795,10 @@ var findTrackToSeek = (allTracks, structure) => {
|
|
|
5759
5795
|
const { samplePositions } = getSamplePositionsFromTrack({
|
|
5760
5796
|
trakBox: firstVideoTrack.trakBox,
|
|
5761
5797
|
moofBoxes: getMoofBoxes(struc.boxes),
|
|
5762
|
-
|
|
5798
|
+
moofComplete: areSamplesComplete({
|
|
5799
|
+
moofBoxes: getMoofBoxes(struc.boxes),
|
|
5800
|
+
tfraBoxes: getTfraBoxes(struc.boxes)
|
|
5801
|
+
})
|
|
5763
5802
|
});
|
|
5764
5803
|
if (samplePositions.length === 0) {
|
|
5765
5804
|
return findAnyTrackWithSamplePositions(allTracks, struc);
|
|
@@ -5899,10 +5938,14 @@ var getSeekingByteFromFragmentedMp4 = async ({
|
|
|
5899
5938
|
if (!tkhdBox) {
|
|
5900
5939
|
throw new Error("Expected tkhd box in trak box");
|
|
5901
5940
|
}
|
|
5941
|
+
const isComplete = areSamplesComplete({
|
|
5942
|
+
moofBoxes: info.moofBoxes,
|
|
5943
|
+
tfraBoxes: info.tfraBoxes
|
|
5944
|
+
});
|
|
5902
5945
|
const { samplePositions: samplePositionsArray } = collectSamplePositionsFromMoofBoxes({
|
|
5903
5946
|
moofBoxes: info.moofBoxes,
|
|
5904
|
-
|
|
5905
|
-
|
|
5947
|
+
tkhdBox,
|
|
5948
|
+
isComplete
|
|
5906
5949
|
});
|
|
5907
5950
|
Log.trace(logLevel, "Fragmented MP4 - Checking if we have seeking info for this time range");
|
|
5908
5951
|
for (const positions of samplePositionsArray) {
|
|
@@ -7125,20 +7168,6 @@ var setSeekingHintsForFlac = ({
|
|
|
7125
7168
|
state.flac.audioSamples.setFromSeekingHints(hints.audioSampleMap);
|
|
7126
7169
|
};
|
|
7127
7170
|
|
|
7128
|
-
// src/state/iso-base-media/precomputed-tfra.ts
|
|
7129
|
-
var precomputedTfraState = () => {
|
|
7130
|
-
let tfraBoxes = [];
|
|
7131
|
-
return {
|
|
7132
|
-
getTfraBoxes: () => tfraBoxes,
|
|
7133
|
-
setTfraBoxes: (boxes) => {
|
|
7134
|
-
tfraBoxes = boxes;
|
|
7135
|
-
}
|
|
7136
|
-
};
|
|
7137
|
-
};
|
|
7138
|
-
var deduplicateTfraBoxesByOffset = (tfraBoxes) => {
|
|
7139
|
-
return tfraBoxes.filter((m, i, arr) => i === arr.findIndex((t) => t.offset === m.offset));
|
|
7140
|
-
};
|
|
7141
|
-
|
|
7142
7171
|
// src/containers/iso-base-media/seeking-hints.ts
|
|
7143
7172
|
var getSeekingHintsFromMp4 = ({
|
|
7144
7173
|
structureState,
|
|
@@ -7159,7 +7188,7 @@ var getSeekingHintsFromMp4 = ({
|
|
|
7159
7188
|
]);
|
|
7160
7189
|
const tfraBoxes = deduplicateTfraBoxesByOffset([
|
|
7161
7190
|
...isoState.tfra.getTfraBoxes(),
|
|
7162
|
-
...getTfraBoxes(structure)
|
|
7191
|
+
...getTfraBoxes(structure.boxes)
|
|
7163
7192
|
]);
|
|
7164
7193
|
if (!moovAtom) {
|
|
7165
7194
|
return null;
|
|
@@ -7418,6 +7447,7 @@ var seekBackwards = async ({
|
|
|
7418
7447
|
}
|
|
7419
7448
|
const time = Date.now();
|
|
7420
7449
|
Log.verbose(logLevel, `Seeking in video from position ${iterator.counter.getOffset()} -> ${seekTo}. Re-reading because this portion is not available.`);
|
|
7450
|
+
await currentReader.getCurrent().abort();
|
|
7421
7451
|
const { reader: newReader } = await readerInterface.read({
|
|
7422
7452
|
src,
|
|
7423
7453
|
range: seekTo,
|
|
@@ -7512,6 +7542,7 @@ var seekForward = async ({
|
|
|
7512
7542
|
}
|
|
7513
7543
|
const time = Date.now();
|
|
7514
7544
|
Log.verbose(logLevel, `Skipping over video data from position ${iterator.counter.getOffset()} -> ${seekTo}. Re-reading because this portion is not available`);
|
|
7545
|
+
await currentReader.getCurrent().abort();
|
|
7515
7546
|
const { reader: newReader } = await readerInterface.read({
|
|
7516
7547
|
src,
|
|
7517
7548
|
range: seekTo,
|
|
@@ -7892,7 +7923,7 @@ var emitAvailableInfo = async ({
|
|
|
7892
7923
|
}
|
|
7893
7924
|
if (key === "slowFps") {
|
|
7894
7925
|
if (hasInfo.slowFps && !emittedFields.slowFps) {
|
|
7895
|
-
const slowFps = state.samplesObserved.getFps();
|
|
7926
|
+
const slowFps = getFps(state) ?? state.samplesObserved.getFps();
|
|
7896
7927
|
await callbackFunctions.onSlowFps?.(slowFps);
|
|
7897
7928
|
if (fieldsInReturnValue.slowFps) {
|
|
7898
7929
|
returnValue.slowFps = slowFps;
|
|
@@ -8188,7 +8219,8 @@ var getAvailableInfo = ({
|
|
|
8188
8219
|
return Boolean(structure && hasDuration(state));
|
|
8189
8220
|
}
|
|
8190
8221
|
if (key === "slowDurationInSeconds") {
|
|
8191
|
-
|
|
8222
|
+
const res = Boolean(structure && hasSlowDuration(state));
|
|
8223
|
+
return res;
|
|
8192
8224
|
}
|
|
8193
8225
|
if (key === "dimensions" || key === "rotation" || key === "unrotatedDimensions") {
|
|
8194
8226
|
return Boolean(structure && hasDimensions(state));
|
|
@@ -8866,18 +8898,31 @@ var parseFlac = ({
|
|
|
8866
8898
|
};
|
|
8867
8899
|
|
|
8868
8900
|
// src/state/iso-base-media/cached-sample-positions.ts
|
|
8869
|
-
var calculateFlatSamples = (
|
|
8901
|
+
var calculateFlatSamples = ({
|
|
8902
|
+
state,
|
|
8903
|
+
mediaSectionStart
|
|
8904
|
+
}) => {
|
|
8870
8905
|
const tracks2 = getTracks(state, true);
|
|
8871
8906
|
const allTracks = [
|
|
8872
8907
|
...tracks2.videoTracks,
|
|
8873
8908
|
...tracks2.audioTracks,
|
|
8874
8909
|
...tracks2.otherTracks
|
|
8875
8910
|
];
|
|
8911
|
+
const moofBoxes = getMoofBoxes(state.structure.getIsoStructure().boxes);
|
|
8912
|
+
const tfraBoxes = deduplicateTfraBoxesByOffset([
|
|
8913
|
+
...state.iso.tfra.getTfraBoxes(),
|
|
8914
|
+
...getTfraBoxes(state.structure.getIsoStructure().boxes)
|
|
8915
|
+
]);
|
|
8916
|
+
const moofComplete = areSamplesComplete({ moofBoxes, tfraBoxes });
|
|
8917
|
+
const relevantMoofBox = moofBoxes.find((moofBox) => moofBox.offset + moofBox.size + 8 === mediaSectionStart);
|
|
8918
|
+
if (moofBoxes.length > 0 && !relevantMoofBox) {
|
|
8919
|
+
throw new Error("No relevant moof box found");
|
|
8920
|
+
}
|
|
8876
8921
|
const flatSamples = allTracks.map((track) => {
|
|
8877
8922
|
const { samplePositions } = getSamplePositionsFromTrack({
|
|
8878
8923
|
trakBox: track.trakBox,
|
|
8879
|
-
moofBoxes:
|
|
8880
|
-
|
|
8924
|
+
moofBoxes: relevantMoofBox ? [relevantMoofBox] : [],
|
|
8925
|
+
moofComplete
|
|
8881
8926
|
});
|
|
8882
8927
|
return samplePositions.map((samplePosition) => {
|
|
8883
8928
|
return {
|
|
@@ -8893,10 +8938,7 @@ var cachedSamplePositionsState = () => {
|
|
|
8893
8938
|
const jumpMarksForMdatStart = {};
|
|
8894
8939
|
return {
|
|
8895
8940
|
getSamples: (mdatStart) => {
|
|
8896
|
-
|
|
8897
|
-
return cachedForMdatStart[mdatStart];
|
|
8898
|
-
}
|
|
8899
|
-
return null;
|
|
8941
|
+
return cachedForMdatStart[mdatStart] ?? null;
|
|
8900
8942
|
},
|
|
8901
8943
|
setSamples: (mdatStart, samples) => {
|
|
8902
8944
|
cachedForMdatStart[mdatStart] = samples;
|
|
@@ -8910,6 +8952,24 @@ var cachedSamplePositionsState = () => {
|
|
|
8910
8952
|
};
|
|
8911
8953
|
};
|
|
8912
8954
|
|
|
8955
|
+
// src/state/iso-base-media/last-moof-box.ts
|
|
8956
|
+
var getLastMoofBox = (boxes) => {
|
|
8957
|
+
if (boxes) {
|
|
8958
|
+
const tfras = boxes.filter((b) => b.type === "tfra-box");
|
|
8959
|
+
const lastMoofOffsets = tfras.map((f) => {
|
|
8960
|
+
if (f.entries.length <= 1) {
|
|
8961
|
+
return null;
|
|
8962
|
+
}
|
|
8963
|
+
return f.entries[f.entries.length - 1].moofOffset;
|
|
8964
|
+
});
|
|
8965
|
+
if (lastMoofOffsets.length > 0) {
|
|
8966
|
+
const maxOffset = Math.max(...lastMoofOffsets.filter(truthy));
|
|
8967
|
+
return maxOffset;
|
|
8968
|
+
}
|
|
8969
|
+
return null;
|
|
8970
|
+
}
|
|
8971
|
+
};
|
|
8972
|
+
|
|
8913
8973
|
// src/state/can-skip-tracks.ts
|
|
8914
8974
|
var needsTracksForField = ({
|
|
8915
8975
|
field,
|
|
@@ -10651,13 +10711,13 @@ var processBox = async ({
|
|
|
10651
10711
|
if (boxType === "ftyp") {
|
|
10652
10712
|
return {
|
|
10653
10713
|
type: "box",
|
|
10654
|
-
box:
|
|
10714
|
+
box: parseFtyp({ iterator, size: boxSize, offset: fileOffset })
|
|
10655
10715
|
};
|
|
10656
10716
|
}
|
|
10657
10717
|
if (boxType === "colr") {
|
|
10658
10718
|
return {
|
|
10659
10719
|
type: "box",
|
|
10660
|
-
box:
|
|
10720
|
+
box: parseColorParameterBox({
|
|
10661
10721
|
iterator,
|
|
10662
10722
|
size: boxSize
|
|
10663
10723
|
})
|
|
@@ -10666,25 +10726,25 @@ var processBox = async ({
|
|
|
10666
10726
|
if (boxType === "mvhd") {
|
|
10667
10727
|
return {
|
|
10668
10728
|
type: "box",
|
|
10669
|
-
box:
|
|
10729
|
+
box: parseMvhd({ iterator, offset: fileOffset, size: boxSize })
|
|
10670
10730
|
};
|
|
10671
10731
|
}
|
|
10672
10732
|
if (boxType === "tkhd") {
|
|
10673
10733
|
return {
|
|
10674
10734
|
type: "box",
|
|
10675
|
-
box:
|
|
10735
|
+
box: parseTkhd({ iterator, offset: fileOffset, size: boxSize })
|
|
10676
10736
|
};
|
|
10677
10737
|
}
|
|
10678
10738
|
if (boxType === "trun") {
|
|
10679
10739
|
return {
|
|
10680
10740
|
type: "box",
|
|
10681
|
-
box:
|
|
10741
|
+
box: parseTrun({ iterator, offset: fileOffset, size: boxSize })
|
|
10682
10742
|
};
|
|
10683
10743
|
}
|
|
10684
10744
|
if (boxType === "tfdt") {
|
|
10685
10745
|
return {
|
|
10686
10746
|
type: "box",
|
|
10687
|
-
box:
|
|
10747
|
+
box: parseTfdt({ iterator, size: boxSize, offset: fileOffset })
|
|
10688
10748
|
};
|
|
10689
10749
|
}
|
|
10690
10750
|
if (boxType === "stsd") {
|
|
@@ -10933,7 +10993,7 @@ var processBox = async ({
|
|
|
10933
10993
|
};
|
|
10934
10994
|
}
|
|
10935
10995
|
if (boxType === "moof") {
|
|
10936
|
-
onlyIfMoovAtomExpected?.isoState?.mfra.triggerLoad();
|
|
10996
|
+
await onlyIfMoovAtomExpected?.isoState?.mfra.triggerLoad();
|
|
10937
10997
|
}
|
|
10938
10998
|
if (boxType === "mdia" || boxType === "minf" || boxType === "stbl" || boxType === "udta" || boxType === "moof" || boxType === "dims" || boxType === "meta" || boxType === "wave" || boxType === "traf" || boxType === "mfra" || boxType === "stsb") {
|
|
10939
10999
|
const children = await getIsoBaseMediaChildren({
|
|
@@ -11209,6 +11269,14 @@ var parseMdatSection = async (state) => {
|
|
|
11209
11269
|
}
|
|
11210
11270
|
const endOfMdat = mediaSection.size + mediaSection.start;
|
|
11211
11271
|
if (maySkipVideoData({ state })) {
|
|
11272
|
+
const mfra = state.iso.mfra.getIfAlreadyLoaded();
|
|
11273
|
+
if (mfra) {
|
|
11274
|
+
const lastMoof = getLastMoofBox(mfra);
|
|
11275
|
+
if (lastMoof && lastMoof > endOfMdat) {
|
|
11276
|
+
Log.verbose(state.logLevel, "Skipping to last moof", lastMoof, "end of mdat", endOfMdat);
|
|
11277
|
+
return makeSkip(lastMoof);
|
|
11278
|
+
}
|
|
11279
|
+
}
|
|
11212
11280
|
return makeSkip(endOfMdat);
|
|
11213
11281
|
}
|
|
11214
11282
|
const alreadyHasMoov = getHasTracks(state, true);
|
|
@@ -11226,7 +11294,10 @@ var parseMdatSection = async (state) => {
|
|
|
11226
11294
|
return parseMdatSection(state);
|
|
11227
11295
|
}
|
|
11228
11296
|
if (!state.iso.flatSamples.getSamples(mediaSection.start)) {
|
|
11229
|
-
const flattedSamples = calculateFlatSamples(
|
|
11297
|
+
const flattedSamples = calculateFlatSamples({
|
|
11298
|
+
state,
|
|
11299
|
+
mediaSectionStart: mediaSection.start
|
|
11300
|
+
});
|
|
11230
11301
|
const calcedJumpMarks = calculateJumpMarks(flattedSamples, endOfMdat);
|
|
11231
11302
|
state.iso.flatSamples.setJumpMarks(mediaSection.start, calcedJumpMarks);
|
|
11232
11303
|
state.iso.flatSamples.setSamples(mediaSection.start, flattedSamples.flat(1));
|
|
@@ -11243,9 +11314,11 @@ var parseMdatSection = async (state) => {
|
|
|
11243
11314
|
iterator.discard(nextSample_.samplePosition.offset - iterator.counter.getOffset());
|
|
11244
11315
|
return null;
|
|
11245
11316
|
}
|
|
11317
|
+
Log.verbose(state.logLevel, "Could not find sample at offset", iterator.counter.getOffset(), "skipping to end of mdat");
|
|
11246
11318
|
return makeSkip(endOfMdat);
|
|
11247
11319
|
}
|
|
11248
11320
|
if (samplesWithIndex.samplePosition.offset + samplesWithIndex.samplePosition.size > state.contentLength) {
|
|
11321
|
+
Log.verbose(state.logLevel, "Sample is beyond the end of the file. Don't process it.", samplesWithIndex.samplePosition.offset + samplesWithIndex.samplePosition.size, endOfMdat);
|
|
11249
11322
|
return makeSkip(endOfMdat);
|
|
11250
11323
|
}
|
|
11251
11324
|
if (iterator.bytesRemaining() < samplesWithIndex.samplePosition.size) {
|
|
@@ -11299,6 +11372,7 @@ var parseMdatSection = async (state) => {
|
|
|
11299
11372
|
}
|
|
11300
11373
|
const jump = jumpMarks.find((j) => j.afterSampleWithOffset === offset);
|
|
11301
11374
|
if (jump) {
|
|
11375
|
+
Log.verbose(state.logLevel, "Found jump mark", jump.jumpToOffset, "skipping to jump mark");
|
|
11302
11376
|
return makeSkip(jump.jumpToOffset);
|
|
11303
11377
|
}
|
|
11304
11378
|
return null;
|
|
@@ -16682,6 +16756,7 @@ var makeParserState = ({
|
|
|
16682
16756
|
fields: fieldsInReturnValue,
|
|
16683
16757
|
callbacks
|
|
16684
16758
|
});
|
|
16759
|
+
const mediaSection = mediaSectionState();
|
|
16685
16760
|
return {
|
|
16686
16761
|
riff: riffSpecificState({
|
|
16687
16762
|
controller,
|
|
@@ -16739,7 +16814,7 @@ var makeParserState = ({
|
|
|
16739
16814
|
samplesObserved,
|
|
16740
16815
|
contentLength,
|
|
16741
16816
|
images,
|
|
16742
|
-
mediaSection
|
|
16817
|
+
mediaSection,
|
|
16743
16818
|
logLevel,
|
|
16744
16819
|
iterator,
|
|
16745
16820
|
controller,
|