@remotion/media-parser 4.0.333 → 4.0.334
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/mdat/mdat.js +39 -47
- package/dist/esm/index.mjs +129 -181
- package/dist/esm/worker-server-entry.mjs +128 -180
- package/dist/esm/worker-web-entry.mjs +128 -180
- package/dist/index.d.ts +11 -4
- package/dist/parse-loop.js +1 -0
- package/dist/perform-seek.d.ts +3 -1
- package/dist/perform-seek.js +4 -1
- package/dist/state/iso-base-media/cached-sample-positions.d.ts +17 -25
- package/dist/state/iso-base-media/cached-sample-positions.js +83 -24
- package/dist/state/iso-base-media/iso-state.d.ts +11 -4
- package/dist/state/parser-state.d.ts +11 -4
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/work-on-seek-request.js +2 -0
- package/package.json +3 -3
|
@@ -11,7 +11,6 @@ const may_skip_video_data_1 = require("../../../state/may-skip-video-data");
|
|
|
11
11
|
const video_section_1 = require("../../../state/video-section");
|
|
12
12
|
const webcodecs_timescale_1 = require("../../../webcodecs-timescale");
|
|
13
13
|
const get_moov_atom_1 = require("../get-moov-atom");
|
|
14
|
-
const calculate_jump_marks_1 = require("./calculate-jump-marks");
|
|
15
14
|
const postprocess_bytes_1 = require("./postprocess-bytes");
|
|
16
15
|
const parseMdatSection = async (state) => {
|
|
17
16
|
const mediaSection = (0, video_section_1.getCurrentMediaSection)({
|
|
@@ -57,63 +56,60 @@ const parseMdatSection = async (state) => {
|
|
|
57
56
|
endOfMdat,
|
|
58
57
|
state,
|
|
59
58
|
});
|
|
59
|
+
const tracksFromMoov = (0, get_tracks_1.getTracksFromMoovBox)(moov);
|
|
60
60
|
state.iso.moov.setMoovBox({
|
|
61
61
|
moovBox: moov,
|
|
62
62
|
precomputed: false,
|
|
63
63
|
});
|
|
64
|
+
const existingTracks = state.callbacks.tracks.getTracks();
|
|
65
|
+
for (const trackFromMoov of tracksFromMoov) {
|
|
66
|
+
if (existingTracks.find((t) => t.trackId === trackFromMoov.trackId)) {
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
if (trackFromMoov.type === 'other') {
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
state.callbacks.tracks.addTrack(trackFromMoov);
|
|
73
|
+
}
|
|
64
74
|
state.callbacks.tracks.setIsDone(state.logLevel);
|
|
65
75
|
state.structure.getIsoStructure().boxes.push(moov);
|
|
66
76
|
return (0, exports.parseMdatSection)(state);
|
|
67
77
|
}
|
|
78
|
+
const tracks = state.callbacks.tracks.getTracks();
|
|
68
79
|
if (!state.iso.flatSamples.getSamples(mediaSection.start)) {
|
|
69
|
-
const
|
|
80
|
+
const samplePosition = (0, cached_sample_positions_1.calculateSamplePositions)({
|
|
70
81
|
state,
|
|
71
82
|
mediaSectionStart: mediaSection.start,
|
|
83
|
+
trackIds: tracks.map((t) => t.trackId),
|
|
72
84
|
});
|
|
73
|
-
|
|
74
|
-
sampleMap: flatSamplesMap,
|
|
75
|
-
offsetsSorted: offsets,
|
|
76
|
-
trackIds,
|
|
77
|
-
endOfMdat,
|
|
78
|
-
});
|
|
79
|
-
state.iso.flatSamples.setJumpMarks(mediaSection.start, calcedJumpMarks);
|
|
80
|
-
state.iso.flatSamples.setSamples(mediaSection.start, flatSamplesMap);
|
|
85
|
+
state.iso.flatSamples.setSamples(mediaSection.start, samplePosition);
|
|
81
86
|
}
|
|
82
|
-
const
|
|
83
|
-
const
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
// There are various reasons why in mdat we find weird stuff:
|
|
88
|
-
// - iphonevideo.hevc has a fake hoov atom which is not mapped
|
|
89
|
-
// - corrupted.mp4 has a corrupt table
|
|
90
|
-
const offsets = Array.from(flatSamples.keys());
|
|
91
|
-
const nextSample_ = offsets
|
|
92
|
-
.filter((s) => s > iterator.counter.getOffset())
|
|
93
|
-
.sort((a, b) => a - b)[0];
|
|
94
|
-
if (nextSample_) {
|
|
95
|
-
iterator.discard(nextSample_ - iterator.counter.getOffset());
|
|
96
|
-
return null;
|
|
97
|
-
}
|
|
98
|
-
// guess we reached the end!
|
|
99
|
-
// iphonevideo.mov has extra padding here, so let's make sure to jump ahead
|
|
100
|
-
log_1.Log.verbose(state.logLevel, 'Could not find sample at offset', iterator.counter.getOffset(), 'skipping to end of mdat');
|
|
87
|
+
const samplePositions = state.iso.flatSamples.getSamples(mediaSection.start);
|
|
88
|
+
const sampleIndices = state.iso.flatSamples.getCurrentSampleIndices(mediaSection.start);
|
|
89
|
+
const nextSampleArray = (0, cached_sample_positions_1.getSampleWithLowestDts)(samplePositions, sampleIndices);
|
|
90
|
+
if (nextSampleArray.length === 0) {
|
|
91
|
+
log_1.Log.verbose(state.logLevel, 'Iterated over all samples.', endOfMdat);
|
|
101
92
|
return (0, skip_1.makeSkip)(endOfMdat);
|
|
102
93
|
}
|
|
94
|
+
const exactMatch = nextSampleArray.find((s) => s.samplePosition.offset === state.iterator.counter.getOffset());
|
|
95
|
+
const nextSample = exactMatch !== null && exactMatch !== void 0 ? exactMatch : nextSampleArray[0];
|
|
96
|
+
if (nextSample.samplePosition.offset !== state.iterator.counter.getOffset()) {
|
|
97
|
+
return (0, skip_1.makeSkip)(nextSample.samplePosition.offset);
|
|
98
|
+
}
|
|
103
99
|
// Corrupt file: Sample is beyond the end of the file. Don't process it.
|
|
104
|
-
if (
|
|
105
|
-
samplesWithIndex.samplePosition.size >
|
|
100
|
+
if (nextSample.samplePosition.offset + nextSample.samplePosition.size >
|
|
106
101
|
state.contentLength) {
|
|
107
|
-
log_1.Log.verbose(state.logLevel, "Sample is beyond the end of the file. Don't process it.",
|
|
108
|
-
samplesWithIndex.samplePosition.size, endOfMdat);
|
|
102
|
+
log_1.Log.verbose(state.logLevel, "Sample is beyond the end of the file. Don't process it.", nextSample.samplePosition.offset + nextSample.samplePosition.size, endOfMdat);
|
|
109
103
|
return (0, skip_1.makeSkip)(endOfMdat);
|
|
110
104
|
}
|
|
105
|
+
const { iterator } = state;
|
|
111
106
|
// Need to fetch more data
|
|
112
|
-
if (iterator.bytesRemaining() <
|
|
113
|
-
return (0, skip_1.makeFetchMoreData)(
|
|
107
|
+
if (iterator.bytesRemaining() < nextSample.samplePosition.size) {
|
|
108
|
+
return (0, skip_1.makeFetchMoreData)(nextSample.samplePosition.size - iterator.bytesRemaining());
|
|
114
109
|
}
|
|
115
|
-
const { timestamp: rawCts, decodingTimestamp: rawDts, duration, isKeyframe, offset, bigEndian, chunkSize, } =
|
|
116
|
-
const
|
|
110
|
+
const { timestamp: rawCts, decodingTimestamp: rawDts, duration, isKeyframe, offset, bigEndian, chunkSize, } = nextSample.samplePosition;
|
|
111
|
+
const track = tracks.find((t) => t.trackId === nextSample.trackId);
|
|
112
|
+
const { originalTimescale, startInSeconds, trackMediaTimeOffsetInTrackTimescale, timescale: trackTimescale, } = track;
|
|
117
113
|
const cts = rawCts +
|
|
118
114
|
startInSeconds * originalTimescale -
|
|
119
115
|
(trackMediaTimeOffsetInTrackTimescale / trackTimescale) *
|
|
@@ -123,11 +119,11 @@ const parseMdatSection = async (state) => {
|
|
|
123
119
|
(trackMediaTimeOffsetInTrackTimescale / trackTimescale) *
|
|
124
120
|
webcodecs_timescale_1.WEBCODECS_TIMESCALE;
|
|
125
121
|
const bytes = (0, postprocess_bytes_1.postprocessBytes)({
|
|
126
|
-
bytes: iterator.getSlice(
|
|
122
|
+
bytes: iterator.getSlice(nextSample.samplePosition.size),
|
|
127
123
|
bigEndian,
|
|
128
124
|
chunkSize,
|
|
129
125
|
});
|
|
130
|
-
if (
|
|
126
|
+
if (track.type === 'audio') {
|
|
131
127
|
const audioSample = (0, convert_audio_or_video_sample_1.convertAudioOrVideoSampleToWebCodecsTimestamps)({
|
|
132
128
|
sample: {
|
|
133
129
|
data: bytes,
|
|
@@ -141,10 +137,10 @@ const parseMdatSection = async (state) => {
|
|
|
141
137
|
});
|
|
142
138
|
await state.callbacks.onAudioSample({
|
|
143
139
|
audioSample,
|
|
144
|
-
trackId:
|
|
140
|
+
trackId: track.trackId,
|
|
145
141
|
});
|
|
146
142
|
}
|
|
147
|
-
if (
|
|
143
|
+
if (track.type === 'video') {
|
|
148
144
|
// https://pub-646d808d9cb240cea53bedc76dd3cd0c.r2.dev/sei_checkpoint.mp4
|
|
149
145
|
// Position in file 0x0001aba615
|
|
150
146
|
// https://github.com/remotion-dev/remotion/issues/4680
|
|
@@ -170,14 +166,10 @@ const parseMdatSection = async (state) => {
|
|
|
170
166
|
});
|
|
171
167
|
await state.callbacks.onVideoSample({
|
|
172
168
|
videoSample,
|
|
173
|
-
trackId:
|
|
169
|
+
trackId: track.trackId,
|
|
174
170
|
});
|
|
175
171
|
}
|
|
176
|
-
|
|
177
|
-
if (jump) {
|
|
178
|
-
log_1.Log.verbose(state.logLevel, 'Found jump mark', jump.jumpToOffset, 'skipping to jump mark');
|
|
179
|
-
return (0, skip_1.makeSkip)(jump.jumpToOffset);
|
|
180
|
-
}
|
|
172
|
+
state.iso.flatSamples.setCurrentSampleIndex(mediaSection.start, nextSample.trackId, nextSample.index + 1);
|
|
181
173
|
return null;
|
|
182
174
|
};
|
|
183
175
|
exports.parseMdatSection = parseMdatSection;
|
package/dist/esm/index.mjs
CHANGED
|
@@ -10035,7 +10035,8 @@ var performSeek = async ({
|
|
|
10035
10035
|
src,
|
|
10036
10036
|
discardReadBytes,
|
|
10037
10037
|
fields,
|
|
10038
|
-
prefetchCache
|
|
10038
|
+
prefetchCache,
|
|
10039
|
+
isoState
|
|
10039
10040
|
}) => {
|
|
10040
10041
|
const byteInMediaSection = isByteInMediaSection({
|
|
10041
10042
|
position: seekTo,
|
|
@@ -10099,6 +10100,9 @@ var performSeek = async ({
|
|
|
10099
10100
|
prefetchCache
|
|
10100
10101
|
});
|
|
10101
10102
|
}
|
|
10103
|
+
if (userInitiated) {
|
|
10104
|
+
isoState.flatSamples.updateAfterSeek(seekTo);
|
|
10105
|
+
}
|
|
10102
10106
|
await controller._internals.checkForAbortAndPause();
|
|
10103
10107
|
};
|
|
10104
10108
|
|
|
@@ -10277,7 +10281,8 @@ var workOnSeekRequest = async (options) => {
|
|
|
10277
10281
|
src,
|
|
10278
10282
|
discardReadBytes,
|
|
10279
10283
|
fields,
|
|
10280
|
-
prefetchCache
|
|
10284
|
+
prefetchCache,
|
|
10285
|
+
isoState
|
|
10281
10286
|
});
|
|
10282
10287
|
return;
|
|
10283
10288
|
}
|
|
@@ -10297,7 +10302,8 @@ var workOnSeekRequest = async (options) => {
|
|
|
10297
10302
|
src,
|
|
10298
10303
|
discardReadBytes,
|
|
10299
10304
|
fields,
|
|
10300
|
-
prefetchCache
|
|
10305
|
+
prefetchCache,
|
|
10306
|
+
isoState
|
|
10301
10307
|
});
|
|
10302
10308
|
const { hasChanged } = controller._internals.seekSignal.clearSeekIfStillSame(seek2);
|
|
10303
10309
|
if (hasChanged) {
|
|
@@ -11397,9 +11403,10 @@ var parseFlac = ({
|
|
|
11397
11403
|
};
|
|
11398
11404
|
|
|
11399
11405
|
// src/state/iso-base-media/cached-sample-positions.ts
|
|
11400
|
-
var
|
|
11406
|
+
var calculateSamplePositions = ({
|
|
11401
11407
|
state,
|
|
11402
|
-
mediaSectionStart
|
|
11408
|
+
mediaSectionStart,
|
|
11409
|
+
trackIds
|
|
11403
11410
|
}) => {
|
|
11404
11411
|
const tracks2 = getTracks(state, true);
|
|
11405
11412
|
const moofBoxes = getMoofBoxes(state.structure.getIsoStructure().boxes);
|
|
@@ -11421,11 +11428,13 @@ var calculateFlatSamples = ({
|
|
|
11421
11428
|
if (!moov) {
|
|
11422
11429
|
throw new Error("No moov box found");
|
|
11423
11430
|
}
|
|
11424
|
-
const
|
|
11425
|
-
const trackIds = [];
|
|
11426
|
-
const map = new Map;
|
|
11431
|
+
const trackIdAndSamplePositions = [];
|
|
11427
11432
|
for (const track of tracks2) {
|
|
11428
11433
|
const trakBox = getTrakBoxByTrackId(moov, track.trackId);
|
|
11434
|
+
if (!trackIds.includes(track.trackId)) {
|
|
11435
|
+
Log.verbose(state.logLevel, "Skipping calculating sample positions for track", track.trackId);
|
|
11436
|
+
continue;
|
|
11437
|
+
}
|
|
11429
11438
|
if (!trakBox) {
|
|
11430
11439
|
throw new Error("No trak box found");
|
|
11431
11440
|
}
|
|
@@ -11435,36 +11444,88 @@ var calculateFlatSamples = ({
|
|
|
11435
11444
|
moofComplete,
|
|
11436
11445
|
trexBoxes: getTrexBoxes(moov)
|
|
11437
11446
|
});
|
|
11438
|
-
|
|
11439
|
-
|
|
11440
|
-
|
|
11441
|
-
|
|
11442
|
-
|
|
11443
|
-
|
|
11444
|
-
|
|
11447
|
+
trackIdAndSamplePositions.push({
|
|
11448
|
+
trackId: track.trackId,
|
|
11449
|
+
samplePositions
|
|
11450
|
+
});
|
|
11451
|
+
}
|
|
11452
|
+
return trackIdAndSamplePositions;
|
|
11453
|
+
};
|
|
11454
|
+
var updateSampleIndicesAfterSeek = ({
|
|
11455
|
+
samplePositionsForMdatStart,
|
|
11456
|
+
seekedByte
|
|
11457
|
+
}) => {
|
|
11458
|
+
const currentSampleIndices = {};
|
|
11459
|
+
const keys = Object.keys(samplePositionsForMdatStart).map(Number).sort();
|
|
11460
|
+
const mdat = keys.find((key) => seekedByte >= key);
|
|
11461
|
+
if (!mdat) {
|
|
11462
|
+
return currentSampleIndices;
|
|
11463
|
+
}
|
|
11464
|
+
const samplePositions = samplePositionsForMdatStart[mdat];
|
|
11465
|
+
if (!samplePositions) {
|
|
11466
|
+
return currentSampleIndices;
|
|
11467
|
+
}
|
|
11468
|
+
for (const track of samplePositions) {
|
|
11469
|
+
const currentSampleIndex = track.samplePositions.findIndex((sample) => sample.offset >= seekedByte);
|
|
11470
|
+
if (!currentSampleIndices[mdat]) {
|
|
11471
|
+
currentSampleIndices[mdat] = {};
|
|
11472
|
+
}
|
|
11473
|
+
if (!currentSampleIndices[mdat][track.trackId]) {
|
|
11474
|
+
currentSampleIndices[mdat][track.trackId] = 0;
|
|
11475
|
+
}
|
|
11476
|
+
if (currentSampleIndex === -1) {
|
|
11477
|
+
currentSampleIndices[mdat][track.trackId] = track.samplePositions.length;
|
|
11478
|
+
} else {
|
|
11479
|
+
currentSampleIndices[mdat][track.trackId] = currentSampleIndex;
|
|
11445
11480
|
}
|
|
11446
11481
|
}
|
|
11447
|
-
|
|
11448
|
-
return { flatSamples: map, offsets, trackIds };
|
|
11482
|
+
return currentSampleIndices;
|
|
11449
11483
|
};
|
|
11450
11484
|
var cachedSamplePositionsState = () => {
|
|
11451
|
-
const
|
|
11452
|
-
|
|
11485
|
+
const samplePositionsForMdatStart = {};
|
|
11486
|
+
let currentSampleIndex = {};
|
|
11453
11487
|
return {
|
|
11454
11488
|
getSamples: (mdatStart) => {
|
|
11455
|
-
return
|
|
11489
|
+
return samplePositionsForMdatStart[mdatStart] ?? null;
|
|
11456
11490
|
},
|
|
11457
11491
|
setSamples: (mdatStart, samples) => {
|
|
11458
|
-
|
|
11492
|
+
samplePositionsForMdatStart[mdatStart] = samples;
|
|
11459
11493
|
},
|
|
11460
|
-
|
|
11461
|
-
|
|
11494
|
+
setCurrentSampleIndex: (mdatStart, trackId, index) => {
|
|
11495
|
+
if (!currentSampleIndex[mdatStart]) {
|
|
11496
|
+
currentSampleIndex[mdatStart] = {};
|
|
11497
|
+
}
|
|
11498
|
+
if (!currentSampleIndex[mdatStart][trackId]) {
|
|
11499
|
+
currentSampleIndex[mdatStart][trackId] = 0;
|
|
11500
|
+
}
|
|
11501
|
+
currentSampleIndex[mdatStart][trackId] = index;
|
|
11462
11502
|
},
|
|
11463
|
-
|
|
11464
|
-
return
|
|
11503
|
+
getCurrentSampleIndices: (mdatStart) => {
|
|
11504
|
+
return currentSampleIndex[mdatStart] ?? {};
|
|
11505
|
+
},
|
|
11506
|
+
updateAfterSeek: (seekedByte) => {
|
|
11507
|
+
currentSampleIndex = updateSampleIndicesAfterSeek({
|
|
11508
|
+
samplePositionsForMdatStart,
|
|
11509
|
+
seekedByte
|
|
11510
|
+
});
|
|
11465
11511
|
}
|
|
11466
11512
|
};
|
|
11467
11513
|
};
|
|
11514
|
+
var getSampleWithLowestDts = (samplePositions, currentSampleIndexMap) => {
|
|
11515
|
+
const lowestDts = [];
|
|
11516
|
+
for (const track of samplePositions) {
|
|
11517
|
+
const currentSampleIndex = currentSampleIndexMap[track.trackId] ?? 0;
|
|
11518
|
+
const currentSample = track.samplePositions[currentSampleIndex];
|
|
11519
|
+
if (currentSample && (lowestDts.length === 0 || currentSample.decodingTimestamp <= lowestDts[0].samplePosition.decodingTimestamp)) {
|
|
11520
|
+
lowestDts.push({
|
|
11521
|
+
samplePosition: currentSample,
|
|
11522
|
+
trackId: track.trackId,
|
|
11523
|
+
index: currentSampleIndex
|
|
11524
|
+
});
|
|
11525
|
+
}
|
|
11526
|
+
}
|
|
11527
|
+
return lowestDts;
|
|
11528
|
+
};
|
|
11468
11529
|
|
|
11469
11530
|
// src/state/iso-base-media/last-moof-box.ts
|
|
11470
11531
|
var getLastMoofBox = (boxes) => {
|
|
@@ -11745,118 +11806,6 @@ var getMoovAtom = async ({
|
|
|
11745
11806
|
return moov;
|
|
11746
11807
|
};
|
|
11747
11808
|
|
|
11748
|
-
// src/containers/iso-base-media/mdat/calculate-jump-marks.ts
|
|
11749
|
-
var MAX_SPREAD_IN_SECONDS = 8;
|
|
11750
|
-
var getKey = (samplePositionTrack) => {
|
|
11751
|
-
return `${samplePositionTrack.track.trackId}-${samplePositionTrack.samplePosition.decodingTimestamp}.${samplePositionTrack.samplePosition.offset}`;
|
|
11752
|
-
};
|
|
11753
|
-
var findBestJump = ({
|
|
11754
|
-
sampleMap,
|
|
11755
|
-
offsetsSorted,
|
|
11756
|
-
visited,
|
|
11757
|
-
progresses
|
|
11758
|
-
}) => {
|
|
11759
|
-
const minProgress = Math.min(...Object.values(progresses));
|
|
11760
|
-
const trackNumberWithLowestProgress = Object.entries(progresses).find(([, progress]) => progress === minProgress)?.[0];
|
|
11761
|
-
const firstSampleAboveMinProgress = offsetsSorted.findIndex((offset) => sampleMap.get(offset).track.trackId === Number(trackNumberWithLowestProgress) && !visited.has(getKey(sampleMap.get(offset))));
|
|
11762
|
-
if (firstSampleAboveMinProgress === -1) {
|
|
11763
|
-
const backup = offsetsSorted.findIndex((offset) => !visited.has(getKey(sampleMap.get(offset))));
|
|
11764
|
-
if (backup === -1) {
|
|
11765
|
-
throw new Error("this should not happen");
|
|
11766
|
-
}
|
|
11767
|
-
return backup;
|
|
11768
|
-
}
|
|
11769
|
-
return firstSampleAboveMinProgress;
|
|
11770
|
-
};
|
|
11771
|
-
var calculateJumpMarks = ({
|
|
11772
|
-
sampleMap,
|
|
11773
|
-
offsetsSorted,
|
|
11774
|
-
trackIds,
|
|
11775
|
-
endOfMdat
|
|
11776
|
-
}) => {
|
|
11777
|
-
const progresses = {};
|
|
11778
|
-
for (const trackId of trackIds) {
|
|
11779
|
-
progresses[trackId] = 0;
|
|
11780
|
-
}
|
|
11781
|
-
const jumpMarks = [];
|
|
11782
|
-
let indexToVisit = 0;
|
|
11783
|
-
const visited = new Set;
|
|
11784
|
-
const increaseIndex = () => {
|
|
11785
|
-
indexToVisit++;
|
|
11786
|
-
if (indexToVisit >= offsetsSorted.length) {
|
|
11787
|
-
throw new Error("should not roll over, should jump");
|
|
11788
|
-
}
|
|
11789
|
-
};
|
|
11790
|
-
let lastVisitedSample = null;
|
|
11791
|
-
const addJumpMark = ({
|
|
11792
|
-
firstSampleAboveMinProgress
|
|
11793
|
-
}) => {
|
|
11794
|
-
if (!lastVisitedSample) {
|
|
11795
|
-
throw new Error("no last visited sample");
|
|
11796
|
-
}
|
|
11797
|
-
const jumpMark = {
|
|
11798
|
-
afterSampleWithOffset: lastVisitedSample.samplePosition.offset,
|
|
11799
|
-
jumpToOffset: offsetsSorted[firstSampleAboveMinProgress]
|
|
11800
|
-
};
|
|
11801
|
-
if (firstSampleAboveMinProgress === offsetsSorted.indexOf(lastVisitedSample.samplePosition.offset) + 1) {
|
|
11802
|
-
indexToVisit = firstSampleAboveMinProgress;
|
|
11803
|
-
return;
|
|
11804
|
-
}
|
|
11805
|
-
indexToVisit = firstSampleAboveMinProgress;
|
|
11806
|
-
jumpMarks.push(jumpMark);
|
|
11807
|
-
};
|
|
11808
|
-
const addFinalJumpIfNecessary = () => {
|
|
11809
|
-
if (indexToVisit === offsetsSorted.length - 1) {
|
|
11810
|
-
return;
|
|
11811
|
-
}
|
|
11812
|
-
jumpMarks.push({
|
|
11813
|
-
afterSampleWithOffset: offsetsSorted[indexToVisit],
|
|
11814
|
-
jumpToOffset: endOfMdat
|
|
11815
|
-
});
|
|
11816
|
-
};
|
|
11817
|
-
const considerJump = () => {
|
|
11818
|
-
const firstSampleAboveMinProgress = findBestJump({
|
|
11819
|
-
sampleMap,
|
|
11820
|
-
offsetsSorted,
|
|
11821
|
-
visited,
|
|
11822
|
-
progresses
|
|
11823
|
-
});
|
|
11824
|
-
addJumpMark({ firstSampleAboveMinProgress });
|
|
11825
|
-
};
|
|
11826
|
-
while (true) {
|
|
11827
|
-
const currentSamplePosition = sampleMap.get(offsetsSorted[indexToVisit]);
|
|
11828
|
-
const sampleKey = getKey(currentSamplePosition);
|
|
11829
|
-
if (visited.has(sampleKey)) {
|
|
11830
|
-
considerJump();
|
|
11831
|
-
continue;
|
|
11832
|
-
}
|
|
11833
|
-
visited.add(sampleKey);
|
|
11834
|
-
lastVisitedSample = currentSamplePosition;
|
|
11835
|
-
if (visited.size === offsetsSorted.length) {
|
|
11836
|
-
addFinalJumpIfNecessary();
|
|
11837
|
-
break;
|
|
11838
|
-
}
|
|
11839
|
-
const timestamp = currentSamplePosition.samplePosition.decodingTimestamp / currentSamplePosition.track.originalTimescale;
|
|
11840
|
-
progresses[currentSamplePosition.track.trackId] = timestamp;
|
|
11841
|
-
const progressValues = Object.values(progresses);
|
|
11842
|
-
const maxProgress = Math.max(...progressValues);
|
|
11843
|
-
const minProgress = Math.min(...progressValues);
|
|
11844
|
-
const spread = maxProgress - minProgress;
|
|
11845
|
-
if (visited.size === offsetsSorted.length) {
|
|
11846
|
-
addFinalJumpIfNecessary();
|
|
11847
|
-
break;
|
|
11848
|
-
}
|
|
11849
|
-
if (spread > MAX_SPREAD_IN_SECONDS) {
|
|
11850
|
-
considerJump();
|
|
11851
|
-
} else if (indexToVisit === offsetsSorted.length - 1) {
|
|
11852
|
-
considerJump();
|
|
11853
|
-
} else {
|
|
11854
|
-
increaseIndex();
|
|
11855
|
-
}
|
|
11856
|
-
}
|
|
11857
|
-
return jumpMarks;
|
|
11858
|
-
};
|
|
11859
|
-
|
|
11860
11809
|
// src/containers/iso-base-media/mdat/postprocess-bytes.ts
|
|
11861
11810
|
var postprocessBytes = ({
|
|
11862
11811
|
bytes,
|
|
@@ -11917,52 +11866,53 @@ var parseMdatSection = async (state) => {
|
|
|
11917
11866
|
endOfMdat,
|
|
11918
11867
|
state
|
|
11919
11868
|
});
|
|
11869
|
+
const tracksFromMoov = getTracksFromMoovBox(moov);
|
|
11920
11870
|
state.iso.moov.setMoovBox({
|
|
11921
11871
|
moovBox: moov,
|
|
11922
11872
|
precomputed: false
|
|
11923
11873
|
});
|
|
11874
|
+
const existingTracks = state.callbacks.tracks.getTracks();
|
|
11875
|
+
for (const trackFromMoov of tracksFromMoov) {
|
|
11876
|
+
if (existingTracks.find((t) => t.trackId === trackFromMoov.trackId)) {
|
|
11877
|
+
continue;
|
|
11878
|
+
}
|
|
11879
|
+
if (trackFromMoov.type === "other") {
|
|
11880
|
+
continue;
|
|
11881
|
+
}
|
|
11882
|
+
state.callbacks.tracks.addTrack(trackFromMoov);
|
|
11883
|
+
}
|
|
11924
11884
|
state.callbacks.tracks.setIsDone(state.logLevel);
|
|
11925
11885
|
state.structure.getIsoStructure().boxes.push(moov);
|
|
11926
11886
|
return parseMdatSection(state);
|
|
11927
11887
|
}
|
|
11888
|
+
const tracks2 = state.callbacks.tracks.getTracks();
|
|
11928
11889
|
if (!state.iso.flatSamples.getSamples(mediaSection.start)) {
|
|
11929
|
-
const {
|
|
11930
|
-
flatSamples: flatSamplesMap,
|
|
11931
|
-
offsets,
|
|
11932
|
-
trackIds
|
|
11933
|
-
} = calculateFlatSamples({
|
|
11890
|
+
const samplePosition = calculateSamplePositions({
|
|
11934
11891
|
state,
|
|
11935
|
-
mediaSectionStart: mediaSection.start
|
|
11936
|
-
|
|
11937
|
-
const calcedJumpMarks = calculateJumpMarks({
|
|
11938
|
-
sampleMap: flatSamplesMap,
|
|
11939
|
-
offsetsSorted: offsets,
|
|
11940
|
-
trackIds,
|
|
11941
|
-
endOfMdat
|
|
11892
|
+
mediaSectionStart: mediaSection.start,
|
|
11893
|
+
trackIds: tracks2.map((t) => t.trackId)
|
|
11942
11894
|
});
|
|
11943
|
-
state.iso.flatSamples.
|
|
11944
|
-
state.iso.flatSamples.setSamples(mediaSection.start, flatSamplesMap);
|
|
11895
|
+
state.iso.flatSamples.setSamples(mediaSection.start, samplePosition);
|
|
11945
11896
|
}
|
|
11946
|
-
const
|
|
11947
|
-
const
|
|
11948
|
-
const
|
|
11949
|
-
|
|
11950
|
-
|
|
11951
|
-
const offsets = Array.from(flatSamples.keys());
|
|
11952
|
-
const nextSample_ = offsets.filter((s) => s > iterator.counter.getOffset()).sort((a, b) => a - b)[0];
|
|
11953
|
-
if (nextSample_) {
|
|
11954
|
-
iterator.discard(nextSample_ - iterator.counter.getOffset());
|
|
11955
|
-
return null;
|
|
11956
|
-
}
|
|
11957
|
-
Log.verbose(state.logLevel, "Could not find sample at offset", iterator.counter.getOffset(), "skipping to end of mdat");
|
|
11897
|
+
const samplePositions = state.iso.flatSamples.getSamples(mediaSection.start);
|
|
11898
|
+
const sampleIndices = state.iso.flatSamples.getCurrentSampleIndices(mediaSection.start);
|
|
11899
|
+
const nextSampleArray = getSampleWithLowestDts(samplePositions, sampleIndices);
|
|
11900
|
+
if (nextSampleArray.length === 0) {
|
|
11901
|
+
Log.verbose(state.logLevel, "Iterated over all samples.", endOfMdat);
|
|
11958
11902
|
return makeSkip(endOfMdat);
|
|
11959
11903
|
}
|
|
11960
|
-
|
|
11961
|
-
|
|
11904
|
+
const exactMatch = nextSampleArray.find((s) => s.samplePosition.offset === state.iterator.counter.getOffset());
|
|
11905
|
+
const nextSample = exactMatch ?? nextSampleArray[0];
|
|
11906
|
+
if (nextSample.samplePosition.offset !== state.iterator.counter.getOffset()) {
|
|
11907
|
+
return makeSkip(nextSample.samplePosition.offset);
|
|
11908
|
+
}
|
|
11909
|
+
if (nextSample.samplePosition.offset + nextSample.samplePosition.size > state.contentLength) {
|
|
11910
|
+
Log.verbose(state.logLevel, "Sample is beyond the end of the file. Don't process it.", nextSample.samplePosition.offset + nextSample.samplePosition.size, endOfMdat);
|
|
11962
11911
|
return makeSkip(endOfMdat);
|
|
11963
11912
|
}
|
|
11964
|
-
|
|
11965
|
-
|
|
11913
|
+
const { iterator } = state;
|
|
11914
|
+
if (iterator.bytesRemaining() < nextSample.samplePosition.size) {
|
|
11915
|
+
return makeFetchMoreData(nextSample.samplePosition.size - iterator.bytesRemaining());
|
|
11966
11916
|
}
|
|
11967
11917
|
const {
|
|
11968
11918
|
timestamp: rawCts,
|
|
@@ -11972,21 +11922,22 @@ var parseMdatSection = async (state) => {
|
|
|
11972
11922
|
offset,
|
|
11973
11923
|
bigEndian,
|
|
11974
11924
|
chunkSize
|
|
11975
|
-
} =
|
|
11925
|
+
} = nextSample.samplePosition;
|
|
11926
|
+
const track = tracks2.find((t) => t.trackId === nextSample.trackId);
|
|
11976
11927
|
const {
|
|
11977
11928
|
originalTimescale,
|
|
11978
11929
|
startInSeconds,
|
|
11979
11930
|
trackMediaTimeOffsetInTrackTimescale,
|
|
11980
11931
|
timescale: trackTimescale
|
|
11981
|
-
} =
|
|
11932
|
+
} = track;
|
|
11982
11933
|
const cts = rawCts + startInSeconds * originalTimescale - trackMediaTimeOffsetInTrackTimescale / trackTimescale * WEBCODECS_TIMESCALE;
|
|
11983
11934
|
const dts = rawDts + startInSeconds * originalTimescale - trackMediaTimeOffsetInTrackTimescale / trackTimescale * WEBCODECS_TIMESCALE;
|
|
11984
11935
|
const bytes = postprocessBytes({
|
|
11985
|
-
bytes: iterator.getSlice(
|
|
11936
|
+
bytes: iterator.getSlice(nextSample.samplePosition.size),
|
|
11986
11937
|
bigEndian,
|
|
11987
11938
|
chunkSize
|
|
11988
11939
|
});
|
|
11989
|
-
if (
|
|
11940
|
+
if (track.type === "audio") {
|
|
11990
11941
|
const audioSample = convertAudioOrVideoSampleToWebCodecsTimestamps({
|
|
11991
11942
|
sample: {
|
|
11992
11943
|
data: bytes,
|
|
@@ -12000,10 +11951,10 @@ var parseMdatSection = async (state) => {
|
|
|
12000
11951
|
});
|
|
12001
11952
|
await state.callbacks.onAudioSample({
|
|
12002
11953
|
audioSample,
|
|
12003
|
-
trackId:
|
|
11954
|
+
trackId: track.trackId
|
|
12004
11955
|
});
|
|
12005
11956
|
}
|
|
12006
|
-
if (
|
|
11957
|
+
if (track.type === "video") {
|
|
12007
11958
|
const nalUnitType = bytes[4] & 31;
|
|
12008
11959
|
let isRecoveryPoint = false;
|
|
12009
11960
|
if (nalUnitType === 6) {
|
|
@@ -12023,14 +11974,10 @@ var parseMdatSection = async (state) => {
|
|
|
12023
11974
|
});
|
|
12024
11975
|
await state.callbacks.onVideoSample({
|
|
12025
11976
|
videoSample,
|
|
12026
|
-
trackId:
|
|
11977
|
+
trackId: track.trackId
|
|
12027
11978
|
});
|
|
12028
11979
|
}
|
|
12029
|
-
|
|
12030
|
-
if (jump) {
|
|
12031
|
-
Log.verbose(state.logLevel, "Found jump mark", jump.jumpToOffset, "skipping to jump mark");
|
|
12032
|
-
return makeSkip(jump.jumpToOffset);
|
|
12033
|
-
}
|
|
11980
|
+
state.iso.flatSamples.setCurrentSampleIndex(mediaSection.start, nextSample.trackId, nextSample.index + 1);
|
|
12034
11981
|
return null;
|
|
12035
11982
|
};
|
|
12036
11983
|
|
|
@@ -16075,7 +16022,8 @@ var parseLoop = async ({
|
|
|
16075
16022
|
fields: state.fields,
|
|
16076
16023
|
src: state.src,
|
|
16077
16024
|
discardReadBytes: state.discardReadBytes,
|
|
16078
|
-
prefetchCache: state.prefetchCache
|
|
16025
|
+
prefetchCache: state.prefetchCache,
|
|
16026
|
+
isoState: state.iso
|
|
16079
16027
|
});
|
|
16080
16028
|
state.timings.timeSeeking += Date.now() - seekStart;
|
|
16081
16029
|
}
|
|
@@ -18237,7 +18185,7 @@ var downloadAndParseMedia = async (options) => {
|
|
|
18237
18185
|
return returnValue;
|
|
18238
18186
|
};
|
|
18239
18187
|
// src/version.ts
|
|
18240
|
-
var VERSION = "4.0.
|
|
18188
|
+
var VERSION = "4.0.334";
|
|
18241
18189
|
|
|
18242
18190
|
// src/index.ts
|
|
18243
18191
|
var MediaParserInternals = {
|