@remotion/media-parser 4.0.285 → 4.0.286
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/aac-codecprivate.d.ts +1 -1
- package/dist/combine-uint8-arrays.d.ts +1 -1
- package/dist/containers/aac/parse-aac.js +0 -3
- package/dist/containers/avc/create-sps-pps-data.d.ts +1 -1
- package/dist/containers/flac/get-channel-count.d.ts +1 -1
- package/dist/containers/flac/parse-flac-frame.js +0 -2
- package/dist/containers/flac/parse-streaminfo.js +0 -2
- package/dist/containers/iso-base-media/collect-sample-positions-from-trak.js +4 -3
- package/dist/containers/iso-base-media/get-moov-atom.js +0 -4
- package/dist/containers/iso-base-media/mdat/mdat.js +0 -3
- package/dist/containers/iso-base-media/mfra/get-mfra-atom.d.ts +3 -3
- package/dist/containers/iso-base-media/parse-boxes.js +0 -2
- package/dist/containers/iso-base-media/process-box.d.ts +0 -2
- package/dist/containers/iso-base-media/process-box.js +1 -3
- package/dist/containers/m3u/iterate-over-segment-files.js +1 -0
- package/dist/containers/m3u/run-over-m3u.js +0 -3
- package/dist/containers/mp3/parse-mpeg-header.js +0 -3
- package/dist/containers/riff/expect-riff-box.js +0 -2
- package/dist/containers/riff/parse-movi.js +0 -3
- package/dist/containers/transport-stream/adts-header.d.ts +1 -1
- package/dist/containers/transport-stream/discard-rest-of-packet.d.ts +1 -1
- package/dist/containers/transport-stream/find-separator.d.ts +17 -1
- package/dist/containers/transport-stream/find-separator.js +6 -5
- package/dist/containers/transport-stream/get-seeking-info.d.ts +4 -0
- package/dist/containers/transport-stream/get-seeking-info.js +17 -0
- package/dist/containers/transport-stream/handle-aac-packet.d.ts +10 -3
- package/dist/containers/transport-stream/handle-aac-packet.js +21 -16
- package/dist/containers/transport-stream/handle-avc-packet.d.ts +10 -3
- package/dist/containers/transport-stream/handle-avc-packet.js +26 -17
- package/dist/containers/transport-stream/parse-packet.d.ts +8 -4
- package/dist/containers/transport-stream/parse-packet.js +15 -16
- package/dist/containers/transport-stream/parse-pes.d.ts +5 -1
- package/dist/containers/transport-stream/parse-pes.js +4 -3
- package/dist/containers/transport-stream/parse-stream-packet.d.ts +6 -6
- package/dist/containers/transport-stream/parse-stream-packet.js +10 -115
- package/dist/containers/transport-stream/parse-transport-stream.js +15 -3
- package/dist/containers/transport-stream/process-stream-buffers.d.ts +26 -6
- package/dist/containers/transport-stream/process-stream-buffers.js +77 -12
- package/dist/containers/transport-stream/traversal.d.ts +3 -1
- package/dist/containers/transport-stream/traversal.js +10 -2
- package/dist/containers/wav/parse-fmt.js +0 -2
- package/dist/containers/wav/parse-media-section.js +0 -2
- package/dist/containers/webm/cues/fetch-web-cues.d.ts +12 -0
- package/dist/containers/webm/cues/fetch-web-cues.js +32 -0
- package/dist/containers/webm/cues/format-cues.d.ts +8 -0
- package/dist/containers/webm/cues/format-cues.js +41 -0
- package/dist/containers/webm/cues/get-seeking-byte.d.ts +14 -0
- package/dist/containers/webm/cues/get-seeking-byte.js +91 -0
- package/dist/containers/webm/fetch-web-cues.d.ts +12 -0
- package/dist/containers/webm/fetch-web-cues.js +29 -0
- package/dist/containers/webm/get-byte-for-cues.d.ts +5 -0
- package/dist/containers/webm/get-byte-for-cues.js +33 -0
- package/dist/containers/webm/get-ready-tracks.d.ts +9 -4
- package/dist/containers/webm/get-ready-tracks.js +6 -6
- package/dist/containers/webm/get-sample-from-block.d.ts +3 -2
- package/dist/containers/webm/get-sample-from-block.js +9 -8
- package/dist/containers/webm/get-seeking-byte.d.ts +14 -0
- package/dist/containers/webm/get-seeking-byte.js +91 -0
- package/dist/containers/webm/get-seeking-info.d.ts +3 -0
- package/dist/containers/webm/get-seeking-info.js +17 -0
- package/dist/containers/webm/parse-ebml.d.ts +5 -4
- package/dist/containers/webm/parse-ebml.js +29 -34
- package/dist/containers/webm/parse-webm-header.js +14 -2
- package/dist/containers/webm/seek/fetch-web-cues.d.ts +12 -0
- package/dist/containers/webm/seek/fetch-web-cues.js +32 -0
- package/dist/containers/webm/seek/format-cues.d.ts +8 -0
- package/dist/containers/webm/seek/format-cues.js +42 -0
- package/dist/containers/webm/seek/get-seeking-byte.d.ts +14 -0
- package/dist/containers/webm/seek/get-seeking-byte.js +100 -0
- package/dist/containers/webm/seek/get-seeking-info.d.ts +3 -0
- package/dist/containers/webm/seek/get-seeking-info.js +17 -0
- package/dist/containers/webm/segments/all-segments.d.ts +1 -0
- package/dist/containers/webm/segments.d.ts +10 -4
- package/dist/containers/webm/segments.js +30 -12
- package/dist/containers/webm/state-for-processing.d.ts +15 -0
- package/dist/containers/webm/state-for-processing.js +14 -0
- package/dist/controller/seek-signal.d.ts +2 -2
- package/dist/download-and-parse-media.js +2 -1
- package/dist/emit-audio-sample.d.ts +2 -5
- package/dist/emit-audio-sample.js +2 -5
- package/dist/esm/index.mjs +5057 -4394
- package/dist/esm/universal.mjs +1 -1
- package/dist/esm/web.mjs +1 -1
- package/dist/esm/worker-server-entry.mjs +2327 -1664
- package/dist/esm/worker-web-entry.mjs +2327 -1664
- package/dist/file-types/detect-file-type.js +3 -1
- package/dist/get-audio-codec.d.ts +2 -1
- package/dist/get-audio-codec.js +15 -1
- package/dist/get-sample-positions-from-mp4.d.ts +3 -0
- package/dist/get-sample-positions-from-mp4.js +46 -0
- package/dist/get-seeking-byte.d.ts +19 -0
- package/dist/get-seeking-byte.js +50 -0
- package/dist/get-seeking-info.d.ts +5 -10
- package/dist/get-seeking-info.js +12 -25
- package/dist/get-tracks.js +6 -2
- package/dist/index.d.ts +44 -19
- package/dist/init-video.js +4 -3
- package/dist/internal-parse-media.js +3 -2
- package/dist/iterator/buffer-iterator.d.ts +3 -3
- package/dist/iterator/buffer-manager.d.ts +3 -3
- package/dist/log.d.ts +5 -5
- package/dist/options.d.ts +1 -0
- package/dist/parse-loop.js +0 -3
- package/dist/parse-media-on-worker-entry.d.ts +1 -1
- package/dist/parse-media.js +2 -1
- package/dist/readers/from-web-file.js +1 -1
- package/dist/register-track.d.ts +2 -5
- package/dist/register-track.js +2 -10
- package/dist/seek-backwards.js +2 -3
- package/dist/seeking-info.d.ts +14 -1
- package/dist/state/iso-base-media/cached-sample-positions.d.ts +1 -1
- package/dist/state/keyframes.js +3 -0
- package/dist/state/matroska/lazy-cues-fetch.d.ts +19 -0
- package/dist/state/matroska/lazy-cues-fetch.js +51 -0
- package/dist/state/matroska/lazy-seek-fetch.d.ts +1 -0
- package/dist/state/matroska/lazy-seek-fetch.js +5 -0
- package/dist/state/matroska/webm.d.ts +46 -0
- package/dist/state/matroska/webm.js +121 -0
- package/dist/state/matroska.d.ts +0 -0
- package/dist/state/matroska.js +1 -0
- package/dist/state/parser-state.d.ts +34 -9
- package/dist/state/parser-state.js +7 -6
- package/dist/state/sample-callbacks.d.ts +1 -1
- package/dist/state/sample-callbacks.js +9 -9
- package/dist/state/samples-observed/slow-duration-fps.d.ts +11 -0
- package/dist/state/samples-observed/slow-duration-fps.js +92 -0
- package/dist/state/seek-infinite-loop.js +12 -2
- package/dist/state/transport-stream/observed-pes-header.d.ts +13 -0
- package/dist/state/transport-stream/observed-pes-header.js +29 -0
- package/dist/state/transport-stream/pts-start-offset.d.ts +5 -0
- package/dist/state/transport-stream/pts-start-offset.js +13 -0
- package/dist/state/transport-stream/start-offset.d.ts +2 -1
- package/dist/state/transport-stream/start-offset.js +3 -3
- package/dist/state/transport-stream/transport-stream.d.ts +6 -0
- package/dist/state/transport-stream/transport-stream.js +4 -2
- package/dist/state/video-section.js +14 -2
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/work-on-seek-request.d.ts +8 -0
- package/dist/work-on-seek-request.js +24 -6
- package/dist/worker-server.js +1 -0
- package/dist/worker.d.ts +0 -1
- package/package.json +4 -4
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.formatCues = void 0;
|
|
4
|
+
const formatCues = (cues) => {
|
|
5
|
+
const matroskaCues = [];
|
|
6
|
+
for (const cue of cues) {
|
|
7
|
+
if (cue.type !== 'CuePoint') {
|
|
8
|
+
throw new Error('Expected CuePoint');
|
|
9
|
+
}
|
|
10
|
+
const cueTime = cue.value.find((cue) => cue.type === 'CueTime');
|
|
11
|
+
if (!cueTime) {
|
|
12
|
+
throw new Error('Expected CueTime');
|
|
13
|
+
}
|
|
14
|
+
const cueTrackPositions = cue.value.find((c) => c.type === 'CueTrackPositions');
|
|
15
|
+
if (!cueTrackPositions) {
|
|
16
|
+
throw new Error('Expected CueTrackPositions');
|
|
17
|
+
}
|
|
18
|
+
const cueTimeValue = cueTime.value.value;
|
|
19
|
+
const cueTrack = cueTrackPositions.value.find((_c) => _c.type === 'CueTrack');
|
|
20
|
+
if (!cueTrack) {
|
|
21
|
+
throw new Error('Expected CueTrack');
|
|
22
|
+
}
|
|
23
|
+
const cueClusterPosition = cueTrackPositions.value.find((_c) => _c.type === 'CueClusterPosition');
|
|
24
|
+
if (!cueClusterPosition) {
|
|
25
|
+
throw new Error('Expected CueClusterPosition');
|
|
26
|
+
}
|
|
27
|
+
const cueRelativePosition = cueTrackPositions.value.find((_c) => _c.type === 'CueRelativePosition');
|
|
28
|
+
if (!cueRelativePosition) {
|
|
29
|
+
throw new Error('Expected CueRelativePosition');
|
|
30
|
+
}
|
|
31
|
+
const matroskaCue = {
|
|
32
|
+
trackId: cueTrack.value.value,
|
|
33
|
+
timeInTimescale: cueTimeValue,
|
|
34
|
+
clusterPositionInSegment: cueClusterPosition.value.value,
|
|
35
|
+
relativePosition: cueRelativePosition.value.value,
|
|
36
|
+
};
|
|
37
|
+
matroskaCues.push(matroskaCue);
|
|
38
|
+
}
|
|
39
|
+
return matroskaCues;
|
|
40
|
+
};
|
|
41
|
+
exports.formatCues = formatCues;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { LogLevel } from '../../../log';
|
|
2
|
+
import type { WebmSeekingInfo } from '../../../seeking-info';
|
|
3
|
+
import type { KeyframesState } from '../../../state/keyframes';
|
|
4
|
+
import type { WebmState } from '../../../state/matroska/webm';
|
|
5
|
+
import type { MediaSectionState } from '../../../state/video-section';
|
|
6
|
+
import type { SeekResolution } from '../../../work-on-seek-request';
|
|
7
|
+
export declare const getSeekingByteFromMatroska: ({ time, webmState, info, logLevel, mediaSection, keyframes, }: {
|
|
8
|
+
time: number;
|
|
9
|
+
webmState: WebmState;
|
|
10
|
+
info: WebmSeekingInfo;
|
|
11
|
+
logLevel: LogLevel;
|
|
12
|
+
mediaSection: MediaSectionState;
|
|
13
|
+
keyframes: KeyframesState;
|
|
14
|
+
}) => Promise<SeekResolution>;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getSeekingByteFromMatroska = void 0;
|
|
4
|
+
const log_1 = require("../../../log");
|
|
5
|
+
const toSeconds = (timeInTimescale, track) => {
|
|
6
|
+
return (timeInTimescale / track.timescale) * 1000;
|
|
7
|
+
};
|
|
8
|
+
const findBiggestCueBeforeTime = ({ cues, time, track, }) => {
|
|
9
|
+
let biggestCueBeforeTime;
|
|
10
|
+
for (const cue of cues) {
|
|
11
|
+
const cueTimeInSeconds = toSeconds(cue.timeInTimescale, track);
|
|
12
|
+
if (cueTimeInSeconds < time &&
|
|
13
|
+
(!biggestCueBeforeTime ||
|
|
14
|
+
cueTimeInSeconds >
|
|
15
|
+
toSeconds(biggestCueBeforeTime.timeInTimescale, track))) {
|
|
16
|
+
biggestCueBeforeTime = cue;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return biggestCueBeforeTime;
|
|
20
|
+
};
|
|
21
|
+
const getStartOfClusterToSeekTo = ({ biggestCueBeforeTime, webmState, segmentOffset, }) => {
|
|
22
|
+
if (biggestCueBeforeTime) {
|
|
23
|
+
return biggestCueBeforeTime.clusterPositionInSegment + segmentOffset;
|
|
24
|
+
}
|
|
25
|
+
const hasMediaSectionWithIndex = webmState.getFirstCluster();
|
|
26
|
+
if (hasMediaSectionWithIndex) {
|
|
27
|
+
return hasMediaSectionWithIndex.start;
|
|
28
|
+
}
|
|
29
|
+
return null;
|
|
30
|
+
};
|
|
31
|
+
const findKeyframeBeforeTime = ({ keyframes, time, }) => {
|
|
32
|
+
let keyframeBeforeTime;
|
|
33
|
+
for (const keyframe of keyframes) {
|
|
34
|
+
if (keyframe.decodingTimeInSeconds < time &&
|
|
35
|
+
(!keyframeBeforeTime ||
|
|
36
|
+
keyframe.decodingTimeInSeconds >
|
|
37
|
+
keyframeBeforeTime.decodingTimeInSeconds)) {
|
|
38
|
+
keyframeBeforeTime = keyframe;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return keyframeBeforeTime;
|
|
42
|
+
};
|
|
43
|
+
const getSeekingByteFromMatroska = async ({ time, webmState, info, logLevel, mediaSection, keyframes, }) => {
|
|
44
|
+
if (!info.track) {
|
|
45
|
+
log_1.Log.trace(logLevel, 'No video track found, cannot seek yet');
|
|
46
|
+
return {
|
|
47
|
+
type: 'valid-but-must-wait',
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
const cuesResponse = await webmState.cues.getLoadedCues();
|
|
51
|
+
if (!cuesResponse) {
|
|
52
|
+
log_1.Log.trace(logLevel, 'Has no Matroska Cues at the moment, continuing...');
|
|
53
|
+
return {
|
|
54
|
+
type: 'valid-but-must-wait',
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
const { cues, segmentOffset } = cuesResponse;
|
|
58
|
+
log_1.Log.trace(logLevel, 'Has Matroska cues. Will use them to perform a seek.');
|
|
59
|
+
const biggestCueBeforeTime = findBiggestCueBeforeTime({
|
|
60
|
+
cues,
|
|
61
|
+
time,
|
|
62
|
+
track: info.track,
|
|
63
|
+
});
|
|
64
|
+
const keyframeBeforeTime = findKeyframeBeforeTime({
|
|
65
|
+
keyframes: keyframes.getKeyframes(),
|
|
66
|
+
time,
|
|
67
|
+
});
|
|
68
|
+
const startOfClusterToSeekTo = getStartOfClusterToSeekTo({
|
|
69
|
+
biggestCueBeforeTime,
|
|
70
|
+
webmState,
|
|
71
|
+
segmentOffset,
|
|
72
|
+
});
|
|
73
|
+
if (!startOfClusterToSeekTo) {
|
|
74
|
+
// dont know what to do
|
|
75
|
+
return {
|
|
76
|
+
type: 'invalid',
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
// we have assured this is in a media section, but it might not be marked yet
|
|
80
|
+
// setting size because there is deduplication and media sections which are encompassed
|
|
81
|
+
// by others will get deleted
|
|
82
|
+
mediaSection.addMediaSection({
|
|
83
|
+
start: startOfClusterToSeekTo,
|
|
84
|
+
size: 1,
|
|
85
|
+
});
|
|
86
|
+
return {
|
|
87
|
+
type: 'do-seek',
|
|
88
|
+
byte: startOfClusterToSeekTo,
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
exports.getSeekingByteFromMatroska = getSeekingByteFromMatroska;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { MediaParserController } from '../../controller/media-parser-controller';
|
|
2
|
+
import type { LogLevel } from '../../log';
|
|
3
|
+
import type { ParseMediaSrc } from '../../options';
|
|
4
|
+
import type { ReaderInterface } from '../../readers/reader';
|
|
5
|
+
import type { PossibleEbml } from './segments/all-segments';
|
|
6
|
+
export declare const fetchWebmCues: ({ src, readerInterface, controller, position, logLevel, }: {
|
|
7
|
+
src: ParseMediaSrc;
|
|
8
|
+
readerInterface: ReaderInterface;
|
|
9
|
+
controller: MediaParserController;
|
|
10
|
+
position: number;
|
|
11
|
+
logLevel: LogLevel;
|
|
12
|
+
}) => Promise<PossibleEbml[] | null>;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fetchWebmCues = void 0;
|
|
4
|
+
const buffer_iterator_1 = require("../../iterator/buffer-iterator");
|
|
5
|
+
const segments_1 = require("./segments");
|
|
6
|
+
const fetchWebmCues = async ({ src, readerInterface, controller, position, logLevel, }) => {
|
|
7
|
+
var _a;
|
|
8
|
+
const result = await readerInterface.read({
|
|
9
|
+
controller,
|
|
10
|
+
range: position,
|
|
11
|
+
src,
|
|
12
|
+
});
|
|
13
|
+
const { value } = await result.reader.reader.read();
|
|
14
|
+
if (!value) {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
result.reader.abort();
|
|
18
|
+
const iterator = (0, buffer_iterator_1.getArrayBufferIterator)(value, value.length);
|
|
19
|
+
const segment = await (0, segments_1.expectSegment)({
|
|
20
|
+
iterator,
|
|
21
|
+
logLevel,
|
|
22
|
+
statesForProcessing: null,
|
|
23
|
+
isInsideSegment: null,
|
|
24
|
+
mediaSectionState: null,
|
|
25
|
+
});
|
|
26
|
+
iterator.destroy();
|
|
27
|
+
return ((_a = segment === null || segment === void 0 ? void 0 : segment.value) !== null && _a !== void 0 ? _a : null);
|
|
28
|
+
};
|
|
29
|
+
exports.fetchWebmCues = fetchWebmCues;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getByteForSeek = void 0;
|
|
4
|
+
const truthy_1 = require("../../truthy");
|
|
5
|
+
const all_segments_1 = require("./segments/all-segments");
|
|
6
|
+
const getByteForSeek = ({ seekHeadSegment, offset, }) => {
|
|
7
|
+
const value = seekHeadSegment.value
|
|
8
|
+
.map((v) => {
|
|
9
|
+
if (v.type !== 'Seek') {
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
const seekId = v.value.find((_v) => {
|
|
13
|
+
// cues
|
|
14
|
+
return _v.type === 'SeekID' && _v.value === all_segments_1.matroskaElements.Cues;
|
|
15
|
+
});
|
|
16
|
+
if (!seekId) {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
const seekPosition = v.value.find((_v) => {
|
|
20
|
+
return _v.type === 'SeekPosition';
|
|
21
|
+
});
|
|
22
|
+
if (!seekPosition) {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
return seekPosition.value;
|
|
26
|
+
})
|
|
27
|
+
.filter(truthy_1.truthy);
|
|
28
|
+
if (value.length === 0) {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
return value[0].value + offset;
|
|
32
|
+
};
|
|
33
|
+
exports.getByteForSeek = getByteForSeek;
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import type { Track } from '../../get-tracks';
|
|
2
|
-
import type {
|
|
2
|
+
import type { WebmState } from '../../state/matroska/webm';
|
|
3
|
+
import type { StructureState } from '../../state/structure';
|
|
3
4
|
export type ResolvedAndUnresolvedTracks = {
|
|
4
5
|
resolved: Track[];
|
|
5
6
|
missingInfo: Track[];
|
|
6
7
|
};
|
|
7
|
-
export declare const getTracksFromMatroska: ({
|
|
8
|
-
|
|
8
|
+
export declare const getTracksFromMatroska: ({ structureState, webmState, }: {
|
|
9
|
+
structureState: StructureState;
|
|
10
|
+
webmState: WebmState;
|
|
9
11
|
}) => ResolvedAndUnresolvedTracks;
|
|
10
|
-
export declare const matroskaHasTracks: (
|
|
12
|
+
export declare const matroskaHasTracks: ({ structureState, webmState, }: {
|
|
13
|
+
structureState: StructureState;
|
|
14
|
+
webmState: WebmState;
|
|
15
|
+
}) => boolean;
|
|
@@ -4,9 +4,8 @@ exports.matroskaHasTracks = exports.getTracksFromMatroska = void 0;
|
|
|
4
4
|
const codec_string_1 = require("../avc/codec-string");
|
|
5
5
|
const make_track_1 = require("./make-track");
|
|
6
6
|
const traversal_1 = require("./traversal");
|
|
7
|
-
const getTracksFromMatroska = ({
|
|
8
|
-
const
|
|
9
|
-
const structure = state.structure.getMatroskaStructure();
|
|
7
|
+
const getTracksFromMatroska = ({ structureState, webmState, }) => {
|
|
8
|
+
const structure = structureState.getMatroskaStructure();
|
|
10
9
|
const mainSegment = (0, traversal_1.getMainSegment)(structure.boxes);
|
|
11
10
|
if (!mainSegment) {
|
|
12
11
|
throw new Error('No main segment');
|
|
@@ -50,15 +49,16 @@ const getTracksFromMatroska = ({ state, }) => {
|
|
|
50
49
|
return { missingInfo, resolved: resolvedTracks };
|
|
51
50
|
};
|
|
52
51
|
exports.getTracksFromMatroska = getTracksFromMatroska;
|
|
53
|
-
const matroskaHasTracks = (
|
|
54
|
-
const structure =
|
|
52
|
+
const matroskaHasTracks = ({ structureState, webmState, }) => {
|
|
53
|
+
const structure = structureState.getMatroskaStructure();
|
|
55
54
|
const mainSegment = (0, traversal_1.getMainSegment)(structure.boxes);
|
|
56
55
|
if (!mainSegment) {
|
|
57
56
|
return false;
|
|
58
57
|
}
|
|
59
58
|
return ((0, traversal_1.getTracksSegment)(mainSegment) !== null &&
|
|
60
59
|
(0, exports.getTracksFromMatroska)({
|
|
61
|
-
|
|
60
|
+
structureState,
|
|
61
|
+
webmState,
|
|
62
62
|
}).missingInfo.length === 0);
|
|
63
63
|
};
|
|
64
64
|
exports.matroskaHasTracks = matroskaHasTracks;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { WebmState } from '../../state/matroska/webm';
|
|
2
|
+
import type { StructureState } from '../../state/structure';
|
|
2
3
|
import type { AudioOrVideoSample } from '../../webcodec-sample-types';
|
|
3
4
|
import type { BlockSegment, SimpleBlockSegment } from './segments/all-segments';
|
|
4
5
|
type SampleResult = {
|
|
@@ -13,5 +14,5 @@ type SampleResult = {
|
|
|
13
14
|
} | {
|
|
14
15
|
type: 'no-sample';
|
|
15
16
|
};
|
|
16
|
-
export declare const getSampleFromBlock: (ebml: BlockSegment | SimpleBlockSegment,
|
|
17
|
+
export declare const getSampleFromBlock: (ebml: BlockSegment | SimpleBlockSegment, webmState: WebmState, offset: number, structureState: StructureState) => SampleResult;
|
|
17
18
|
export {};
|
|
@@ -6,18 +6,18 @@ const parse_avc_1 = require("../avc/parse-avc");
|
|
|
6
6
|
const get_ready_tracks_1 = require("./get-ready-tracks");
|
|
7
7
|
const all_segments_1 = require("./segments/all-segments");
|
|
8
8
|
const block_simple_block_flags_1 = require("./segments/block-simple-block-flags");
|
|
9
|
-
const addAvcToTrackIfNecessary = ({ partialVideoSample, codec,
|
|
9
|
+
const addAvcToTrackIfNecessary = ({ partialVideoSample, codec, structureState, webmState, trackNumber, }) => {
|
|
10
10
|
if (codec === 'V_MPEG4/ISO/AVC' &&
|
|
11
|
-
(0, get_ready_tracks_1.getTracksFromMatroska)({
|
|
11
|
+
(0, get_ready_tracks_1.getTracksFromMatroska)({ structureState, webmState }).missingInfo.length > 0) {
|
|
12
12
|
const parsed = (0, parse_avc_1.parseAvc)(partialVideoSample.data);
|
|
13
13
|
for (const parse of parsed) {
|
|
14
14
|
if (parse.type === 'avc-profile') {
|
|
15
|
-
|
|
15
|
+
webmState.setAvcProfileForTrackNumber(trackNumber, parse);
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
};
|
|
20
|
-
const getSampleFromBlock = (ebml,
|
|
20
|
+
const getSampleFromBlock = (ebml, webmState, offset, structureState) => {
|
|
21
21
|
const iterator = (0, buffer_iterator_1.getArrayBufferIterator)(ebml.value, ebml.value.length);
|
|
22
22
|
const trackNumber = iterator.getVint();
|
|
23
23
|
if (trackNumber === null) {
|
|
@@ -27,9 +27,9 @@ const getSampleFromBlock = (ebml, state, offset) => {
|
|
|
27
27
|
const { keyframe } = (0, block_simple_block_flags_1.parseBlockFlags)(iterator, ebml.type === 'SimpleBlock'
|
|
28
28
|
? all_segments_1.matroskaElements.SimpleBlock
|
|
29
29
|
: all_segments_1.matroskaElements.Block);
|
|
30
|
-
const { codec, trackTimescale } =
|
|
31
|
-
const clusterOffset =
|
|
32
|
-
const timescale =
|
|
30
|
+
const { codec, trackTimescale } = webmState.getTrackInfoByNumber(trackNumber);
|
|
31
|
+
const clusterOffset = webmState.getTimestampOffsetForByteOffset(offset);
|
|
32
|
+
const timescale = webmState.getTimescale();
|
|
33
33
|
if (clusterOffset === undefined) {
|
|
34
34
|
throw new Error('Could not find offset for byte offset ' + offset);
|
|
35
35
|
}
|
|
@@ -65,7 +65,8 @@ const getSampleFromBlock = (ebml, state, offset) => {
|
|
|
65
65
|
addAvcToTrackIfNecessary({
|
|
66
66
|
codec,
|
|
67
67
|
partialVideoSample,
|
|
68
|
-
|
|
68
|
+
structureState,
|
|
69
|
+
webmState,
|
|
69
70
|
trackNumber,
|
|
70
71
|
});
|
|
71
72
|
const sample = {
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { LogLevel } from '../../log';
|
|
2
|
+
import type { WebmSeekingInfo } from '../../seeking-info';
|
|
3
|
+
import type { KeyframesState } from '../../state/keyframes';
|
|
4
|
+
import type { WebmState } from '../../state/matroska/webm';
|
|
5
|
+
import type { MediaSectionState } from '../../state/video-section';
|
|
6
|
+
import type { SeekResolution } from '../../work-on-seek-request';
|
|
7
|
+
export declare const getSeekingByteFromMatroska: ({ time, webmState, info, logLevel, mediaSection, keyframes, }: {
|
|
8
|
+
time: number;
|
|
9
|
+
webmState: WebmState;
|
|
10
|
+
info: WebmSeekingInfo;
|
|
11
|
+
logLevel: LogLevel;
|
|
12
|
+
mediaSection: MediaSectionState;
|
|
13
|
+
keyframes: KeyframesState;
|
|
14
|
+
}) => Promise<SeekResolution>;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getSeekingByteFromMatroska = void 0;
|
|
4
|
+
const log_1 = require("../../log");
|
|
5
|
+
const toSeconds = (timeInTimescale, track) => {
|
|
6
|
+
return (timeInTimescale / track.timescale) * 1000;
|
|
7
|
+
};
|
|
8
|
+
const findBiggestCueBeforeTime = ({ cues, time, track, }) => {
|
|
9
|
+
let biggestCueBeforeTime;
|
|
10
|
+
for (const cue of cues) {
|
|
11
|
+
const cueTimeInSeconds = toSeconds(cue.timeInTimescale, track);
|
|
12
|
+
if (cueTimeInSeconds < time &&
|
|
13
|
+
(!biggestCueBeforeTime ||
|
|
14
|
+
cueTimeInSeconds >
|
|
15
|
+
toSeconds(biggestCueBeforeTime.timeInTimescale, track))) {
|
|
16
|
+
biggestCueBeforeTime = cue;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return biggestCueBeforeTime;
|
|
20
|
+
};
|
|
21
|
+
const getStartOfClusterToSeekTo = ({ biggestCueBeforeTime, webmState, segmentOffset, }) => {
|
|
22
|
+
if (biggestCueBeforeTime) {
|
|
23
|
+
return biggestCueBeforeTime.clusterPositionInSegment + segmentOffset;
|
|
24
|
+
}
|
|
25
|
+
const hasMediaSectionWithIndex = webmState.getFirstCluster();
|
|
26
|
+
if (hasMediaSectionWithIndex) {
|
|
27
|
+
return hasMediaSectionWithIndex.start;
|
|
28
|
+
}
|
|
29
|
+
return null;
|
|
30
|
+
};
|
|
31
|
+
const findKeyframeBeforeTime = ({ keyframes, time, }) => {
|
|
32
|
+
let keyframeBeforeTime;
|
|
33
|
+
for (const keyframe of keyframes) {
|
|
34
|
+
if (keyframe.decodingTimeInSeconds < time &&
|
|
35
|
+
(!keyframeBeforeTime ||
|
|
36
|
+
keyframe.decodingTimeInSeconds >
|
|
37
|
+
keyframeBeforeTime.decodingTimeInSeconds)) {
|
|
38
|
+
keyframeBeforeTime = keyframe;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return keyframeBeforeTime;
|
|
42
|
+
};
|
|
43
|
+
const getSeekingByteFromMatroska = async ({ time, webmState, info, logLevel, mediaSection, keyframes, }) => {
|
|
44
|
+
if (!info.track) {
|
|
45
|
+
log_1.Log.trace(logLevel, 'No video track found, cannot seek yet');
|
|
46
|
+
return {
|
|
47
|
+
type: 'valid-but-must-wait',
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
const cuesResponse = await webmState.cues.getLoadedCues();
|
|
51
|
+
if (!cuesResponse) {
|
|
52
|
+
log_1.Log.trace(logLevel, 'Has no Matroska Cues at the moment, continuing...');
|
|
53
|
+
return {
|
|
54
|
+
type: 'valid-but-must-wait',
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
const { cues, segmentOffset } = cuesResponse;
|
|
58
|
+
log_1.Log.trace(logLevel, 'Has Matroska cues. Will use them to perform a seek.');
|
|
59
|
+
const biggestCueBeforeTime = findBiggestCueBeforeTime({
|
|
60
|
+
cues,
|
|
61
|
+
time,
|
|
62
|
+
track: info.track,
|
|
63
|
+
});
|
|
64
|
+
const keyframeBeforeTime = findKeyframeBeforeTime({
|
|
65
|
+
keyframes: keyframes.getKeyframes(),
|
|
66
|
+
time,
|
|
67
|
+
});
|
|
68
|
+
const startOfClusterToSeekTo = getStartOfClusterToSeekTo({
|
|
69
|
+
biggestCueBeforeTime,
|
|
70
|
+
webmState,
|
|
71
|
+
segmentOffset,
|
|
72
|
+
});
|
|
73
|
+
if (!startOfClusterToSeekTo) {
|
|
74
|
+
// dont know what to do
|
|
75
|
+
return {
|
|
76
|
+
type: 'invalid',
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
// we have assured this is in a media section, but it might not be marked yet
|
|
80
|
+
// setting size because there is deduplication and media sections which are encompassed
|
|
81
|
+
// by others will get deleted
|
|
82
|
+
mediaSection.addMediaSection({
|
|
83
|
+
start: startOfClusterToSeekTo,
|
|
84
|
+
size: 1,
|
|
85
|
+
});
|
|
86
|
+
return {
|
|
87
|
+
type: 'do-seek',
|
|
88
|
+
byte: startOfClusterToSeekTo,
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
exports.getSeekingByteFromMatroska = getSeekingByteFromMatroska;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getSeekingInfoFromMatroska = void 0;
|
|
4
|
+
const getSeekingInfoFromMatroska = (tracksState) => {
|
|
5
|
+
const tracks = tracksState.getTracks();
|
|
6
|
+
const firstVideoTrack = tracks.find((track) => track.type === 'video');
|
|
7
|
+
return {
|
|
8
|
+
type: 'webm-seeking-info',
|
|
9
|
+
track: firstVideoTrack
|
|
10
|
+
? {
|
|
11
|
+
timescale: firstVideoTrack.timescale,
|
|
12
|
+
trackId: firstVideoTrack.trackId,
|
|
13
|
+
}
|
|
14
|
+
: null,
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
exports.getSeekingInfoFromMatroska = getSeekingInfoFromMatroska;
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { BufferIterator } from '../../iterator/buffer-iterator';
|
|
2
2
|
import type { PossibleEbml } from './segments/all-segments';
|
|
3
|
+
import type { WebmRequiredStatesForProcessing } from './state-for-processing';
|
|
3
4
|
export type Prettify<T> = {
|
|
4
5
|
[K in keyof T]: T[K];
|
|
5
6
|
} & {};
|
|
6
|
-
export declare const parseEbml: (
|
|
7
|
-
export declare const postprocessEbml: ({ offset, ebml,
|
|
7
|
+
export declare const parseEbml: (iterator: BufferIterator, statesForProcessing: WebmRequiredStatesForProcessing | null) => Promise<Prettify<PossibleEbml>>;
|
|
8
|
+
export declare const postprocessEbml: ({ offset, ebml, statesForProcessing: { webmState, callbacks, logLevel, onAudioTrack, onVideoTrack, structureState, }, }: {
|
|
8
9
|
offset: number;
|
|
9
10
|
ebml: Prettify<PossibleEbml>;
|
|
10
|
-
|
|
11
|
+
statesForProcessing: WebmRequiredStatesForProcessing;
|
|
11
12
|
}) => Promise<Prettify<PossibleEbml>>;
|
|
@@ -3,12 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.postprocessEbml = exports.parseEbml = void 0;
|
|
4
4
|
const emit_audio_sample_1 = require("../../emit-audio-sample");
|
|
5
5
|
const register_track_1 = require("../../register-track");
|
|
6
|
-
const work_on_seek_request_1 = require("../../work-on-seek-request");
|
|
7
6
|
const get_sample_from_block_1 = require("./get-sample-from-block");
|
|
8
7
|
const make_track_1 = require("./make-track");
|
|
9
8
|
const all_segments_1 = require("./segments/all-segments");
|
|
10
|
-
const parseEbml = async (
|
|
11
|
-
const { iterator } = state;
|
|
9
|
+
const parseEbml = async (iterator, statesForProcessing) => {
|
|
12
10
|
const hex = iterator.getMatroskaSegmentId();
|
|
13
11
|
if (hex === null) {
|
|
14
12
|
throw new Error('Not enough bytes left to parse EBML - this should not happen');
|
|
@@ -86,13 +84,15 @@ const parseEbml = async (state) => {
|
|
|
86
84
|
break;
|
|
87
85
|
}
|
|
88
86
|
const offset = iterator.counter.getOffset();
|
|
89
|
-
const value = await (0, exports.parseEbml)(
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
87
|
+
const value = await (0, exports.parseEbml)(iterator, statesForProcessing);
|
|
88
|
+
const remapped = statesForProcessing
|
|
89
|
+
? // eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
90
|
+
await (0, exports.postprocessEbml)({
|
|
91
|
+
offset,
|
|
92
|
+
ebml: value,
|
|
93
|
+
statesForProcessing,
|
|
94
|
+
})
|
|
95
|
+
: value;
|
|
96
96
|
children.push(remapped);
|
|
97
97
|
const offsetNow = iterator.counter.getOffset();
|
|
98
98
|
if (offsetNow - startOffset > size) {
|
|
@@ -108,53 +108,50 @@ const parseEbml = async (state) => {
|
|
|
108
108
|
throw new Error(`Unknown segment type ${hasInMap.type}`);
|
|
109
109
|
};
|
|
110
110
|
exports.parseEbml = parseEbml;
|
|
111
|
-
const postprocessEbml = async ({ offset, ebml,
|
|
111
|
+
const postprocessEbml = async ({ offset, ebml, statesForProcessing: { webmState, callbacks, logLevel, onAudioTrack, onVideoTrack, structureState, }, }) => {
|
|
112
112
|
if (ebml.type === 'TimestampScale') {
|
|
113
|
-
|
|
113
|
+
webmState.setTimescale(ebml.value.value);
|
|
114
114
|
}
|
|
115
115
|
if (ebml.type === 'Tracks') {
|
|
116
|
-
|
|
116
|
+
callbacks.tracks.setIsDone(logLevel);
|
|
117
117
|
}
|
|
118
118
|
if (ebml.type === 'TrackEntry') {
|
|
119
|
-
|
|
119
|
+
webmState.onTrackEntrySegment(ebml);
|
|
120
120
|
const track = (0, make_track_1.getTrack)({
|
|
121
121
|
track: ebml,
|
|
122
|
-
timescale:
|
|
122
|
+
timescale: webmState.getTimescale(),
|
|
123
123
|
});
|
|
124
124
|
if (track && track.type === 'audio') {
|
|
125
125
|
await (0, register_track_1.registerAudioTrack)({
|
|
126
|
-
workOnSeekRequestOptions: (0, work_on_seek_request_1.getWorkOnSeekRequestOptions)(state),
|
|
127
126
|
track,
|
|
128
127
|
container: 'webm',
|
|
129
|
-
registerAudioSampleCallback:
|
|
130
|
-
tracks:
|
|
131
|
-
logLevel
|
|
132
|
-
onAudioTrack
|
|
128
|
+
registerAudioSampleCallback: callbacks.registerAudioSampleCallback,
|
|
129
|
+
tracks: callbacks.tracks,
|
|
130
|
+
logLevel,
|
|
131
|
+
onAudioTrack,
|
|
133
132
|
});
|
|
134
133
|
}
|
|
135
134
|
if (track && track.type === 'video') {
|
|
136
135
|
await (0, register_track_1.registerVideoTrack)({
|
|
137
|
-
workOnSeekRequestOptions: (0, work_on_seek_request_1.getWorkOnSeekRequestOptions)(state),
|
|
138
136
|
track,
|
|
139
137
|
container: 'webm',
|
|
140
|
-
logLevel
|
|
141
|
-
onVideoTrack
|
|
142
|
-
registerVideoSampleCallback:
|
|
143
|
-
tracks:
|
|
138
|
+
logLevel,
|
|
139
|
+
onVideoTrack,
|
|
140
|
+
registerVideoSampleCallback: callbacks.registerVideoSampleCallback,
|
|
141
|
+
tracks: callbacks.tracks,
|
|
144
142
|
});
|
|
145
143
|
}
|
|
146
144
|
}
|
|
147
145
|
if (ebml.type === 'Timestamp') {
|
|
148
|
-
|
|
146
|
+
webmState.setTimestampOffset(offset, ebml.value.value);
|
|
149
147
|
}
|
|
150
148
|
if (ebml.type === 'Block' || ebml.type === 'SimpleBlock') {
|
|
151
|
-
const sample = (0, get_sample_from_block_1.getSampleFromBlock)(ebml,
|
|
149
|
+
const sample = (0, get_sample_from_block_1.getSampleFromBlock)(ebml, webmState, offset, structureState);
|
|
152
150
|
if (sample.type === 'video-sample') {
|
|
153
151
|
await (0, emit_audio_sample_1.emitVideoSample)({
|
|
154
152
|
trackId: sample.videoSample.trackId,
|
|
155
153
|
videoSample: sample.videoSample,
|
|
156
|
-
|
|
157
|
-
callbacks: state.callbacks,
|
|
154
|
+
callbacks,
|
|
158
155
|
});
|
|
159
156
|
return {
|
|
160
157
|
type: 'Block',
|
|
@@ -166,8 +163,7 @@ const postprocessEbml = async ({ offset, ebml, state, }) => {
|
|
|
166
163
|
await (0, emit_audio_sample_1.emitAudioSample)({
|
|
167
164
|
trackId: sample.audioSample.trackId,
|
|
168
165
|
audioSample: sample.audioSample,
|
|
169
|
-
|
|
170
|
-
callbacks: state.callbacks,
|
|
166
|
+
callbacks,
|
|
171
167
|
});
|
|
172
168
|
return {
|
|
173
169
|
type: 'Block',
|
|
@@ -195,7 +191,7 @@ const postprocessEbml = async ({ offset, ebml, state, }) => {
|
|
|
195
191
|
const hasReferenceBlock = ebml.value.find((c) => c.type === 'ReferenceBlock');
|
|
196
192
|
const sample = block.value.length === 0
|
|
197
193
|
? null
|
|
198
|
-
: (0, get_sample_from_block_1.getSampleFromBlock)(block,
|
|
194
|
+
: (0, get_sample_from_block_1.getSampleFromBlock)(block, webmState, offset, structureState);
|
|
199
195
|
if (sample && sample.type === 'partial-video-sample') {
|
|
200
196
|
const completeFrame = {
|
|
201
197
|
...sample.partialVideoSample,
|
|
@@ -204,8 +200,7 @@ const postprocessEbml = async ({ offset, ebml, state, }) => {
|
|
|
204
200
|
await (0, emit_audio_sample_1.emitVideoSample)({
|
|
205
201
|
trackId: sample.partialVideoSample.trackId,
|
|
206
202
|
videoSample: completeFrame,
|
|
207
|
-
|
|
208
|
-
callbacks: state.callbacks,
|
|
203
|
+
callbacks,
|
|
209
204
|
});
|
|
210
205
|
}
|
|
211
206
|
return {
|