@remotion/media-parser 4.0.293 → 4.0.295
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
|
@@ -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,
|
|
@@ -402,42 +404,29 @@ var webFileReadContent = ({ src, range, controller }) => {
|
|
|
402
404
|
if (typeof src === "string" || src instanceof URL) {
|
|
403
405
|
throw new Error("`inputTypeFileReader` only supports `File` objects");
|
|
404
406
|
}
|
|
405
|
-
const part = range === null ? src : typeof range === "number" ? src.slice(range) : src.slice(range[0], range[1]);
|
|
406
|
-
const
|
|
407
|
-
|
|
408
|
-
const ownController = new AbortController;
|
|
409
|
-
if (ownController) {
|
|
410
|
-
ownController.signal.addEventListener("abort", () => {
|
|
411
|
-
reader.abort();
|
|
412
|
-
}, { once: true });
|
|
413
|
-
}
|
|
407
|
+
const part = range === null ? src : typeof range === "number" ? src.slice(range) : src.slice(range[0], range[1] + 1);
|
|
408
|
+
const stream = part.stream();
|
|
409
|
+
const streamReader = stream.getReader();
|
|
414
410
|
if (controller) {
|
|
415
411
|
controller._internals.signal.addEventListener("abort", () => {
|
|
416
|
-
|
|
412
|
+
streamReader.cancel();
|
|
417
413
|
}, { once: true });
|
|
418
414
|
}
|
|
419
|
-
return
|
|
420
|
-
reader
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
contentType: src.type,
|
|
435
|
-
needsContentRange: true
|
|
436
|
-
});
|
|
437
|
-
};
|
|
438
|
-
reader.onerror = () => {
|
|
439
|
-
reject(reader.error);
|
|
440
|
-
};
|
|
415
|
+
return Promise.resolve({
|
|
416
|
+
reader: {
|
|
417
|
+
reader: streamReader,
|
|
418
|
+
async abort() {
|
|
419
|
+
try {
|
|
420
|
+
await streamReader.cancel();
|
|
421
|
+
} catch {}
|
|
422
|
+
return Promise.resolve();
|
|
423
|
+
}
|
|
424
|
+
},
|
|
425
|
+
contentLength: src.size,
|
|
426
|
+
name: src instanceof File ? src.name : src.toString(),
|
|
427
|
+
supportsContentRange: true,
|
|
428
|
+
contentType: src.type,
|
|
429
|
+
needsContentRange: true
|
|
441
430
|
});
|
|
442
431
|
};
|
|
443
432
|
var webFileReadWholeAsText = () => {
|
|
@@ -807,7 +796,8 @@ var toMoofBox = (box) => {
|
|
|
807
796
|
}
|
|
808
797
|
return {
|
|
809
798
|
offset: box.offset,
|
|
810
|
-
trafBoxes: box.children.filter((c) => c.type === "regular-box" && c.boxType === "traf")
|
|
799
|
+
trafBoxes: box.children.filter((c) => c.type === "regular-box" && c.boxType === "traf"),
|
|
800
|
+
size: box.boxSize
|
|
811
801
|
};
|
|
812
802
|
};
|
|
813
803
|
var deduplicateMoofBoxesByOffset = (moofBoxes) => {
|
|
@@ -981,13 +971,16 @@ var getTrunBoxes = (segment) => {
|
|
|
981
971
|
const trunBoxes = segment.children.filter((c) => c.type === "trun-box");
|
|
982
972
|
return trunBoxes;
|
|
983
973
|
};
|
|
974
|
+
var getTfraBoxesFromMfraBoxChildren = (mfraBoxChildren) => {
|
|
975
|
+
const tfraBoxes = mfraBoxChildren.filter((b) => b.type === "tfra-box");
|
|
976
|
+
return tfraBoxes;
|
|
977
|
+
};
|
|
984
978
|
var getTfraBoxes = (structure) => {
|
|
985
|
-
const mfraBox = structure.
|
|
979
|
+
const mfraBox = structure.find((b) => b.type === "regular-box" && b.boxType === "mfra");
|
|
986
980
|
if (!mfraBox) {
|
|
987
981
|
return [];
|
|
988
982
|
}
|
|
989
|
-
|
|
990
|
-
return tfraBoxes;
|
|
983
|
+
return getTfraBoxesFromMfraBoxChildren(mfraBox.children);
|
|
991
984
|
};
|
|
992
985
|
|
|
993
986
|
// src/containers/riff/traversal.ts
|
|
@@ -4579,6 +4572,17 @@ var getDurationFromFlac = (parserState) => {
|
|
|
4579
4572
|
return streaminfo.totalSamples / streaminfo.sampleRate;
|
|
4580
4573
|
};
|
|
4581
4574
|
|
|
4575
|
+
// src/containers/iso-base-media/are-samples-complete.ts
|
|
4576
|
+
var areSamplesComplete = ({
|
|
4577
|
+
moofBoxes,
|
|
4578
|
+
tfraBoxes
|
|
4579
|
+
}) => {
|
|
4580
|
+
if (moofBoxes.length === 0) {
|
|
4581
|
+
return true;
|
|
4582
|
+
}
|
|
4583
|
+
return tfraBoxes.length > 0 && tfraBoxes.every((t) => t.entries.length === moofBoxes.length);
|
|
4584
|
+
};
|
|
4585
|
+
|
|
4582
4586
|
// src/samples-from-moof.ts
|
|
4583
4587
|
var getSamplesFromTraf = (trafSegment, moofOffset) => {
|
|
4584
4588
|
if (trafSegment.type !== "regular-box" || trafSegment.boxType !== "traf") {
|
|
@@ -4652,10 +4656,9 @@ var getSamplesFromMoof = ({
|
|
|
4652
4656
|
// src/containers/iso-base-media/collect-sample-positions-from-moof-boxes.ts
|
|
4653
4657
|
var collectSamplePositionsFromMoofBoxes = ({
|
|
4654
4658
|
moofBoxes,
|
|
4655
|
-
|
|
4656
|
-
|
|
4659
|
+
tkhdBox,
|
|
4660
|
+
isComplete
|
|
4657
4661
|
}) => {
|
|
4658
|
-
const isComplete = tfraBoxes.length > 0 && tfraBoxes.every((t) => t.entries.length === moofBoxes.length);
|
|
4659
4662
|
const samplePositions = moofBoxes.map((m, index) => {
|
|
4660
4663
|
const isLastFragment = index === moofBoxes.length - 1 && isComplete;
|
|
4661
4664
|
return {
|
|
@@ -4835,21 +4838,21 @@ var collectSamplePositionsFromTrak = (trakBox) => {
|
|
|
4835
4838
|
var getSamplePositionsFromTrack = ({
|
|
4836
4839
|
trakBox,
|
|
4837
4840
|
moofBoxes,
|
|
4838
|
-
|
|
4841
|
+
moofComplete
|
|
4839
4842
|
}) => {
|
|
4840
4843
|
const tkhdBox = getTkhdBox(trakBox);
|
|
4841
4844
|
if (!tkhdBox) {
|
|
4842
4845
|
throw new Error("Expected tkhd box in trak box");
|
|
4843
4846
|
}
|
|
4844
4847
|
if (moofBoxes.length > 0) {
|
|
4845
|
-
const {
|
|
4848
|
+
const { samplePositions } = collectSamplePositionsFromMoofBoxes({
|
|
4846
4849
|
moofBoxes,
|
|
4847
|
-
|
|
4848
|
-
|
|
4850
|
+
tkhdBox,
|
|
4851
|
+
isComplete: moofComplete
|
|
4849
4852
|
});
|
|
4850
4853
|
return {
|
|
4851
4854
|
samplePositions: samplePositions.map((s) => s.samples).flat(1),
|
|
4852
|
-
isComplete
|
|
4855
|
+
isComplete: moofComplete
|
|
4853
4856
|
};
|
|
4854
4857
|
}
|
|
4855
4858
|
return {
|
|
@@ -5052,6 +5055,20 @@ var getDurationFromWav = (state) => {
|
|
|
5052
5055
|
return durationInSeconds;
|
|
5053
5056
|
};
|
|
5054
5057
|
|
|
5058
|
+
// src/state/iso-base-media/precomputed-tfra.ts
|
|
5059
|
+
var precomputedTfraState = () => {
|
|
5060
|
+
let tfraBoxes = [];
|
|
5061
|
+
return {
|
|
5062
|
+
getTfraBoxes: () => tfraBoxes,
|
|
5063
|
+
setTfraBoxes: (boxes) => {
|
|
5064
|
+
tfraBoxes = boxes;
|
|
5065
|
+
}
|
|
5066
|
+
};
|
|
5067
|
+
};
|
|
5068
|
+
var deduplicateTfraBoxesByOffset = (tfraBoxes) => {
|
|
5069
|
+
return tfraBoxes.filter((m, i, arr) => i === arr.findIndex((t) => t.offset === m.offset));
|
|
5070
|
+
};
|
|
5071
|
+
|
|
5055
5072
|
// src/get-duration.ts
|
|
5056
5073
|
var getDurationFromMatroska = (segments) => {
|
|
5057
5074
|
const mainSegment = segments.find((s) => s.type === "Segment");
|
|
@@ -5089,7 +5106,14 @@ var getDurationFromIsoBaseMedia = (parserState) => {
|
|
|
5089
5106
|
return null;
|
|
5090
5107
|
}
|
|
5091
5108
|
const moofBoxes = getMoofBoxes(structure.boxes);
|
|
5092
|
-
const
|
|
5109
|
+
const mfra = parserState.iso.mfra.getIfAlreadyLoaded();
|
|
5110
|
+
const tfraBoxes = deduplicateTfraBoxesByOffset([
|
|
5111
|
+
...mfra ? getTfraBoxesFromMfraBoxChildren(mfra) : [],
|
|
5112
|
+
...getTfraBoxes(structure.boxes)
|
|
5113
|
+
]);
|
|
5114
|
+
if (!areSamplesComplete({ moofBoxes, tfraBoxes })) {
|
|
5115
|
+
return null;
|
|
5116
|
+
}
|
|
5093
5117
|
const mvhdBox = getMvhdBox(moovBox);
|
|
5094
5118
|
if (!mvhdBox) {
|
|
5095
5119
|
return null;
|
|
@@ -5111,7 +5135,7 @@ var getDurationFromIsoBaseMedia = (parserState) => {
|
|
|
5111
5135
|
const { samplePositions, isComplete } = getSamplePositionsFromTrack({
|
|
5112
5136
|
trakBox: t.trakBox,
|
|
5113
5137
|
moofBoxes,
|
|
5114
|
-
tfraBoxes
|
|
5138
|
+
moofComplete: areSamplesComplete({ moofBoxes, tfraBoxes })
|
|
5115
5139
|
});
|
|
5116
5140
|
if (!isComplete) {
|
|
5117
5141
|
return null;
|
|
@@ -5168,7 +5192,10 @@ var hasDuration = (parserState) => {
|
|
|
5168
5192
|
};
|
|
5169
5193
|
var hasSlowDuration = (parserState) => {
|
|
5170
5194
|
try {
|
|
5171
|
-
|
|
5195
|
+
if (!hasDuration(parserState)) {
|
|
5196
|
+
return false;
|
|
5197
|
+
}
|
|
5198
|
+
return getDuration(parserState) !== null;
|
|
5172
5199
|
} catch {
|
|
5173
5200
|
return false;
|
|
5174
5201
|
}
|
|
@@ -5196,13 +5223,16 @@ var getKeyframesFromIsoBaseMedia = (state) => {
|
|
|
5196
5223
|
});
|
|
5197
5224
|
const structure = state.structure.getIsoStructure();
|
|
5198
5225
|
const moofBoxes = getMoofBoxes(structure.boxes);
|
|
5199
|
-
const tfraBoxes = getTfraBoxes(structure);
|
|
5226
|
+
const tfraBoxes = getTfraBoxes(structure.boxes);
|
|
5200
5227
|
const allSamples = videoTracks.map((t) => {
|
|
5201
5228
|
const { timescale: ts } = t;
|
|
5202
5229
|
const { samplePositions, isComplete } = getSamplePositionsFromTrack({
|
|
5203
5230
|
trakBox: t.trakBox,
|
|
5204
5231
|
moofBoxes,
|
|
5205
|
-
|
|
5232
|
+
moofComplete: areSamplesComplete({
|
|
5233
|
+
moofBoxes,
|
|
5234
|
+
tfraBoxes
|
|
5235
|
+
})
|
|
5206
5236
|
});
|
|
5207
5237
|
if (!isComplete) {
|
|
5208
5238
|
return [];
|
|
@@ -5655,7 +5685,10 @@ var findAnyTrackWithSamplePositions = (allTracks, struc) => {
|
|
|
5655
5685
|
const { samplePositions } = getSamplePositionsFromTrack({
|
|
5656
5686
|
trakBox: track.trakBox,
|
|
5657
5687
|
moofBoxes: getMoofBoxes(struc.boxes),
|
|
5658
|
-
|
|
5688
|
+
moofComplete: areSamplesComplete({
|
|
5689
|
+
moofBoxes: getMoofBoxes(struc.boxes),
|
|
5690
|
+
tfraBoxes: getTfraBoxes(struc.boxes)
|
|
5691
|
+
})
|
|
5659
5692
|
});
|
|
5660
5693
|
if (samplePositions.length === 0) {
|
|
5661
5694
|
continue;
|
|
@@ -5674,7 +5707,10 @@ var findTrackToSeek = (allTracks, structure) => {
|
|
|
5674
5707
|
const { samplePositions } = getSamplePositionsFromTrack({
|
|
5675
5708
|
trakBox: firstVideoTrack.trakBox,
|
|
5676
5709
|
moofBoxes: getMoofBoxes(struc.boxes),
|
|
5677
|
-
|
|
5710
|
+
moofComplete: areSamplesComplete({
|
|
5711
|
+
moofBoxes: getMoofBoxes(struc.boxes),
|
|
5712
|
+
tfraBoxes: getTfraBoxes(struc.boxes)
|
|
5713
|
+
})
|
|
5678
5714
|
});
|
|
5679
5715
|
if (samplePositions.length === 0) {
|
|
5680
5716
|
return findAnyTrackWithSamplePositions(allTracks, struc);
|
|
@@ -5814,10 +5850,14 @@ var getSeekingByteFromFragmentedMp4 = async ({
|
|
|
5814
5850
|
if (!tkhdBox) {
|
|
5815
5851
|
throw new Error("Expected tkhd box in trak box");
|
|
5816
5852
|
}
|
|
5853
|
+
const isComplete = areSamplesComplete({
|
|
5854
|
+
moofBoxes: info.moofBoxes,
|
|
5855
|
+
tfraBoxes: info.tfraBoxes
|
|
5856
|
+
});
|
|
5817
5857
|
const { samplePositions: samplePositionsArray } = collectSamplePositionsFromMoofBoxes({
|
|
5818
5858
|
moofBoxes: info.moofBoxes,
|
|
5819
|
-
|
|
5820
|
-
|
|
5859
|
+
tkhdBox,
|
|
5860
|
+
isComplete
|
|
5821
5861
|
});
|
|
5822
5862
|
Log.trace(logLevel, "Fragmented MP4 - Checking if we have seeking info for this time range");
|
|
5823
5863
|
for (const positions of samplePositionsArray) {
|
|
@@ -7040,20 +7080,6 @@ var setSeekingHintsForFlac = ({
|
|
|
7040
7080
|
state.flac.audioSamples.setFromSeekingHints(hints.audioSampleMap);
|
|
7041
7081
|
};
|
|
7042
7082
|
|
|
7043
|
-
// src/state/iso-base-media/precomputed-tfra.ts
|
|
7044
|
-
var precomputedTfraState = () => {
|
|
7045
|
-
let tfraBoxes = [];
|
|
7046
|
-
return {
|
|
7047
|
-
getTfraBoxes: () => tfraBoxes,
|
|
7048
|
-
setTfraBoxes: (boxes) => {
|
|
7049
|
-
tfraBoxes = boxes;
|
|
7050
|
-
}
|
|
7051
|
-
};
|
|
7052
|
-
};
|
|
7053
|
-
var deduplicateTfraBoxesByOffset = (tfraBoxes) => {
|
|
7054
|
-
return tfraBoxes.filter((m, i, arr) => i === arr.findIndex((t) => t.offset === m.offset));
|
|
7055
|
-
};
|
|
7056
|
-
|
|
7057
7083
|
// src/containers/iso-base-media/seeking-hints.ts
|
|
7058
7084
|
var getSeekingHintsFromMp4 = ({
|
|
7059
7085
|
structureState,
|
|
@@ -7074,7 +7100,7 @@ var getSeekingHintsFromMp4 = ({
|
|
|
7074
7100
|
]);
|
|
7075
7101
|
const tfraBoxes = deduplicateTfraBoxesByOffset([
|
|
7076
7102
|
...isoState.tfra.getTfraBoxes(),
|
|
7077
|
-
...getTfraBoxes(structure)
|
|
7103
|
+
...getTfraBoxes(structure.boxes)
|
|
7078
7104
|
]);
|
|
7079
7105
|
if (!moovAtom) {
|
|
7080
7106
|
return null;
|
|
@@ -7333,6 +7359,7 @@ var seekBackwards = async ({
|
|
|
7333
7359
|
}
|
|
7334
7360
|
const time = Date.now();
|
|
7335
7361
|
Log.verbose(logLevel, `Seeking in video from position ${iterator.counter.getOffset()} -> ${seekTo}. Re-reading because this portion is not available.`);
|
|
7362
|
+
await currentReader.getCurrent().abort();
|
|
7336
7363
|
const { reader: newReader } = await readerInterface.read({
|
|
7337
7364
|
src,
|
|
7338
7365
|
range: seekTo,
|
|
@@ -7427,6 +7454,7 @@ var seekForward = async ({
|
|
|
7427
7454
|
}
|
|
7428
7455
|
const time = Date.now();
|
|
7429
7456
|
Log.verbose(logLevel, `Skipping over video data from position ${iterator.counter.getOffset()} -> ${seekTo}. Re-reading because this portion is not available`);
|
|
7457
|
+
await currentReader.getCurrent().abort();
|
|
7430
7458
|
const { reader: newReader } = await readerInterface.read({
|
|
7431
7459
|
src,
|
|
7432
7460
|
range: seekTo,
|
|
@@ -7807,7 +7835,7 @@ var emitAvailableInfo = async ({
|
|
|
7807
7835
|
}
|
|
7808
7836
|
if (key === "slowFps") {
|
|
7809
7837
|
if (hasInfo.slowFps && !emittedFields.slowFps) {
|
|
7810
|
-
const slowFps = state.samplesObserved.getFps();
|
|
7838
|
+
const slowFps = getFps(state) ?? state.samplesObserved.getFps();
|
|
7811
7839
|
await callbackFunctions.onSlowFps?.(slowFps);
|
|
7812
7840
|
if (fieldsInReturnValue.slowFps) {
|
|
7813
7841
|
returnValue.slowFps = slowFps;
|
|
@@ -8103,7 +8131,8 @@ var getAvailableInfo = ({
|
|
|
8103
8131
|
return Boolean(structure && hasDuration(state));
|
|
8104
8132
|
}
|
|
8105
8133
|
if (key === "slowDurationInSeconds") {
|
|
8106
|
-
|
|
8134
|
+
const res = Boolean(structure && hasSlowDuration(state));
|
|
8135
|
+
return res;
|
|
8107
8136
|
}
|
|
8108
8137
|
if (key === "dimensions" || key === "rotation" || key === "unrotatedDimensions") {
|
|
8109
8138
|
return Boolean(structure && hasDimensions(state));
|
|
@@ -8781,18 +8810,31 @@ var parseFlac = ({
|
|
|
8781
8810
|
};
|
|
8782
8811
|
|
|
8783
8812
|
// src/state/iso-base-media/cached-sample-positions.ts
|
|
8784
|
-
var calculateFlatSamples = (
|
|
8813
|
+
var calculateFlatSamples = ({
|
|
8814
|
+
state,
|
|
8815
|
+
mediaSectionStart
|
|
8816
|
+
}) => {
|
|
8785
8817
|
const tracks2 = getTracks(state, true);
|
|
8786
8818
|
const allTracks = [
|
|
8787
8819
|
...tracks2.videoTracks,
|
|
8788
8820
|
...tracks2.audioTracks,
|
|
8789
8821
|
...tracks2.otherTracks
|
|
8790
8822
|
];
|
|
8823
|
+
const moofBoxes = getMoofBoxes(state.structure.getIsoStructure().boxes);
|
|
8824
|
+
const tfraBoxes = deduplicateTfraBoxesByOffset([
|
|
8825
|
+
...state.iso.tfra.getTfraBoxes(),
|
|
8826
|
+
...getTfraBoxes(state.structure.getIsoStructure().boxes)
|
|
8827
|
+
]);
|
|
8828
|
+
const moofComplete = areSamplesComplete({ moofBoxes, tfraBoxes });
|
|
8829
|
+
const relevantMoofBox = moofBoxes.find((moofBox) => moofBox.offset + moofBox.size + 8 === mediaSectionStart);
|
|
8830
|
+
if (moofBoxes.length > 0 && !relevantMoofBox) {
|
|
8831
|
+
throw new Error("No relevant moof box found");
|
|
8832
|
+
}
|
|
8791
8833
|
const flatSamples = allTracks.map((track) => {
|
|
8792
8834
|
const { samplePositions } = getSamplePositionsFromTrack({
|
|
8793
8835
|
trakBox: track.trakBox,
|
|
8794
|
-
moofBoxes:
|
|
8795
|
-
|
|
8836
|
+
moofBoxes: relevantMoofBox ? [relevantMoofBox] : [],
|
|
8837
|
+
moofComplete
|
|
8796
8838
|
});
|
|
8797
8839
|
return samplePositions.map((samplePosition) => {
|
|
8798
8840
|
return {
|
|
@@ -8808,10 +8850,7 @@ var cachedSamplePositionsState = () => {
|
|
|
8808
8850
|
const jumpMarksForMdatStart = {};
|
|
8809
8851
|
return {
|
|
8810
8852
|
getSamples: (mdatStart) => {
|
|
8811
|
-
|
|
8812
|
-
return cachedForMdatStart[mdatStart];
|
|
8813
|
-
}
|
|
8814
|
-
return null;
|
|
8853
|
+
return cachedForMdatStart[mdatStart] ?? null;
|
|
8815
8854
|
},
|
|
8816
8855
|
setSamples: (mdatStart, samples) => {
|
|
8817
8856
|
cachedForMdatStart[mdatStart] = samples;
|
|
@@ -8825,6 +8864,24 @@ var cachedSamplePositionsState = () => {
|
|
|
8825
8864
|
};
|
|
8826
8865
|
};
|
|
8827
8866
|
|
|
8867
|
+
// src/state/iso-base-media/last-moof-box.ts
|
|
8868
|
+
var getLastMoofBox = (boxes) => {
|
|
8869
|
+
if (boxes) {
|
|
8870
|
+
const tfras = boxes.filter((b) => b.type === "tfra-box");
|
|
8871
|
+
const lastMoofOffsets = tfras.map((f) => {
|
|
8872
|
+
if (f.entries.length <= 1) {
|
|
8873
|
+
return null;
|
|
8874
|
+
}
|
|
8875
|
+
return f.entries[f.entries.length - 1].moofOffset;
|
|
8876
|
+
});
|
|
8877
|
+
if (lastMoofOffsets.length > 0) {
|
|
8878
|
+
const maxOffset = Math.max(...lastMoofOffsets.filter(truthy));
|
|
8879
|
+
return maxOffset;
|
|
8880
|
+
}
|
|
8881
|
+
return null;
|
|
8882
|
+
}
|
|
8883
|
+
};
|
|
8884
|
+
|
|
8828
8885
|
// src/state/can-skip-tracks.ts
|
|
8829
8886
|
var needsTracksForField = ({
|
|
8830
8887
|
field,
|
|
@@ -10566,13 +10623,13 @@ var processBox = async ({
|
|
|
10566
10623
|
if (boxType === "ftyp") {
|
|
10567
10624
|
return {
|
|
10568
10625
|
type: "box",
|
|
10569
|
-
box:
|
|
10626
|
+
box: parseFtyp({ iterator, size: boxSize, offset: fileOffset })
|
|
10570
10627
|
};
|
|
10571
10628
|
}
|
|
10572
10629
|
if (boxType === "colr") {
|
|
10573
10630
|
return {
|
|
10574
10631
|
type: "box",
|
|
10575
|
-
box:
|
|
10632
|
+
box: parseColorParameterBox({
|
|
10576
10633
|
iterator,
|
|
10577
10634
|
size: boxSize
|
|
10578
10635
|
})
|
|
@@ -10581,25 +10638,25 @@ var processBox = async ({
|
|
|
10581
10638
|
if (boxType === "mvhd") {
|
|
10582
10639
|
return {
|
|
10583
10640
|
type: "box",
|
|
10584
|
-
box:
|
|
10641
|
+
box: parseMvhd({ iterator, offset: fileOffset, size: boxSize })
|
|
10585
10642
|
};
|
|
10586
10643
|
}
|
|
10587
10644
|
if (boxType === "tkhd") {
|
|
10588
10645
|
return {
|
|
10589
10646
|
type: "box",
|
|
10590
|
-
box:
|
|
10647
|
+
box: parseTkhd({ iterator, offset: fileOffset, size: boxSize })
|
|
10591
10648
|
};
|
|
10592
10649
|
}
|
|
10593
10650
|
if (boxType === "trun") {
|
|
10594
10651
|
return {
|
|
10595
10652
|
type: "box",
|
|
10596
|
-
box:
|
|
10653
|
+
box: parseTrun({ iterator, offset: fileOffset, size: boxSize })
|
|
10597
10654
|
};
|
|
10598
10655
|
}
|
|
10599
10656
|
if (boxType === "tfdt") {
|
|
10600
10657
|
return {
|
|
10601
10658
|
type: "box",
|
|
10602
|
-
box:
|
|
10659
|
+
box: parseTfdt({ iterator, size: boxSize, offset: fileOffset })
|
|
10603
10660
|
};
|
|
10604
10661
|
}
|
|
10605
10662
|
if (boxType === "stsd") {
|
|
@@ -10848,7 +10905,7 @@ var processBox = async ({
|
|
|
10848
10905
|
};
|
|
10849
10906
|
}
|
|
10850
10907
|
if (boxType === "moof") {
|
|
10851
|
-
onlyIfMoovAtomExpected?.isoState?.mfra.triggerLoad();
|
|
10908
|
+
await onlyIfMoovAtomExpected?.isoState?.mfra.triggerLoad();
|
|
10852
10909
|
}
|
|
10853
10910
|
if (boxType === "mdia" || boxType === "minf" || boxType === "stbl" || boxType === "udta" || boxType === "moof" || boxType === "dims" || boxType === "meta" || boxType === "wave" || boxType === "traf" || boxType === "mfra" || boxType === "stsb") {
|
|
10854
10911
|
const children = await getIsoBaseMediaChildren({
|
|
@@ -11124,6 +11181,14 @@ var parseMdatSection = async (state) => {
|
|
|
11124
11181
|
}
|
|
11125
11182
|
const endOfMdat = mediaSection.size + mediaSection.start;
|
|
11126
11183
|
if (maySkipVideoData({ state })) {
|
|
11184
|
+
const mfra = state.iso.mfra.getIfAlreadyLoaded();
|
|
11185
|
+
if (mfra) {
|
|
11186
|
+
const lastMoof = getLastMoofBox(mfra);
|
|
11187
|
+
if (lastMoof && lastMoof > endOfMdat) {
|
|
11188
|
+
Log.verbose(state.logLevel, "Skipping to last moof", lastMoof, "end of mdat", endOfMdat);
|
|
11189
|
+
return makeSkip(lastMoof);
|
|
11190
|
+
}
|
|
11191
|
+
}
|
|
11127
11192
|
return makeSkip(endOfMdat);
|
|
11128
11193
|
}
|
|
11129
11194
|
const alreadyHasMoov = getHasTracks(state, true);
|
|
@@ -11141,7 +11206,10 @@ var parseMdatSection = async (state) => {
|
|
|
11141
11206
|
return parseMdatSection(state);
|
|
11142
11207
|
}
|
|
11143
11208
|
if (!state.iso.flatSamples.getSamples(mediaSection.start)) {
|
|
11144
|
-
const flattedSamples = calculateFlatSamples(
|
|
11209
|
+
const flattedSamples = calculateFlatSamples({
|
|
11210
|
+
state,
|
|
11211
|
+
mediaSectionStart: mediaSection.start
|
|
11212
|
+
});
|
|
11145
11213
|
const calcedJumpMarks = calculateJumpMarks(flattedSamples, endOfMdat);
|
|
11146
11214
|
state.iso.flatSamples.setJumpMarks(mediaSection.start, calcedJumpMarks);
|
|
11147
11215
|
state.iso.flatSamples.setSamples(mediaSection.start, flattedSamples.flat(1));
|
|
@@ -11158,9 +11226,11 @@ var parseMdatSection = async (state) => {
|
|
|
11158
11226
|
iterator.discard(nextSample_.samplePosition.offset - iterator.counter.getOffset());
|
|
11159
11227
|
return null;
|
|
11160
11228
|
}
|
|
11229
|
+
Log.verbose(state.logLevel, "Could not find sample at offset", iterator.counter.getOffset(), "skipping to end of mdat");
|
|
11161
11230
|
return makeSkip(endOfMdat);
|
|
11162
11231
|
}
|
|
11163
11232
|
if (samplesWithIndex.samplePosition.offset + samplesWithIndex.samplePosition.size > state.contentLength) {
|
|
11233
|
+
Log.verbose(state.logLevel, "Sample is beyond the end of the file. Don't process it.", samplesWithIndex.samplePosition.offset + samplesWithIndex.samplePosition.size, endOfMdat);
|
|
11164
11234
|
return makeSkip(endOfMdat);
|
|
11165
11235
|
}
|
|
11166
11236
|
if (iterator.bytesRemaining() < samplesWithIndex.samplePosition.size) {
|
|
@@ -11214,6 +11284,7 @@ var parseMdatSection = async (state) => {
|
|
|
11214
11284
|
}
|
|
11215
11285
|
const jump = jumpMarks.find((j) => j.afterSampleWithOffset === offset);
|
|
11216
11286
|
if (jump) {
|
|
11287
|
+
Log.verbose(state.logLevel, "Found jump mark", jump.jumpToOffset, "skipping to jump mark");
|
|
11217
11288
|
return makeSkip(jump.jumpToOffset);
|
|
11218
11289
|
}
|
|
11219
11290
|
return null;
|
|
@@ -16569,6 +16640,7 @@ var makeParserState = ({
|
|
|
16569
16640
|
fields: fieldsInReturnValue,
|
|
16570
16641
|
callbacks
|
|
16571
16642
|
});
|
|
16643
|
+
const mediaSection = mediaSectionState();
|
|
16572
16644
|
return {
|
|
16573
16645
|
riff: riffSpecificState({
|
|
16574
16646
|
controller,
|
|
@@ -16626,7 +16698,7 @@ var makeParserState = ({
|
|
|
16626
16698
|
samplesObserved,
|
|
16627
16699
|
contentLength,
|
|
16628
16700
|
images,
|
|
16629
|
-
mediaSection
|
|
16701
|
+
mediaSection,
|
|
16630
16702
|
logLevel,
|
|
16631
16703
|
iterator,
|
|
16632
16704
|
controller,
|
package/dist/get-duration.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.hasSlowDuration = exports.hasDuration = exports.getDuration = exports.isMatroska = void 0;
|
|
4
4
|
const get_duration_from_flac_1 = require("./containers/flac/get-duration-from-flac");
|
|
5
|
+
const are_samples_complete_1 = require("./containers/iso-base-media/are-samples-complete");
|
|
5
6
|
const get_sample_positions_from_track_1 = require("./containers/iso-base-media/get-sample-positions-from-track");
|
|
6
7
|
const traversal_1 = require("./containers/iso-base-media/traversal");
|
|
7
8
|
const get_duration_from_m3u_1 = require("./containers/m3u/get-duration-from-m3u");
|
|
@@ -9,6 +10,7 @@ const get_duration_1 = require("./containers/mp3/get-duration");
|
|
|
9
10
|
const get_duration_2 = require("./containers/riff/get-duration");
|
|
10
11
|
const get_duration_from_wav_1 = require("./containers/wav/get-duration-from-wav");
|
|
11
12
|
const get_tracks_1 = require("./get-tracks");
|
|
13
|
+
const precomputed_tfra_1 = require("./state/iso-base-media/precomputed-tfra");
|
|
12
14
|
const getDurationFromMatroska = (segments) => {
|
|
13
15
|
const mainSegment = segments.find((s) => s.type === 'Segment');
|
|
14
16
|
if (!mainSegment || mainSegment.type !== 'Segment') {
|
|
@@ -51,7 +53,14 @@ const getDurationFromIsoBaseMedia = (parserState) => {
|
|
|
51
53
|
return null;
|
|
52
54
|
}
|
|
53
55
|
const moofBoxes = (0, traversal_1.getMoofBoxes)(structure.boxes);
|
|
54
|
-
const
|
|
56
|
+
const mfra = parserState.iso.mfra.getIfAlreadyLoaded();
|
|
57
|
+
const tfraBoxes = (0, precomputed_tfra_1.deduplicateTfraBoxesByOffset)([
|
|
58
|
+
...(mfra ? (0, traversal_1.getTfraBoxesFromMfraBoxChildren)(mfra) : []),
|
|
59
|
+
...(0, traversal_1.getTfraBoxes)(structure.boxes),
|
|
60
|
+
]);
|
|
61
|
+
if (!(0, are_samples_complete_1.areSamplesComplete)({ moofBoxes, tfraBoxes })) {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
55
64
|
const mvhdBox = (0, traversal_1.getMvhdBox)(moovBox);
|
|
56
65
|
if (!mvhdBox) {
|
|
57
66
|
return null;
|
|
@@ -73,7 +82,7 @@ const getDurationFromIsoBaseMedia = (parserState) => {
|
|
|
73
82
|
const { samplePositions, isComplete } = (0, get_sample_positions_from_track_1.getSamplePositionsFromTrack)({
|
|
74
83
|
trakBox: t.trakBox,
|
|
75
84
|
moofBoxes,
|
|
76
|
-
tfraBoxes,
|
|
85
|
+
moofComplete: (0, are_samples_complete_1.areSamplesComplete)({ moofBoxes, tfraBoxes }),
|
|
77
86
|
});
|
|
78
87
|
if (!isComplete) {
|
|
79
88
|
return null;
|
|
@@ -136,7 +145,10 @@ exports.hasDuration = hasDuration;
|
|
|
136
145
|
// Unless it it somewhere in the metadata and is non-null
|
|
137
146
|
const hasSlowDuration = (parserState) => {
|
|
138
147
|
try {
|
|
139
|
-
|
|
148
|
+
if (!(0, exports.hasDuration)(parserState)) {
|
|
149
|
+
return false;
|
|
150
|
+
}
|
|
151
|
+
return (0, exports.getDuration)(parserState) !== null;
|
|
140
152
|
}
|
|
141
153
|
catch (_a) {
|
|
142
154
|
return false;
|
package/dist/has-all-info.js
CHANGED
|
@@ -27,7 +27,8 @@ const getAvailableInfo = ({ state, }) => {
|
|
|
27
27
|
return Boolean(structure && (0, get_duration_1.hasDuration)(state));
|
|
28
28
|
}
|
|
29
29
|
if (key === 'slowDurationInSeconds') {
|
|
30
|
-
|
|
30
|
+
const res = Boolean(structure && (0, get_duration_1.hasSlowDuration)(state));
|
|
31
|
+
return res;
|
|
31
32
|
}
|
|
32
33
|
if (key === 'dimensions' ||
|
|
33
34
|
key === 'rotation' ||
|
package/dist/index.d.ts
CHANGED
|
@@ -858,7 +858,7 @@ export declare const MediaParserInternals: {
|
|
|
858
858
|
};
|
|
859
859
|
iso: {
|
|
860
860
|
flatSamples: {
|
|
861
|
-
getSamples: (mdatStart: number) => import("./state/iso-base-media/cached-sample-positions").FlatSample[]
|
|
861
|
+
getSamples: (mdatStart: number) => import("./state/iso-base-media/cached-sample-positions").FlatSample[];
|
|
862
862
|
setSamples: (mdatStart: number, samples: import("./state/iso-base-media/cached-sample-positions").FlatSample[]) => void;
|
|
863
863
|
setJumpMarks: (mdatStart: number, marks: import("./containers/iso-base-media/mdat/calculate-jump-marks").JumpMark[]) => void;
|
|
864
864
|
getJumpMarks: (mdatStart: number) => import("./containers/iso-base-media/mdat/calculate-jump-marks").JumpMark[];
|
|
@@ -33,8 +33,9 @@ const getLengthAndReader = async ({ canLiveWithoutContentLength, res, ownControl
|
|
|
33
33
|
contentLength: encoded.byteLength,
|
|
34
34
|
reader: {
|
|
35
35
|
reader: stream.getReader(),
|
|
36
|
-
abort() {
|
|
36
|
+
abort: () => {
|
|
37
37
|
ownController.abort();
|
|
38
|
+
return Promise.resolve();
|
|
38
39
|
},
|
|
39
40
|
},
|
|
40
41
|
needsContentRange: false,
|
|
@@ -49,6 +50,7 @@ const getLengthAndReader = async ({ canLiveWithoutContentLength, res, ownControl
|
|
|
49
50
|
reader,
|
|
50
51
|
abort: () => {
|
|
51
52
|
ownController.abort();
|
|
53
|
+
return Promise.resolve();
|
|
52
54
|
},
|
|
53
55
|
},
|
|
54
56
|
contentLength,
|
|
@@ -15,7 +15,6 @@ const nodeReadContent = ({ src, range, controller }) => {
|
|
|
15
15
|
: typeof range === 'number'
|
|
16
16
|
? Infinity
|
|
17
17
|
: range[1],
|
|
18
|
-
signal: ownController.signal,
|
|
19
18
|
});
|
|
20
19
|
controller._internals.signal.addEventListener('abort', () => {
|
|
21
20
|
ownController.abort();
|
|
@@ -50,8 +49,13 @@ const nodeReadContent = ({ src, range, controller }) => {
|
|
|
50
49
|
return Promise.resolve({
|
|
51
50
|
reader: {
|
|
52
51
|
reader,
|
|
53
|
-
abort: () => {
|
|
54
|
-
|
|
52
|
+
abort: async () => {
|
|
53
|
+
try {
|
|
54
|
+
stream.destroy();
|
|
55
|
+
ownController.abort();
|
|
56
|
+
await reader.cancel();
|
|
57
|
+
}
|
|
58
|
+
catch (_a) { }
|
|
55
59
|
},
|
|
56
60
|
},
|
|
57
61
|
contentLength: stats.size,
|