@remotion/media-parser 4.0.288 → 4.0.290
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/containers/aac/get-seeking-byte.d.ts +6 -0
- package/dist/containers/aac/get-seeking-byte.js +30 -0
- package/dist/containers/aac/parse-aac.js +23 -18
- package/dist/containers/aac/seeking-hints.d.ts +13 -0
- package/dist/containers/aac/seeking-hints.js +14 -0
- package/dist/containers/flac/get-channel-count.d.ts +1 -1
- package/dist/containers/flac/get-seeking-byte.d.ts +1 -2
- package/dist/containers/flac/get-seeking-byte.js +6 -2
- package/dist/containers/flac/parse-flac-frame.js +18 -17
- package/dist/containers/flac/parse-flac.js +5 -25
- package/dist/containers/flac/seeking-hints.d.ts +4 -1
- package/dist/containers/flac/seeking-hints.js +2 -1
- package/dist/containers/iso-base-media/get-children.d.ts +2 -1
- package/dist/containers/iso-base-media/get-children.js +2 -1
- package/dist/containers/iso-base-media/get-mfra-seeking-box.js +1 -0
- package/dist/containers/iso-base-media/get-moov-atom.js +2 -1
- package/dist/containers/iso-base-media/mdat/mdat.js +26 -33
- package/dist/containers/iso-base-media/moov/moov.d.ts +2 -1
- package/dist/containers/iso-base-media/moov/moov.js +2 -1
- package/dist/containers/iso-base-media/parse-boxes.js +1 -0
- package/dist/containers/iso-base-media/process-box.d.ts +2 -1
- package/dist/containers/iso-base-media/process-box.js +10 -4
- package/dist/containers/iso-base-media/seeking-hints.d.ts +1 -1
- package/dist/containers/iso-base-media/stsd/mebx.d.ts +2 -1
- package/dist/containers/iso-base-media/stsd/mebx.js +2 -1
- package/dist/containers/iso-base-media/stsd/samples.d.ts +4 -2
- package/dist/containers/iso-base-media/stsd/samples.js +7 -2
- package/dist/containers/iso-base-media/stsd/stsd.d.ts +2 -1
- package/dist/containers/iso-base-media/stsd/stsd.js +2 -1
- package/dist/containers/iso-base-media/trak/trak.d.ts +2 -1
- package/dist/containers/iso-base-media/trak/trak.js +2 -1
- package/dist/containers/mp3/audio-sample-from-cbr.d.ts +11 -0
- package/dist/containers/mp3/audio-sample-from-cbr.js +35 -0
- package/dist/containers/mp3/get-duration.d.ts +5 -0
- package/dist/containers/mp3/get-duration.js +33 -6
- package/dist/containers/mp3/get-seeking-byte.d.ts +6 -0
- package/dist/containers/mp3/get-seeking-byte.js +49 -0
- package/dist/containers/mp3/parse-mp3.js +9 -0
- package/dist/containers/mp3/parse-mpeg-header.js +74 -263
- package/dist/containers/mp3/parse-packet-header.d.ts +30 -0
- package/dist/containers/mp3/parse-packet-header.js +258 -0
- package/dist/containers/mp3/parse-xing.d.ts +19 -0
- package/dist/containers/mp3/parse-xing.js +120 -0
- package/dist/containers/mp3/seek/audio-sample-from-cbr.d.ts +16 -0
- package/dist/containers/mp3/seek/audio-sample-from-cbr.js +35 -0
- package/dist/containers/mp3/seek/audio-sample-from-vbr.d.ts +8 -0
- package/dist/containers/mp3/seek/audio-sample-from-vbr.js +47 -0
- package/dist/containers/mp3/seek/get-approximate-byte-from-bitrate.d.ts +9 -0
- package/dist/containers/mp3/seek/get-approximate-byte-from-bitrate.js +28 -0
- package/dist/containers/mp3/seek/get-byte-from-observed-samples.d.ts +6 -0
- package/dist/containers/mp3/seek/get-byte-from-observed-samples.js +27 -0
- package/dist/containers/mp3/seek/get-seek-point-from-xing.d.ts +7 -0
- package/dist/containers/mp3/seek/get-seek-point-from-xing.js +29 -0
- package/dist/containers/mp3/seek/wait-until-syncword.d.ts +4 -0
- package/dist/containers/mp3/seek/wait-until-syncword.js +25 -0
- package/dist/containers/mp3/seeking-hints.d.ts +24 -0
- package/dist/containers/mp3/seeking-hints.js +21 -0
- package/dist/containers/riff/expect-riff-box.d.ts +6 -1
- package/dist/containers/riff/expect-riff-box.js +37 -27
- package/dist/containers/riff/get-seeking-byte.d.ts +8 -0
- package/dist/containers/riff/get-seeking-byte.js +56 -0
- package/dist/containers/riff/has-index.d.ts +2 -0
- package/dist/containers/riff/has-index.js +8 -0
- package/dist/containers/riff/parse-avih.js +3 -0
- package/dist/containers/riff/parse-idx1.d.ts +6 -0
- package/dist/containers/riff/parse-idx1.js +47 -0
- package/dist/containers/riff/parse-list-box.d.ts +4 -2
- package/dist/containers/riff/parse-list-box.js +8 -3
- package/dist/containers/riff/parse-movi.js +35 -40
- package/dist/containers/riff/parse-riff-body.js +5 -1
- package/dist/containers/riff/parse-riff-box.d.ts +4 -2
- package/dist/containers/riff/parse-riff-box.js +10 -3
- package/dist/containers/riff/riff-box.d.ts +14 -1
- package/dist/containers/riff/seek/fetch-idx1.d.ts +15 -0
- package/dist/containers/riff/seek/fetch-idx1.js +38 -0
- package/dist/containers/riff/seeking-hints.d.ts +23 -0
- package/dist/containers/riff/seeking-hints.js +36 -0
- package/dist/containers/transport-stream/handle-aac-packet.js +4 -8
- package/dist/containers/transport-stream/handle-avc-packet.js +4 -8
- package/dist/containers/wav/get-duration-from-wav.d.ts +0 -1
- package/dist/containers/wav/get-duration-from-wav.js +1 -10
- package/dist/containers/wav/parse-media-section.js +14 -18
- package/dist/containers/webm/parse-ebml.js +3 -16
- package/dist/containers/webm/seek/seeking-hints.js +1 -1
- package/dist/emit-available-info.js +8 -8
- package/dist/esm/index.mjs +1479 -383
- package/dist/esm/worker-server-entry.mjs +1475 -379
- package/dist/esm/worker-web-entry.mjs +1475 -379
- package/dist/find-last-keyframe.d.ts +5 -0
- package/dist/find-last-keyframe.js +18 -0
- package/dist/get-seeking-byte.d.ts +3 -1
- package/dist/get-seeking-byte.js +45 -7
- package/dist/get-seeking-hints.d.ts +12 -1
- package/dist/get-seeking-hints.js +40 -9
- package/dist/index.d.ts +56 -8
- package/dist/internal-parse-media.js +6 -0
- package/dist/parse-loop.js +15 -0
- package/dist/seeking-hints.d.ts +5 -1
- package/dist/set-seeking-hints.js +28 -8
- package/dist/state/aac-state.d.ts +6 -0
- package/dist/state/aac-state.js +7 -2
- package/dist/state/flac-state.d.ts +6 -0
- package/dist/state/flac-state.js +3 -0
- package/dist/state/keyframes.d.ts +1 -2
- package/dist/state/keyframes.js +2 -2
- package/dist/state/matroska/lazy-cues-fetch.js +13 -1
- package/dist/state/mp3.d.ts +16 -5
- package/dist/state/mp3.js +7 -5
- package/dist/state/parser-state.d.ts +52 -6
- package/dist/state/parser-state.js +6 -6
- package/dist/state/riff/lazy-idx1-fetch.d.ts +30 -0
- package/dist/state/riff/lazy-idx1-fetch.js +63 -0
- package/dist/state/riff/riff-keyframes.d.ts +10 -0
- package/dist/state/riff/riff-keyframes.js +26 -0
- package/dist/state/riff/sample-counter.d.ts +12 -0
- package/dist/state/riff/sample-counter.js +52 -0
- package/dist/state/riff.d.ts +41 -1
- package/dist/state/riff.js +12 -1
- package/dist/state/sample-callbacks.d.ts +3 -4
- package/dist/state/sample-callbacks.js +3 -16
- package/dist/state/samples-observed/slow-duration-fps.d.ts +3 -1
- package/dist/state/samples-observed/slow-duration-fps.js +7 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/work-on-seek-request.d.ts +10 -0
- package/dist/work-on-seek-request.js +20 -2
- package/package.json +3 -3
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseIdx1 = void 0;
|
|
4
|
+
const AVIIF_KEYFRAME = 0x00000010;
|
|
5
|
+
const parseIdx1 = ({ iterator, size, }) => {
|
|
6
|
+
const box = iterator.startBox(size);
|
|
7
|
+
const offset = iterator.counter.getOffset();
|
|
8
|
+
const entries = [];
|
|
9
|
+
const sampleCounts = {};
|
|
10
|
+
let videoTrackIndex = null;
|
|
11
|
+
while (iterator.counter.getOffset() < offset + size) {
|
|
12
|
+
const chunkId = iterator.getByteString(4, false);
|
|
13
|
+
const flags = iterator.getUint32Le();
|
|
14
|
+
const moffset = iterator.getUint32Le();
|
|
15
|
+
const msize = iterator.getUint32Le();
|
|
16
|
+
const chunk = chunkId.match(/^([0-9]{2})(wb|dc)$/);
|
|
17
|
+
const isVideo = chunkId.endsWith('dc');
|
|
18
|
+
if (isVideo) {
|
|
19
|
+
videoTrackIndex = chunk ? parseInt(chunk[1], 10) : null;
|
|
20
|
+
}
|
|
21
|
+
const trackId = chunk ? parseInt(chunk[1], 10) : null;
|
|
22
|
+
if (trackId === null) {
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
if (!sampleCounts[trackId]) {
|
|
26
|
+
sampleCounts[trackId] = 0;
|
|
27
|
+
}
|
|
28
|
+
const isKeyFrame = (flags & AVIIF_KEYFRAME) !== 0;
|
|
29
|
+
if (isKeyFrame) {
|
|
30
|
+
entries.push({
|
|
31
|
+
flags,
|
|
32
|
+
id: chunkId,
|
|
33
|
+
offset: moffset,
|
|
34
|
+
size: msize,
|
|
35
|
+
sampleCounts: { ...sampleCounts },
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
sampleCounts[trackId]++;
|
|
39
|
+
}
|
|
40
|
+
box.expectNoMoreBytes();
|
|
41
|
+
return {
|
|
42
|
+
type: 'idx1-box',
|
|
43
|
+
entries,
|
|
44
|
+
videoTrackIndex,
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
exports.parseIdx1 = parseIdx1;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import type { BufferIterator } from '../../iterator/buffer-iterator';
|
|
1
2
|
import type { ParserState } from '../../state/parser-state';
|
|
2
3
|
import type { RiffBox } from './riff-box';
|
|
3
|
-
export declare const parseListBox: ({ size,
|
|
4
|
+
export declare const parseListBox: ({ size, iterator, stateIfExpectingSideEffects, }: {
|
|
4
5
|
size: number;
|
|
5
|
-
|
|
6
|
+
iterator: BufferIterator;
|
|
7
|
+
stateIfExpectingSideEffects: ParserState | null;
|
|
6
8
|
}) => Promise<RiffBox>;
|
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.parseListBox = void 0;
|
|
4
4
|
const expect_riff_box_1 = require("./expect-riff-box");
|
|
5
|
-
const parseListBox = async ({ size,
|
|
6
|
-
const { iterator } = state;
|
|
5
|
+
const parseListBox = async ({ size, iterator, stateIfExpectingSideEffects, }) => {
|
|
7
6
|
const counter = iterator.counter.getOffset();
|
|
8
7
|
const listType = iterator.getByteString(4, false);
|
|
9
8
|
if (listType === 'movi') {
|
|
@@ -12,10 +11,16 @@ const parseListBox = async ({ size, state, }) => {
|
|
|
12
11
|
const boxes = [];
|
|
13
12
|
const maxOffset = counter + size;
|
|
14
13
|
while (iterator.counter.getOffset() < maxOffset) {
|
|
15
|
-
const box = await (0, expect_riff_box_1.expectRiffBox)(
|
|
14
|
+
const box = await (0, expect_riff_box_1.expectRiffBox)({
|
|
15
|
+
iterator,
|
|
16
|
+
stateIfExpectingSideEffects,
|
|
17
|
+
});
|
|
16
18
|
if (box === null) {
|
|
17
19
|
throw new Error('Unexpected result');
|
|
18
20
|
}
|
|
21
|
+
if (stateIfExpectingSideEffects) {
|
|
22
|
+
await (0, expect_riff_box_1.postProcessRiffBox)(stateIfExpectingSideEffects, box);
|
|
23
|
+
}
|
|
19
24
|
boxes.push(box);
|
|
20
25
|
}
|
|
21
26
|
return {
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.parseMovi = exports.handleChunk = void 0;
|
|
4
4
|
const convert_audio_or_video_sample_1 = require("../../convert-audio-or-video-sample");
|
|
5
|
-
const emit_audio_sample_1 = require("../../emit-audio-sample");
|
|
6
5
|
const key_1 = require("../avc/key");
|
|
7
6
|
const parse_avc_1 = require("../avc/parse-avc");
|
|
8
7
|
const traversal_1 = require("./traversal");
|
|
@@ -20,13 +19,13 @@ const getStrhForIndex = (structure, trackId) => {
|
|
|
20
19
|
};
|
|
21
20
|
const handleChunk = async ({ state, ckId, ckSize, }) => {
|
|
22
21
|
const { iterator } = state;
|
|
23
|
-
const offset = iterator.counter.getOffset();
|
|
22
|
+
const offset = iterator.counter.getOffset() - 8;
|
|
24
23
|
const videoChunk = ckId.match(/^([0-9]{2})dc$/);
|
|
25
24
|
if (videoChunk) {
|
|
26
25
|
const trackId = parseInt(videoChunk[1], 10);
|
|
27
26
|
const strh = getStrhForIndex(state.structure.getRiffStructure(), trackId);
|
|
28
27
|
const samplesPerSecond = strh.rate / strh.scale;
|
|
29
|
-
const nthSample = state.
|
|
28
|
+
const nthSample = state.riff.sampleCounter.getSamplesForTrack(trackId);
|
|
30
29
|
const timeInSec = nthSample / samplesPerSecond;
|
|
31
30
|
const timestamp = timeInSec;
|
|
32
31
|
const data = iterator.getSlice(ckSize);
|
|
@@ -38,27 +37,25 @@ const handleChunk = async ({ state, ckId, ckSize, }) => {
|
|
|
38
37
|
await state.riff.onProfile({ pps: ppsProfile, sps: avcProfile });
|
|
39
38
|
state.callbacks.tracks.setIsDone(state.logLevel);
|
|
40
39
|
}
|
|
40
|
+
const videoSample = (0, convert_audio_or_video_sample_1.convertAudioOrVideoSampleToWebCodecsTimestamps)({
|
|
41
|
+
sample: {
|
|
42
|
+
cts: timestamp,
|
|
43
|
+
dts: timestamp,
|
|
44
|
+
data,
|
|
45
|
+
duration: undefined,
|
|
46
|
+
timestamp,
|
|
47
|
+
trackId,
|
|
48
|
+
type: keyOrDelta,
|
|
49
|
+
offset,
|
|
50
|
+
timescale: samplesPerSecond,
|
|
51
|
+
},
|
|
52
|
+
timescale: 1,
|
|
53
|
+
});
|
|
54
|
+
state.riff.sampleCounter.onVideoSample(trackId, videoSample);
|
|
41
55
|
// We must also NOT pass a duration because if the the next sample is 0,
|
|
42
56
|
// this sample would be longer. Chrome will pad it with silence.
|
|
43
57
|
// If we'd pass a duration instead, it would shift the audio and we think that audio is not finished
|
|
44
|
-
await (
|
|
45
|
-
trackId,
|
|
46
|
-
videoSample: (0, convert_audio_or_video_sample_1.convertAudioOrVideoSampleToWebCodecsTimestamps)({
|
|
47
|
-
sample: {
|
|
48
|
-
cts: timestamp,
|
|
49
|
-
dts: timestamp,
|
|
50
|
-
data,
|
|
51
|
-
duration: undefined,
|
|
52
|
-
timestamp,
|
|
53
|
-
trackId,
|
|
54
|
-
type: keyOrDelta,
|
|
55
|
-
offset,
|
|
56
|
-
timescale: samplesPerSecond,
|
|
57
|
-
},
|
|
58
|
-
timescale: 1,
|
|
59
|
-
}),
|
|
60
|
-
callbacks: state.callbacks,
|
|
61
|
-
});
|
|
58
|
+
await state.callbacks.onVideoSample(trackId, videoSample);
|
|
62
59
|
return;
|
|
63
60
|
}
|
|
64
61
|
const audioChunk = ckId.match(/^([0-9]{2})wb$/);
|
|
@@ -66,33 +63,31 @@ const handleChunk = async ({ state, ckId, ckSize, }) => {
|
|
|
66
63
|
const trackId = parseInt(audioChunk[1], 10);
|
|
67
64
|
const strh = getStrhForIndex(state.structure.getRiffStructure(), trackId);
|
|
68
65
|
const samplesPerSecond = strh.rate / strh.scale;
|
|
69
|
-
const nthSample = state.
|
|
66
|
+
const nthSample = state.riff.sampleCounter.getSamplesForTrack(trackId);
|
|
70
67
|
const timeInSec = nthSample / samplesPerSecond;
|
|
71
68
|
const timestamp = timeInSec;
|
|
72
69
|
const data = iterator.getSlice(ckSize);
|
|
70
|
+
const audioSample = (0, convert_audio_or_video_sample_1.convertAudioOrVideoSampleToWebCodecsTimestamps)({
|
|
71
|
+
sample: {
|
|
72
|
+
cts: timestamp,
|
|
73
|
+
dts: timestamp,
|
|
74
|
+
data,
|
|
75
|
+
duration: undefined,
|
|
76
|
+
timestamp,
|
|
77
|
+
trackId,
|
|
78
|
+
type: 'key',
|
|
79
|
+
offset,
|
|
80
|
+
timescale: samplesPerSecond,
|
|
81
|
+
},
|
|
82
|
+
timescale: 1,
|
|
83
|
+
});
|
|
84
|
+
state.riff.sampleCounter.onAudioSample(trackId, audioSample);
|
|
73
85
|
// In example.avi, we have samples with 0 data
|
|
74
86
|
// Chrome fails on these
|
|
75
87
|
// We must also NOT pass a duration because if the the next sample is 0,
|
|
76
88
|
// this sample would be longer. Chrome will pad it with silence.
|
|
77
89
|
// If we'd pass a duration instead, it would shift the audio and we think that audio is not finished
|
|
78
|
-
await (
|
|
79
|
-
trackId,
|
|
80
|
-
audioSample: (0, convert_audio_or_video_sample_1.convertAudioOrVideoSampleToWebCodecsTimestamps)({
|
|
81
|
-
sample: {
|
|
82
|
-
cts: timestamp,
|
|
83
|
-
dts: timestamp,
|
|
84
|
-
data,
|
|
85
|
-
duration: undefined,
|
|
86
|
-
timestamp,
|
|
87
|
-
trackId,
|
|
88
|
-
type: 'key',
|
|
89
|
-
offset,
|
|
90
|
-
timescale: samplesPerSecond,
|
|
91
|
-
},
|
|
92
|
-
timescale: 1,
|
|
93
|
-
}),
|
|
94
|
-
callbacks: state.callbacks,
|
|
95
|
-
});
|
|
90
|
+
await state.callbacks.onAudioSample(trackId, audioSample);
|
|
96
91
|
}
|
|
97
92
|
};
|
|
98
93
|
exports.handleChunk = handleChunk;
|
|
@@ -26,8 +26,12 @@ const parseRiffBody = async (state) => {
|
|
|
26
26
|
await (0, parse_video_section_1.parseMediaSection)(state);
|
|
27
27
|
return null;
|
|
28
28
|
}
|
|
29
|
-
const box = await (0, expect_riff_box_1.expectRiffBox)(
|
|
29
|
+
const box = await (0, expect_riff_box_1.expectRiffBox)({
|
|
30
|
+
iterator: state.iterator,
|
|
31
|
+
stateIfExpectingSideEffects: state,
|
|
32
|
+
});
|
|
30
33
|
if (box !== null) {
|
|
34
|
+
await (0, expect_riff_box_1.postProcessRiffBox)(state, box);
|
|
31
35
|
const structure = state.structure.getRiffStructure();
|
|
32
36
|
structure.boxes.push(box);
|
|
33
37
|
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import type { BufferIterator } from '../../iterator/buffer-iterator';
|
|
1
2
|
import type { ParserState } from '../../state/parser-state';
|
|
2
3
|
import type { RiffBox } from './riff-box';
|
|
3
|
-
export declare const parseRiffBox: ({ size, id,
|
|
4
|
+
export declare const parseRiffBox: ({ size, id, iterator, stateIfExpectingSideEffects, }: {
|
|
4
5
|
size: number;
|
|
5
6
|
id: string;
|
|
6
|
-
|
|
7
|
+
iterator: BufferIterator;
|
|
8
|
+
stateIfExpectingSideEffects: ParserState | null;
|
|
7
9
|
}) => Promise<RiffBox>;
|
|
@@ -2,13 +2,17 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.parseRiffBox = void 0;
|
|
4
4
|
const parse_avih_1 = require("./parse-avih");
|
|
5
|
+
const parse_idx1_1 = require("./parse-idx1");
|
|
5
6
|
const parse_isft_1 = require("./parse-isft");
|
|
6
7
|
const parse_list_box_1 = require("./parse-list-box");
|
|
7
8
|
const parse_strh_1 = require("./parse-strh");
|
|
8
|
-
const parseRiffBox = ({ size, id,
|
|
9
|
-
const { iterator } = state;
|
|
9
|
+
const parseRiffBox = ({ size, id, iterator, stateIfExpectingSideEffects, }) => {
|
|
10
10
|
if (id === 'LIST') {
|
|
11
|
-
return (0, parse_list_box_1.parseListBox)({
|
|
11
|
+
return (0, parse_list_box_1.parseListBox)({
|
|
12
|
+
size,
|
|
13
|
+
iterator,
|
|
14
|
+
stateIfExpectingSideEffects,
|
|
15
|
+
});
|
|
12
16
|
}
|
|
13
17
|
if (id === 'ISFT') {
|
|
14
18
|
return Promise.resolve((0, parse_isft_1.parseIsft)({ iterator, size }));
|
|
@@ -19,6 +23,9 @@ const parseRiffBox = ({ size, id, state, }) => {
|
|
|
19
23
|
if (id === 'strh') {
|
|
20
24
|
return Promise.resolve((0, parse_strh_1.parseStrh)({ iterator, size }));
|
|
21
25
|
}
|
|
26
|
+
if (id === 'idx1') {
|
|
27
|
+
return Promise.resolve((0, parse_idx1_1.parseIdx1)({ iterator, size }));
|
|
28
|
+
}
|
|
22
29
|
iterator.discard(size);
|
|
23
30
|
const box = {
|
|
24
31
|
type: 'riff-box',
|
|
@@ -20,6 +20,7 @@ export type AvihBox = {
|
|
|
20
20
|
suggestedBufferSize: number;
|
|
21
21
|
width: number;
|
|
22
22
|
height: number;
|
|
23
|
+
hasIndex: boolean;
|
|
23
24
|
};
|
|
24
25
|
export type FccType = 'vids' | 'auds';
|
|
25
26
|
export type StrhBox = {
|
|
@@ -72,7 +73,19 @@ export type IsftBox = {
|
|
|
72
73
|
type: 'isft-box';
|
|
73
74
|
software: string;
|
|
74
75
|
};
|
|
75
|
-
export type
|
|
76
|
+
export type Idx1Box = {
|
|
77
|
+
type: 'idx1-box';
|
|
78
|
+
entries: Idx1Entry[];
|
|
79
|
+
videoTrackIndex: number | null;
|
|
80
|
+
};
|
|
81
|
+
export type Idx1Entry = {
|
|
82
|
+
id: string;
|
|
83
|
+
flags: number;
|
|
84
|
+
offset: number;
|
|
85
|
+
size: number;
|
|
86
|
+
sampleCounts: Record<number, number>;
|
|
87
|
+
};
|
|
88
|
+
export type RiffBox = RiffRegularBox | RiffHeader | ListBox | AvihBox | StrhBox | StrfBoxVideo | StrfBoxAudio | Idx1Box | IsftBox;
|
|
76
89
|
export type RiffStructure = {
|
|
77
90
|
type: 'riff';
|
|
78
91
|
boxes: RiffBox[];
|
|
@@ -0,0 +1,15 @@
|
|
|
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
|
+
export declare const fetchIdx1: ({ src, readerInterface, controller, position, logLevel, }: {
|
|
6
|
+
src: ParseMediaSrc;
|
|
7
|
+
readerInterface: ReaderInterface;
|
|
8
|
+
controller: MediaParserController;
|
|
9
|
+
position: number;
|
|
10
|
+
logLevel: LogLevel;
|
|
11
|
+
}) => Promise<{
|
|
12
|
+
entries: import("../riff-box").Idx1Entry[];
|
|
13
|
+
videoTrackIndex: number | null;
|
|
14
|
+
}>;
|
|
15
|
+
export type FetchIdx1Result = Awaited<ReturnType<typeof fetchIdx1>>;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fetchIdx1 = void 0;
|
|
4
|
+
const buffer_iterator_1 = require("../../../iterator/buffer-iterator");
|
|
5
|
+
const log_1 = require("../../../log");
|
|
6
|
+
const expect_riff_box_1 = require("../expect-riff-box");
|
|
7
|
+
const fetchIdx1 = async ({ src, readerInterface, controller, position, logLevel, }) => {
|
|
8
|
+
log_1.Log.verbose(logLevel, 'Making request to fetch idx1 from ', src, 'position', position);
|
|
9
|
+
const result = await readerInterface.read({
|
|
10
|
+
controller,
|
|
11
|
+
range: position,
|
|
12
|
+
src,
|
|
13
|
+
});
|
|
14
|
+
const iterator = (0, buffer_iterator_1.getArrayBufferIterator)(new Uint8Array(), Infinity);
|
|
15
|
+
while (true) {
|
|
16
|
+
const res = await result.reader.reader.read();
|
|
17
|
+
if (res.value) {
|
|
18
|
+
iterator.addData(res.value);
|
|
19
|
+
}
|
|
20
|
+
if (res.done) {
|
|
21
|
+
break;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
const box = await (0, expect_riff_box_1.expectRiffBox)({
|
|
25
|
+
iterator,
|
|
26
|
+
stateIfExpectingSideEffects: null,
|
|
27
|
+
});
|
|
28
|
+
iterator.destroy();
|
|
29
|
+
if (box === null || box.type !== 'idx1-box') {
|
|
30
|
+
throw new Error('Expected idx1-box');
|
|
31
|
+
}
|
|
32
|
+
// only store video chunks, those end with "dc", e.g. "01dc"
|
|
33
|
+
return {
|
|
34
|
+
entries: box.entries.filter((entry) => entry.id.endsWith('dc')),
|
|
35
|
+
videoTrackIndex: box.videoTrackIndex,
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
exports.fetchIdx1 = fetchIdx1;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ParserState } from '../../state/parser-state';
|
|
2
|
+
import type { RiffState } from '../../state/riff';
|
|
3
|
+
import type { RiffKeyframe } from '../../state/riff/riff-keyframes';
|
|
4
|
+
import type { StructureState } from '../../state/structure';
|
|
5
|
+
import type { MediaSectionState } from '../../state/video-section';
|
|
6
|
+
import type { FetchIdx1Result } from './seek/fetch-idx1';
|
|
7
|
+
export type RiffSeekingHints = {
|
|
8
|
+
type: 'riff-seeking-hints';
|
|
9
|
+
hasIndex: boolean;
|
|
10
|
+
idx1Entries: FetchIdx1Result | null;
|
|
11
|
+
samplesPerSecond: number | null;
|
|
12
|
+
moviOffset: number | null;
|
|
13
|
+
observedKeyframes: RiffKeyframe[];
|
|
14
|
+
};
|
|
15
|
+
export declare const getSeekingHintsForRiff: ({ structureState, riffState, mediaSectionState, }: {
|
|
16
|
+
structureState: StructureState;
|
|
17
|
+
riffState: RiffState;
|
|
18
|
+
mediaSectionState: MediaSectionState;
|
|
19
|
+
}) => RiffSeekingHints;
|
|
20
|
+
export declare const setSeekingHintsForRiff: ({ hints, state, }: {
|
|
21
|
+
hints: RiffSeekingHints;
|
|
22
|
+
state: ParserState;
|
|
23
|
+
}) => void;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.setSeekingHintsForRiff = exports.getSeekingHintsForRiff = void 0;
|
|
4
|
+
const has_index_1 = require("./has-index");
|
|
5
|
+
const traversal_1 = require("./traversal");
|
|
6
|
+
const getSeekingHintsForRiff = ({ structureState, riffState, mediaSectionState, }) => {
|
|
7
|
+
var _a, _b;
|
|
8
|
+
const structure = structureState.getRiffStructure();
|
|
9
|
+
const strl = (0, traversal_1.getStrlBoxes)(structure);
|
|
10
|
+
let samplesPerSecond = null;
|
|
11
|
+
for (const s of strl) {
|
|
12
|
+
const strh = (0, traversal_1.getStrhBox)(s.children);
|
|
13
|
+
if (!strh) {
|
|
14
|
+
throw new Error('No strh box');
|
|
15
|
+
}
|
|
16
|
+
if (strh.strf.type !== 'strf-box-video') {
|
|
17
|
+
continue;
|
|
18
|
+
}
|
|
19
|
+
samplesPerSecond = strh.rate / strh.scale;
|
|
20
|
+
break;
|
|
21
|
+
}
|
|
22
|
+
return {
|
|
23
|
+
type: 'riff-seeking-hints',
|
|
24
|
+
hasIndex: (0, has_index_1.riffHasIndex)(structure),
|
|
25
|
+
idx1Entries: riffState.lazyIdx1.getIfAlreadyLoaded(),
|
|
26
|
+
samplesPerSecond,
|
|
27
|
+
moviOffset: (_b = (_a = mediaSectionState.getMediaSections()[0]) === null || _a === void 0 ? void 0 : _a.start) !== null && _b !== void 0 ? _b : null,
|
|
28
|
+
observedKeyframes: riffState.sampleCounter.riffKeys.getKeyframes(),
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
exports.getSeekingHintsForRiff = getSeekingHintsForRiff;
|
|
32
|
+
const setSeekingHintsForRiff = ({ hints, state, }) => {
|
|
33
|
+
state.riff.lazyIdx1.setFromSeekingHints(hints);
|
|
34
|
+
state.riff.sampleCounter.riffKeys.setFromSeekingHints(hints.observedKeyframes);
|
|
35
|
+
};
|
|
36
|
+
exports.setSeekingHintsForRiff = setSeekingHintsForRiff;
|
|
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.handleAacPacket = void 0;
|
|
4
4
|
const aac_codecprivate_1 = require("../../aac-codecprivate");
|
|
5
5
|
const convert_audio_or_video_sample_1 = require("../../convert-audio-or-video-sample");
|
|
6
|
-
const emit_audio_sample_1 = require("../../emit-audio-sample");
|
|
7
6
|
const register_track_1 = require("../../register-track");
|
|
8
7
|
const adts_header_1 = require("./adts-header");
|
|
9
8
|
const handle_avc_packet_1 = require("./handle-avc-packet");
|
|
@@ -61,14 +60,11 @@ const handleAacPacket = async ({ streamBuffer, programId, offset, sampleCallback
|
|
|
61
60
|
offset,
|
|
62
61
|
timescale: handle_avc_packet_1.MPEG_TIMESCALE,
|
|
63
62
|
};
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
sample,
|
|
68
|
-
timescale: handle_avc_packet_1.MPEG_TIMESCALE,
|
|
69
|
-
}),
|
|
70
|
-
callbacks: sampleCallbacks,
|
|
63
|
+
const audioSample = (0, convert_audio_or_video_sample_1.convertAudioOrVideoSampleToWebCodecsTimestamps)({
|
|
64
|
+
sample,
|
|
65
|
+
timescale: handle_avc_packet_1.MPEG_TIMESCALE,
|
|
71
66
|
});
|
|
67
|
+
await sampleCallbacks.onAudioSample(programId, audioSample);
|
|
72
68
|
transportStream.lastEmittedSample.setLastEmittedSample(sample);
|
|
73
69
|
};
|
|
74
70
|
exports.handleAacPacket = handleAacPacket;
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.handleAvcPacket = exports.MPEG_TIMESCALE = void 0;
|
|
4
4
|
const convert_audio_or_video_sample_1 = require("../../convert-audio-or-video-sample");
|
|
5
|
-
const emit_audio_sample_1 = require("../../emit-audio-sample");
|
|
6
5
|
const register_track_1 = require("../../register-track");
|
|
7
6
|
const codec_string_1 = require("../avc/codec-string");
|
|
8
7
|
const create_sps_pps_data_1 = require("../avc/create-sps-pps-data");
|
|
@@ -80,14 +79,11 @@ const handleAvcPacket = async ({ streamBuffer, programId, offset, sampleCallback
|
|
|
80
79
|
if (type === 'key') {
|
|
81
80
|
transportStream.observedPesHeaders.markPtsAsKeyframe(streamBuffer.pesHeader.pts);
|
|
82
81
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
sample,
|
|
87
|
-
timescale: exports.MPEG_TIMESCALE,
|
|
88
|
-
}),
|
|
89
|
-
callbacks: sampleCallbacks,
|
|
82
|
+
const videoSample = (0, convert_audio_or_video_sample_1.convertAudioOrVideoSampleToWebCodecsTimestamps)({
|
|
83
|
+
sample,
|
|
84
|
+
timescale: exports.MPEG_TIMESCALE,
|
|
90
85
|
});
|
|
86
|
+
await sampleCallbacks.onVideoSample(programId, videoSample);
|
|
91
87
|
transportStream.lastEmittedSample.setLastEmittedSample(sample);
|
|
92
88
|
};
|
|
93
89
|
exports.handleAvcPacket = handleAvcPacket;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.getDurationFromWav = void 0;
|
|
4
4
|
const getDurationFromWav = (state) => {
|
|
5
5
|
const structure = state.structure.getWavStructure();
|
|
6
6
|
const fmt = structure.boxes.find((b) => b.type === 'wav-fmt');
|
|
@@ -15,12 +15,3 @@ const getDurationFromWav = (state) => {
|
|
|
15
15
|
return durationInSeconds;
|
|
16
16
|
};
|
|
17
17
|
exports.getDurationFromWav = getDurationFromWav;
|
|
18
|
-
const hasDurationFromWav = (state) => {
|
|
19
|
-
try {
|
|
20
|
-
return (0, exports.getDurationFromWav)(state);
|
|
21
|
-
}
|
|
22
|
-
catch (_a) {
|
|
23
|
-
return false;
|
|
24
|
-
}
|
|
25
|
-
};
|
|
26
|
-
exports.hasDurationFromWav = hasDurationFromWav;
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.parseMediaSection = void 0;
|
|
4
4
|
const convert_audio_or_video_sample_1 = require("../../convert-audio-or-video-sample");
|
|
5
|
-
const emit_audio_sample_1 = require("../../emit-audio-sample");
|
|
6
5
|
const get_seeking_byte_1 = require("./get-seeking-byte");
|
|
7
6
|
const parseMediaSection = async ({ state, }) => {
|
|
8
7
|
const { iterator } = state;
|
|
@@ -19,24 +18,21 @@ const parseMediaSection = async ({ state, }) => {
|
|
|
19
18
|
const duration = toRead / (fmtBox.sampleRate * fmtBox.blockAlign);
|
|
20
19
|
const timestamp = (offset - videoSection.start) / (fmtBox.sampleRate * fmtBox.blockAlign);
|
|
21
20
|
const data = iterator.getSlice(toRead);
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
},
|
|
36
|
-
timescale: 1,
|
|
37
|
-
}),
|
|
38
|
-
callbacks: state.callbacks,
|
|
21
|
+
const audioSample = (0, convert_audio_or_video_sample_1.convertAudioOrVideoSampleToWebCodecsTimestamps)({
|
|
22
|
+
sample: {
|
|
23
|
+
cts: timestamp,
|
|
24
|
+
dts: timestamp,
|
|
25
|
+
data,
|
|
26
|
+
duration,
|
|
27
|
+
timestamp,
|
|
28
|
+
trackId: 0,
|
|
29
|
+
type: 'key',
|
|
30
|
+
offset,
|
|
31
|
+
timescale: 1000000,
|
|
32
|
+
},
|
|
33
|
+
timescale: 1,
|
|
39
34
|
});
|
|
35
|
+
await state.callbacks.onAudioSample(0, audioSample);
|
|
40
36
|
return null;
|
|
41
37
|
};
|
|
42
38
|
exports.parseMediaSection = parseMediaSection;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.postprocessEbml = exports.parseEbml = void 0;
|
|
4
|
-
const emit_audio_sample_1 = require("../../emit-audio-sample");
|
|
5
4
|
const register_track_1 = require("../../register-track");
|
|
6
5
|
const get_sample_from_block_1 = require("./get-sample-from-block");
|
|
7
6
|
const make_track_1 = require("./make-track");
|
|
@@ -148,11 +147,7 @@ const postprocessEbml = async ({ offset, ebml, statesForProcessing: { webmState,
|
|
|
148
147
|
if (ebml.type === 'Block' || ebml.type === 'SimpleBlock') {
|
|
149
148
|
const sample = (0, get_sample_from_block_1.getSampleFromBlock)(ebml, webmState, offset, structureState);
|
|
150
149
|
if (sample.type === 'video-sample') {
|
|
151
|
-
await (
|
|
152
|
-
trackId: sample.videoSample.trackId,
|
|
153
|
-
videoSample: sample.videoSample,
|
|
154
|
-
callbacks,
|
|
155
|
-
});
|
|
150
|
+
await callbacks.onVideoSample(sample.videoSample.trackId, sample.videoSample);
|
|
156
151
|
return {
|
|
157
152
|
type: 'Block',
|
|
158
153
|
value: new Uint8Array([]),
|
|
@@ -160,11 +155,7 @@ const postprocessEbml = async ({ offset, ebml, statesForProcessing: { webmState,
|
|
|
160
155
|
};
|
|
161
156
|
}
|
|
162
157
|
if (sample.type === 'audio-sample') {
|
|
163
|
-
await (
|
|
164
|
-
trackId: sample.audioSample.trackId,
|
|
165
|
-
audioSample: sample.audioSample,
|
|
166
|
-
callbacks,
|
|
167
|
-
});
|
|
158
|
+
await callbacks.onAudioSample(sample.audioSample.trackId, sample.audioSample);
|
|
168
159
|
return {
|
|
169
160
|
type: 'Block',
|
|
170
161
|
value: new Uint8Array([]),
|
|
@@ -197,11 +188,7 @@ const postprocessEbml = async ({ offset, ebml, statesForProcessing: { webmState,
|
|
|
197
188
|
...sample.partialVideoSample,
|
|
198
189
|
type: hasReferenceBlock ? 'delta' : 'key',
|
|
199
190
|
};
|
|
200
|
-
await (
|
|
201
|
-
trackId: sample.partialVideoSample.trackId,
|
|
202
|
-
videoSample: completeFrame,
|
|
203
|
-
callbacks,
|
|
204
|
-
});
|
|
191
|
+
await callbacks.onVideoSample(sample.partialVideoSample.trackId, completeFrame);
|
|
205
192
|
}
|
|
206
193
|
return {
|
|
207
194
|
type: 'BlockGroup',
|
|
@@ -22,7 +22,7 @@ const getSeekingHintsFromMatroska = (tracksState, keyframesState, webmState) =>
|
|
|
22
22
|
exports.getSeekingHintsFromMatroska = getSeekingHintsFromMatroska;
|
|
23
23
|
const setSeekingHintsForWebm = ({ hints, state, }) => {
|
|
24
24
|
state.webm.cues.setFromSeekingHints(hints);
|
|
25
|
-
state.keyframes.setFromSeekingHints(hints);
|
|
25
|
+
state.keyframes.setFromSeekingHints(hints.keyframes);
|
|
26
26
|
state.webm.setTimeStampMapForSeekingHints(hints.timestampMap);
|
|
27
27
|
};
|
|
28
28
|
exports.setSeekingHintsForWebm = setSeekingHintsForWebm;
|
|
@@ -48,7 +48,7 @@ const emitAvailableInfo = async ({ hasInfo, state, }) => {
|
|
|
48
48
|
if (key === 'slowDurationInSeconds') {
|
|
49
49
|
if (hasInfo.slowDurationInSeconds &&
|
|
50
50
|
!emittedFields.slowDurationInSeconds) {
|
|
51
|
-
const slowDurationInSeconds = (_c = (0, get_duration_1.getDuration)(state)) !== null && _c !== void 0 ? _c : state.
|
|
51
|
+
const slowDurationInSeconds = (_c = (0, get_duration_1.getDuration)(state)) !== null && _c !== void 0 ? _c : state.samplesObserved.getSlowDurationInSeconds();
|
|
52
52
|
await ((_d = callbackFunctions.onSlowDurationInSeconds) === null || _d === void 0 ? void 0 : _d.call(callbackFunctions, slowDurationInSeconds));
|
|
53
53
|
if (fieldsInReturnValue.slowDurationInSeconds) {
|
|
54
54
|
returnValue.slowDurationInSeconds = slowDurationInSeconds;
|
|
@@ -83,7 +83,7 @@ const emitAvailableInfo = async ({ hasInfo, state, }) => {
|
|
|
83
83
|
// must be handled after fps
|
|
84
84
|
if (key === 'slowFps') {
|
|
85
85
|
if (hasInfo.slowFps && !emittedFields.slowFps) {
|
|
86
|
-
const slowFps = state.
|
|
86
|
+
const slowFps = state.samplesObserved.getFps();
|
|
87
87
|
await ((_g = callbackFunctions.onSlowFps) === null || _g === void 0 ? void 0 : _g.call(callbackFunctions, slowFps));
|
|
88
88
|
if (fieldsInReturnValue.slowFps) {
|
|
89
89
|
returnValue.slowFps = slowFps;
|
|
@@ -268,10 +268,10 @@ const emitAvailableInfo = async ({ hasInfo, state, }) => {
|
|
|
268
268
|
}
|
|
269
269
|
if (key === 'slowNumberOfFrames') {
|
|
270
270
|
if (!emittedFields.slowNumberOfFrames && hasInfo.slowNumberOfFrames) {
|
|
271
|
-
await ((_y = callbackFunctions.onSlowNumberOfFrames) === null || _y === void 0 ? void 0 : _y.call(callbackFunctions, state.
|
|
271
|
+
await ((_y = callbackFunctions.onSlowNumberOfFrames) === null || _y === void 0 ? void 0 : _y.call(callbackFunctions, state.samplesObserved.getSlowNumberOfFrames()));
|
|
272
272
|
if (fieldsInReturnValue.slowNumberOfFrames) {
|
|
273
273
|
returnValue.slowNumberOfFrames =
|
|
274
|
-
state.
|
|
274
|
+
state.samplesObserved.getSlowNumberOfFrames();
|
|
275
275
|
}
|
|
276
276
|
emittedFields.slowNumberOfFrames = true;
|
|
277
277
|
}
|
|
@@ -279,10 +279,10 @@ const emitAvailableInfo = async ({ hasInfo, state, }) => {
|
|
|
279
279
|
}
|
|
280
280
|
if (key === 'slowAudioBitrate') {
|
|
281
281
|
if (!emittedFields.slowAudioBitrate && hasInfo.slowAudioBitrate) {
|
|
282
|
-
await ((_z = callbackFunctions.onSlowAudioBitrate) === null || _z === void 0 ? void 0 : _z.call(callbackFunctions, state.
|
|
282
|
+
await ((_z = callbackFunctions.onSlowAudioBitrate) === null || _z === void 0 ? void 0 : _z.call(callbackFunctions, state.samplesObserved.getAudioBitrate()));
|
|
283
283
|
if (fieldsInReturnValue.slowAudioBitrate) {
|
|
284
284
|
returnValue.slowAudioBitrate =
|
|
285
|
-
state.
|
|
285
|
+
state.samplesObserved.getAudioBitrate();
|
|
286
286
|
}
|
|
287
287
|
emittedFields.slowAudioBitrate = true;
|
|
288
288
|
}
|
|
@@ -290,10 +290,10 @@ const emitAvailableInfo = async ({ hasInfo, state, }) => {
|
|
|
290
290
|
}
|
|
291
291
|
if (key === 'slowVideoBitrate') {
|
|
292
292
|
if (!emittedFields.slowVideoBitrate && hasInfo.slowVideoBitrate) {
|
|
293
|
-
await ((_0 = callbackFunctions.onSlowVideoBitrate) === null || _0 === void 0 ? void 0 : _0.call(callbackFunctions, state.
|
|
293
|
+
await ((_0 = callbackFunctions.onSlowVideoBitrate) === null || _0 === void 0 ? void 0 : _0.call(callbackFunctions, state.samplesObserved.getVideoBitrate()));
|
|
294
294
|
if (fieldsInReturnValue.slowVideoBitrate) {
|
|
295
295
|
returnValue.slowVideoBitrate =
|
|
296
|
-
state.
|
|
296
|
+
state.samplesObserved.getVideoBitrate();
|
|
297
297
|
}
|
|
298
298
|
emittedFields.slowVideoBitrate = true;
|
|
299
299
|
}
|