@remotion/media-parser 4.0.241 → 4.0.242
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/add-avc-profile-to-track.js +2 -2
- package/dist/boxes/avc/codec-private.js +2 -2
- package/dist/boxes/avc/create-sps-pps-data.d.ts +2 -0
- package/dist/boxes/avc/create-sps-pps-data.js +28 -0
- package/dist/boxes/iso-base-media/get-keyframes.d.ts +3 -0
- package/dist/boxes/iso-base-media/get-keyframes.js +30 -0
- package/dist/boxes/iso-base-media/mdat/mdat.d.ts +3 -3
- package/dist/boxes/iso-base-media/mdat/mdat.js +9 -5
- package/dist/boxes/iso-base-media/moov/moov.d.ts +3 -3
- package/dist/boxes/iso-base-media/moov/moov.js +5 -4
- package/dist/boxes/iso-base-media/process-box.d.ts +9 -9
- package/dist/boxes/iso-base-media/process-box.js +48 -56
- package/dist/boxes/iso-base-media/stsd/mebx.d.ts +3 -3
- package/dist/boxes/iso-base-media/stsd/mebx.js +5 -4
- package/dist/boxes/iso-base-media/stsd/samples.d.ts +5 -5
- package/dist/boxes/iso-base-media/stsd/samples.js +19 -16
- package/dist/boxes/iso-base-media/stsd/stsd.d.ts +3 -3
- package/dist/boxes/iso-base-media/stsd/stsd.js +2 -2
- package/dist/boxes/iso-base-media/trak/trak.d.ts +3 -3
- package/dist/boxes/iso-base-media/trak/trak.js +7 -6
- package/dist/boxes/riff/expect-riff-box.d.ts +3 -3
- package/dist/boxes/riff/expect-riff-box.js +5 -5
- package/dist/boxes/riff/get-tracks-from-avi.js +1 -1
- package/dist/boxes/riff/parse-box.d.ts +7 -7
- package/dist/boxes/riff/parse-box.js +29 -24
- package/dist/boxes/riff/parse-list-box.d.ts +3 -3
- package/dist/boxes/riff/parse-list-box.js +2 -2
- package/dist/boxes/riff/parse-movi.d.ts +5 -5
- package/dist/boxes/riff/parse-movi.js +35 -20
- package/dist/boxes/riff/parse-riff-box.d.ts +3 -3
- package/dist/boxes/riff/parse-riff-box.js +2 -2
- package/dist/boxes/transport-stream/get-tracks.js +1 -1
- package/dist/boxes/transport-stream/handle-aac-packet.d.ts +4 -3
- package/dist/boxes/transport-stream/handle-aac-packet.js +6 -4
- package/dist/boxes/transport-stream/handle-avc-packet.d.ts +4 -3
- package/dist/boxes/transport-stream/handle-avc-packet.js +8 -6
- package/dist/boxes/transport-stream/parse-packet.d.ts +3 -3
- package/dist/boxes/transport-stream/parse-packet.js +2 -2
- package/dist/boxes/transport-stream/parse-stream-packet.d.ts +3 -3
- package/dist/boxes/transport-stream/parse-stream-packet.js +14 -7
- package/dist/boxes/transport-stream/parse-transport-stream.d.ts +5 -6
- package/dist/boxes/transport-stream/parse-transport-stream.js +10 -9
- package/dist/boxes/transport-stream/process-stream-buffers.d.ts +6 -5
- package/dist/boxes/transport-stream/process-stream-buffers.js +18 -8
- package/dist/boxes/webm/ebml.d.ts +1 -1
- package/dist/boxes/webm/get-sample-from-block.d.ts +2 -2
- package/dist/boxes/webm/get-sample-from-block.js +8 -4
- package/dist/boxes/webm/parse-ebml.d.ts +4 -4
- package/dist/boxes/webm/parse-ebml.js +18 -18
- package/dist/boxes/webm/parse-webm-header.d.ts +5 -5
- package/dist/boxes/webm/parse-webm-header.js +6 -5
- package/dist/boxes/webm/segments/parse-children.d.ts +5 -5
- package/dist/boxes/webm/segments/parse-children.js +12 -13
- package/dist/boxes/webm/segments.d.ts +3 -3
- package/dist/boxes/webm/segments.js +13 -13
- package/dist/convert-audio-or-video-sample.js +2 -0
- package/dist/emit-available-info.d.ts +4 -5
- package/dist/emit-available-info.js +171 -57
- package/dist/esm/index.mjs +881 -490
- package/dist/get-duration.d.ts +1 -0
- package/dist/get-duration.js +14 -1
- package/dist/get-fields-from-callbacks.js +5 -0
- package/dist/get-fps.d.ts +1 -0
- package/dist/get-fps.js +17 -12
- package/dist/get-keyframes.d.ts +5 -0
- package/dist/get-keyframes.js +20 -0
- package/dist/get-tracks.d.ts +7 -1
- package/dist/get-tracks.js +15 -10
- package/dist/has-all-info.d.ts +2 -5
- package/dist/has-all-info.js +23 -4
- package/dist/index.d.ts +2 -1
- package/dist/may-skip-video-data/may-skip-video-data.d.ts +4 -0
- package/dist/may-skip-video-data/may-skip-video-data.js +14 -0
- package/dist/may-skip-video-data/need-samples-for-fields.d.ts +5 -0
- package/dist/may-skip-video-data/need-samples-for-fields.js +33 -0
- package/dist/options.d.ts +32 -0
- package/dist/parse-media.js +12 -40
- package/dist/parse-result.d.ts +2 -4
- package/dist/parse-video.d.ts +5 -5
- package/dist/parse-video.js +24 -10
- package/dist/register-track.d.ts +5 -5
- package/dist/register-track.js +12 -12
- package/dist/state/can-skip-tracks.js +5 -0
- package/dist/state/emitted-fields.d.ts +2 -0
- package/dist/state/emitted-fields.js +31 -0
- package/dist/state/has-tracks-section.d.ts +1 -0
- package/dist/state/keyframes.d.ts +6 -0
- package/dist/state/keyframes.js +15 -0
- package/dist/state/parser-state.d.ts +60 -29
- package/dist/state/parser-state.js +32 -150
- package/dist/state/riff.d.ts +10 -0
- package/dist/state/riff.js +32 -0
- package/dist/state/sample-callbacks.d.ts +31 -0
- package/dist/state/sample-callbacks.js +96 -0
- package/dist/state/slow-duration-fps.d.ts +8 -0
- package/dist/state/slow-duration-fps.js +36 -0
- package/dist/state/structure.d.ts +7 -0
- package/dist/state/structure.js +21 -0
- package/dist/state/tracks-and-samples.d.ts +0 -0
- package/dist/state/tracks-and-samples.js +1 -0
- package/dist/state/webm.d.ts +11 -0
- package/dist/state/webm.js +67 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/webcodec-sample-types.d.ts +2 -0
- package/package.json +3 -3
package/dist/esm/index.mjs
CHANGED
|
@@ -1367,7 +1367,7 @@ var createIsoBaseMediaFtyp = ({
|
|
|
1367
1367
|
};
|
|
1368
1368
|
|
|
1369
1369
|
// src/version.ts
|
|
1370
|
-
var VERSION = "4.0.
|
|
1370
|
+
var VERSION = "4.0.242";
|
|
1371
1371
|
|
|
1372
1372
|
// src/create/iso-base-media/create-ilst.ts
|
|
1373
1373
|
var createIlst = (items) => {
|
|
@@ -4127,19 +4127,22 @@ var getFps = (segments) => {
|
|
|
4127
4127
|
}
|
|
4128
4128
|
throw new Error("Cannot get fps, not implemented");
|
|
4129
4129
|
};
|
|
4130
|
-
var
|
|
4130
|
+
var hasFpsSuitedForSlowFps = (boxes) => {
|
|
4131
4131
|
try {
|
|
4132
|
-
if (boxes.type === "matroska") {
|
|
4133
|
-
return true;
|
|
4134
|
-
}
|
|
4135
|
-
if (boxes.type === "transport-stream") {
|
|
4136
|
-
return true;
|
|
4137
|
-
}
|
|
4138
4132
|
return getFps(boxes) !== null;
|
|
4139
4133
|
} catch {
|
|
4140
4134
|
return false;
|
|
4141
4135
|
}
|
|
4142
4136
|
};
|
|
4137
|
+
var hasFps = (boxes) => {
|
|
4138
|
+
if (boxes.type === "matroska") {
|
|
4139
|
+
return true;
|
|
4140
|
+
}
|
|
4141
|
+
if (boxes.type === "transport-stream") {
|
|
4142
|
+
return true;
|
|
4143
|
+
}
|
|
4144
|
+
return hasFpsSuitedForSlowFps(boxes);
|
|
4145
|
+
};
|
|
4143
4146
|
|
|
4144
4147
|
// src/get-audio-codec.ts
|
|
4145
4148
|
var getAudioCodec = (boxes, parserState) => {
|
|
@@ -5454,14 +5457,19 @@ var makeBaseMediaTrack = (trakBox) => {
|
|
|
5454
5457
|
return track;
|
|
5455
5458
|
};
|
|
5456
5459
|
|
|
5457
|
-
// src/boxes/avc/codec-
|
|
5458
|
-
var
|
|
5460
|
+
// src/boxes/avc/codec-string.ts
|
|
5461
|
+
var getCodecStringFromSpsAndPps = (sps) => {
|
|
5462
|
+
return `avc1.${sps.spsData.profile.toString(16).padStart(2, "0")}${sps.spsData.compatibility.toString(16).padStart(2, "0")}${sps.spsData.level.toString(16).padStart(2, "0")}`;
|
|
5463
|
+
};
|
|
5464
|
+
|
|
5465
|
+
// src/boxes/avc/create-sps-pps-data.ts
|
|
5466
|
+
var createSpsPpsData = (avc1Profile) => {
|
|
5459
5467
|
return combineUint8Arrays([
|
|
5460
5468
|
new Uint8Array([
|
|
5461
5469
|
1,
|
|
5462
|
-
avc1Profile.sps.spsData.level,
|
|
5463
|
-
avc1Profile.sps.spsData.compatibility,
|
|
5464
5470
|
avc1Profile.sps.spsData.profile,
|
|
5471
|
+
avc1Profile.sps.spsData.compatibility,
|
|
5472
|
+
avc1Profile.sps.spsData.level,
|
|
5465
5473
|
255,
|
|
5466
5474
|
225
|
|
5467
5475
|
]),
|
|
@@ -5473,11 +5481,6 @@ var getAvccBoxContent = (avc1Profile) => {
|
|
|
5473
5481
|
]);
|
|
5474
5482
|
};
|
|
5475
5483
|
|
|
5476
|
-
// src/boxes/avc/codec-string.ts
|
|
5477
|
-
var getCodecStringFromSpsAndPps = (sps) => {
|
|
5478
|
-
return `avc1.${sps.spsData.profile.toString(16).padStart(2, "0")}${sps.spsData.compatibility.toString(16).padStart(2, "0")}${sps.spsData.level.toString(16).padStart(2, "0")}`;
|
|
5479
|
-
};
|
|
5480
|
-
|
|
5481
5484
|
// src/add-avc-profile-to-track.ts
|
|
5482
5485
|
var addAvcProfileToTrack = (track, avc1Profile) => {
|
|
5483
5486
|
if (avc1Profile === null) {
|
|
@@ -5486,7 +5489,7 @@ var addAvcProfileToTrack = (track, avc1Profile) => {
|
|
|
5486
5489
|
return {
|
|
5487
5490
|
...track,
|
|
5488
5491
|
codec: getCodecStringFromSpsAndPps(avc1Profile.sps),
|
|
5489
|
-
codecPrivate:
|
|
5492
|
+
codecPrivate: createSpsPpsData(avc1Profile)
|
|
5490
5493
|
};
|
|
5491
5494
|
};
|
|
5492
5495
|
|
|
@@ -5575,7 +5578,7 @@ var getTracksFromAvi = (structure, state) => {
|
|
|
5575
5578
|
continue;
|
|
5576
5579
|
}
|
|
5577
5580
|
if (strf.type === "strf-box-video") {
|
|
5578
|
-
videoTracks.push(addAvcProfileToTrack(makeAviVideoTrack({ strh, strf, index: i }), state.getAvcProfile()));
|
|
5581
|
+
videoTracks.push(addAvcProfileToTrack(makeAviVideoTrack({ strh, strf, index: i }), state.riff.getAvcProfile()));
|
|
5579
5582
|
} else if (strh.fccType === "auds") {
|
|
5580
5583
|
audioTracks.push(makeAviAudioTrack({ strf, index: i }));
|
|
5581
5584
|
} else {
|
|
@@ -5627,7 +5630,7 @@ var getStreamForId = (structure, packetIdentifier) => {
|
|
|
5627
5630
|
// src/boxes/transport-stream/get-tracks.ts
|
|
5628
5631
|
var getTracksFromTransportStream = (structure, parserState) => {
|
|
5629
5632
|
const programMapTable = findProgramMapTableOrThrow(structure);
|
|
5630
|
-
const parserTracks = parserState.tracks.getTracks();
|
|
5633
|
+
const parserTracks = parserState.callbacks.tracks.getTracks();
|
|
5631
5634
|
const mapped = programMapTable.streams.map((stream) => {
|
|
5632
5635
|
return parserTracks.find((track) => track.trackId === stream.pid);
|
|
5633
5636
|
}).filter(truthy);
|
|
@@ -6029,6 +6032,15 @@ var getNumberOfTracks2 = (moovBox) => {
|
|
|
6029
6032
|
}
|
|
6030
6033
|
return mvHdBox.nextTrackId - 1;
|
|
6031
6034
|
};
|
|
6035
|
+
var isoBaseMediaHasTracks = (structure) => {
|
|
6036
|
+
const moovBox = getMoovBox(structure.boxes);
|
|
6037
|
+
if (!moovBox) {
|
|
6038
|
+
return false;
|
|
6039
|
+
}
|
|
6040
|
+
const numberOfTracks = getNumberOfTracks2(moovBox);
|
|
6041
|
+
const tracks2 = getTraks(moovBox);
|
|
6042
|
+
return tracks2.length === numberOfTracks;
|
|
6043
|
+
};
|
|
6032
6044
|
var hasTracks = (structure, state) => {
|
|
6033
6045
|
if (structure.type === "matroska") {
|
|
6034
6046
|
const mainSegment = getMainSegment(structure.boxes);
|
|
@@ -6038,13 +6050,7 @@ var hasTracks = (structure, state) => {
|
|
|
6038
6050
|
return getTracksSegment(mainSegment) !== null;
|
|
6039
6051
|
}
|
|
6040
6052
|
if (structure.type === "iso-base-media") {
|
|
6041
|
-
|
|
6042
|
-
if (!moovBox) {
|
|
6043
|
-
return false;
|
|
6044
|
-
}
|
|
6045
|
-
const numberOfTracks = getNumberOfTracks2(moovBox);
|
|
6046
|
-
const tracks2 = getTraks(moovBox);
|
|
6047
|
-
return tracks2.length === numberOfTracks;
|
|
6053
|
+
return isoBaseMediaHasTracks(structure);
|
|
6048
6054
|
}
|
|
6049
6055
|
if (structure.type === "riff") {
|
|
6050
6056
|
return hasAllTracksFromAvi(structure, state);
|
|
@@ -6062,7 +6068,7 @@ var getTracksFromMa = (segments, state) => {
|
|
|
6062
6068
|
if (!mainSegment) {
|
|
6063
6069
|
throw new Error("No main segment found");
|
|
6064
6070
|
}
|
|
6065
|
-
const matroskaTracks = getTracksFromMatroska(mainSegment, state.getTimescale());
|
|
6071
|
+
const matroskaTracks = getTracksFromMatroska(mainSegment, state.webm.getTimescale());
|
|
6066
6072
|
for (const track of matroskaTracks) {
|
|
6067
6073
|
if (track.type === "video") {
|
|
6068
6074
|
videoTracks.push(track);
|
|
@@ -6473,6 +6479,13 @@ var getDuration = (structure, parserState) => {
|
|
|
6473
6479
|
var hasDuration = (structure, parserState) => {
|
|
6474
6480
|
return hasTracks(structure, parserState);
|
|
6475
6481
|
};
|
|
6482
|
+
var hasSlowDuration = (structure, parserState) => {
|
|
6483
|
+
try {
|
|
6484
|
+
return getDuration(structure, parserState) !== null;
|
|
6485
|
+
} catch {
|
|
6486
|
+
return false;
|
|
6487
|
+
}
|
|
6488
|
+
};
|
|
6476
6489
|
|
|
6477
6490
|
// src/get-is-hdr.ts
|
|
6478
6491
|
var isVideoTrackHdr = (track) => {
|
|
@@ -6486,6 +6499,43 @@ var hasHdr = (boxes, state) => {
|
|
|
6486
6499
|
return hasTracks(boxes, state);
|
|
6487
6500
|
};
|
|
6488
6501
|
|
|
6502
|
+
// src/boxes/iso-base-media/get-keyframes.ts
|
|
6503
|
+
var getKeyframesFromIsoBaseMedia = (structure) => {
|
|
6504
|
+
const { videoTracks } = getTracksFromIsoBaseMedia(structure.boxes);
|
|
6505
|
+
const moofBox = getMoofBox(structure.boxes);
|
|
6506
|
+
const allSamples = videoTracks.map((t) => {
|
|
6507
|
+
const { timescale: ts } = t;
|
|
6508
|
+
const samplePositions = getSamplePositionsFromTrack(t.trakBox, moofBox);
|
|
6509
|
+
const keyframes = samplePositions.filter((k) => {
|
|
6510
|
+
return k.isKeyframe;
|
|
6511
|
+
}).map((k) => {
|
|
6512
|
+
return {
|
|
6513
|
+
trackId: t.trackId,
|
|
6514
|
+
presentationTimeInSeconds: k.cts / ts,
|
|
6515
|
+
decodingTimeInSeconds: k.dts / ts,
|
|
6516
|
+
positionInBytes: k.offset,
|
|
6517
|
+
sizeInBytes: k.size
|
|
6518
|
+
};
|
|
6519
|
+
});
|
|
6520
|
+
return keyframes;
|
|
6521
|
+
});
|
|
6522
|
+
return allSamples.flat();
|
|
6523
|
+
};
|
|
6524
|
+
|
|
6525
|
+
// src/get-keyframes.ts
|
|
6526
|
+
var getKeyframes = (structure) => {
|
|
6527
|
+
if (structure.type === "iso-base-media") {
|
|
6528
|
+
return getKeyframesFromIsoBaseMedia(structure);
|
|
6529
|
+
}
|
|
6530
|
+
return null;
|
|
6531
|
+
};
|
|
6532
|
+
var hasKeyframes = (structure, parserState) => {
|
|
6533
|
+
if (structure.type === "iso-base-media") {
|
|
6534
|
+
return hasTracks(structure, parserState);
|
|
6535
|
+
}
|
|
6536
|
+
return true;
|
|
6537
|
+
};
|
|
6538
|
+
|
|
6489
6539
|
// src/get-location.ts
|
|
6490
6540
|
function parseLocation(locationString) {
|
|
6491
6541
|
const locationPattern = /^([+-]\d{2}\.?\d{0,10})([+-]\d{3}\.?\d{0,10})([+-]\d+(\.\d+)?)?\/$/;
|
|
@@ -6529,35 +6579,93 @@ var emitAvailableInfo = ({
|
|
|
6529
6579
|
contentLength,
|
|
6530
6580
|
name,
|
|
6531
6581
|
mimeType,
|
|
6532
|
-
fieldsInReturnValue
|
|
6533
|
-
emittedFields
|
|
6582
|
+
fieldsInReturnValue
|
|
6534
6583
|
}) => {
|
|
6535
6584
|
const keys = Object.keys(hasInfo);
|
|
6585
|
+
const segments = state.structure.getStructureOrNull();
|
|
6586
|
+
const { emittedFields } = state;
|
|
6536
6587
|
for (const key of keys) {
|
|
6537
6588
|
if (key === "structure") {
|
|
6538
|
-
if (parseResult && hasInfo.structure && !emittedFields.structure) {
|
|
6539
|
-
callbacks.onStructure?.(
|
|
6589
|
+
if (parseResult && hasInfo.structure && !emittedFields.structure && segments) {
|
|
6590
|
+
callbacks.onStructure?.(segments);
|
|
6540
6591
|
if (fieldsInReturnValue.structure) {
|
|
6541
|
-
returnValue.structure =
|
|
6592
|
+
returnValue.structure = segments;
|
|
6542
6593
|
}
|
|
6543
6594
|
emittedFields.structure = true;
|
|
6544
6595
|
}
|
|
6545
6596
|
continue;
|
|
6546
6597
|
}
|
|
6547
6598
|
if (key === "durationInSeconds") {
|
|
6548
|
-
if (hasInfo.durationInSeconds &&
|
|
6549
|
-
|
|
6550
|
-
|
|
6551
|
-
|
|
6552
|
-
|
|
6599
|
+
if (hasInfo.durationInSeconds && parseResult && segments) {
|
|
6600
|
+
if (!emittedFields.durationInSeconds) {
|
|
6601
|
+
const durationInSeconds = getDuration(segments, state);
|
|
6602
|
+
callbacks.onDurationInSeconds?.(durationInSeconds);
|
|
6603
|
+
if (fieldsInReturnValue.durationInSeconds) {
|
|
6604
|
+
returnValue.durationInSeconds = durationInSeconds;
|
|
6605
|
+
}
|
|
6606
|
+
emittedFields.durationInSeconds = true;
|
|
6607
|
+
}
|
|
6608
|
+
if (!emittedFields.slowDurationInSeconds) {
|
|
6609
|
+
const durationInSeconds = getDuration(segments, state);
|
|
6610
|
+
if (durationInSeconds !== null) {
|
|
6611
|
+
callbacks.onSlowDurationInSeconds?.(durationInSeconds);
|
|
6612
|
+
if (fieldsInReturnValue.slowDurationInSeconds) {
|
|
6613
|
+
returnValue.slowDurationInSeconds = durationInSeconds;
|
|
6614
|
+
}
|
|
6615
|
+
emittedFields.slowDurationInSeconds = true;
|
|
6616
|
+
}
|
|
6617
|
+
}
|
|
6618
|
+
}
|
|
6619
|
+
continue;
|
|
6620
|
+
}
|
|
6621
|
+
if (key === "slowDurationInSeconds") {
|
|
6622
|
+
if (hasInfo.slowDurationInSeconds && !emittedFields.slowDurationInSeconds && parseResult && segments) {
|
|
6623
|
+
const slowDurationInSeconds = state.slowDurationAndFps.getSlowDurationInSeconds();
|
|
6624
|
+
callbacks.onSlowDurationInSeconds?.(slowDurationInSeconds);
|
|
6625
|
+
if (fieldsInReturnValue.slowDurationInSeconds) {
|
|
6626
|
+
returnValue.slowDurationInSeconds = slowDurationInSeconds;
|
|
6627
|
+
}
|
|
6628
|
+
emittedFields.slowDurationInSeconds = true;
|
|
6629
|
+
}
|
|
6630
|
+
continue;
|
|
6631
|
+
}
|
|
6632
|
+
if (key === "fps") {
|
|
6633
|
+
if (hasInfo.fps && parseResult && segments) {
|
|
6634
|
+
if (!emittedFields.fps) {
|
|
6635
|
+
const fps = getFps(segments);
|
|
6636
|
+
callbacks.onFps?.(fps);
|
|
6637
|
+
if (fieldsInReturnValue.fps) {
|
|
6638
|
+
returnValue.fps = fps;
|
|
6639
|
+
}
|
|
6640
|
+
emittedFields.fps = true;
|
|
6641
|
+
}
|
|
6642
|
+
if (!emittedFields.slowFps) {
|
|
6643
|
+
const fps = getFps(segments);
|
|
6644
|
+
if (fps) {
|
|
6645
|
+
callbacks.onSlowFps?.(fps);
|
|
6646
|
+
if (fieldsInReturnValue.slowFps) {
|
|
6647
|
+
returnValue.slowFps = fps;
|
|
6648
|
+
}
|
|
6649
|
+
emittedFields.slowFps = true;
|
|
6650
|
+
}
|
|
6651
|
+
}
|
|
6652
|
+
}
|
|
6653
|
+
continue;
|
|
6654
|
+
}
|
|
6655
|
+
if (key === "slowFps") {
|
|
6656
|
+
if (hasInfo.slowFps && !emittedFields.slowFps && parseResult && segments) {
|
|
6657
|
+
const slowFps = state.slowDurationAndFps.getFps();
|
|
6658
|
+
callbacks.onSlowFps?.(slowFps);
|
|
6659
|
+
if (fieldsInReturnValue.slowFps) {
|
|
6660
|
+
returnValue.slowFps = slowFps;
|
|
6553
6661
|
}
|
|
6554
|
-
emittedFields.
|
|
6662
|
+
emittedFields.slowFps = true;
|
|
6555
6663
|
}
|
|
6556
6664
|
continue;
|
|
6557
6665
|
}
|
|
6558
6666
|
if (key === "dimensions") {
|
|
6559
|
-
if (hasInfo.dimensions && !emittedFields.dimensions && parseResult) {
|
|
6560
|
-
const dimensionsQueried = getDimensions(
|
|
6667
|
+
if (hasInfo.dimensions && !emittedFields.dimensions && parseResult && segments) {
|
|
6668
|
+
const dimensionsQueried = getDimensions(segments, state);
|
|
6561
6669
|
const dimensions = {
|
|
6562
6670
|
height: dimensionsQueried.height,
|
|
6563
6671
|
width: dimensionsQueried.width
|
|
@@ -6571,8 +6679,8 @@ var emitAvailableInfo = ({
|
|
|
6571
6679
|
continue;
|
|
6572
6680
|
}
|
|
6573
6681
|
if (key === "unrotatedDimensions") {
|
|
6574
|
-
if (hasInfo.unrotatedDimensions && !emittedFields.unrotatedDimensions && parseResult) {
|
|
6575
|
-
const dimensionsQueried = getDimensions(
|
|
6682
|
+
if (hasInfo.unrotatedDimensions && !emittedFields.unrotatedDimensions && parseResult && segments) {
|
|
6683
|
+
const dimensionsQueried = getDimensions(segments, state);
|
|
6576
6684
|
const unrotatedDimensions = {
|
|
6577
6685
|
height: dimensionsQueried.unrotatedHeight,
|
|
6578
6686
|
width: dimensionsQueried.unrotatedWidth
|
|
@@ -6586,8 +6694,8 @@ var emitAvailableInfo = ({
|
|
|
6586
6694
|
continue;
|
|
6587
6695
|
}
|
|
6588
6696
|
if (key === "rotation") {
|
|
6589
|
-
if (hasInfo.rotation && !emittedFields.rotation && parseResult) {
|
|
6590
|
-
const dimensionsQueried = getDimensions(
|
|
6697
|
+
if (hasInfo.rotation && !emittedFields.rotation && parseResult && segments) {
|
|
6698
|
+
const dimensionsQueried = getDimensions(segments, state);
|
|
6591
6699
|
const { rotation } = dimensionsQueried;
|
|
6592
6700
|
callbacks.onRotation?.(rotation);
|
|
6593
6701
|
if (fieldsInReturnValue.rotation) {
|
|
@@ -6597,20 +6705,9 @@ var emitAvailableInfo = ({
|
|
|
6597
6705
|
}
|
|
6598
6706
|
continue;
|
|
6599
6707
|
}
|
|
6600
|
-
if (key === "fps") {
|
|
6601
|
-
if (!emittedFields.fps && hasInfo.fps && parseResult) {
|
|
6602
|
-
const fps = getFps(parseResult.segments);
|
|
6603
|
-
callbacks.onFps?.(fps);
|
|
6604
|
-
if (fieldsInReturnValue.fps) {
|
|
6605
|
-
returnValue.fps = fps;
|
|
6606
|
-
}
|
|
6607
|
-
emittedFields.fps = true;
|
|
6608
|
-
}
|
|
6609
|
-
continue;
|
|
6610
|
-
}
|
|
6611
6708
|
if (key === "videoCodec") {
|
|
6612
|
-
if (!emittedFields.videoCodec && hasInfo.videoCodec && parseResult) {
|
|
6613
|
-
const videoCodec = getVideoCodec(
|
|
6709
|
+
if (!emittedFields.videoCodec && hasInfo.videoCodec && parseResult && segments) {
|
|
6710
|
+
const videoCodec = getVideoCodec(segments, state);
|
|
6614
6711
|
callbacks.onVideoCodec?.(videoCodec);
|
|
6615
6712
|
if (fieldsInReturnValue.videoCodec) {
|
|
6616
6713
|
returnValue.videoCodec = videoCodec;
|
|
@@ -6620,8 +6717,8 @@ var emitAvailableInfo = ({
|
|
|
6620
6717
|
continue;
|
|
6621
6718
|
}
|
|
6622
6719
|
if (key === "audioCodec") {
|
|
6623
|
-
if (!emittedFields.audioCodec && hasInfo.audioCodec && parseResult) {
|
|
6624
|
-
const audioCodec = getAudioCodec(
|
|
6720
|
+
if (!emittedFields.audioCodec && hasInfo.audioCodec && parseResult && segments) {
|
|
6721
|
+
const audioCodec = getAudioCodec(segments, state);
|
|
6625
6722
|
callbacks.onAudioCodec?.(audioCodec);
|
|
6626
6723
|
if (fieldsInReturnValue.audioCodec) {
|
|
6627
6724
|
returnValue.audioCodec = audioCodec;
|
|
@@ -6631,8 +6728,8 @@ var emitAvailableInfo = ({
|
|
|
6631
6728
|
continue;
|
|
6632
6729
|
}
|
|
6633
6730
|
if (key === "tracks") {
|
|
6634
|
-
if (!emittedFields.tracks && hasInfo.tracks && parseResult) {
|
|
6635
|
-
const { videoTracks, audioTracks } = getTracks(
|
|
6731
|
+
if (!emittedFields.tracks && hasInfo.tracks && parseResult && segments) {
|
|
6732
|
+
const { videoTracks, audioTracks } = getTracks(segments, state);
|
|
6636
6733
|
callbacks.onTracks?.({ videoTracks, audioTracks });
|
|
6637
6734
|
if (fieldsInReturnValue.tracks) {
|
|
6638
6735
|
returnValue.tracks = { videoTracks, audioTracks };
|
|
@@ -6682,8 +6779,8 @@ var emitAvailableInfo = ({
|
|
|
6682
6779
|
continue;
|
|
6683
6780
|
}
|
|
6684
6781
|
if (key === "isHdr") {
|
|
6685
|
-
if (!returnValue.isHdr && hasInfo.isHdr && parseResult) {
|
|
6686
|
-
const isHdr = getIsHdr(
|
|
6782
|
+
if (!returnValue.isHdr && hasInfo.isHdr && parseResult && segments) {
|
|
6783
|
+
const isHdr = getIsHdr(segments, state);
|
|
6687
6784
|
callbacks.onIsHdr?.(isHdr);
|
|
6688
6785
|
if (fieldsInReturnValue.isHdr) {
|
|
6689
6786
|
returnValue.isHdr = isHdr;
|
|
@@ -6693,8 +6790,8 @@ var emitAvailableInfo = ({
|
|
|
6693
6790
|
continue;
|
|
6694
6791
|
}
|
|
6695
6792
|
if (key === "container") {
|
|
6696
|
-
if (!returnValue.container && hasInfo.container && parseResult) {
|
|
6697
|
-
const container = getContainer(
|
|
6793
|
+
if (!returnValue.container && hasInfo.container && parseResult && segments) {
|
|
6794
|
+
const container = getContainer(segments);
|
|
6698
6795
|
callbacks.onContainer?.(container);
|
|
6699
6796
|
if (fieldsInReturnValue.container) {
|
|
6700
6797
|
returnValue.container = container;
|
|
@@ -6704,8 +6801,8 @@ var emitAvailableInfo = ({
|
|
|
6704
6801
|
continue;
|
|
6705
6802
|
}
|
|
6706
6803
|
if (key === "metadata") {
|
|
6707
|
-
if (!emittedFields.metadata && hasInfo.metadata && parseResult) {
|
|
6708
|
-
const metadata = getMetadata(
|
|
6804
|
+
if (!emittedFields.metadata && hasInfo.metadata && parseResult && segments) {
|
|
6805
|
+
const metadata = getMetadata(segments);
|
|
6709
6806
|
callbacks.onMetadata?.(metadata);
|
|
6710
6807
|
if (fieldsInReturnValue.metadata) {
|
|
6711
6808
|
returnValue.metadata = metadata;
|
|
@@ -6715,8 +6812,8 @@ var emitAvailableInfo = ({
|
|
|
6715
6812
|
continue;
|
|
6716
6813
|
}
|
|
6717
6814
|
if (key === "location") {
|
|
6718
|
-
if (!emittedFields.location && hasInfo.location && parseResult) {
|
|
6719
|
-
const location = getLocation(
|
|
6815
|
+
if (!emittedFields.location && hasInfo.location && parseResult && segments) {
|
|
6816
|
+
const location = getLocation(segments);
|
|
6720
6817
|
callbacks.onLocation?.(location);
|
|
6721
6818
|
if (fieldsInReturnValue.location) {
|
|
6722
6819
|
returnValue.location = location;
|
|
@@ -6725,6 +6822,36 @@ var emitAvailableInfo = ({
|
|
|
6725
6822
|
}
|
|
6726
6823
|
continue;
|
|
6727
6824
|
}
|
|
6825
|
+
if (key === "slowKeyframes") {
|
|
6826
|
+
if (!emittedFields.slowKeyframes && hasInfo.slowKeyframes && parseResult) {
|
|
6827
|
+
callbacks.onSlowKeyframes?.(state.keyframes.getKeyframes());
|
|
6828
|
+
if (fieldsInReturnValue.slowKeyframes) {
|
|
6829
|
+
returnValue.slowKeyframes = state.keyframes.getKeyframes();
|
|
6830
|
+
}
|
|
6831
|
+
emittedFields.slowKeyframes = true;
|
|
6832
|
+
}
|
|
6833
|
+
continue;
|
|
6834
|
+
}
|
|
6835
|
+
if (key === "slowNumberOfFrames") {
|
|
6836
|
+
if (!emittedFields.slowNumberOfFrames && hasInfo.slowNumberOfFrames && parseResult) {
|
|
6837
|
+
callbacks.onSlowNumberOfFrames?.(state.slowDurationAndFps.getSlowNumberOfFrames());
|
|
6838
|
+
if (fieldsInReturnValue.slowNumberOfFrames) {
|
|
6839
|
+
returnValue.slowNumberOfFrames = state.slowDurationAndFps.getSlowNumberOfFrames();
|
|
6840
|
+
}
|
|
6841
|
+
emittedFields.slowNumberOfFrames = true;
|
|
6842
|
+
}
|
|
6843
|
+
continue;
|
|
6844
|
+
}
|
|
6845
|
+
if (key === "keyframes") {
|
|
6846
|
+
if (!emittedFields.keyframes && hasInfo.keyframes && parseResult) {
|
|
6847
|
+
callbacks.onKeyframes?.(getKeyframes(state.structure.getStructure()));
|
|
6848
|
+
if (fieldsInReturnValue.keyframes) {
|
|
6849
|
+
returnValue.keyframes = getKeyframes(state.structure.getStructure());
|
|
6850
|
+
}
|
|
6851
|
+
emittedFields.keyframes = true;
|
|
6852
|
+
}
|
|
6853
|
+
continue;
|
|
6854
|
+
}
|
|
6728
6855
|
throw new Error(`Unhandled key: ${key}`);
|
|
6729
6856
|
}
|
|
6730
6857
|
};
|
|
@@ -6752,18 +6879,65 @@ var getFieldsFromCallback = ({
|
|
|
6752
6879
|
tracks: Boolean(callbacks.onTracks),
|
|
6753
6880
|
unrotatedDimensions: Boolean(callbacks.onUnrotatedDimensions),
|
|
6754
6881
|
videoCodec: Boolean(callbacks.onVideoCodec),
|
|
6882
|
+
slowKeyframes: Boolean(callbacks.onSlowKeyframes),
|
|
6883
|
+
slowDurationInSeconds: Boolean(callbacks.onSlowDurationInSeconds),
|
|
6884
|
+
slowFps: Boolean(callbacks.onSlowFps),
|
|
6885
|
+
slowNumberOfFrames: Boolean(callbacks.onSlowNumberOfFrames),
|
|
6886
|
+
keyframes: Boolean(callbacks.onKeyframes),
|
|
6755
6887
|
...fields
|
|
6756
6888
|
};
|
|
6757
6889
|
return newFields;
|
|
6758
6890
|
};
|
|
6759
6891
|
|
|
6892
|
+
// src/may-skip-video-data/need-samples-for-fields.ts
|
|
6893
|
+
var needsSamples = {
|
|
6894
|
+
slowDurationInSeconds: true,
|
|
6895
|
+
slowFps: true,
|
|
6896
|
+
slowKeyframes: true,
|
|
6897
|
+
slowNumberOfFrames: true,
|
|
6898
|
+
audioCodec: false,
|
|
6899
|
+
container: false,
|
|
6900
|
+
dimensions: false,
|
|
6901
|
+
durationInSeconds: false,
|
|
6902
|
+
fps: false,
|
|
6903
|
+
internalStats: false,
|
|
6904
|
+
isHdr: false,
|
|
6905
|
+
name: false,
|
|
6906
|
+
rotation: false,
|
|
6907
|
+
size: false,
|
|
6908
|
+
structure: false,
|
|
6909
|
+
tracks: false,
|
|
6910
|
+
unrotatedDimensions: false,
|
|
6911
|
+
videoCodec: false,
|
|
6912
|
+
metadata: false,
|
|
6913
|
+
location: false,
|
|
6914
|
+
mimeType: false,
|
|
6915
|
+
keyframes: false
|
|
6916
|
+
};
|
|
6917
|
+
var needsToIterateOverSamples = ({
|
|
6918
|
+
fields,
|
|
6919
|
+
emittedFields
|
|
6920
|
+
}) => {
|
|
6921
|
+
const keys = Object.keys(fields ?? {});
|
|
6922
|
+
const selectedKeys = keys.filter((k) => fields[k]);
|
|
6923
|
+
return selectedKeys.some((k) => needsSamples[k] && !emittedFields[k]);
|
|
6924
|
+
};
|
|
6925
|
+
|
|
6926
|
+
// src/may-skip-video-data/may-skip-video-data.ts
|
|
6927
|
+
var maySkipVideoData = ({ state }) => {
|
|
6928
|
+
return state.callbacks.tracks.hasAllTracks() && Object.values(state.callbacks.videoSampleCallbacks).length === 0 && Object.values(state.callbacks.audioSampleCallbacks).length === 0 && !needsToIterateOverSamples({
|
|
6929
|
+
emittedFields: state.emittedFields,
|
|
6930
|
+
fields: state.fields
|
|
6931
|
+
});
|
|
6932
|
+
};
|
|
6933
|
+
|
|
6760
6934
|
// src/has-all-info.ts
|
|
6761
6935
|
var getAvailableInfo = ({
|
|
6762
6936
|
fieldsToFetch,
|
|
6763
|
-
structure,
|
|
6764
6937
|
state
|
|
6765
6938
|
}) => {
|
|
6766
6939
|
const keys = Object.entries(fieldsToFetch).filter(([, value]) => value);
|
|
6940
|
+
const structure = state.structure.getStructureOrNull();
|
|
6767
6941
|
const infos = keys.map(([_key]) => {
|
|
6768
6942
|
const key = _key;
|
|
6769
6943
|
if (key === "structure") {
|
|
@@ -6772,12 +6946,18 @@ var getAvailableInfo = ({
|
|
|
6772
6946
|
if (key === "durationInSeconds") {
|
|
6773
6947
|
return Boolean(structure && hasDuration(structure, state));
|
|
6774
6948
|
}
|
|
6949
|
+
if (key === "slowDurationInSeconds") {
|
|
6950
|
+
return Boolean(structure && hasSlowDuration(structure, state));
|
|
6951
|
+
}
|
|
6775
6952
|
if (key === "dimensions" || key === "rotation" || key === "unrotatedDimensions") {
|
|
6776
6953
|
return Boolean(structure && hasDimensions(structure, state));
|
|
6777
6954
|
}
|
|
6778
6955
|
if (key === "fps") {
|
|
6779
6956
|
return Boolean(structure && hasFps(structure));
|
|
6780
6957
|
}
|
|
6958
|
+
if (key === "slowFps") {
|
|
6959
|
+
return Boolean(structure && hasFpsSuitedForSlowFps(structure));
|
|
6960
|
+
}
|
|
6781
6961
|
if (key === "isHdr") {
|
|
6782
6962
|
return Boolean(structure && hasHdr(structure, state));
|
|
6783
6963
|
}
|
|
@@ -6790,6 +6970,9 @@ var getAvailableInfo = ({
|
|
|
6790
6970
|
if (key === "tracks") {
|
|
6791
6971
|
return Boolean(structure && hasTracks(structure, state));
|
|
6792
6972
|
}
|
|
6973
|
+
if (key === "keyframes") {
|
|
6974
|
+
return Boolean(structure && hasKeyframes(structure, state));
|
|
6975
|
+
}
|
|
6793
6976
|
if (key === "internalStats") {
|
|
6794
6977
|
return true;
|
|
6795
6978
|
}
|
|
@@ -6808,6 +6991,12 @@ var getAvailableInfo = ({
|
|
|
6808
6991
|
if (key === "metadata" || key === "location") {
|
|
6809
6992
|
return false;
|
|
6810
6993
|
}
|
|
6994
|
+
if (key === "slowKeyframes") {
|
|
6995
|
+
return false;
|
|
6996
|
+
}
|
|
6997
|
+
if (key === "slowNumberOfFrames") {
|
|
6998
|
+
return false;
|
|
6999
|
+
}
|
|
6811
7000
|
throw new Error(`Unknown key: ${key}`);
|
|
6812
7001
|
});
|
|
6813
7002
|
const entries = [];
|
|
@@ -6819,46 +7008,44 @@ var getAvailableInfo = ({
|
|
|
6819
7008
|
};
|
|
6820
7009
|
var hasAllInfo = ({
|
|
6821
7010
|
fields,
|
|
6822
|
-
state
|
|
6823
|
-
structure
|
|
7011
|
+
state
|
|
6824
7012
|
}) => {
|
|
6825
7013
|
const availableInfo = getAvailableInfo({
|
|
6826
7014
|
fieldsToFetch: fields ?? {},
|
|
6827
|
-
structure,
|
|
6828
7015
|
state
|
|
6829
7016
|
});
|
|
6830
|
-
return Object.values(availableInfo).every(Boolean) && (
|
|
7017
|
+
return Object.values(availableInfo).every(Boolean) && (maySkipVideoData({ state }) || state.callbacks.canSkipTracksState.canSkipTracks());
|
|
6831
7018
|
};
|
|
6832
7019
|
|
|
6833
7020
|
// src/register-track.ts
|
|
6834
7021
|
var registerTrack = async ({
|
|
6835
|
-
|
|
7022
|
+
state,
|
|
6836
7023
|
track,
|
|
6837
7024
|
container
|
|
6838
7025
|
}) => {
|
|
6839
7026
|
if (track.type === "video") {
|
|
6840
|
-
|
|
6841
|
-
if (
|
|
6842
|
-
const callback = await
|
|
6843
|
-
await
|
|
7027
|
+
state.callbacks.tracks.addTrack(track);
|
|
7028
|
+
if (state.onVideoTrack) {
|
|
7029
|
+
const callback = await state.onVideoTrack({ track, container });
|
|
7030
|
+
await state.callbacks.registerVideoSampleCallback(track.trackId, callback ?? null);
|
|
6844
7031
|
}
|
|
6845
7032
|
}
|
|
6846
7033
|
if (track.type === "audio") {
|
|
6847
|
-
|
|
6848
|
-
if (
|
|
6849
|
-
const callback = await
|
|
6850
|
-
await
|
|
7034
|
+
state.callbacks.tracks.addTrack(track);
|
|
7035
|
+
if (state.onAudioTrack) {
|
|
7036
|
+
const callback = await state.onAudioTrack({ track, container });
|
|
7037
|
+
await state.callbacks.registerAudioSampleCallback(track.trackId, callback ?? null);
|
|
6851
7038
|
}
|
|
6852
7039
|
}
|
|
6853
7040
|
};
|
|
6854
7041
|
var registerVideoTrackWhenProfileIsAvailable = ({
|
|
6855
|
-
|
|
7042
|
+
state,
|
|
6856
7043
|
track,
|
|
6857
7044
|
container
|
|
6858
7045
|
}) => {
|
|
6859
|
-
|
|
7046
|
+
state.riff.registerOnAvcProfileCallback(async (profile) => {
|
|
6860
7047
|
await registerTrack({
|
|
6861
|
-
|
|
7048
|
+
state,
|
|
6862
7049
|
track: addAvcProfileToTrack(track, profile),
|
|
6863
7050
|
container
|
|
6864
7051
|
});
|
|
@@ -7033,7 +7220,9 @@ var convertAudioOrVideoSampleToWebCodecsTimestamps = (sample, timescale2) => {
|
|
|
7033
7220
|
duration: (sample.duration ?? 0) * 1e6 / timescale2,
|
|
7034
7221
|
data: sample.data,
|
|
7035
7222
|
trackId: sample.trackId,
|
|
7036
|
-
type: sample.type
|
|
7223
|
+
type: sample.type,
|
|
7224
|
+
offset: sample.offset,
|
|
7225
|
+
timescale: 1e6
|
|
7037
7226
|
};
|
|
7038
7227
|
};
|
|
7039
7228
|
|
|
@@ -7043,14 +7232,14 @@ var parseMdat = async ({
|
|
|
7043
7232
|
size,
|
|
7044
7233
|
fileOffset,
|
|
7045
7234
|
existingBoxes,
|
|
7046
|
-
|
|
7235
|
+
state,
|
|
7047
7236
|
signal,
|
|
7048
7237
|
maySkipSampleProcessing
|
|
7049
7238
|
}) => {
|
|
7050
7239
|
const alreadyHas = hasTracks({
|
|
7051
7240
|
type: "iso-base-media",
|
|
7052
7241
|
boxes: existingBoxes
|
|
7053
|
-
},
|
|
7242
|
+
}, state);
|
|
7054
7243
|
if (!alreadyHas) {
|
|
7055
7244
|
if (maySkipSampleProcessing) {
|
|
7056
7245
|
data.discard(size - (data.counter.getOffset() - fileOffset));
|
|
@@ -7070,7 +7259,7 @@ var parseMdat = async ({
|
|
|
7070
7259
|
fileOffset
|
|
7071
7260
|
});
|
|
7072
7261
|
}
|
|
7073
|
-
const tracks2 = getTracks({ type: "iso-base-media", boxes: existingBoxes },
|
|
7262
|
+
const tracks2 = getTracks({ type: "iso-base-media", boxes: existingBoxes }, state);
|
|
7074
7263
|
const allTracks = [
|
|
7075
7264
|
...tracks2.videoTracks,
|
|
7076
7265
|
...tracks2.audioTracks,
|
|
@@ -7112,25 +7301,29 @@ var parseMdat = async ({
|
|
|
7112
7301
|
const bytes = data.getSlice(samplesWithIndex.samplePosition.size);
|
|
7113
7302
|
const { cts, dts, duration: duration2 } = samplesWithIndex.samplePosition;
|
|
7114
7303
|
if (samplesWithIndex.track.type === "audio") {
|
|
7115
|
-
await
|
|
7304
|
+
await state.callbacks.onAudioSample(samplesWithIndex.track.trackId, convertAudioOrVideoSampleToWebCodecsTimestamps({
|
|
7116
7305
|
data: bytes,
|
|
7117
7306
|
timestamp: cts,
|
|
7118
7307
|
duration: duration2,
|
|
7119
7308
|
cts,
|
|
7120
7309
|
dts,
|
|
7121
7310
|
trackId: samplesWithIndex.track.trackId,
|
|
7122
|
-
type: samplesWithIndex.samplePosition.isKeyframe ? "key" : "delta"
|
|
7311
|
+
type: samplesWithIndex.samplePosition.isKeyframe ? "key" : "delta",
|
|
7312
|
+
offset: samplesWithIndex.samplePosition.offset,
|
|
7313
|
+
timescale: samplesWithIndex.track.timescale
|
|
7123
7314
|
}, samplesWithIndex.track.timescale));
|
|
7124
7315
|
}
|
|
7125
7316
|
if (samplesWithIndex.track.type === "video") {
|
|
7126
|
-
await
|
|
7317
|
+
await state.callbacks.onVideoSample(samplesWithIndex.track.trackId, convertAudioOrVideoSampleToWebCodecsTimestamps({
|
|
7127
7318
|
data: bytes,
|
|
7128
7319
|
timestamp: cts,
|
|
7129
7320
|
duration: duration2,
|
|
7130
7321
|
cts,
|
|
7131
7322
|
dts,
|
|
7132
7323
|
trackId: samplesWithIndex.track.trackId,
|
|
7133
|
-
type: samplesWithIndex.samplePosition.isKeyframe ? "key" : "delta"
|
|
7324
|
+
type: samplesWithIndex.samplePosition.isKeyframe ? "key" : "delta",
|
|
7325
|
+
offset: samplesWithIndex.samplePosition.offset,
|
|
7326
|
+
timescale: samplesWithIndex.track.timescale
|
|
7134
7327
|
}, samplesWithIndex.track.timescale));
|
|
7135
7328
|
}
|
|
7136
7329
|
const remaining = size - (data.counter.getOffset() - fileOffset);
|
|
@@ -7295,17 +7488,18 @@ var parseMoov = async ({
|
|
|
7295
7488
|
iterator,
|
|
7296
7489
|
offset,
|
|
7297
7490
|
size,
|
|
7298
|
-
|
|
7491
|
+
state,
|
|
7299
7492
|
signal,
|
|
7300
7493
|
logLevel,
|
|
7301
7494
|
fields
|
|
7302
7495
|
}) => {
|
|
7496
|
+
const boxes = [];
|
|
7303
7497
|
const children = await parseIsoBaseMediaBoxes({
|
|
7304
7498
|
iterator,
|
|
7305
7499
|
maxBytes: size - (iterator.counter.getOffset() - offset),
|
|
7306
7500
|
allowIncompleteBoxes: false,
|
|
7307
|
-
initialBoxes:
|
|
7308
|
-
|
|
7501
|
+
initialBoxes: boxes,
|
|
7502
|
+
state,
|
|
7309
7503
|
continueMdat: false,
|
|
7310
7504
|
signal,
|
|
7311
7505
|
logLevel,
|
|
@@ -7318,7 +7512,7 @@ var parseMoov = async ({
|
|
|
7318
7512
|
offset,
|
|
7319
7513
|
boxSize: size,
|
|
7320
7514
|
type: "moov-box",
|
|
7321
|
-
children:
|
|
7515
|
+
children: boxes
|
|
7322
7516
|
};
|
|
7323
7517
|
};
|
|
7324
7518
|
|
|
@@ -7651,18 +7845,19 @@ var parseMebx = async ({
|
|
|
7651
7845
|
iterator,
|
|
7652
7846
|
offset,
|
|
7653
7847
|
size,
|
|
7654
|
-
|
|
7848
|
+
state,
|
|
7655
7849
|
signal,
|
|
7656
7850
|
fields
|
|
7657
7851
|
}) => {
|
|
7658
7852
|
iterator.discard(6);
|
|
7659
7853
|
const dataReferenceIndex = iterator.getUint16();
|
|
7854
|
+
const boxes = [];
|
|
7660
7855
|
const children = await parseIsoBaseMediaBoxes({
|
|
7661
7856
|
iterator,
|
|
7662
7857
|
maxBytes: iterator.counter.getOffset() - offset,
|
|
7663
7858
|
allowIncompleteBoxes: false,
|
|
7664
|
-
initialBoxes:
|
|
7665
|
-
|
|
7859
|
+
initialBoxes: boxes,
|
|
7860
|
+
state,
|
|
7666
7861
|
continueMdat: false,
|
|
7667
7862
|
signal,
|
|
7668
7863
|
logLevel: "info",
|
|
@@ -7677,7 +7872,7 @@ var parseMebx = async ({
|
|
|
7677
7872
|
offset,
|
|
7678
7873
|
dataReferenceIndex,
|
|
7679
7874
|
format: "mebx",
|
|
7680
|
-
children:
|
|
7875
|
+
children: boxes
|
|
7681
7876
|
};
|
|
7682
7877
|
};
|
|
7683
7878
|
|
|
@@ -7830,7 +8025,7 @@ var audioTags = [
|
|
|
7830
8025
|
];
|
|
7831
8026
|
var processSample = async ({
|
|
7832
8027
|
iterator,
|
|
7833
|
-
options,
|
|
8028
|
+
state: options,
|
|
7834
8029
|
signal,
|
|
7835
8030
|
logLevel,
|
|
7836
8031
|
fields
|
|
@@ -7870,12 +8065,13 @@ var processSample = async ({
|
|
|
7870
8065
|
const packetSize = iterator.getUint16();
|
|
7871
8066
|
const sampleRate = iterator.getFixedPointUnsigned1616Number();
|
|
7872
8067
|
const bytesRemainingInBox = boxSize - (iterator.counter.getOffset() - fileOffset);
|
|
8068
|
+
const initialBoxes = [];
|
|
7873
8069
|
const children = await parseIsoBaseMediaBoxes({
|
|
7874
8070
|
iterator,
|
|
7875
8071
|
allowIncompleteBoxes: false,
|
|
7876
8072
|
maxBytes: bytesRemainingInBox,
|
|
7877
|
-
initialBoxes
|
|
7878
|
-
options,
|
|
8073
|
+
initialBoxes,
|
|
8074
|
+
state: options,
|
|
7879
8075
|
continueMdat: false,
|
|
7880
8076
|
signal,
|
|
7881
8077
|
logLevel,
|
|
@@ -7903,7 +8099,7 @@ var processSample = async ({
|
|
|
7903
8099
|
bytesPerPacket: null,
|
|
7904
8100
|
bytesPerFrame: null,
|
|
7905
8101
|
bitsPerSample: null,
|
|
7906
|
-
children:
|
|
8102
|
+
children: initialBoxes
|
|
7907
8103
|
}
|
|
7908
8104
|
};
|
|
7909
8105
|
}
|
|
@@ -7918,12 +8114,13 @@ var processSample = async ({
|
|
|
7918
8114
|
const bytesPerFrame = iterator.getUint32();
|
|
7919
8115
|
const bytesPerSample = iterator.getUint32();
|
|
7920
8116
|
const bytesRemainingInBox = boxSize - (iterator.counter.getOffset() - fileOffset);
|
|
8117
|
+
const initialBoxes = [];
|
|
7921
8118
|
const children = await parseIsoBaseMediaBoxes({
|
|
7922
8119
|
iterator,
|
|
7923
8120
|
allowIncompleteBoxes: false,
|
|
7924
8121
|
maxBytes: bytesRemainingInBox,
|
|
7925
|
-
initialBoxes
|
|
7926
|
-
options,
|
|
8122
|
+
initialBoxes,
|
|
8123
|
+
state: options,
|
|
7927
8124
|
continueMdat: false,
|
|
7928
8125
|
signal,
|
|
7929
8126
|
logLevel,
|
|
@@ -7951,7 +8148,7 @@ var processSample = async ({
|
|
|
7951
8148
|
bytesPerPacket,
|
|
7952
8149
|
bytesPerFrame,
|
|
7953
8150
|
bitsPerSample: bytesPerSample,
|
|
7954
|
-
children:
|
|
8151
|
+
children: initialBoxes
|
|
7955
8152
|
}
|
|
7956
8153
|
};
|
|
7957
8154
|
}
|
|
@@ -7975,7 +8172,7 @@ var processSample = async ({
|
|
|
7975
8172
|
allowIncompleteBoxes: false,
|
|
7976
8173
|
maxBytes: bytesRemainingInBox,
|
|
7977
8174
|
initialBoxes: [],
|
|
7978
|
-
options,
|
|
8175
|
+
state: options,
|
|
7979
8176
|
continueMdat: false,
|
|
7980
8177
|
signal,
|
|
7981
8178
|
logLevel,
|
|
@@ -7984,6 +8181,7 @@ var processSample = async ({
|
|
|
7984
8181
|
if (children.status === "incomplete") {
|
|
7985
8182
|
throw new Error("Incomplete boxes are not allowed");
|
|
7986
8183
|
}
|
|
8184
|
+
const initialBoxes = [];
|
|
7987
8185
|
return {
|
|
7988
8186
|
sample: {
|
|
7989
8187
|
format: boxFormat,
|
|
@@ -8003,7 +8201,7 @@ var processSample = async ({
|
|
|
8003
8201
|
bytesPerPacket: null,
|
|
8004
8202
|
bytesPerFrame,
|
|
8005
8203
|
bitsPerSample: bitsPerChannel,
|
|
8006
|
-
children:
|
|
8204
|
+
children: initialBoxes
|
|
8007
8205
|
}
|
|
8008
8206
|
};
|
|
8009
8207
|
}
|
|
@@ -8025,17 +8223,18 @@ var processSample = async ({
|
|
|
8025
8223
|
const depth = iterator.getUint16();
|
|
8026
8224
|
const colorTableId = iterator.getInt16();
|
|
8027
8225
|
const bytesRemainingInBox = boxSize - (iterator.counter.getOffset() - fileOffset);
|
|
8226
|
+
const initialBoxes = [];
|
|
8028
8227
|
const children = bytesRemainingInBox > 8 ? await parseIsoBaseMediaBoxes({
|
|
8029
8228
|
iterator,
|
|
8030
8229
|
allowIncompleteBoxes: false,
|
|
8031
8230
|
maxBytes: bytesRemainingInBox,
|
|
8032
|
-
initialBoxes
|
|
8033
|
-
options,
|
|
8231
|
+
initialBoxes,
|
|
8232
|
+
state: options,
|
|
8034
8233
|
continueMdat: false,
|
|
8035
8234
|
signal,
|
|
8036
8235
|
logLevel,
|
|
8037
8236
|
fields
|
|
8038
|
-
}) : (iterator.discard(bytesRemainingInBox), { status: "done"
|
|
8237
|
+
}) : (iterator.discard(bytesRemainingInBox), { status: "done" });
|
|
8039
8238
|
if (children.status === "incomplete") {
|
|
8040
8239
|
throw new Error("Incomplete boxes are not allowed");
|
|
8041
8240
|
}
|
|
@@ -8060,7 +8259,7 @@ var processSample = async ({
|
|
|
8060
8259
|
compressorName,
|
|
8061
8260
|
depth,
|
|
8062
8261
|
colorTableId,
|
|
8063
|
-
descriptors:
|
|
8262
|
+
descriptors: initialBoxes
|
|
8064
8263
|
}
|
|
8065
8264
|
};
|
|
8066
8265
|
}
|
|
@@ -8069,7 +8268,7 @@ var processSample = async ({
|
|
|
8069
8268
|
var parseSamples = async ({
|
|
8070
8269
|
iterator,
|
|
8071
8270
|
maxBytes,
|
|
8072
|
-
|
|
8271
|
+
state,
|
|
8073
8272
|
signal,
|
|
8074
8273
|
logLevel,
|
|
8075
8274
|
fields
|
|
@@ -8079,7 +8278,7 @@ var parseSamples = async ({
|
|
|
8079
8278
|
while (iterator.bytesRemaining() > 0 && iterator.counter.getOffset() - initialOffset < maxBytes) {
|
|
8080
8279
|
const { sample } = await processSample({
|
|
8081
8280
|
iterator,
|
|
8082
|
-
|
|
8281
|
+
state,
|
|
8083
8282
|
signal,
|
|
8084
8283
|
logLevel,
|
|
8085
8284
|
fields
|
|
@@ -8096,7 +8295,7 @@ var parseStsd = async ({
|
|
|
8096
8295
|
iterator,
|
|
8097
8296
|
offset,
|
|
8098
8297
|
size,
|
|
8099
|
-
|
|
8298
|
+
state,
|
|
8100
8299
|
signal,
|
|
8101
8300
|
fields
|
|
8102
8301
|
}) => {
|
|
@@ -8110,7 +8309,7 @@ var parseStsd = async ({
|
|
|
8110
8309
|
const boxes = await parseSamples({
|
|
8111
8310
|
iterator,
|
|
8112
8311
|
maxBytes: bytesRemainingInBox,
|
|
8113
|
-
|
|
8312
|
+
state,
|
|
8114
8313
|
signal,
|
|
8115
8314
|
logLevel: "info",
|
|
8116
8315
|
fields
|
|
@@ -8382,30 +8581,31 @@ var parseTrak = async ({
|
|
|
8382
8581
|
data,
|
|
8383
8582
|
size,
|
|
8384
8583
|
offsetAtStart,
|
|
8385
|
-
options,
|
|
8584
|
+
state: options,
|
|
8386
8585
|
signal,
|
|
8387
8586
|
logLevel,
|
|
8388
8587
|
fields
|
|
8389
8588
|
}) => {
|
|
8390
|
-
const
|
|
8589
|
+
const initialBoxes = [];
|
|
8590
|
+
const result = await parseIsoBaseMediaBoxes({
|
|
8391
8591
|
iterator: data,
|
|
8392
8592
|
maxBytes: size - (data.counter.getOffset() - offsetAtStart),
|
|
8393
8593
|
allowIncompleteBoxes: false,
|
|
8394
|
-
initialBoxes
|
|
8395
|
-
options,
|
|
8594
|
+
initialBoxes,
|
|
8595
|
+
state: options,
|
|
8396
8596
|
continueMdat: false,
|
|
8397
8597
|
signal,
|
|
8398
8598
|
logLevel,
|
|
8399
8599
|
fields
|
|
8400
8600
|
});
|
|
8401
|
-
if (
|
|
8601
|
+
if (result.status === "incomplete") {
|
|
8402
8602
|
throw new Error("Incomplete boxes are not allowed");
|
|
8403
8603
|
}
|
|
8404
8604
|
return {
|
|
8405
8605
|
offset: offsetAtStart,
|
|
8406
8606
|
boxSize: size,
|
|
8407
8607
|
type: "trak-box",
|
|
8408
|
-
children:
|
|
8608
|
+
children: initialBoxes
|
|
8409
8609
|
};
|
|
8410
8610
|
};
|
|
8411
8611
|
|
|
@@ -8456,19 +8656,20 @@ var getChildren = async ({
|
|
|
8456
8656
|
boxType,
|
|
8457
8657
|
iterator,
|
|
8458
8658
|
bytesRemainingInBox,
|
|
8459
|
-
|
|
8659
|
+
state,
|
|
8460
8660
|
signal,
|
|
8461
8661
|
logLevel,
|
|
8462
8662
|
fields
|
|
8463
8663
|
}) => {
|
|
8464
8664
|
const parseChildren = boxType === "mdia" || boxType === "minf" || boxType === "stbl" || boxType === "udta" || boxType === "moof" || boxType === "dims" || boxType === "meta" || boxType === "wave" || boxType === "traf" || boxType === "stsb";
|
|
8465
8665
|
if (parseChildren) {
|
|
8666
|
+
const boxes = [];
|
|
8466
8667
|
const parsed = await parseIsoBaseMediaBoxes({
|
|
8467
8668
|
iterator,
|
|
8468
8669
|
maxBytes: bytesRemainingInBox,
|
|
8469
8670
|
allowIncompleteBoxes: false,
|
|
8470
|
-
initialBoxes:
|
|
8471
|
-
|
|
8671
|
+
initialBoxes: boxes,
|
|
8672
|
+
state,
|
|
8472
8673
|
continueMdat: false,
|
|
8473
8674
|
signal,
|
|
8474
8675
|
logLevel,
|
|
@@ -8477,7 +8678,7 @@ var getChildren = async ({
|
|
|
8477
8678
|
if (parsed.status === "incomplete") {
|
|
8478
8679
|
throw new Error("Incomplete boxes are not allowed");
|
|
8479
8680
|
}
|
|
8480
|
-
return
|
|
8681
|
+
return boxes;
|
|
8481
8682
|
}
|
|
8482
8683
|
if (bytesRemainingInBox < 0) {
|
|
8483
8684
|
throw new Error("Box size is too big " + JSON.stringify({ boxType }));
|
|
@@ -8490,7 +8691,7 @@ var parseMdatPartially = async ({
|
|
|
8490
8691
|
boxSize,
|
|
8491
8692
|
fileOffset,
|
|
8492
8693
|
parsedBoxes,
|
|
8493
|
-
|
|
8694
|
+
state,
|
|
8494
8695
|
signal
|
|
8495
8696
|
}) => {
|
|
8496
8697
|
const box = await parseMdat({
|
|
@@ -8498,9 +8699,9 @@ var parseMdatPartially = async ({
|
|
|
8498
8699
|
size: boxSize,
|
|
8499
8700
|
fileOffset,
|
|
8500
8701
|
existingBoxes: parsedBoxes,
|
|
8501
|
-
|
|
8702
|
+
state,
|
|
8502
8703
|
signal,
|
|
8503
|
-
maySkipSampleProcessing:
|
|
8704
|
+
maySkipSampleProcessing: state.supportsContentRange
|
|
8504
8705
|
});
|
|
8505
8706
|
if ((box.status === "samples-processed" || box.status === "samples-buffered") && box.fileOffset + boxSize === iterator.counter.getOffset()) {
|
|
8506
8707
|
return {
|
|
@@ -8520,7 +8721,7 @@ var processBox = async ({
|
|
|
8520
8721
|
iterator,
|
|
8521
8722
|
allowIncompleteBoxes,
|
|
8522
8723
|
parsedBoxes,
|
|
8523
|
-
|
|
8724
|
+
state,
|
|
8524
8725
|
signal,
|
|
8525
8726
|
logLevel,
|
|
8526
8727
|
fields
|
|
@@ -8552,7 +8753,7 @@ var processBox = async ({
|
|
|
8552
8753
|
const boxSize = boxSizeRaw === 1 ? iterator.getEightByteNumber() : boxSizeRaw;
|
|
8553
8754
|
if (bytesRemaining < boxSize) {
|
|
8554
8755
|
if (boxType === "mdat") {
|
|
8555
|
-
const shouldSkip =
|
|
8756
|
+
const shouldSkip = maySkipVideoData({ state }) || !hasTracks({ type: "iso-base-media", boxes: parsedBoxes }, state) && state.supportsContentRange;
|
|
8556
8757
|
if (shouldSkip) {
|
|
8557
8758
|
const skipTo = fileOffset + boxSize;
|
|
8558
8759
|
const bytesToSkip = skipTo - iterator.counter.getOffset();
|
|
@@ -8575,7 +8776,7 @@ var processBox = async ({
|
|
|
8575
8776
|
boxSize,
|
|
8576
8777
|
fileOffset,
|
|
8577
8778
|
parsedBoxes,
|
|
8578
|
-
|
|
8779
|
+
state,
|
|
8579
8780
|
signal
|
|
8580
8781
|
});
|
|
8581
8782
|
}
|
|
@@ -8650,7 +8851,7 @@ var processBox = async ({
|
|
|
8650
8851
|
iterator,
|
|
8651
8852
|
offset: fileOffset,
|
|
8652
8853
|
size: boxSize,
|
|
8653
|
-
|
|
8854
|
+
state,
|
|
8654
8855
|
signal,
|
|
8655
8856
|
fields
|
|
8656
8857
|
});
|
|
@@ -8745,7 +8946,7 @@ var processBox = async ({
|
|
|
8745
8946
|
iterator,
|
|
8746
8947
|
offset: fileOffset,
|
|
8747
8948
|
size: boxSize,
|
|
8748
|
-
|
|
8949
|
+
state,
|
|
8749
8950
|
signal,
|
|
8750
8951
|
fields
|
|
8751
8952
|
});
|
|
@@ -8792,12 +8993,12 @@ var processBox = async ({
|
|
|
8792
8993
|
iterator,
|
|
8793
8994
|
offset: fileOffset,
|
|
8794
8995
|
size: boxSize,
|
|
8795
|
-
|
|
8996
|
+
state,
|
|
8796
8997
|
signal,
|
|
8797
8998
|
logLevel,
|
|
8798
8999
|
fields
|
|
8799
9000
|
});
|
|
8800
|
-
|
|
9001
|
+
state.callbacks.tracks.setIsDone();
|
|
8801
9002
|
return {
|
|
8802
9003
|
type: "complete",
|
|
8803
9004
|
box,
|
|
@@ -8810,7 +9011,7 @@ var processBox = async ({
|
|
|
8810
9011
|
data: iterator,
|
|
8811
9012
|
size: boxSize,
|
|
8812
9013
|
offsetAtStart: fileOffset,
|
|
8813
|
-
|
|
9014
|
+
state,
|
|
8814
9015
|
signal,
|
|
8815
9016
|
logLevel,
|
|
8816
9017
|
fields
|
|
@@ -8818,7 +9019,7 @@ var processBox = async ({
|
|
|
8818
9019
|
const transformedTrack = makeBaseMediaTrack(box);
|
|
8819
9020
|
if (transformedTrack) {
|
|
8820
9021
|
await registerTrack({
|
|
8821
|
-
|
|
9022
|
+
state,
|
|
8822
9023
|
track: transformedTrack,
|
|
8823
9024
|
container: "mp4"
|
|
8824
9025
|
});
|
|
@@ -8925,9 +9126,9 @@ var processBox = async ({
|
|
|
8925
9126
|
size: boxSize,
|
|
8926
9127
|
fileOffset,
|
|
8927
9128
|
existingBoxes: parsedBoxes,
|
|
8928
|
-
|
|
9129
|
+
state,
|
|
8929
9130
|
signal,
|
|
8930
|
-
maySkipSampleProcessing:
|
|
9131
|
+
maySkipSampleProcessing: state.supportsContentRange
|
|
8931
9132
|
});
|
|
8932
9133
|
if (box === null) {
|
|
8933
9134
|
throw new Error("Unexpected null");
|
|
@@ -8944,7 +9145,7 @@ var processBox = async ({
|
|
|
8944
9145
|
boxType,
|
|
8945
9146
|
iterator,
|
|
8946
9147
|
bytesRemainingInBox,
|
|
8947
|
-
|
|
9148
|
+
state,
|
|
8948
9149
|
signal,
|
|
8949
9150
|
logLevel,
|
|
8950
9151
|
fields
|
|
@@ -8967,31 +9168,27 @@ var parseIsoBaseMediaBoxes = async ({
|
|
|
8967
9168
|
maxBytes,
|
|
8968
9169
|
allowIncompleteBoxes,
|
|
8969
9170
|
initialBoxes,
|
|
8970
|
-
|
|
9171
|
+
state,
|
|
8971
9172
|
continueMdat,
|
|
8972
9173
|
signal,
|
|
8973
9174
|
logLevel,
|
|
8974
9175
|
fields
|
|
8975
9176
|
}) => {
|
|
8976
|
-
const structure = {
|
|
8977
|
-
type: "iso-base-media",
|
|
8978
|
-
boxes: initialBoxes
|
|
8979
|
-
};
|
|
8980
9177
|
const initialOffset = iterator.counter.getOffset();
|
|
8981
|
-
const alreadyHasMdat = structure.boxes.find((b) => b.type === "mdat-box");
|
|
9178
|
+
const alreadyHasMdat = state.structure.getStructureOrNull()?.boxes.find((b) => b.type === "mdat-box");
|
|
8982
9179
|
while (iterator.bytesRemaining() > 0 && iterator.counter.getOffset() - initialOffset < maxBytes) {
|
|
8983
9180
|
const result = continueMdat ? await parseMdatPartially({
|
|
8984
9181
|
iterator,
|
|
8985
9182
|
boxSize: continueMdat.boxSize,
|
|
8986
9183
|
fileOffset: continueMdat.fileOffset,
|
|
8987
9184
|
parsedBoxes: initialBoxes,
|
|
8988
|
-
|
|
9185
|
+
state,
|
|
8989
9186
|
signal
|
|
8990
9187
|
}) : await processBox({
|
|
8991
9188
|
iterator,
|
|
8992
9189
|
allowIncompleteBoxes,
|
|
8993
9190
|
parsedBoxes: initialBoxes,
|
|
8994
|
-
|
|
9191
|
+
state,
|
|
8995
9192
|
signal,
|
|
8996
9193
|
logLevel,
|
|
8997
9194
|
fields
|
|
@@ -9002,14 +9199,13 @@ var parseIsoBaseMediaBoxes = async ({
|
|
|
9002
9199
|
}
|
|
9003
9200
|
return {
|
|
9004
9201
|
status: "incomplete",
|
|
9005
|
-
segments: structure,
|
|
9006
9202
|
continueParsing: () => {
|
|
9007
9203
|
return parseIsoBaseMediaBoxes({
|
|
9008
9204
|
iterator,
|
|
9009
9205
|
maxBytes,
|
|
9010
9206
|
allowIncompleteBoxes,
|
|
9011
|
-
initialBoxes
|
|
9012
|
-
|
|
9207
|
+
initialBoxes,
|
|
9208
|
+
state,
|
|
9013
9209
|
continueMdat: false,
|
|
9014
9210
|
signal,
|
|
9015
9211
|
logLevel,
|
|
@@ -9022,14 +9218,13 @@ var parseIsoBaseMediaBoxes = async ({
|
|
|
9022
9218
|
if (result.type === "partial-mdat-box") {
|
|
9023
9219
|
return {
|
|
9024
9220
|
status: "incomplete",
|
|
9025
|
-
segments: structure,
|
|
9026
9221
|
continueParsing: () => {
|
|
9027
9222
|
return Promise.resolve(parseIsoBaseMediaBoxes({
|
|
9028
9223
|
iterator,
|
|
9029
9224
|
maxBytes,
|
|
9030
9225
|
allowIncompleteBoxes,
|
|
9031
|
-
initialBoxes
|
|
9032
|
-
|
|
9226
|
+
initialBoxes,
|
|
9227
|
+
state,
|
|
9033
9228
|
continueMdat: result,
|
|
9034
9229
|
signal,
|
|
9035
9230
|
logLevel,
|
|
@@ -9040,36 +9235,34 @@ var parseIsoBaseMediaBoxes = async ({
|
|
|
9040
9235
|
};
|
|
9041
9236
|
}
|
|
9042
9237
|
if (result.box.type === "mdat-box" && alreadyHasMdat) {
|
|
9043
|
-
|
|
9044
|
-
|
|
9238
|
+
initialBoxes = initialBoxes.filter((b) => b.type !== "mdat-box");
|
|
9239
|
+
initialBoxes.push(result.box);
|
|
9045
9240
|
iterator.allowDiscard();
|
|
9046
9241
|
if (result.box.status !== "samples-processed") {
|
|
9047
9242
|
throw new Error("unexpected");
|
|
9048
9243
|
}
|
|
9049
9244
|
break;
|
|
9050
9245
|
} else {
|
|
9051
|
-
|
|
9052
|
-
if (hasAllInfo({ fields, state
|
|
9246
|
+
initialBoxes.push(result.box);
|
|
9247
|
+
if (hasAllInfo({ fields, state })) {
|
|
9053
9248
|
return {
|
|
9054
|
-
status: "done"
|
|
9055
|
-
segments: structure
|
|
9249
|
+
status: "done"
|
|
9056
9250
|
};
|
|
9057
9251
|
}
|
|
9058
9252
|
}
|
|
9059
9253
|
if (result.skipTo !== null) {
|
|
9060
|
-
if (!
|
|
9254
|
+
if (!state.supportsContentRange) {
|
|
9061
9255
|
throw new Error("Content-Range header is not supported by the reader, but was asked to seek");
|
|
9062
9256
|
}
|
|
9063
9257
|
return {
|
|
9064
9258
|
status: "incomplete",
|
|
9065
|
-
segments: structure,
|
|
9066
9259
|
continueParsing: () => {
|
|
9067
9260
|
return parseIsoBaseMediaBoxes({
|
|
9068
9261
|
iterator,
|
|
9069
9262
|
maxBytes,
|
|
9070
9263
|
allowIncompleteBoxes,
|
|
9071
|
-
initialBoxes
|
|
9072
|
-
|
|
9264
|
+
initialBoxes,
|
|
9265
|
+
state,
|
|
9073
9266
|
continueMdat: false,
|
|
9074
9267
|
signal,
|
|
9075
9268
|
logLevel,
|
|
@@ -9082,14 +9275,13 @@ var parseIsoBaseMediaBoxes = async ({
|
|
|
9082
9275
|
if (iterator.bytesRemaining() < 0) {
|
|
9083
9276
|
return {
|
|
9084
9277
|
status: "incomplete",
|
|
9085
|
-
segments: structure,
|
|
9086
9278
|
continueParsing: () => {
|
|
9087
9279
|
return parseIsoBaseMediaBoxes({
|
|
9088
9280
|
iterator,
|
|
9089
9281
|
maxBytes,
|
|
9090
9282
|
allowIncompleteBoxes,
|
|
9091
|
-
initialBoxes
|
|
9092
|
-
|
|
9283
|
+
initialBoxes,
|
|
9284
|
+
state,
|
|
9093
9285
|
continueMdat: false,
|
|
9094
9286
|
signal,
|
|
9095
9287
|
logLevel,
|
|
@@ -9101,13 +9293,12 @@ var parseIsoBaseMediaBoxes = async ({
|
|
|
9101
9293
|
}
|
|
9102
9294
|
iterator.removeBytesRead();
|
|
9103
9295
|
}
|
|
9104
|
-
const mdatState = getMdatBox(
|
|
9105
|
-
const skipped = mdatState?.status === "samples-skipped" && !
|
|
9106
|
-
const buffered = mdatState?.status === "samples-buffered" && !
|
|
9296
|
+
const mdatState = getMdatBox(initialBoxes);
|
|
9297
|
+
const skipped = mdatState?.status === "samples-skipped" && !maySkipVideoData({ state }) && state.supportsContentRange;
|
|
9298
|
+
const buffered = mdatState?.status === "samples-buffered" && !maySkipVideoData({ state });
|
|
9107
9299
|
if (skipped || buffered) {
|
|
9108
9300
|
return {
|
|
9109
9301
|
status: "incomplete",
|
|
9110
|
-
segments: structure,
|
|
9111
9302
|
continueParsing: () => {
|
|
9112
9303
|
if (buffered) {
|
|
9113
9304
|
iterator.skipTo(mdatState.fileOffset, false);
|
|
@@ -9116,8 +9307,8 @@ var parseIsoBaseMediaBoxes = async ({
|
|
|
9116
9307
|
iterator,
|
|
9117
9308
|
maxBytes,
|
|
9118
9309
|
allowIncompleteBoxes: false,
|
|
9119
|
-
initialBoxes
|
|
9120
|
-
|
|
9310
|
+
initialBoxes,
|
|
9311
|
+
state,
|
|
9121
9312
|
continueMdat: false,
|
|
9122
9313
|
signal,
|
|
9123
9314
|
logLevel,
|
|
@@ -9128,8 +9319,7 @@ var parseIsoBaseMediaBoxes = async ({
|
|
|
9128
9319
|
};
|
|
9129
9320
|
}
|
|
9130
9321
|
return {
|
|
9131
|
-
status: "done"
|
|
9132
|
-
segments: structure
|
|
9322
|
+
status: "done"
|
|
9133
9323
|
};
|
|
9134
9324
|
};
|
|
9135
9325
|
|
|
@@ -9397,37 +9587,39 @@ var getStrhForIndex = (structure, trackId) => {
|
|
|
9397
9587
|
};
|
|
9398
9588
|
var handleChunk = async ({
|
|
9399
9589
|
iterator,
|
|
9400
|
-
|
|
9590
|
+
state,
|
|
9401
9591
|
structure,
|
|
9402
9592
|
ckId,
|
|
9403
9593
|
ckSize
|
|
9404
9594
|
}) => {
|
|
9595
|
+
const offset = iterator.counter.getOffset();
|
|
9405
9596
|
const videoChunk = ckId.match(/^([0-9]{2})dc$/);
|
|
9406
9597
|
if (videoChunk) {
|
|
9407
9598
|
const trackId = parseInt(videoChunk[1], 10);
|
|
9408
9599
|
const strh = getStrhForIndex(structure, trackId);
|
|
9409
9600
|
const samplesPerSecond = strh.rate / strh.scale;
|
|
9410
|
-
const nthSample =
|
|
9601
|
+
const nthSample = state.callbacks.getSamplesForTrack(trackId);
|
|
9411
9602
|
const timeInSec = nthSample / samplesPerSecond;
|
|
9412
|
-
const timestamp =
|
|
9413
|
-
const duration2 = Math.floor(1 / samplesPerSecond);
|
|
9603
|
+
const timestamp = timeInSec;
|
|
9414
9604
|
const data = iterator.getSlice(ckSize);
|
|
9415
9605
|
const infos = parseAvc(data);
|
|
9416
9606
|
const keyOrDelta = getKeyFrameOrDeltaFromAvcInfo(infos);
|
|
9417
9607
|
const avcProfile = infos.find((i) => i.type === "avc-profile");
|
|
9418
9608
|
const ppsProfile = infos.find((i) => i.type === "avc-pps");
|
|
9419
9609
|
if (avcProfile && ppsProfile) {
|
|
9420
|
-
await
|
|
9421
|
-
|
|
9610
|
+
await state.riff.onProfile({ pps: ppsProfile, sps: avcProfile });
|
|
9611
|
+
state.callbacks.tracks.setIsDone();
|
|
9422
9612
|
}
|
|
9423
|
-
await
|
|
9613
|
+
await state.callbacks.onVideoSample(trackId, convertAudioOrVideoSampleToWebCodecsTimestamps({
|
|
9424
9614
|
cts: timestamp,
|
|
9425
9615
|
dts: timestamp,
|
|
9426
9616
|
data,
|
|
9427
|
-
duration:
|
|
9617
|
+
duration: undefined,
|
|
9428
9618
|
timestamp,
|
|
9429
9619
|
trackId,
|
|
9430
|
-
type: keyOrDelta
|
|
9620
|
+
type: keyOrDelta,
|
|
9621
|
+
offset,
|
|
9622
|
+
timescale: samplesPerSecond
|
|
9431
9623
|
}, 1));
|
|
9432
9624
|
return;
|
|
9433
9625
|
}
|
|
@@ -9436,25 +9628,27 @@ var handleChunk = async ({
|
|
|
9436
9628
|
const trackId = parseInt(audioChunk[1], 10);
|
|
9437
9629
|
const strh = getStrhForIndex(structure, trackId);
|
|
9438
9630
|
const samplesPerSecond = strh.rate / strh.scale;
|
|
9439
|
-
const nthSample =
|
|
9631
|
+
const nthSample = state.callbacks.getSamplesForTrack(trackId);
|
|
9440
9632
|
const timeInSec = nthSample / samplesPerSecond;
|
|
9441
9633
|
const timestamp = timeInSec;
|
|
9442
|
-
const
|
|
9443
|
-
await
|
|
9634
|
+
const data = iterator.getSlice(ckSize);
|
|
9635
|
+
await state.callbacks.onAudioSample(trackId, convertAudioOrVideoSampleToWebCodecsTimestamps({
|
|
9444
9636
|
cts: timestamp,
|
|
9445
9637
|
dts: timestamp,
|
|
9446
|
-
data
|
|
9447
|
-
duration:
|
|
9638
|
+
data,
|
|
9639
|
+
duration: undefined,
|
|
9448
9640
|
timestamp,
|
|
9449
9641
|
trackId,
|
|
9450
|
-
type: "key"
|
|
9642
|
+
type: "key",
|
|
9643
|
+
offset,
|
|
9644
|
+
timescale: samplesPerSecond
|
|
9451
9645
|
}, 1));
|
|
9452
9646
|
}
|
|
9453
9647
|
};
|
|
9454
9648
|
var parseMovi = async ({
|
|
9455
9649
|
iterator,
|
|
9456
9650
|
maxOffset,
|
|
9457
|
-
|
|
9651
|
+
state,
|
|
9458
9652
|
structure
|
|
9459
9653
|
}) => {
|
|
9460
9654
|
while (iterator.counter.getOffset() < maxOffset) {
|
|
@@ -9462,13 +9656,15 @@ var parseMovi = async ({
|
|
|
9462
9656
|
return {
|
|
9463
9657
|
type: "incomplete",
|
|
9464
9658
|
continueParsing: () => {
|
|
9465
|
-
return Promise.resolve(parseMovi({ iterator, maxOffset,
|
|
9659
|
+
return Promise.resolve(parseMovi({ iterator, maxOffset, state, structure }));
|
|
9466
9660
|
}
|
|
9467
9661
|
};
|
|
9468
9662
|
}
|
|
9469
9663
|
const ckId = iterator.getByteString(4);
|
|
9470
9664
|
const ckSize = iterator.getUint32Le();
|
|
9471
|
-
if (
|
|
9665
|
+
if (maySkipVideoData({
|
|
9666
|
+
state
|
|
9667
|
+
}) && state.riff.getAvcProfile()) {
|
|
9472
9668
|
return {
|
|
9473
9669
|
type: "complete",
|
|
9474
9670
|
box: {
|
|
@@ -9482,11 +9678,11 @@ var parseMovi = async ({
|
|
|
9482
9678
|
return {
|
|
9483
9679
|
type: "incomplete",
|
|
9484
9680
|
continueParsing: () => {
|
|
9485
|
-
return Promise.resolve(parseMovi({ iterator, maxOffset,
|
|
9681
|
+
return Promise.resolve(parseMovi({ iterator, maxOffset, state, structure }));
|
|
9486
9682
|
}
|
|
9487
9683
|
};
|
|
9488
9684
|
}
|
|
9489
|
-
await handleChunk({ iterator,
|
|
9685
|
+
await handleChunk({ iterator, state, structure, ckId, ckSize });
|
|
9490
9686
|
while (iterator.counter.getOffset() < maxOffset && iterator.bytesRemaining() > 0) {
|
|
9491
9687
|
if (iterator.getUint8() !== 0) {
|
|
9492
9688
|
iterator.counter.decrement(1);
|
|
@@ -9509,7 +9705,7 @@ var parseMovi = async ({
|
|
|
9509
9705
|
return {
|
|
9510
9706
|
type: "incomplete",
|
|
9511
9707
|
continueParsing: () => {
|
|
9512
|
-
return Promise.resolve(parseMovi({ iterator, maxOffset,
|
|
9708
|
+
return Promise.resolve(parseMovi({ iterator, maxOffset, state, structure }));
|
|
9513
9709
|
}
|
|
9514
9710
|
};
|
|
9515
9711
|
};
|
|
@@ -9604,7 +9800,7 @@ var parseIsft = ({
|
|
|
9604
9800
|
var parseListBox = async ({
|
|
9605
9801
|
iterator,
|
|
9606
9802
|
size,
|
|
9607
|
-
|
|
9803
|
+
state
|
|
9608
9804
|
}) => {
|
|
9609
9805
|
const counter = iterator.counter.getOffset();
|
|
9610
9806
|
const listType = iterator.getByteString(4);
|
|
@@ -9619,7 +9815,7 @@ var parseListBox = async ({
|
|
|
9619
9815
|
structure,
|
|
9620
9816
|
iterator,
|
|
9621
9817
|
maxOffset: counter + size,
|
|
9622
|
-
|
|
9818
|
+
state
|
|
9623
9819
|
});
|
|
9624
9820
|
if (result.status === "incomplete") {
|
|
9625
9821
|
throw new Error(`Should only parse complete boxes (${listType})`);
|
|
@@ -9759,13 +9955,13 @@ var parseRiffBox = ({
|
|
|
9759
9955
|
size,
|
|
9760
9956
|
id,
|
|
9761
9957
|
boxes,
|
|
9762
|
-
|
|
9958
|
+
state
|
|
9763
9959
|
}) => {
|
|
9764
9960
|
if (id === "fmt") {
|
|
9765
9961
|
return Promise.resolve(parseFmtBox({ iterator, boxes, size }));
|
|
9766
9962
|
}
|
|
9767
9963
|
if (id === "LIST") {
|
|
9768
|
-
return parseListBox({ iterator, size,
|
|
9964
|
+
return parseListBox({ iterator, size, state });
|
|
9769
9965
|
}
|
|
9770
9966
|
if (id === "ISFT") {
|
|
9771
9967
|
return Promise.resolve(parseIsft({ iterator, size }));
|
|
@@ -9791,14 +9987,14 @@ var parseRiffBox = ({
|
|
|
9791
9987
|
// src/boxes/riff/expect-riff-box.ts
|
|
9792
9988
|
var expectRiffBox = async ({
|
|
9793
9989
|
iterator,
|
|
9794
|
-
|
|
9990
|
+
state,
|
|
9795
9991
|
structure
|
|
9796
9992
|
}) => {
|
|
9797
9993
|
if (iterator.bytesRemaining() < 16) {
|
|
9798
9994
|
return {
|
|
9799
9995
|
type: "incomplete",
|
|
9800
9996
|
continueParsing() {
|
|
9801
|
-
return expectRiffBox({ structure, iterator,
|
|
9997
|
+
return expectRiffBox({ structure, iterator, state });
|
|
9802
9998
|
}
|
|
9803
9999
|
};
|
|
9804
10000
|
}
|
|
@@ -9809,7 +10005,7 @@ var expectRiffBox = async ({
|
|
|
9809
10005
|
return parseMovi({
|
|
9810
10006
|
iterator,
|
|
9811
10007
|
maxOffset: ckSize + iterator.counter.getOffset() - 4,
|
|
9812
|
-
|
|
10008
|
+
state,
|
|
9813
10009
|
structure
|
|
9814
10010
|
});
|
|
9815
10011
|
}
|
|
@@ -9818,7 +10014,7 @@ var expectRiffBox = async ({
|
|
|
9818
10014
|
return {
|
|
9819
10015
|
type: "incomplete",
|
|
9820
10016
|
continueParsing: () => {
|
|
9821
|
-
return expectRiffBox({ structure, iterator,
|
|
10017
|
+
return expectRiffBox({ structure, iterator, state });
|
|
9822
10018
|
}
|
|
9823
10019
|
};
|
|
9824
10020
|
}
|
|
@@ -9829,7 +10025,7 @@ var expectRiffBox = async ({
|
|
|
9829
10025
|
iterator,
|
|
9830
10026
|
size: ckSize,
|
|
9831
10027
|
boxes: structure.boxes,
|
|
9832
|
-
|
|
10028
|
+
state
|
|
9833
10029
|
}),
|
|
9834
10030
|
skipTo: null
|
|
9835
10031
|
};
|
|
@@ -9841,7 +10037,7 @@ var continueAfterRiffBoxResult = ({
|
|
|
9841
10037
|
structure,
|
|
9842
10038
|
iterator,
|
|
9843
10039
|
maxOffset,
|
|
9844
|
-
options
|
|
10040
|
+
state: options
|
|
9845
10041
|
}) => {
|
|
9846
10042
|
if (result.type === "incomplete") {
|
|
9847
10043
|
return Promise.resolve({
|
|
@@ -9852,7 +10048,7 @@ var continueAfterRiffBoxResult = ({
|
|
|
9852
10048
|
structure,
|
|
9853
10049
|
iterator,
|
|
9854
10050
|
maxOffset,
|
|
9855
|
-
options
|
|
10051
|
+
state: options
|
|
9856
10052
|
}));
|
|
9857
10053
|
},
|
|
9858
10054
|
segments: structure,
|
|
@@ -9862,30 +10058,29 @@ var continueAfterRiffBoxResult = ({
|
|
|
9862
10058
|
if (result.type === "complete" && result.box) {
|
|
9863
10059
|
structure.boxes.push(result.box);
|
|
9864
10060
|
}
|
|
9865
|
-
return parseRiffBody({ iterator, maxOffset, options, structure });
|
|
10061
|
+
return parseRiffBody({ iterator, maxOffset, state: options, structure });
|
|
9866
10062
|
};
|
|
9867
10063
|
var parseRiffBody = async ({
|
|
9868
10064
|
iterator,
|
|
9869
10065
|
structure,
|
|
9870
10066
|
maxOffset,
|
|
9871
|
-
|
|
10067
|
+
state
|
|
9872
10068
|
}) => {
|
|
9873
10069
|
while (iterator.bytesRemaining() > 0 && iterator.counter.getOffset() < maxOffset) {
|
|
9874
10070
|
const result = await expectRiffBox({
|
|
9875
10071
|
iterator,
|
|
9876
|
-
|
|
10072
|
+
state,
|
|
9877
10073
|
structure
|
|
9878
10074
|
});
|
|
9879
10075
|
if (result.type === "complete" && result.skipTo !== null) {
|
|
9880
10076
|
return {
|
|
9881
10077
|
status: "incomplete",
|
|
9882
10078
|
skipTo: result.skipTo,
|
|
9883
|
-
segments: structure,
|
|
9884
10079
|
continueParsing() {
|
|
9885
10080
|
return Promise.resolve(continueAfterRiffBoxResult({
|
|
9886
10081
|
iterator,
|
|
9887
10082
|
maxOffset,
|
|
9888
|
-
|
|
10083
|
+
state,
|
|
9889
10084
|
result,
|
|
9890
10085
|
structure
|
|
9891
10086
|
}));
|
|
@@ -9899,12 +10094,11 @@ var parseRiffBody = async ({
|
|
|
9899
10094
|
return Promise.resolve(continueAfterRiffBoxResult({
|
|
9900
10095
|
iterator,
|
|
9901
10096
|
maxOffset,
|
|
9902
|
-
|
|
10097
|
+
state,
|
|
9903
10098
|
result: await result.continueParsing(),
|
|
9904
10099
|
structure
|
|
9905
10100
|
}));
|
|
9906
10101
|
},
|
|
9907
|
-
segments: structure,
|
|
9908
10102
|
skipTo: null
|
|
9909
10103
|
};
|
|
9910
10104
|
}
|
|
@@ -9913,13 +10107,13 @@ var parseRiffBody = async ({
|
|
|
9913
10107
|
}
|
|
9914
10108
|
structure.boxes.push(result.box);
|
|
9915
10109
|
if (result.box.type === "list-box" && result.box.listType === "hdrl") {
|
|
9916
|
-
const tracks2 = getTracks(structure,
|
|
10110
|
+
const tracks2 = getTracks(structure, state);
|
|
9917
10111
|
if (!tracks2.videoTracks.some((t) => t.codec === TO_BE_OVERRIDDEN_LATER)) {
|
|
9918
|
-
|
|
10112
|
+
state.callbacks.tracks.setIsDone();
|
|
9919
10113
|
}
|
|
9920
10114
|
}
|
|
9921
10115
|
if (result.box.type === "wave-format-box") {
|
|
9922
|
-
|
|
10116
|
+
state.callbacks.tracks.setIsDone();
|
|
9923
10117
|
}
|
|
9924
10118
|
if (result.box.type === "strf-box-video" || result.box.type === "strf-box-audio") {
|
|
9925
10119
|
const strh = getStrhBox(structure.boxes);
|
|
@@ -9927,60 +10121,67 @@ var parseRiffBody = async ({
|
|
|
9927
10121
|
if (!strh || !strf) {
|
|
9928
10122
|
throw new Error("strh or strf box missing");
|
|
9929
10123
|
}
|
|
9930
|
-
if (strf.type === "strf-box-audio" &&
|
|
10124
|
+
if (strf.type === "strf-box-audio" && state.onAudioTrack) {
|
|
9931
10125
|
const audioTrack = makeAviAudioTrack({
|
|
9932
|
-
index:
|
|
10126
|
+
index: state.riff.getNextTrackIndex(),
|
|
9933
10127
|
strf
|
|
9934
10128
|
});
|
|
9935
10129
|
await registerTrack({
|
|
9936
|
-
|
|
10130
|
+
state,
|
|
9937
10131
|
track: audioTrack,
|
|
9938
10132
|
container: "avi"
|
|
9939
10133
|
});
|
|
9940
10134
|
}
|
|
9941
|
-
if (
|
|
10135
|
+
if (state.onVideoTrack && strf.type === "strf-box-video") {
|
|
9942
10136
|
const videoTrack = makeAviVideoTrack({
|
|
9943
10137
|
strh,
|
|
9944
|
-
index:
|
|
10138
|
+
index: state.riff.getNextTrackIndex(),
|
|
9945
10139
|
strf
|
|
9946
10140
|
});
|
|
9947
10141
|
registerVideoTrackWhenProfileIsAvailable({
|
|
9948
|
-
|
|
10142
|
+
state,
|
|
9949
10143
|
track: videoTrack,
|
|
9950
10144
|
container: "avi"
|
|
9951
10145
|
});
|
|
9952
10146
|
}
|
|
9953
|
-
|
|
10147
|
+
state.riff.incrementNextTrackIndex();
|
|
9954
10148
|
}
|
|
9955
10149
|
}
|
|
9956
10150
|
return {
|
|
9957
|
-
status: "done"
|
|
9958
|
-
segments: structure
|
|
10151
|
+
status: "done"
|
|
9959
10152
|
};
|
|
9960
10153
|
};
|
|
9961
10154
|
var parseRiff = ({
|
|
9962
10155
|
iterator,
|
|
9963
|
-
|
|
10156
|
+
state,
|
|
9964
10157
|
fields
|
|
9965
10158
|
}) => {
|
|
9966
|
-
const structure = { type: "riff", boxes: [] };
|
|
9967
10159
|
const riff = iterator.getByteString(4);
|
|
9968
10160
|
if (riff !== "RIFF") {
|
|
9969
10161
|
throw new Error("Not a RIFF file");
|
|
9970
10162
|
}
|
|
10163
|
+
const structure = state.structure.getStructure();
|
|
10164
|
+
if (structure.type !== "riff") {
|
|
10165
|
+
throw new Error("Structure is not a RIFF structure");
|
|
10166
|
+
}
|
|
9971
10167
|
const size = iterator.getUint32Le();
|
|
9972
10168
|
const fileType = iterator.getByteString(4);
|
|
9973
10169
|
if (fileType !== "WAVE" && fileType !== "AVI") {
|
|
9974
10170
|
throw new Error(`File type ${fileType} not supported`);
|
|
9975
10171
|
}
|
|
9976
10172
|
structure.boxes.push({ type: "riff-header", fileSize: size, fileType });
|
|
9977
|
-
if (hasAllInfo({ fields,
|
|
10173
|
+
if (hasAllInfo({ fields, state })) {
|
|
9978
10174
|
return Promise.resolve({
|
|
9979
10175
|
status: "done",
|
|
9980
10176
|
segments: structure
|
|
9981
10177
|
});
|
|
9982
10178
|
}
|
|
9983
|
-
return parseRiffBody({
|
|
10179
|
+
return parseRiffBody({
|
|
10180
|
+
iterator,
|
|
10181
|
+
maxOffset: Infinity,
|
|
10182
|
+
state,
|
|
10183
|
+
structure
|
|
10184
|
+
});
|
|
9984
10185
|
};
|
|
9985
10186
|
|
|
9986
10187
|
// src/boxes/transport-stream/next-pes-header-store.ts
|
|
@@ -10320,10 +10521,11 @@ var MPEG_TIMESCALE = 90000;
|
|
|
10320
10521
|
var handleAvcPacket = async ({
|
|
10321
10522
|
streamBuffer,
|
|
10322
10523
|
programId,
|
|
10323
|
-
|
|
10524
|
+
state,
|
|
10525
|
+
offset
|
|
10324
10526
|
}) => {
|
|
10325
10527
|
const avc = parseAvc(streamBuffer.buffer);
|
|
10326
|
-
const isTrackRegistered =
|
|
10528
|
+
const isTrackRegistered = state.callbacks.tracks.getTracks().find((t) => {
|
|
10327
10529
|
return t.trackId === programId;
|
|
10328
10530
|
});
|
|
10329
10531
|
if (!isTrackRegistered) {
|
|
@@ -10336,7 +10538,7 @@ var handleAvcPacket = async ({
|
|
|
10336
10538
|
type: "video",
|
|
10337
10539
|
timescale: MPEG_TIMESCALE,
|
|
10338
10540
|
codec: getCodecStringFromSpsAndPps(spsAndPps.sps),
|
|
10339
|
-
codecPrivate:
|
|
10541
|
+
codecPrivate: createSpsPpsData(spsAndPps),
|
|
10340
10542
|
fps: null,
|
|
10341
10543
|
codedWidth: dimensions.width,
|
|
10342
10544
|
codedHeight: dimensions.height,
|
|
@@ -10353,7 +10555,7 @@ var handleAvcPacket = async ({
|
|
|
10353
10555
|
},
|
|
10354
10556
|
color: getVideoColorFromSps(spsAndPps.sps.spsData)
|
|
10355
10557
|
};
|
|
10356
|
-
await registerTrack({ track,
|
|
10558
|
+
await registerTrack({ track, state, container: "transport-stream" });
|
|
10357
10559
|
}
|
|
10358
10560
|
const sample = {
|
|
10359
10561
|
cts: streamBuffer.pesHeader.pts,
|
|
@@ -10362,23 +10564,26 @@ var handleAvcPacket = async ({
|
|
|
10362
10564
|
duration: undefined,
|
|
10363
10565
|
data: new Uint8Array(streamBuffer.buffer),
|
|
10364
10566
|
trackId: programId,
|
|
10365
|
-
type: getKeyFrameOrDeltaFromAvcInfo(avc)
|
|
10567
|
+
type: getKeyFrameOrDeltaFromAvcInfo(avc),
|
|
10568
|
+
offset,
|
|
10569
|
+
timescale: MPEG_TIMESCALE
|
|
10366
10570
|
};
|
|
10367
|
-
await
|
|
10571
|
+
await state.callbacks.onVideoSample(programId, convertAudioOrVideoSampleToWebCodecsTimestamps(sample, MPEG_TIMESCALE));
|
|
10368
10572
|
};
|
|
10369
10573
|
|
|
10370
10574
|
// src/boxes/transport-stream/handle-aac-packet.ts
|
|
10371
10575
|
var handleAacPacket = async ({
|
|
10372
10576
|
streamBuffer,
|
|
10373
|
-
|
|
10374
|
-
programId
|
|
10577
|
+
state,
|
|
10578
|
+
programId,
|
|
10579
|
+
offset
|
|
10375
10580
|
}) => {
|
|
10376
10581
|
const adtsHeader = readAdtsHeader(streamBuffer.buffer);
|
|
10377
10582
|
if (!adtsHeader) {
|
|
10378
10583
|
throw new Error("Invalid ADTS header - too short");
|
|
10379
10584
|
}
|
|
10380
10585
|
const { channelConfiguration, codecPrivate: codecPrivate2, sampleRate, audioObjectType } = adtsHeader;
|
|
10381
|
-
const isTrackRegistered =
|
|
10586
|
+
const isTrackRegistered = state.callbacks.tracks.getTracks().find((t) => {
|
|
10382
10587
|
return t.trackId === programId;
|
|
10383
10588
|
});
|
|
10384
10589
|
if (!isTrackRegistered) {
|
|
@@ -10396,7 +10601,7 @@ var handleAacPacket = async ({
|
|
|
10396
10601
|
};
|
|
10397
10602
|
await registerTrack({
|
|
10398
10603
|
track,
|
|
10399
|
-
|
|
10604
|
+
state,
|
|
10400
10605
|
container: "transport-stream"
|
|
10401
10606
|
});
|
|
10402
10607
|
}
|
|
@@ -10407,15 +10612,17 @@ var handleAacPacket = async ({
|
|
|
10407
10612
|
duration: undefined,
|
|
10408
10613
|
data: new Uint8Array(streamBuffer.buffer),
|
|
10409
10614
|
trackId: programId,
|
|
10410
|
-
type: "key"
|
|
10615
|
+
type: "key",
|
|
10616
|
+
offset,
|
|
10617
|
+
timescale: MPEG_TIMESCALE
|
|
10411
10618
|
};
|
|
10412
|
-
await
|
|
10619
|
+
await state.callbacks.onAudioSample(programId, convertAudioOrVideoSampleToWebCodecsTimestamps(sample, MPEG_TIMESCALE));
|
|
10413
10620
|
};
|
|
10414
10621
|
|
|
10415
10622
|
// src/boxes/transport-stream/process-stream-buffers.ts
|
|
10416
10623
|
var processStreamBuffer = async ({
|
|
10417
10624
|
streamBuffer,
|
|
10418
|
-
|
|
10625
|
+
state,
|
|
10419
10626
|
programId,
|
|
10420
10627
|
structure
|
|
10421
10628
|
}) => {
|
|
@@ -10424,28 +10631,38 @@ var processStreamBuffer = async ({
|
|
|
10424
10631
|
throw new Error("No stream found");
|
|
10425
10632
|
}
|
|
10426
10633
|
if (stream.streamType === 27) {
|
|
10427
|
-
await handleAvcPacket({
|
|
10634
|
+
await handleAvcPacket({
|
|
10635
|
+
programId,
|
|
10636
|
+
streamBuffer,
|
|
10637
|
+
state,
|
|
10638
|
+
offset: streamBuffer.offset
|
|
10639
|
+
});
|
|
10428
10640
|
} else if (stream.streamType === 15) {
|
|
10429
|
-
await handleAacPacket({
|
|
10641
|
+
await handleAacPacket({
|
|
10642
|
+
streamBuffer,
|
|
10643
|
+
state,
|
|
10644
|
+
programId,
|
|
10645
|
+
offset: streamBuffer.offset
|
|
10646
|
+
});
|
|
10430
10647
|
}
|
|
10431
|
-
if (!
|
|
10432
|
-
const tracksRegistered =
|
|
10648
|
+
if (!state.callbacks.tracks.hasAllTracks()) {
|
|
10649
|
+
const tracksRegistered = state.callbacks.tracks.getTracks().length;
|
|
10433
10650
|
const { streams } = findProgramMapTableOrThrow(structure);
|
|
10434
10651
|
if (streams.length === tracksRegistered) {
|
|
10435
|
-
|
|
10652
|
+
state.callbacks.tracks.setIsDone();
|
|
10436
10653
|
}
|
|
10437
10654
|
}
|
|
10438
10655
|
};
|
|
10439
10656
|
var processFinalStreamBuffers = async ({
|
|
10440
10657
|
streamBufferMap,
|
|
10441
|
-
|
|
10658
|
+
state,
|
|
10442
10659
|
structure
|
|
10443
10660
|
}) => {
|
|
10444
10661
|
for (const [programId, buffer] of streamBufferMap) {
|
|
10445
10662
|
if (buffer.buffer.byteLength > 0) {
|
|
10446
10663
|
await processStreamBuffer({
|
|
10447
10664
|
streamBuffer: buffer,
|
|
10448
|
-
|
|
10665
|
+
state,
|
|
10449
10666
|
programId,
|
|
10450
10667
|
structure
|
|
10451
10668
|
});
|
|
@@ -10460,14 +10677,16 @@ var parseAdtsStream = async ({
|
|
|
10460
10677
|
transportStreamEntry,
|
|
10461
10678
|
streamBuffers,
|
|
10462
10679
|
nextPesHeader,
|
|
10463
|
-
|
|
10464
|
-
structure
|
|
10680
|
+
state,
|
|
10681
|
+
structure,
|
|
10682
|
+
offset
|
|
10465
10683
|
}) => {
|
|
10466
10684
|
const streamBuffer = streamBuffers.get(transportStreamEntry.pid);
|
|
10467
10685
|
if (!streamBuffer) {
|
|
10468
10686
|
streamBuffers.set(transportStreamEntry.pid, {
|
|
10469
10687
|
buffer: restOfPacket,
|
|
10470
|
-
pesHeader: nextPesHeader
|
|
10688
|
+
pesHeader: nextPesHeader,
|
|
10689
|
+
offset
|
|
10471
10690
|
});
|
|
10472
10691
|
return;
|
|
10473
10692
|
}
|
|
@@ -10481,13 +10700,14 @@ var parseAdtsStream = async ({
|
|
|
10481
10700
|
await processStreamBuffer({
|
|
10482
10701
|
streamBuffer,
|
|
10483
10702
|
programId: transportStreamEntry.pid,
|
|
10484
|
-
|
|
10703
|
+
state,
|
|
10485
10704
|
structure
|
|
10486
10705
|
});
|
|
10487
10706
|
const rest = restOfPacket.slice(bytesToTake);
|
|
10488
10707
|
streamBuffers.set(transportStreamEntry.pid, {
|
|
10489
10708
|
buffer: rest,
|
|
10490
|
-
pesHeader: nextPesHeader
|
|
10709
|
+
pesHeader: nextPesHeader,
|
|
10710
|
+
offset
|
|
10491
10711
|
});
|
|
10492
10712
|
}
|
|
10493
10713
|
};
|
|
@@ -10497,8 +10717,9 @@ var parseAvcStream = async ({
|
|
|
10497
10717
|
streamBuffers,
|
|
10498
10718
|
nextPesHeader,
|
|
10499
10719
|
programId,
|
|
10500
|
-
|
|
10501
|
-
structure
|
|
10720
|
+
state,
|
|
10721
|
+
structure,
|
|
10722
|
+
offset
|
|
10502
10723
|
}) => {
|
|
10503
10724
|
const indexOfSeparator = findNextSeparator(restOfPacket, transportStreamEntry);
|
|
10504
10725
|
const streamBuffer = streamBuffers.get(transportStreamEntry.pid);
|
|
@@ -10512,7 +10733,8 @@ var parseAvcStream = async ({
|
|
|
10512
10733
|
}
|
|
10513
10734
|
streamBuffers.set(programId, {
|
|
10514
10735
|
pesHeader: nextPesHeader,
|
|
10515
|
-
buffer: restOfPacket
|
|
10736
|
+
buffer: restOfPacket,
|
|
10737
|
+
offset
|
|
10516
10738
|
});
|
|
10517
10739
|
return;
|
|
10518
10740
|
}
|
|
@@ -10520,7 +10742,7 @@ var parseAvcStream = async ({
|
|
|
10520
10742
|
const packet = restOfPacket.slice(0, indexOfSeparator);
|
|
10521
10743
|
streamBuffer.buffer = combineUint8Arrays([streamBuffer.buffer, packet]);
|
|
10522
10744
|
await processStreamBuffer({
|
|
10523
|
-
|
|
10745
|
+
state,
|
|
10524
10746
|
streamBuffer,
|
|
10525
10747
|
programId,
|
|
10526
10748
|
structure
|
|
@@ -10528,7 +10750,8 @@ var parseAvcStream = async ({
|
|
|
10528
10750
|
const rest = restOfPacket.slice(indexOfSeparator);
|
|
10529
10751
|
streamBuffers.set(programId, {
|
|
10530
10752
|
pesHeader: nextPesHeader,
|
|
10531
|
-
buffer: rest
|
|
10753
|
+
buffer: rest,
|
|
10754
|
+
offset
|
|
10532
10755
|
});
|
|
10533
10756
|
return;
|
|
10534
10757
|
}
|
|
@@ -10537,14 +10760,15 @@ var parseAvcStream = async ({
|
|
|
10537
10760
|
}
|
|
10538
10761
|
streamBuffers.set(programId, {
|
|
10539
10762
|
pesHeader: nextPesHeader,
|
|
10540
|
-
buffer: restOfPacket.slice(indexOfSeparator)
|
|
10763
|
+
buffer: restOfPacket.slice(indexOfSeparator),
|
|
10764
|
+
offset
|
|
10541
10765
|
});
|
|
10542
10766
|
};
|
|
10543
10767
|
var parseStream = ({
|
|
10544
10768
|
iterator,
|
|
10545
10769
|
transportStreamEntry,
|
|
10546
10770
|
streamBuffers,
|
|
10547
|
-
|
|
10771
|
+
state,
|
|
10548
10772
|
programId,
|
|
10549
10773
|
structure,
|
|
10550
10774
|
nextPesHeader
|
|
@@ -10556,9 +10780,10 @@ var parseStream = ({
|
|
|
10556
10780
|
transportStreamEntry,
|
|
10557
10781
|
streamBuffers,
|
|
10558
10782
|
nextPesHeader,
|
|
10559
|
-
|
|
10783
|
+
state,
|
|
10560
10784
|
programId,
|
|
10561
|
-
structure
|
|
10785
|
+
structure,
|
|
10786
|
+
offset: iterator.counter.getOffset()
|
|
10562
10787
|
});
|
|
10563
10788
|
}
|
|
10564
10789
|
if (transportStreamEntry.streamType === 15) {
|
|
@@ -10567,8 +10792,9 @@ var parseStream = ({
|
|
|
10567
10792
|
transportStreamEntry,
|
|
10568
10793
|
streamBuffers,
|
|
10569
10794
|
nextPesHeader,
|
|
10570
|
-
|
|
10571
|
-
structure
|
|
10795
|
+
state,
|
|
10796
|
+
structure,
|
|
10797
|
+
offset: iterator.counter.getOffset()
|
|
10572
10798
|
});
|
|
10573
10799
|
}
|
|
10574
10800
|
throw new Error(`Unsupported stream type ${transportStreamEntry.streamType}`);
|
|
@@ -10579,7 +10805,7 @@ var parsePacket = async ({
|
|
|
10579
10805
|
iterator,
|
|
10580
10806
|
structure,
|
|
10581
10807
|
streamBuffers,
|
|
10582
|
-
|
|
10808
|
+
parserState,
|
|
10583
10809
|
nextPesHeaderStore
|
|
10584
10810
|
}) => {
|
|
10585
10811
|
const offset = iterator.counter.getOffset();
|
|
@@ -10643,7 +10869,7 @@ var parsePacket = async ({
|
|
|
10643
10869
|
transportStreamEntry: stream,
|
|
10644
10870
|
streamBuffers,
|
|
10645
10871
|
nextPesHeader: nextPesHeaderStore.getNextPesHeader(),
|
|
10646
|
-
|
|
10872
|
+
state: parserState,
|
|
10647
10873
|
programId,
|
|
10648
10874
|
structure
|
|
10649
10875
|
});
|
|
@@ -10655,16 +10881,19 @@ var parsePacket = async ({
|
|
|
10655
10881
|
// src/boxes/transport-stream/parse-transport-stream.ts
|
|
10656
10882
|
var parseTransportStream = async ({
|
|
10657
10883
|
iterator,
|
|
10658
|
-
|
|
10659
|
-
structure,
|
|
10884
|
+
state,
|
|
10660
10885
|
streamBuffers,
|
|
10661
10886
|
fields,
|
|
10662
10887
|
nextPesHeaderStore
|
|
10663
10888
|
}) => {
|
|
10889
|
+
const structure = state.structure.getStructure();
|
|
10890
|
+
if (structure.type !== "transport-stream") {
|
|
10891
|
+
throw new Error("Invalid structure type");
|
|
10892
|
+
}
|
|
10664
10893
|
if (iterator.bytesRemaining() === 0) {
|
|
10665
10894
|
await processFinalStreamBuffers({
|
|
10666
10895
|
streamBufferMap: streamBuffers,
|
|
10667
|
-
|
|
10896
|
+
state,
|
|
10668
10897
|
structure
|
|
10669
10898
|
});
|
|
10670
10899
|
return Promise.resolve({
|
|
@@ -10675,8 +10904,7 @@ var parseTransportStream = async ({
|
|
|
10675
10904
|
while (true) {
|
|
10676
10905
|
if (hasAllInfo({
|
|
10677
10906
|
fields,
|
|
10678
|
-
state
|
|
10679
|
-
structure
|
|
10907
|
+
state
|
|
10680
10908
|
})) {
|
|
10681
10909
|
break;
|
|
10682
10910
|
}
|
|
@@ -10688,8 +10916,7 @@ var parseTransportStream = async ({
|
|
|
10688
10916
|
continueParsing: () => {
|
|
10689
10917
|
return parseTransportStream({
|
|
10690
10918
|
iterator,
|
|
10691
|
-
|
|
10692
|
-
structure,
|
|
10919
|
+
state,
|
|
10693
10920
|
streamBuffers,
|
|
10694
10921
|
fields,
|
|
10695
10922
|
nextPesHeaderStore
|
|
@@ -10701,7 +10928,7 @@ var parseTransportStream = async ({
|
|
|
10701
10928
|
iterator,
|
|
10702
10929
|
structure,
|
|
10703
10930
|
streamBuffers,
|
|
10704
|
-
|
|
10931
|
+
parserState: state,
|
|
10705
10932
|
nextPesHeaderStore
|
|
10706
10933
|
});
|
|
10707
10934
|
if (packet) {
|
|
@@ -10715,8 +10942,7 @@ var parseTransportStream = async ({
|
|
|
10715
10942
|
continueParsing() {
|
|
10716
10943
|
return parseTransportStream({
|
|
10717
10944
|
iterator,
|
|
10718
|
-
|
|
10719
|
-
structure,
|
|
10945
|
+
state,
|
|
10720
10946
|
streamBuffers,
|
|
10721
10947
|
fields,
|
|
10722
10948
|
nextPesHeaderStore
|
|
@@ -10759,7 +10985,7 @@ var parseBlockFlags = (iterator, type) => {
|
|
|
10759
10985
|
};
|
|
10760
10986
|
|
|
10761
10987
|
// src/boxes/webm/get-sample-from-block.ts
|
|
10762
|
-
var getSampleFromBlock = (ebml,
|
|
10988
|
+
var getSampleFromBlock = (ebml, state, offset) => {
|
|
10763
10989
|
const iterator = getArrayBufferIterator(ebml.value, ebml.value.length);
|
|
10764
10990
|
const trackNumber2 = iterator.getVint();
|
|
10765
10991
|
if (trackNumber2 === null) {
|
|
@@ -10767,9 +10993,9 @@ var getSampleFromBlock = (ebml, parserContext, offset) => {
|
|
|
10767
10993
|
}
|
|
10768
10994
|
const timecodeRelativeToCluster = iterator.getInt16();
|
|
10769
10995
|
const { keyframe } = parseBlockFlags(iterator, ebml.type === "SimpleBlock" ? matroskaElements.SimpleBlock : matroskaElements.Block);
|
|
10770
|
-
const { codec, trackTimescale } =
|
|
10771
|
-
const clusterOffset =
|
|
10772
|
-
const timescale2 =
|
|
10996
|
+
const { codec, trackTimescale } = state.webm.getTrackInfoByNumber(trackNumber2);
|
|
10997
|
+
const clusterOffset = state.webm.getTimestampOffsetForByteOffset(offset);
|
|
10998
|
+
const timescale2 = state.webm.getTimescale();
|
|
10773
10999
|
if (clusterOffset === undefined) {
|
|
10774
11000
|
throw new Error("Could not find offset for byte offset " + offset);
|
|
10775
11001
|
}
|
|
@@ -10786,7 +11012,9 @@ var getSampleFromBlock = (ebml, parserContext, offset) => {
|
|
|
10786
11012
|
dts: timecodeInMicroseconds,
|
|
10787
11013
|
duration: undefined,
|
|
10788
11014
|
trackId: trackNumber2,
|
|
10789
|
-
timestamp: timecodeInMicroseconds
|
|
11015
|
+
timestamp: timecodeInMicroseconds,
|
|
11016
|
+
offset,
|
|
11017
|
+
timescale: timescale2
|
|
10790
11018
|
};
|
|
10791
11019
|
if (keyframe === null) {
|
|
10792
11020
|
iterator.destroy();
|
|
@@ -10813,7 +11041,9 @@ var getSampleFromBlock = (ebml, parserContext, offset) => {
|
|
|
10813
11041
|
type: "key",
|
|
10814
11042
|
duration: undefined,
|
|
10815
11043
|
cts: timecodeInMicroseconds,
|
|
10816
|
-
dts: timecodeInMicroseconds
|
|
11044
|
+
dts: timecodeInMicroseconds,
|
|
11045
|
+
offset,
|
|
11046
|
+
timescale: timescale2
|
|
10817
11047
|
};
|
|
10818
11048
|
iterator.destroy();
|
|
10819
11049
|
return {
|
|
@@ -10828,7 +11058,7 @@ var getSampleFromBlock = (ebml, parserContext, offset) => {
|
|
|
10828
11058
|
};
|
|
10829
11059
|
|
|
10830
11060
|
// src/boxes/webm/parse-ebml.ts
|
|
10831
|
-
var parseEbml = async (iterator,
|
|
11061
|
+
var parseEbml = async (iterator, state) => {
|
|
10832
11062
|
const hex = iterator.getMatroskaSegmentId();
|
|
10833
11063
|
if (hex === null) {
|
|
10834
11064
|
throw new Error("Not enough bytes left to parse EBML - this should not happen");
|
|
@@ -10897,11 +11127,11 @@ var parseEbml = async (iterator, parserContext) => {
|
|
|
10897
11127
|
break;
|
|
10898
11128
|
}
|
|
10899
11129
|
const offset = iterator.counter.getOffset();
|
|
10900
|
-
const value = await parseEbml(iterator,
|
|
11130
|
+
const value = await parseEbml(iterator, state);
|
|
10901
11131
|
const remapped = await postprocessEbml({
|
|
10902
11132
|
offset,
|
|
10903
11133
|
ebml: value,
|
|
10904
|
-
|
|
11134
|
+
state
|
|
10905
11135
|
});
|
|
10906
11136
|
children.push(remapped);
|
|
10907
11137
|
const offsetNow = iterator.counter.getOffset();
|
|
@@ -10919,47 +11149,47 @@ var parseEbml = async (iterator, parserContext) => {
|
|
|
10919
11149
|
var postprocessEbml = async ({
|
|
10920
11150
|
offset,
|
|
10921
11151
|
ebml,
|
|
10922
|
-
|
|
11152
|
+
state
|
|
10923
11153
|
}) => {
|
|
10924
11154
|
if (ebml.type === "TimestampScale") {
|
|
10925
|
-
|
|
11155
|
+
state.webm.setTimescale(ebml.value.value);
|
|
10926
11156
|
}
|
|
10927
11157
|
if (ebml.type === "TrackEntry") {
|
|
10928
|
-
|
|
11158
|
+
state.webm.onTrackEntrySegment(ebml);
|
|
10929
11159
|
const track = getTrack({
|
|
10930
11160
|
track: ebml,
|
|
10931
|
-
timescale:
|
|
11161
|
+
timescale: state.webm.getTimescale()
|
|
10932
11162
|
});
|
|
10933
11163
|
if (track) {
|
|
10934
11164
|
await registerTrack({
|
|
10935
|
-
|
|
11165
|
+
state,
|
|
10936
11166
|
track,
|
|
10937
11167
|
container: "webm"
|
|
10938
11168
|
});
|
|
10939
11169
|
}
|
|
10940
11170
|
}
|
|
10941
11171
|
if (ebml.type === "Timestamp") {
|
|
10942
|
-
|
|
11172
|
+
state.webm.setTimestampOffset(offset, ebml.value.value);
|
|
10943
11173
|
}
|
|
10944
11174
|
if (ebml.type === "Block" || ebml.type === "SimpleBlock") {
|
|
10945
|
-
const sample = getSampleFromBlock(ebml,
|
|
10946
|
-
if (sample.type === "video-sample" &&
|
|
10947
|
-
await
|
|
11175
|
+
const sample = getSampleFromBlock(ebml, state, offset);
|
|
11176
|
+
if (sample.type === "video-sample" && state.nullifySamples) {
|
|
11177
|
+
await state.callbacks.onVideoSample(sample.videoSample.trackId, sample.videoSample);
|
|
10948
11178
|
return {
|
|
10949
11179
|
type: "Block",
|
|
10950
11180
|
value: new Uint8Array([]),
|
|
10951
11181
|
minVintWidth: ebml.minVintWidth
|
|
10952
11182
|
};
|
|
10953
11183
|
}
|
|
10954
|
-
if (sample.type === "audio-sample" &&
|
|
10955
|
-
await
|
|
11184
|
+
if (sample.type === "audio-sample" && state.nullifySamples) {
|
|
11185
|
+
await state.callbacks.onAudioSample(sample.audioSample.trackId, sample.audioSample);
|
|
10956
11186
|
return {
|
|
10957
11187
|
type: "Block",
|
|
10958
11188
|
value: new Uint8Array([]),
|
|
10959
11189
|
minVintWidth: ebml.minVintWidth
|
|
10960
11190
|
};
|
|
10961
11191
|
}
|
|
10962
|
-
if (sample.type === "no-sample" &&
|
|
11192
|
+
if (sample.type === "no-sample" && state.nullifySamples) {
|
|
10963
11193
|
return {
|
|
10964
11194
|
type: "Block",
|
|
10965
11195
|
value: new Uint8Array([]),
|
|
@@ -10973,15 +11203,15 @@ var postprocessEbml = async ({
|
|
|
10973
11203
|
throw new Error("Expected block segment");
|
|
10974
11204
|
}
|
|
10975
11205
|
const hasReferenceBlock = ebml.value.find((c) => c.type === "ReferenceBlock");
|
|
10976
|
-
const sample = block2.value.length === 0 ? null : getSampleFromBlock(block2,
|
|
11206
|
+
const sample = block2.value.length === 0 ? null : getSampleFromBlock(block2, state, offset);
|
|
10977
11207
|
if (sample && sample.type === "partial-video-sample") {
|
|
10978
11208
|
const completeFrame = {
|
|
10979
11209
|
...sample.partialVideoSample,
|
|
10980
11210
|
type: hasReferenceBlock ? "delta" : "key"
|
|
10981
11211
|
};
|
|
10982
|
-
await
|
|
11212
|
+
await state.callbacks.onVideoSample(sample.partialVideoSample.trackId, completeFrame);
|
|
10983
11213
|
}
|
|
10984
|
-
if (
|
|
11214
|
+
if (state.nullifySamples) {
|
|
10985
11215
|
return {
|
|
10986
11216
|
type: "BlockGroup",
|
|
10987
11217
|
value: [],
|
|
@@ -10996,7 +11226,7 @@ var postprocessEbml = async ({
|
|
|
10996
11226
|
var continueAfterMatroskaParseResult = async ({
|
|
10997
11227
|
result,
|
|
10998
11228
|
iterator,
|
|
10999
|
-
|
|
11229
|
+
state,
|
|
11000
11230
|
segment
|
|
11001
11231
|
}) => {
|
|
11002
11232
|
if (result.status === "done") {
|
|
@@ -11014,7 +11244,7 @@ var continueAfterMatroskaParseResult = async ({
|
|
|
11014
11244
|
return continueAfterMatroskaParseResult({
|
|
11015
11245
|
result: proceeded,
|
|
11016
11246
|
iterator,
|
|
11017
|
-
|
|
11247
|
+
state,
|
|
11018
11248
|
segment
|
|
11019
11249
|
});
|
|
11020
11250
|
},
|
|
@@ -11024,7 +11254,7 @@ var continueAfterMatroskaParseResult = async ({
|
|
|
11024
11254
|
};
|
|
11025
11255
|
var expectSegment = async ({
|
|
11026
11256
|
iterator,
|
|
11027
|
-
|
|
11257
|
+
state,
|
|
11028
11258
|
offset,
|
|
11029
11259
|
children,
|
|
11030
11260
|
fields,
|
|
@@ -11037,7 +11267,7 @@ var expectSegment = async ({
|
|
|
11037
11267
|
continueParsing: () => {
|
|
11038
11268
|
return expectAndProcessSegment({
|
|
11039
11269
|
iterator,
|
|
11040
|
-
|
|
11270
|
+
state,
|
|
11041
11271
|
offset,
|
|
11042
11272
|
children,
|
|
11043
11273
|
fields,
|
|
@@ -11055,7 +11285,7 @@ var expectSegment = async ({
|
|
|
11055
11285
|
continueParsing: () => {
|
|
11056
11286
|
return expectAndProcessSegment({
|
|
11057
11287
|
iterator,
|
|
11058
|
-
|
|
11288
|
+
state,
|
|
11059
11289
|
offset,
|
|
11060
11290
|
children,
|
|
11061
11291
|
fields,
|
|
@@ -11075,7 +11305,7 @@ var expectSegment = async ({
|
|
|
11075
11305
|
continueParsing: () => {
|
|
11076
11306
|
return expectSegment({
|
|
11077
11307
|
iterator,
|
|
11078
|
-
|
|
11308
|
+
state,
|
|
11079
11309
|
offset,
|
|
11080
11310
|
children,
|
|
11081
11311
|
fields,
|
|
@@ -11096,7 +11326,7 @@ var expectSegment = async ({
|
|
|
11096
11326
|
iterator,
|
|
11097
11327
|
length,
|
|
11098
11328
|
children: newSegment.value,
|
|
11099
|
-
|
|
11329
|
+
state,
|
|
11100
11330
|
startOffset: iterator.counter.getOffset(),
|
|
11101
11331
|
fields,
|
|
11102
11332
|
topLevelStructure
|
|
@@ -11107,7 +11337,7 @@ var expectSegment = async ({
|
|
|
11107
11337
|
continueParsing: () => {
|
|
11108
11338
|
return continueAfterMatroskaParseResult({
|
|
11109
11339
|
iterator,
|
|
11110
|
-
|
|
11340
|
+
state,
|
|
11111
11341
|
result: main,
|
|
11112
11342
|
segment: newSegment
|
|
11113
11343
|
});
|
|
@@ -11129,7 +11359,7 @@ var expectSegment = async ({
|
|
|
11129
11359
|
continueParsing: () => {
|
|
11130
11360
|
return expectSegment({
|
|
11131
11361
|
iterator,
|
|
11132
|
-
|
|
11362
|
+
state,
|
|
11133
11363
|
offset,
|
|
11134
11364
|
children,
|
|
11135
11365
|
fields,
|
|
@@ -11142,7 +11372,7 @@ var expectSegment = async ({
|
|
|
11142
11372
|
segmentId,
|
|
11143
11373
|
iterator,
|
|
11144
11374
|
length,
|
|
11145
|
-
|
|
11375
|
+
state,
|
|
11146
11376
|
headerReadSoFar: iterator.counter.getOffset() - offset
|
|
11147
11377
|
});
|
|
11148
11378
|
return {
|
|
@@ -11154,7 +11384,7 @@ var parseSegment = async ({
|
|
|
11154
11384
|
segmentId,
|
|
11155
11385
|
iterator,
|
|
11156
11386
|
length,
|
|
11157
|
-
|
|
11387
|
+
state,
|
|
11158
11388
|
headerReadSoFar
|
|
11159
11389
|
}) => {
|
|
11160
11390
|
if (length < 0) {
|
|
@@ -11162,8 +11392,8 @@ var parseSegment = async ({
|
|
|
11162
11392
|
}
|
|
11163
11393
|
iterator.counter.decrement(headerReadSoFar);
|
|
11164
11394
|
const offset = iterator.counter.getOffset();
|
|
11165
|
-
const ebml = await parseEbml(iterator,
|
|
11166
|
-
const remapped = await postprocessEbml({ offset, ebml,
|
|
11395
|
+
const ebml = await parseEbml(iterator, state);
|
|
11396
|
+
const remapped = await postprocessEbml({ offset, ebml, state });
|
|
11167
11397
|
return remapped;
|
|
11168
11398
|
};
|
|
11169
11399
|
|
|
@@ -11177,14 +11407,14 @@ var processParseResult = ({
|
|
|
11177
11407
|
}) => {
|
|
11178
11408
|
if (parseResult.segment && !children.includes(parseResult.segment)) {
|
|
11179
11409
|
children.push(parseResult.segment);
|
|
11180
|
-
if (hasAllInfo({ fields, state
|
|
11410
|
+
if (hasAllInfo({ fields, state })) {
|
|
11181
11411
|
return {
|
|
11182
11412
|
status: "done",
|
|
11183
11413
|
segment: parseResult.segment
|
|
11184
11414
|
};
|
|
11185
11415
|
}
|
|
11186
11416
|
if (parseResult.segment.type === "Tracks") {
|
|
11187
|
-
state.tracks.setIsDone();
|
|
11417
|
+
state.callbacks.tracks.setIsDone();
|
|
11188
11418
|
}
|
|
11189
11419
|
}
|
|
11190
11420
|
if (parseResult.status === "incomplete") {
|
|
@@ -11210,7 +11440,7 @@ var processParseResult = ({
|
|
|
11210
11440
|
};
|
|
11211
11441
|
var expectAndProcessSegment = async ({
|
|
11212
11442
|
iterator,
|
|
11213
|
-
|
|
11443
|
+
state,
|
|
11214
11444
|
offset,
|
|
11215
11445
|
children,
|
|
11216
11446
|
fields,
|
|
@@ -11218,7 +11448,7 @@ var expectAndProcessSegment = async ({
|
|
|
11218
11448
|
}) => {
|
|
11219
11449
|
const segment = await expectSegment({
|
|
11220
11450
|
iterator,
|
|
11221
|
-
|
|
11451
|
+
state,
|
|
11222
11452
|
offset,
|
|
11223
11453
|
children,
|
|
11224
11454
|
fields,
|
|
@@ -11227,7 +11457,7 @@ var expectAndProcessSegment = async ({
|
|
|
11227
11457
|
return processParseResult({
|
|
11228
11458
|
children,
|
|
11229
11459
|
parseResult: segment,
|
|
11230
|
-
state
|
|
11460
|
+
state,
|
|
11231
11461
|
fields,
|
|
11232
11462
|
topLevelStructure
|
|
11233
11463
|
});
|
|
@@ -11236,7 +11466,7 @@ var continueAfterSegmentResult = async ({
|
|
|
11236
11466
|
result,
|
|
11237
11467
|
length,
|
|
11238
11468
|
children,
|
|
11239
|
-
|
|
11469
|
+
state,
|
|
11240
11470
|
iterator,
|
|
11241
11471
|
startOffset,
|
|
11242
11472
|
fields,
|
|
@@ -11254,7 +11484,7 @@ var continueAfterSegmentResult = async ({
|
|
|
11254
11484
|
children,
|
|
11255
11485
|
iterator,
|
|
11256
11486
|
length,
|
|
11257
|
-
|
|
11487
|
+
state,
|
|
11258
11488
|
startOffset,
|
|
11259
11489
|
fields,
|
|
11260
11490
|
topLevelStructure
|
|
@@ -11271,7 +11501,7 @@ var continueAfterSegmentResult = async ({
|
|
|
11271
11501
|
children,
|
|
11272
11502
|
iterator,
|
|
11273
11503
|
length,
|
|
11274
|
-
|
|
11504
|
+
state,
|
|
11275
11505
|
startOffset,
|
|
11276
11506
|
fields,
|
|
11277
11507
|
topLevelStructure
|
|
@@ -11284,7 +11514,7 @@ var expectChildren = async ({
|
|
|
11284
11514
|
iterator,
|
|
11285
11515
|
length,
|
|
11286
11516
|
children,
|
|
11287
|
-
|
|
11517
|
+
state,
|
|
11288
11518
|
startOffset,
|
|
11289
11519
|
fields,
|
|
11290
11520
|
topLevelStructure
|
|
@@ -11296,7 +11526,7 @@ var expectChildren = async ({
|
|
|
11296
11526
|
const currentOffset = iterator.counter.getOffset();
|
|
11297
11527
|
const child = await expectAndProcessSegment({
|
|
11298
11528
|
iterator,
|
|
11299
|
-
|
|
11529
|
+
state,
|
|
11300
11530
|
offset: currentOffset,
|
|
11301
11531
|
children,
|
|
11302
11532
|
fields,
|
|
@@ -11304,8 +11534,7 @@ var expectChildren = async ({
|
|
|
11304
11534
|
});
|
|
11305
11535
|
if (hasAllInfo({
|
|
11306
11536
|
fields,
|
|
11307
|
-
state
|
|
11308
|
-
structure: topLevelStructure
|
|
11537
|
+
state
|
|
11309
11538
|
})) {
|
|
11310
11539
|
return {
|
|
11311
11540
|
status: "done"
|
|
@@ -11320,7 +11549,7 @@ var expectChildren = async ({
|
|
|
11320
11549
|
children,
|
|
11321
11550
|
iterator,
|
|
11322
11551
|
length: length - (currentOffset - startOffset),
|
|
11323
|
-
|
|
11552
|
+
state,
|
|
11324
11553
|
startOffset: currentOffset,
|
|
11325
11554
|
fields,
|
|
11326
11555
|
topLevelStructure
|
|
@@ -11339,13 +11568,11 @@ var expectChildren = async ({
|
|
|
11339
11568
|
var continueAfterMatroskaResult = (result, structure) => {
|
|
11340
11569
|
if (result.status === "done") {
|
|
11341
11570
|
return {
|
|
11342
|
-
status: "done"
|
|
11343
|
-
segments: structure
|
|
11571
|
+
status: "done"
|
|
11344
11572
|
};
|
|
11345
11573
|
}
|
|
11346
11574
|
return {
|
|
11347
11575
|
status: "incomplete",
|
|
11348
|
-
segments: structure,
|
|
11349
11576
|
continueParsing: async () => {
|
|
11350
11577
|
const newResult = await result.continueParsing();
|
|
11351
11578
|
return continueAfterMatroskaResult(newResult, structure);
|
|
@@ -11355,15 +11582,18 @@ var continueAfterMatroskaResult = (result, structure) => {
|
|
|
11355
11582
|
};
|
|
11356
11583
|
var parseWebm = async ({
|
|
11357
11584
|
counter,
|
|
11358
|
-
|
|
11585
|
+
state,
|
|
11359
11586
|
fields
|
|
11360
11587
|
}) => {
|
|
11361
|
-
const structure =
|
|
11588
|
+
const structure = state.structure.getStructure();
|
|
11589
|
+
if (structure.type !== "matroska") {
|
|
11590
|
+
throw new Error("Invalid structure type");
|
|
11591
|
+
}
|
|
11362
11592
|
const results = await expectChildren({
|
|
11363
11593
|
iterator: counter,
|
|
11364
11594
|
length: Infinity,
|
|
11365
11595
|
children: structure.boxes,
|
|
11366
|
-
|
|
11596
|
+
state,
|
|
11367
11597
|
startOffset: counter.counter.getOffset(),
|
|
11368
11598
|
fields,
|
|
11369
11599
|
topLevelStructure: structure
|
|
@@ -11374,7 +11604,7 @@ var parseWebm = async ({
|
|
|
11374
11604
|
// src/parse-video.ts
|
|
11375
11605
|
var parseVideo = ({
|
|
11376
11606
|
iterator,
|
|
11377
|
-
|
|
11607
|
+
state,
|
|
11378
11608
|
signal,
|
|
11379
11609
|
logLevel,
|
|
11380
11610
|
fields,
|
|
@@ -11388,16 +11618,25 @@ var parseVideo = ({
|
|
|
11388
11618
|
const fileType = iterator.detectFileType();
|
|
11389
11619
|
if (fileType.type === "riff") {
|
|
11390
11620
|
Log.verbose(logLevel, "Detected RIFF container");
|
|
11391
|
-
|
|
11621
|
+
state.structure.setStructure({
|
|
11622
|
+
type: "riff",
|
|
11623
|
+
boxes: []
|
|
11624
|
+
});
|
|
11625
|
+
return Promise.resolve(parseRiff({ iterator, state, fields }));
|
|
11392
11626
|
}
|
|
11393
11627
|
if (fileType.type === "iso-base-media") {
|
|
11394
11628
|
Log.verbose(logLevel, "Detected ISO Base Media container");
|
|
11629
|
+
const initialBoxes = [];
|
|
11630
|
+
state.structure.setStructure({
|
|
11631
|
+
type: "iso-base-media",
|
|
11632
|
+
boxes: initialBoxes
|
|
11633
|
+
});
|
|
11395
11634
|
return parseIsoBaseMediaBoxes({
|
|
11396
11635
|
iterator,
|
|
11397
11636
|
maxBytes: Infinity,
|
|
11398
11637
|
allowIncompleteBoxes: true,
|
|
11399
|
-
initialBoxes
|
|
11400
|
-
|
|
11638
|
+
initialBoxes,
|
|
11639
|
+
state,
|
|
11401
11640
|
continueMdat: false,
|
|
11402
11641
|
signal,
|
|
11403
11642
|
logLevel,
|
|
@@ -11406,16 +11645,21 @@ var parseVideo = ({
|
|
|
11406
11645
|
}
|
|
11407
11646
|
if (fileType.type === "webm") {
|
|
11408
11647
|
Log.verbose(logLevel, "Detected Matroska container");
|
|
11409
|
-
|
|
11648
|
+
state.structure.setStructure({
|
|
11649
|
+
boxes: [],
|
|
11650
|
+
type: "matroska"
|
|
11651
|
+
});
|
|
11652
|
+
return parseWebm({ counter: iterator, state, fields });
|
|
11410
11653
|
}
|
|
11411
11654
|
if (fileType.type === "transport-stream") {
|
|
11655
|
+
Log.verbose(logLevel, "Detected MPEG-2 Transport Stream");
|
|
11656
|
+
state.structure.setStructure({
|
|
11657
|
+
boxes: [],
|
|
11658
|
+
type: "transport-stream"
|
|
11659
|
+
});
|
|
11412
11660
|
return parseTransportStream({
|
|
11413
11661
|
iterator,
|
|
11414
|
-
|
|
11415
|
-
structure: {
|
|
11416
|
-
type: "transport-stream",
|
|
11417
|
-
boxes: []
|
|
11418
|
-
},
|
|
11662
|
+
state,
|
|
11419
11663
|
streamBuffers: new Map,
|
|
11420
11664
|
fields,
|
|
11421
11665
|
nextPesHeaderStore: makeNextPesHeaderStore()
|
|
@@ -11485,12 +11729,86 @@ var parseVideo = ({
|
|
|
11485
11729
|
return Promise.reject(new Error("Unknown video format " + fileType));
|
|
11486
11730
|
};
|
|
11487
11731
|
|
|
11732
|
+
// src/state/emitted-fields.ts
|
|
11733
|
+
var emittedState = () => {
|
|
11734
|
+
const emittedFields = {
|
|
11735
|
+
audioCodec: false,
|
|
11736
|
+
container: false,
|
|
11737
|
+
dimensions: false,
|
|
11738
|
+
durationInSeconds: false,
|
|
11739
|
+
fps: false,
|
|
11740
|
+
internalStats: false,
|
|
11741
|
+
isHdr: false,
|
|
11742
|
+
location: false,
|
|
11743
|
+
metadata: false,
|
|
11744
|
+
mimeType: false,
|
|
11745
|
+
name: false,
|
|
11746
|
+
rotation: false,
|
|
11747
|
+
size: false,
|
|
11748
|
+
structure: false,
|
|
11749
|
+
tracks: false,
|
|
11750
|
+
videoCodec: false,
|
|
11751
|
+
unrotatedDimensions: false,
|
|
11752
|
+
slowDurationInSeconds: false,
|
|
11753
|
+
slowFps: false,
|
|
11754
|
+
slowKeyframes: false,
|
|
11755
|
+
slowNumberOfFrames: false,
|
|
11756
|
+
keyframes: false
|
|
11757
|
+
};
|
|
11758
|
+
return emittedFields;
|
|
11759
|
+
};
|
|
11760
|
+
|
|
11761
|
+
// src/state/keyframes.ts
|
|
11762
|
+
var keyframesState = () => {
|
|
11763
|
+
const keyframes = [];
|
|
11764
|
+
return {
|
|
11765
|
+
addKeyframe: (keyframe) => {
|
|
11766
|
+
keyframes.push(keyframe);
|
|
11767
|
+
},
|
|
11768
|
+
getKeyframes: () => {
|
|
11769
|
+
return keyframes;
|
|
11770
|
+
}
|
|
11771
|
+
};
|
|
11772
|
+
};
|
|
11773
|
+
|
|
11774
|
+
// src/state/riff.ts
|
|
11775
|
+
var riffSpecificState = () => {
|
|
11776
|
+
let avcProfile = null;
|
|
11777
|
+
let nextTrackIndex = 0;
|
|
11778
|
+
const profileCallbacks = [];
|
|
11779
|
+
const registerOnAvcProfileCallback = (callback) => {
|
|
11780
|
+
profileCallbacks.push(callback);
|
|
11781
|
+
};
|
|
11782
|
+
const onProfile = async (profile) => {
|
|
11783
|
+
avcProfile = profile;
|
|
11784
|
+
for (const callback of profileCallbacks) {
|
|
11785
|
+
await callback(profile);
|
|
11786
|
+
}
|
|
11787
|
+
profileCallbacks.length = 0;
|
|
11788
|
+
};
|
|
11789
|
+
return {
|
|
11790
|
+
getAvcProfile: () => {
|
|
11791
|
+
return avcProfile;
|
|
11792
|
+
},
|
|
11793
|
+
onProfile,
|
|
11794
|
+
registerOnAvcProfileCallback,
|
|
11795
|
+
getNextTrackIndex: () => {
|
|
11796
|
+
return nextTrackIndex;
|
|
11797
|
+
},
|
|
11798
|
+
incrementNextTrackIndex: () => {
|
|
11799
|
+
nextTrackIndex++;
|
|
11800
|
+
}
|
|
11801
|
+
};
|
|
11802
|
+
};
|
|
11803
|
+
|
|
11488
11804
|
// src/state/can-skip-tracks.ts
|
|
11489
11805
|
var needsTracksField = {
|
|
11490
11806
|
audioCodec: true,
|
|
11491
11807
|
container: false,
|
|
11492
11808
|
dimensions: true,
|
|
11493
11809
|
durationInSeconds: true,
|
|
11810
|
+
slowDurationInSeconds: true,
|
|
11811
|
+
slowFps: true,
|
|
11494
11812
|
fps: true,
|
|
11495
11813
|
internalStats: false,
|
|
11496
11814
|
isHdr: true,
|
|
@@ -11503,7 +11821,10 @@ var needsTracksField = {
|
|
|
11503
11821
|
videoCodec: true,
|
|
11504
11822
|
metadata: true,
|
|
11505
11823
|
location: true,
|
|
11506
|
-
mimeType: false
|
|
11824
|
+
mimeType: false,
|
|
11825
|
+
slowKeyframes: true,
|
|
11826
|
+
slowNumberOfFrames: true,
|
|
11827
|
+
keyframes: true
|
|
11507
11828
|
};
|
|
11508
11829
|
var makeCanSkipTracksState = ({
|
|
11509
11830
|
hasAudioTrackHandlers,
|
|
@@ -11546,92 +11867,28 @@ var makeTracksSectionState = (canSkipTracksState) => {
|
|
|
11546
11867
|
};
|
|
11547
11868
|
};
|
|
11548
11869
|
|
|
11549
|
-
// src/state/
|
|
11550
|
-
var
|
|
11870
|
+
// src/state/sample-callbacks.ts
|
|
11871
|
+
var sampleCallback = ({
|
|
11872
|
+
signal,
|
|
11551
11873
|
hasAudioTrackHandlers,
|
|
11552
11874
|
hasVideoTrackHandlers,
|
|
11553
|
-
|
|
11554
|
-
|
|
11555
|
-
|
|
11875
|
+
fields,
|
|
11876
|
+
keyframes,
|
|
11877
|
+
emittedFields,
|
|
11878
|
+
slowDurationAndFpsState
|
|
11556
11879
|
}) => {
|
|
11557
|
-
const trackEntries = {};
|
|
11558
|
-
const onTrackEntrySegment = (trackEntry2) => {
|
|
11559
|
-
const trackId = getTrackId(trackEntry2);
|
|
11560
|
-
if (!trackId) {
|
|
11561
|
-
throw new Error("Expected track id");
|
|
11562
|
-
}
|
|
11563
|
-
if (trackEntries[trackId]) {
|
|
11564
|
-
return;
|
|
11565
|
-
}
|
|
11566
|
-
const codec = getTrackCodec(trackEntry2);
|
|
11567
|
-
if (!codec) {
|
|
11568
|
-
throw new Error("Expected codec");
|
|
11569
|
-
}
|
|
11570
|
-
const trackTimescale = getTrackTimestampScale(trackEntry2);
|
|
11571
|
-
trackEntries[trackId] = {
|
|
11572
|
-
codec: codec.value,
|
|
11573
|
-
trackTimescale: trackTimescale?.value ?? null
|
|
11574
|
-
};
|
|
11575
|
-
};
|
|
11576
11880
|
const videoSampleCallbacks = {};
|
|
11577
11881
|
const audioSampleCallbacks = {};
|
|
11578
11882
|
const queuedAudioSamples = {};
|
|
11579
11883
|
const queuedVideoSamples = {};
|
|
11580
|
-
let timescale2 = null;
|
|
11581
|
-
let skippedBytes = 0;
|
|
11582
|
-
const getTimescale = () => {
|
|
11583
|
-
if (timescale2 === null) {
|
|
11584
|
-
return 1e6;
|
|
11585
|
-
}
|
|
11586
|
-
return timescale2;
|
|
11587
|
-
};
|
|
11588
|
-
const increaseSkippedBytes = (bytes) => {
|
|
11589
|
-
skippedBytes += bytes;
|
|
11590
|
-
};
|
|
11591
|
-
const setTimescale = (newTimescale) => {
|
|
11592
|
-
timescale2 = newTimescale;
|
|
11593
|
-
};
|
|
11594
|
-
const timestampMap = new Map;
|
|
11595
|
-
const setTimestampOffset = (byteOffset, timestamp) => {
|
|
11596
|
-
timestampMap.set(byteOffset, timestamp);
|
|
11597
|
-
};
|
|
11598
|
-
const getTimestampOffsetForByteOffset = (byteOffset) => {
|
|
11599
|
-
const entries = Array.from(timestampMap.entries());
|
|
11600
|
-
const sortedByByteOffset = entries.sort((a, b) => {
|
|
11601
|
-
return a[0] - b[0];
|
|
11602
|
-
}).reverse();
|
|
11603
|
-
for (const [offset, timestamp] of sortedByByteOffset) {
|
|
11604
|
-
if (offset >= byteOffset) {
|
|
11605
|
-
continue;
|
|
11606
|
-
}
|
|
11607
|
-
return timestamp;
|
|
11608
|
-
}
|
|
11609
|
-
return timestampMap.get(byteOffset);
|
|
11610
|
-
};
|
|
11611
|
-
const samplesForTrack = {};
|
|
11612
|
-
const profileCallbacks = [];
|
|
11613
|
-
const registerOnAvcProfileCallback = (callback) => {
|
|
11614
|
-
profileCallbacks.push(callback);
|
|
11615
|
-
};
|
|
11616
|
-
let avcProfile = null;
|
|
11617
|
-
const onProfile = async (profile) => {
|
|
11618
|
-
avcProfile = profile;
|
|
11619
|
-
for (const callback of profileCallbacks) {
|
|
11620
|
-
await callback(profile);
|
|
11621
|
-
}
|
|
11622
|
-
profileCallbacks.length = 0;
|
|
11623
|
-
};
|
|
11624
11884
|
const canSkipTracksState = makeCanSkipTracksState({
|
|
11625
11885
|
hasAudioTrackHandlers,
|
|
11626
11886
|
fields,
|
|
11627
11887
|
hasVideoTrackHandlers
|
|
11628
11888
|
});
|
|
11629
11889
|
const tracksState = makeTracksSectionState(canSkipTracksState);
|
|
11890
|
+
const samplesForTrack = {};
|
|
11630
11891
|
return {
|
|
11631
|
-
onTrackEntrySegment,
|
|
11632
|
-
onProfile,
|
|
11633
|
-
registerOnAvcProfileCallback,
|
|
11634
|
-
getTrackInfoByNumber: (id) => trackEntries[id],
|
|
11635
11892
|
registerVideoSampleCallback: async (id, callback) => {
|
|
11636
11893
|
if (callback === null) {
|
|
11637
11894
|
delete videoSampleCallbacks[id];
|
|
@@ -11643,19 +11900,6 @@ var makeParserState = ({
|
|
|
11643
11900
|
}
|
|
11644
11901
|
queuedVideoSamples[id] = [];
|
|
11645
11902
|
},
|
|
11646
|
-
setTimestampOffset,
|
|
11647
|
-
getTimestampOffsetForByteOffset,
|
|
11648
|
-
registerAudioSampleCallback: async (id, callback) => {
|
|
11649
|
-
if (callback === null) {
|
|
11650
|
-
delete audioSampleCallbacks[id];
|
|
11651
|
-
return;
|
|
11652
|
-
}
|
|
11653
|
-
audioSampleCallbacks[id] = callback;
|
|
11654
|
-
for (const queued of queuedAudioSamples[id] ?? []) {
|
|
11655
|
-
await callback(queued);
|
|
11656
|
-
}
|
|
11657
|
-
queuedAudioSamples[id] = [];
|
|
11658
|
-
},
|
|
11659
11903
|
onAudioSample: async (trackId, audioSample) => {
|
|
11660
11904
|
if (signal?.aborted) {
|
|
11661
11905
|
throw new Error("Aborted");
|
|
@@ -11669,6 +11913,9 @@ var makeParserState = ({
|
|
|
11669
11913
|
await callback(audioSample);
|
|
11670
11914
|
}
|
|
11671
11915
|
},
|
|
11916
|
+
getSamplesForTrack: (trackId) => {
|
|
11917
|
+
return samplesForTrack[trackId] ?? 0;
|
|
11918
|
+
},
|
|
11672
11919
|
onVideoSample: async (trackId, videoSample) => {
|
|
11673
11920
|
if (signal?.aborted) {
|
|
11674
11921
|
throw new Error("Aborted");
|
|
@@ -11678,29 +11925,200 @@ var makeParserState = ({
|
|
|
11678
11925
|
}
|
|
11679
11926
|
samplesForTrack[trackId]++;
|
|
11680
11927
|
const callback = videoSampleCallbacks[trackId];
|
|
11681
|
-
if (callback) {
|
|
11928
|
+
if (callback && videoSample.data.length > 0) {
|
|
11682
11929
|
await callback(videoSample);
|
|
11683
11930
|
}
|
|
11931
|
+
if (needsToIterateOverSamples({
|
|
11932
|
+
fields,
|
|
11933
|
+
emittedFields
|
|
11934
|
+
})) {
|
|
11935
|
+
if (fields.slowKeyframes && videoSample.type === "key") {
|
|
11936
|
+
keyframes.addKeyframe({
|
|
11937
|
+
trackId,
|
|
11938
|
+
decodingTimeInSeconds: videoSample.dts / videoSample.timescale,
|
|
11939
|
+
positionInBytes: videoSample.offset,
|
|
11940
|
+
presentationTimeInSeconds: videoSample.cts / videoSample.timescale,
|
|
11941
|
+
sizeInBytes: videoSample.data.length
|
|
11942
|
+
});
|
|
11943
|
+
}
|
|
11944
|
+
slowDurationAndFpsState.addSample(videoSample);
|
|
11945
|
+
}
|
|
11684
11946
|
},
|
|
11685
|
-
|
|
11686
|
-
|
|
11687
|
-
|
|
11688
|
-
|
|
11947
|
+
canSkipTracksState,
|
|
11948
|
+
registerAudioSampleCallback: async (id, callback) => {
|
|
11949
|
+
if (callback === null) {
|
|
11950
|
+
delete audioSampleCallbacks[id];
|
|
11951
|
+
return;
|
|
11952
|
+
}
|
|
11953
|
+
audioSampleCallbacks[id] = callback;
|
|
11954
|
+
for (const queued of queuedAudioSamples[id] ?? []) {
|
|
11955
|
+
await callback(queued);
|
|
11956
|
+
}
|
|
11957
|
+
queuedAudioSamples[id] = [];
|
|
11689
11958
|
},
|
|
11690
|
-
|
|
11691
|
-
|
|
11959
|
+
tracks: tracksState,
|
|
11960
|
+
audioSampleCallbacks,
|
|
11961
|
+
videoSampleCallbacks
|
|
11962
|
+
};
|
|
11963
|
+
};
|
|
11964
|
+
|
|
11965
|
+
// src/state/slow-duration-fps.ts
|
|
11966
|
+
var slowDurationAndFpsState = () => {
|
|
11967
|
+
let smallestSample;
|
|
11968
|
+
let largestSample;
|
|
11969
|
+
let samples = 0;
|
|
11970
|
+
const getSlowDurationInSeconds = () => {
|
|
11971
|
+
if (smallestSample !== undefined && largestSample !== undefined) {
|
|
11972
|
+
const startingTimestampDifference = largestSample - smallestSample;
|
|
11973
|
+
const timeBetweenSamples = startingTimestampDifference / (samples - 1);
|
|
11974
|
+
return timeBetweenSamples * samples;
|
|
11975
|
+
}
|
|
11976
|
+
throw new Error("No samples");
|
|
11977
|
+
};
|
|
11978
|
+
return {
|
|
11979
|
+
addSample: (videoSample) => {
|
|
11980
|
+
samples++;
|
|
11981
|
+
const presentationTimeInSeconds = videoSample.cts / videoSample.timescale;
|
|
11982
|
+
if (largestSample === undefined || presentationTimeInSeconds > largestSample) {
|
|
11983
|
+
largestSample = presentationTimeInSeconds;
|
|
11984
|
+
}
|
|
11985
|
+
if (smallestSample === undefined || presentationTimeInSeconds < smallestSample) {
|
|
11986
|
+
smallestSample = presentationTimeInSeconds;
|
|
11987
|
+
}
|
|
11988
|
+
},
|
|
11989
|
+
getSlowDurationInSeconds,
|
|
11990
|
+
getFps: () => {
|
|
11991
|
+
return samples / getSlowDurationInSeconds();
|
|
11992
|
+
},
|
|
11993
|
+
getSlowNumberOfFrames: () => samples
|
|
11994
|
+
};
|
|
11995
|
+
};
|
|
11996
|
+
|
|
11997
|
+
// src/state/structure.ts
|
|
11998
|
+
var structureState = () => {
|
|
11999
|
+
let structure = null;
|
|
12000
|
+
return {
|
|
12001
|
+
getStructureOrNull: () => {
|
|
12002
|
+
return structure;
|
|
12003
|
+
},
|
|
12004
|
+
getStructure: () => {
|
|
12005
|
+
if (structure === null) {
|
|
12006
|
+
throw new Error("Expected structure");
|
|
12007
|
+
}
|
|
12008
|
+
return structure;
|
|
11692
12009
|
},
|
|
12010
|
+
setStructure: (value) => {
|
|
12011
|
+
structure = value;
|
|
12012
|
+
}
|
|
12013
|
+
};
|
|
12014
|
+
};
|
|
12015
|
+
|
|
12016
|
+
// src/state/webm.ts
|
|
12017
|
+
var webmState = () => {
|
|
12018
|
+
const trackEntries = {};
|
|
12019
|
+
const onTrackEntrySegment = (trackEntry2) => {
|
|
12020
|
+
const trackId = getTrackId(trackEntry2);
|
|
12021
|
+
if (!trackId) {
|
|
12022
|
+
throw new Error("Expected track id");
|
|
12023
|
+
}
|
|
12024
|
+
if (trackEntries[trackId]) {
|
|
12025
|
+
return;
|
|
12026
|
+
}
|
|
12027
|
+
const codec = getTrackCodec(trackEntry2);
|
|
12028
|
+
if (!codec) {
|
|
12029
|
+
throw new Error("Expected codec");
|
|
12030
|
+
}
|
|
12031
|
+
const trackTimescale = getTrackTimestampScale(trackEntry2);
|
|
12032
|
+
trackEntries[trackId] = {
|
|
12033
|
+
codec: codec.value,
|
|
12034
|
+
trackTimescale: trackTimescale?.value ?? null
|
|
12035
|
+
};
|
|
12036
|
+
};
|
|
12037
|
+
const timestampMap = new Map;
|
|
12038
|
+
const getTimestampOffsetForByteOffset = (byteOffset) => {
|
|
12039
|
+
const entries = Array.from(timestampMap.entries());
|
|
12040
|
+
const sortedByByteOffset = entries.sort((a, b) => {
|
|
12041
|
+
return a[0] - b[0];
|
|
12042
|
+
}).reverse();
|
|
12043
|
+
for (const [offset, timestamp] of sortedByByteOffset) {
|
|
12044
|
+
if (offset >= byteOffset) {
|
|
12045
|
+
continue;
|
|
12046
|
+
}
|
|
12047
|
+
return timestamp;
|
|
12048
|
+
}
|
|
12049
|
+
return timestampMap.get(byteOffset);
|
|
12050
|
+
};
|
|
12051
|
+
const setTimestampOffset = (byteOffset, timestamp) => {
|
|
12052
|
+
timestampMap.set(byteOffset, timestamp);
|
|
12053
|
+
};
|
|
12054
|
+
let timescale2 = null;
|
|
12055
|
+
const setTimescale = (newTimescale) => {
|
|
12056
|
+
timescale2 = newTimescale;
|
|
12057
|
+
};
|
|
12058
|
+
const getTimescale = () => {
|
|
12059
|
+
if (timescale2 === null) {
|
|
12060
|
+
return 1e6;
|
|
12061
|
+
}
|
|
12062
|
+
return timescale2;
|
|
12063
|
+
};
|
|
12064
|
+
return {
|
|
12065
|
+
onTrackEntrySegment,
|
|
12066
|
+
getTrackInfoByNumber: (id) => trackEntries[id],
|
|
12067
|
+
setTimestampOffset,
|
|
12068
|
+
getTimestampOffsetForByteOffset,
|
|
12069
|
+
timescale: timescale2,
|
|
12070
|
+
getTimescale,
|
|
12071
|
+
setTimescale
|
|
12072
|
+
};
|
|
12073
|
+
};
|
|
12074
|
+
|
|
12075
|
+
// src/state/parser-state.ts
|
|
12076
|
+
var makeParserState = ({
|
|
12077
|
+
hasAudioTrackHandlers,
|
|
12078
|
+
hasVideoTrackHandlers,
|
|
12079
|
+
signal,
|
|
12080
|
+
getIterator,
|
|
12081
|
+
fields,
|
|
12082
|
+
nullifySamples,
|
|
12083
|
+
onAudioTrack,
|
|
12084
|
+
onVideoTrack,
|
|
12085
|
+
supportsContentRange
|
|
12086
|
+
}) => {
|
|
12087
|
+
let skippedBytes = 0;
|
|
12088
|
+
const increaseSkippedBytes = (bytes) => {
|
|
12089
|
+
skippedBytes += bytes;
|
|
12090
|
+
};
|
|
12091
|
+
const structure = structureState();
|
|
12092
|
+
const keyframes = keyframesState();
|
|
12093
|
+
const emittedFields = emittedState();
|
|
12094
|
+
const slowDurationAndFps = slowDurationAndFpsState();
|
|
12095
|
+
return {
|
|
12096
|
+
riff: riffSpecificState(),
|
|
12097
|
+
callbacks: sampleCallback({
|
|
12098
|
+
signal,
|
|
12099
|
+
hasAudioTrackHandlers,
|
|
12100
|
+
hasVideoTrackHandlers,
|
|
12101
|
+
fields,
|
|
12102
|
+
keyframes,
|
|
12103
|
+
emittedFields,
|
|
12104
|
+
slowDurationAndFpsState: slowDurationAndFps
|
|
12105
|
+
}),
|
|
11693
12106
|
getInternalStats: () => ({
|
|
11694
12107
|
skippedBytes,
|
|
11695
12108
|
finalCursorOffset: getIterator()?.counter.getOffset() ?? 0
|
|
11696
12109
|
}),
|
|
11697
12110
|
getSkipBytes: () => skippedBytes,
|
|
11698
12111
|
increaseSkippedBytes,
|
|
11699
|
-
|
|
11700
|
-
|
|
11701
|
-
|
|
11702
|
-
|
|
11703
|
-
|
|
12112
|
+
keyframes,
|
|
12113
|
+
structure,
|
|
12114
|
+
nullifySamples,
|
|
12115
|
+
onAudioTrack,
|
|
12116
|
+
onVideoTrack,
|
|
12117
|
+
supportsContentRange,
|
|
12118
|
+
webm: webmState(),
|
|
12119
|
+
emittedFields,
|
|
12120
|
+
fields,
|
|
12121
|
+
slowDurationAndFps
|
|
11704
12122
|
};
|
|
11705
12123
|
};
|
|
11706
12124
|
|
|
@@ -11723,13 +12141,6 @@ var parseMedia = async function({
|
|
|
11723
12141
|
fields: fieldsInReturnValue,
|
|
11724
12142
|
callbacks: more
|
|
11725
12143
|
});
|
|
11726
|
-
const state = makeParserState({
|
|
11727
|
-
hasAudioTrackHandlers: Boolean(onAudioTrack),
|
|
11728
|
-
hasVideoTrackHandlers: Boolean(onVideoTrack),
|
|
11729
|
-
signal,
|
|
11730
|
-
getIterator: () => iterator,
|
|
11731
|
-
fields
|
|
11732
|
-
});
|
|
11733
12144
|
const {
|
|
11734
12145
|
reader,
|
|
11735
12146
|
contentLength,
|
|
@@ -11737,41 +12148,24 @@ var parseMedia = async function({
|
|
|
11737
12148
|
contentType,
|
|
11738
12149
|
supportsContentRange: readerSupportsContentRange
|
|
11739
12150
|
} = await readerInterface.read(src, null, signal);
|
|
11740
|
-
let currentReader = reader;
|
|
11741
|
-
const emittedFields = {
|
|
11742
|
-
audioCodec: false,
|
|
11743
|
-
container: false,
|
|
11744
|
-
dimensions: false,
|
|
11745
|
-
durationInSeconds: false,
|
|
11746
|
-
fps: false,
|
|
11747
|
-
internalStats: false,
|
|
11748
|
-
isHdr: false,
|
|
11749
|
-
location: false,
|
|
11750
|
-
metadata: false,
|
|
11751
|
-
mimeType: false,
|
|
11752
|
-
name: false,
|
|
11753
|
-
rotation: false,
|
|
11754
|
-
size: false,
|
|
11755
|
-
structure: false,
|
|
11756
|
-
tracks: false,
|
|
11757
|
-
videoCodec: false,
|
|
11758
|
-
unrotatedDimensions: false
|
|
11759
|
-
};
|
|
11760
12151
|
const supportsContentRange = readerSupportsContentRange && !(typeof process !== "undefined" && typeof process.env !== "undefined" && process.env.DISABLE_CONTENT_RANGE === "true");
|
|
11761
|
-
const
|
|
11762
|
-
|
|
11763
|
-
|
|
12152
|
+
const state = makeParserState({
|
|
12153
|
+
hasAudioTrackHandlers: Boolean(onAudioTrack),
|
|
12154
|
+
hasVideoTrackHandlers: Boolean(onVideoTrack),
|
|
12155
|
+
signal,
|
|
12156
|
+
getIterator: () => iterator,
|
|
12157
|
+
fields,
|
|
11764
12158
|
onAudioTrack: onAudioTrack ?? null,
|
|
11765
12159
|
onVideoTrack: onVideoTrack ?? null,
|
|
11766
|
-
parserState: state,
|
|
11767
12160
|
nullifySamples: !(typeof process !== "undefined" && typeof process.env !== "undefined" && process.env.KEEP_SAMPLES === "true"),
|
|
11768
|
-
supportsContentRange
|
|
11769
|
-
|
|
11770
|
-
|
|
12161
|
+
supportsContentRange
|
|
12162
|
+
});
|
|
12163
|
+
let currentReader = reader;
|
|
12164
|
+
const returnValue = {};
|
|
12165
|
+
const moreFields = more;
|
|
11771
12166
|
const triggerInfoEmit = () => {
|
|
11772
12167
|
const availableInfo = getAvailableInfo({
|
|
11773
12168
|
fieldsToFetch: fields,
|
|
11774
|
-
structure: parseResult?.segments ?? null,
|
|
11775
12169
|
state
|
|
11776
12170
|
});
|
|
11777
12171
|
emitAvailableInfo({
|
|
@@ -11783,8 +12177,7 @@ var parseMedia = async function({
|
|
|
11783
12177
|
returnValue,
|
|
11784
12178
|
contentLength,
|
|
11785
12179
|
name,
|
|
11786
|
-
mimeType: contentType
|
|
11787
|
-
emittedFields
|
|
12180
|
+
mimeType: contentType
|
|
11788
12181
|
});
|
|
11789
12182
|
};
|
|
11790
12183
|
triggerInfoEmit();
|
|
@@ -11821,12 +12214,12 @@ var parseMedia = async function({
|
|
|
11821
12214
|
});
|
|
11822
12215
|
triggerInfoEmit();
|
|
11823
12216
|
if (parseResult && parseResult.status === "incomplete") {
|
|
11824
|
-
Log.
|
|
12217
|
+
Log.trace(logLevel, "Continuing parsing of file, currently at position", iterator.counter.getOffset());
|
|
11825
12218
|
parseResult = await parseResult.continueParsing();
|
|
11826
12219
|
} else {
|
|
11827
12220
|
parseResult = await parseVideo({
|
|
11828
12221
|
iterator,
|
|
11829
|
-
|
|
12222
|
+
state,
|
|
11830
12223
|
signal: signal ?? null,
|
|
11831
12224
|
logLevel,
|
|
11832
12225
|
fields,
|
|
@@ -11840,7 +12233,6 @@ var parseMedia = async function({
|
|
|
11840
12233
|
}
|
|
11841
12234
|
if (hasAllInfo({
|
|
11842
12235
|
fields,
|
|
11843
|
-
structure: parseResult.segments,
|
|
11844
12236
|
state
|
|
11845
12237
|
})) {
|
|
11846
12238
|
Log.verbose(logLevel, "Got all info, skipping to the end.");
|
|
@@ -11880,12 +12272,11 @@ var parseMedia = async function({
|
|
|
11880
12272
|
returnValue,
|
|
11881
12273
|
contentLength,
|
|
11882
12274
|
mimeType: contentType,
|
|
11883
|
-
name
|
|
11884
|
-
emittedFields
|
|
12275
|
+
name
|
|
11885
12276
|
});
|
|
11886
12277
|
currentReader.abort();
|
|
11887
12278
|
iterator?.destroy();
|
|
11888
|
-
state.tracks.ensureHasTracksAtEnd();
|
|
12279
|
+
state.callbacks.tracks.ensureHasTracksAtEnd();
|
|
11889
12280
|
return returnValue;
|
|
11890
12281
|
};
|
|
11891
12282
|
// src/index.ts
|