@remotion/media-parser 4.0.201 → 4.0.204
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/av1-codec-string.d.ts +0 -5
- package/dist/av1-codec-string.js +1 -18
- package/dist/boxes/iso-base-media/ftype.d.ts +9 -0
- package/dist/boxes/iso-base-media/ftype.js +31 -0
- package/dist/boxes/iso-base-media/get-sample-positions-from-track.d.ts +4 -0
- package/dist/boxes/iso-base-media/get-sample-positions-from-track.js +48 -0
- package/dist/boxes/iso-base-media/mvhd.js +2 -2
- package/dist/boxes/iso-base-media/stsd/keys.js +1 -1
- package/dist/boxes/iso-base-media/tfdt.d.ts +12 -0
- package/dist/boxes/iso-base-media/tfdt.js +20 -0
- package/dist/boxes/iso-base-media/tfhd.d.ts +16 -0
- package/dist/boxes/iso-base-media/tfhd.js +41 -0
- package/dist/boxes/iso-base-media/trun.d.ts +21 -0
- package/dist/boxes/iso-base-media/trun.js +44 -0
- package/dist/boxes/webm/av1-codec-private.js +1 -1
- package/dist/boxes/webm/bitstream/av1.js +1 -10
- package/dist/boxes/webm/description.d.ts +2 -2
- package/dist/boxes/webm/description.js +2 -2
- package/dist/boxes/webm/ebml.d.ts +2 -2
- package/dist/boxes/webm/ebml.js +23 -1
- package/dist/boxes/webm/get-ready-tracks.d.ts +1 -1
- package/dist/boxes/webm/get-ready-tracks.js +3 -3
- package/dist/boxes/webm/get-sample-from-block.d.ts +17 -0
- package/dist/boxes/webm/get-sample-from-block.js +78 -0
- package/dist/boxes/webm/get-track.d.ts +2 -2
- package/dist/boxes/webm/get-track.js +26 -25
- package/dist/boxes/webm/make-header.d.ts +3 -8
- package/dist/boxes/webm/make-header.js +43 -20
- package/dist/boxes/webm/parse-ebml.d.ts +9 -4
- package/dist/boxes/webm/parse-ebml.js +122 -13
- package/dist/boxes/webm/segments/all-segments.d.ts +421 -107
- package/dist/boxes/webm/segments/all-segments.js +260 -33
- package/dist/boxes/webm/segments/track-entry.d.ts +3 -191
- package/dist/boxes/webm/segments/track-entry.js +2 -456
- package/dist/boxes/webm/segments.d.ts +3 -16
- package/dist/boxes/webm/segments.js +12 -196
- package/dist/boxes/webm/tracks.d.ts +8 -0
- package/dist/boxes/webm/tracks.js +21 -0
- package/dist/boxes/webm/traversal.d.ts +5 -6
- package/dist/boxes/webm/traversal.js +6 -6
- package/dist/buffer-iterator.d.ts +1 -1
- package/dist/buffer-iterator.js +3 -3
- package/dist/from-web.js +6 -15
- package/dist/get-audio-codec.d.ts +1 -1
- package/dist/get-audio-codec.js +13 -13
- package/dist/get-duration.js +12 -14
- package/dist/get-tracks.js +2 -2
- package/dist/get-video-codec.js +13 -13
- package/dist/get-video-metadata.d.ts +2 -0
- package/dist/get-video-metadata.js +44 -0
- package/dist/parse-media.js +4 -1
- package/dist/parser-context.d.ts +1 -0
- package/dist/parser-state.js +3 -2
- package/dist/read-and-increment-offset.d.ts +28 -0
- package/dist/read-and-increment-offset.js +177 -0
- package/dist/samples-from-moof.d.ts +6 -0
- package/dist/samples-from-moof.js +74 -0
- package/dist/traversal.d.ts +19 -17
- package/dist/traversal.js +38 -39
- package/dist/understand-vorbis.d.ts +1 -0
- package/dist/understand-vorbis.js +12 -0
- package/input.webm +0 -0
- package/package.json +2 -2
- package/src/boxes/iso-base-media/get-sample-positions-from-track.ts +69 -0
- package/src/boxes/iso-base-media/make-track.ts +4 -45
- package/src/boxes/iso-base-media/mdat/mdat.ts +33 -24
- package/src/boxes/iso-base-media/mdhd.ts +10 -7
- package/src/boxes/iso-base-media/mvhd.ts +17 -16
- package/src/boxes/iso-base-media/process-box.ts +42 -0
- package/src/boxes/iso-base-media/stsd/keys.ts +1 -1
- package/src/boxes/iso-base-media/tfdt.ts +37 -0
- package/src/boxes/iso-base-media/tfhd.ts +66 -0
- package/src/boxes/iso-base-media/tkhd.ts +11 -13
- package/src/boxes/iso-base-media/trun.ts +74 -0
- package/src/boxes/webm/av1-codec-private.ts +1 -1
- package/src/boxes/webm/description.ts +7 -4
- package/src/boxes/webm/ebml.ts +24 -4
- package/src/boxes/webm/get-ready-tracks.ts +4 -4
- package/src/boxes/webm/get-sample-from-block.ts +125 -0
- package/src/boxes/webm/get-track.ts +40 -33
- package/src/boxes/webm/make-header.ts +58 -51
- package/src/boxes/webm/parse-ebml.ts +170 -16
- package/src/boxes/webm/segments/all-segments.ts +379 -62
- package/src/boxes/webm/segments/track-entry.ts +3 -846
- package/src/boxes/webm/segments.ts +18 -410
- package/src/boxes/webm/traversal.ts +17 -17
- package/src/buffer-iterator.ts +8 -6
- package/src/get-audio-codec.ts +14 -16
- package/src/get-duration.ts +55 -21
- package/src/get-tracks.ts +6 -6
- package/src/get-video-codec.ts +13 -15
- package/src/has-all-info.ts +1 -1
- package/src/parse-media.ts +7 -2
- package/src/parse-result.ts +7 -1
- package/src/parser-context.ts +1 -0
- package/src/parser-state.ts +2 -2
- package/src/samples-from-moof.ts +101 -0
- package/src/test/create-matroska.test.ts +237 -23
- package/src/test/matroska.test.ts +283 -348
- package/src/test/mvhd.test.ts +1 -1
- package/src/test/parse-esds.test.ts +2 -2
- package/src/test/parse-stco.test.ts +2 -2
- package/src/test/parse-stsc.test.ts +2 -2
- package/src/test/parse-stsz.test.ts +2 -2
- package/src/test/parse-stts.test.ts +1 -1
- package/src/test/samples-from-moof.test.ts +2496 -0
- package/src/test/stream-local.test.ts +28 -30
- package/src/test/stream-samples.test.ts +153 -231
- package/src/test/stsd.test.ts +4 -2
- package/src/test/tkhd.test.ts +1 -1
- package/src/traversal.ts +118 -86
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/bitstream/av1.d.ts +0 -2
- package/dist/bitstream/av1.js +0 -12
- package/dist/boxes/iso-base-media/avcc-hvcc.d.ts +0 -20
- package/dist/boxes/iso-base-media/avcc-hvcc.js +0 -73
- package/dist/boxes/iso-base-media/avcc.d.ts +0 -18
- package/dist/boxes/iso-base-media/avcc.js +0 -27
- package/dist/boxes/iso-base-media/esds-descriptors.d.ts +0 -21
- package/dist/boxes/iso-base-media/esds-descriptors.js +0 -62
- package/dist/boxes/iso-base-media/esds.d.ts +0 -15
- package/dist/boxes/iso-base-media/esds.js +0 -27
- package/dist/from-input-type-file.d.ts +0 -2
- package/dist/from-input-type-file.js +0 -37
- package/dist/get-codec.d.ts +0 -4
- package/dist/get-codec.js +0 -22
- package/dist/web-file.d.ts +0 -2
- package/dist/web-file.js +0 -37
- package/src/boxes/webm/segments/duration.ts +0 -29
- package/src/boxes/webm/segments/info.ts +0 -34
- package/src/boxes/webm/segments/main.ts +0 -6
- package/src/boxes/webm/segments/muxing.ts +0 -18
- package/src/boxes/webm/segments/seek-head.ts +0 -34
- package/src/boxes/webm/segments/seek-position.ts +0 -18
- package/src/boxes/webm/segments/seek.ts +0 -55
- package/src/boxes/webm/segments/timestamp-scale.ts +0 -17
- package/src/boxes/webm/segments/tracks.ts +0 -32
- package/src/boxes/webm/segments/void.ts +0 -18
- package/src/boxes/webm/segments/writing.ts +0 -18
- package/src/combine-uint8array.ts +0 -13
- /package/dist/{get-samples.d.ts → boxes/webm/bitstream/av1/frame.d.ts} +0 -0
- /package/dist/{get-samples.js → boxes/webm/bitstream/av1/frame.js} +0 -0
- /package/dist/{sample-aspect-ratio.d.ts → boxes/webm/bitstream/h264/get-h264-descriptor.d.ts} +0 -0
- /package/dist/{sample-aspect-ratio.js → boxes/webm/bitstream/h264/get-h264-descriptor.js} +0 -0
|
@@ -6,12 +6,13 @@ const make_hvc1_codec_strings_1 = require("../../make-hvc1-codec-strings");
|
|
|
6
6
|
const traversal_1 = require("../../traversal");
|
|
7
7
|
const av1_codec_private_1 = require("./av1-codec-private");
|
|
8
8
|
const description_1 = require("./description");
|
|
9
|
+
const track_entry_1 = require("./segments/track-entry");
|
|
9
10
|
const getDescription = (track) => {
|
|
10
11
|
const codec = (0, traversal_1.getCodecSegment)(track);
|
|
11
12
|
if (!codec) {
|
|
12
13
|
return undefined;
|
|
13
14
|
}
|
|
14
|
-
if (codec.
|
|
15
|
+
if (codec.value === 'V_MPEG4/ISO/AVC' || codec.value === 'V_MPEGH/ISO/HEVC') {
|
|
15
16
|
const priv = (0, traversal_1.getPrivateData)(track);
|
|
16
17
|
if (priv) {
|
|
17
18
|
return priv;
|
|
@@ -20,49 +21,49 @@ const getDescription = (track) => {
|
|
|
20
21
|
return undefined;
|
|
21
22
|
};
|
|
22
23
|
const getMatroskaVideoCodecString = ({ track, codecSegment: codec, }) => {
|
|
23
|
-
if (codec.
|
|
24
|
+
if (codec.value === 'V_VP8') {
|
|
24
25
|
return 'vp8';
|
|
25
26
|
}
|
|
26
|
-
if (codec.
|
|
27
|
+
if (codec.value === 'V_VP9') {
|
|
27
28
|
const priv = (0, traversal_1.getPrivateData)(track);
|
|
28
29
|
if (priv) {
|
|
29
30
|
throw new Error('@remotion/media-parser cannot handle the private data for VP9. Do you have an example file you could send so we can implement it?');
|
|
30
31
|
}
|
|
31
32
|
return 'vp09.00.10.08';
|
|
32
33
|
}
|
|
33
|
-
if (codec.
|
|
34
|
+
if (codec.value === 'V_MPEG4/ISO/AVC') {
|
|
34
35
|
const priv = (0, traversal_1.getPrivateData)(track);
|
|
35
36
|
if (priv) {
|
|
36
37
|
return `avc1.${priv[1].toString(16).padStart(2, '0')}${priv[2].toString(16).padStart(2, '0')}${priv[3].toString(16).padStart(2, '0')}`;
|
|
37
38
|
}
|
|
38
39
|
throw new Error('Could not find a CodecPrivate field in TrackEntry');
|
|
39
40
|
}
|
|
40
|
-
if (codec.
|
|
41
|
+
if (codec.value === 'V_AV1') {
|
|
41
42
|
const priv = (0, traversal_1.getPrivateData)(track);
|
|
42
43
|
if (!priv) {
|
|
43
44
|
throw new Error('Expected private data in AV1 track');
|
|
44
45
|
}
|
|
45
46
|
return (0, av1_codec_private_1.parseAv1PrivateData)(priv, null);
|
|
46
47
|
}
|
|
47
|
-
if (codec.
|
|
48
|
+
if (codec.value === 'V_MPEGH/ISO/HEVC') {
|
|
48
49
|
const priv = (0, traversal_1.getPrivateData)(track);
|
|
49
|
-
const iterator = (0, buffer_iterator_1.getArrayBufferIterator)(priv);
|
|
50
|
+
const iterator = (0, buffer_iterator_1.getArrayBufferIterator)(priv, priv.length);
|
|
50
51
|
return 'hvc1.' + (0, make_hvc1_codec_strings_1.getHvc1CodecString)(iterator);
|
|
51
52
|
}
|
|
52
|
-
throw new Error(`Unknown codec: ${codec.
|
|
53
|
+
throw new Error(`Unknown codec: ${codec.value}`);
|
|
53
54
|
};
|
|
54
55
|
const getMatroskaAudioCodecString = (track) => {
|
|
55
56
|
const codec = (0, traversal_1.getCodecSegment)(track);
|
|
56
57
|
if (!codec) {
|
|
57
58
|
throw new Error('Expected codec segment');
|
|
58
59
|
}
|
|
59
|
-
if (codec.
|
|
60
|
+
if (codec.value === 'A_OPUS') {
|
|
60
61
|
return 'opus';
|
|
61
62
|
}
|
|
62
|
-
if (codec.
|
|
63
|
+
if (codec.value === 'A_VORBIS') {
|
|
63
64
|
return 'vorbis';
|
|
64
65
|
}
|
|
65
|
-
if (codec.
|
|
66
|
+
if (codec.value === 'A_PCM/INT/LIT') {
|
|
66
67
|
// https://github.com/ietf-wg-cellar/matroska-specification/issues/142#issuecomment-330004950
|
|
67
68
|
// Audio samples MUST be considered as signed values, except if the audio bit depth is 8 which MUST be interpreted as unsigned values.
|
|
68
69
|
const bitDepth = (0, traversal_1.getBitDepth)(track);
|
|
@@ -74,9 +75,9 @@ const getMatroskaAudioCodecString = (track) => {
|
|
|
74
75
|
}
|
|
75
76
|
return 'pcm-s' + bitDepth;
|
|
76
77
|
}
|
|
77
|
-
if (codec.
|
|
78
|
+
if (codec.value === 'A_AAC') {
|
|
78
79
|
const priv = (0, traversal_1.getPrivateData)(track);
|
|
79
|
-
const iterator = (0, buffer_iterator_1.getArrayBufferIterator)(priv);
|
|
80
|
+
const iterator = (0, buffer_iterator_1.getArrayBufferIterator)(priv, priv.length);
|
|
80
81
|
iterator.startReadingBits();
|
|
81
82
|
/**
|
|
82
83
|
* ChatGPT
|
|
@@ -104,10 +105,10 @@ const getMatroskaAudioCodecString = (track) => {
|
|
|
104
105
|
iterator.destroy();
|
|
105
106
|
return `mp4a.40.${profile.toString().padStart(2, '0')}`;
|
|
106
107
|
}
|
|
107
|
-
if (codec.
|
|
108
|
+
if (codec.value === 'A_MPEG/L3') {
|
|
108
109
|
return 'mp3';
|
|
109
110
|
}
|
|
110
|
-
throw new Error(`Unknown codec: ${codec.
|
|
111
|
+
throw new Error(`Unknown codec: ${codec.value}`);
|
|
111
112
|
};
|
|
112
113
|
const getTrack = ({ timescale, track, }) => {
|
|
113
114
|
const trackType = (0, traversal_1.getTrackTypeSegment)(track);
|
|
@@ -115,7 +116,7 @@ const getTrack = ({ timescale, track, }) => {
|
|
|
115
116
|
throw new Error('Expected track type segment');
|
|
116
117
|
}
|
|
117
118
|
const trackId = (0, traversal_1.getTrackId)(track);
|
|
118
|
-
if (trackType.
|
|
119
|
+
if ((0, track_entry_1.trackTypeToString)(trackType.value.value) === 'video') {
|
|
119
120
|
const width = (0, traversal_1.getWidthSegment)(track);
|
|
120
121
|
if (width === null) {
|
|
121
122
|
throw new Error('Expected width segment');
|
|
@@ -142,26 +143,26 @@ const getTrack = ({ timescale, track, }) => {
|
|
|
142
143
|
trackId,
|
|
143
144
|
codec: codecString,
|
|
144
145
|
description: getDescription(track),
|
|
145
|
-
height: displayHeight ? displayHeight.
|
|
146
|
-
width: displayWidth ? displayWidth.
|
|
146
|
+
height: displayHeight ? displayHeight.value.value : height.value.value,
|
|
147
|
+
width: displayWidth ? displayWidth.value.value : width.value.value,
|
|
147
148
|
sampleAspectRatio: {
|
|
148
149
|
numerator: 1,
|
|
149
150
|
denominator: 1,
|
|
150
151
|
},
|
|
151
152
|
timescale,
|
|
152
153
|
samplePositions: [],
|
|
153
|
-
codedHeight: height.
|
|
154
|
-
codedWidth: width.
|
|
154
|
+
codedHeight: height.value.value,
|
|
155
|
+
codedWidth: width.value.value,
|
|
155
156
|
displayAspectHeight: displayHeight
|
|
156
|
-
? displayHeight.
|
|
157
|
-
: height.
|
|
157
|
+
? displayHeight.value.value
|
|
158
|
+
: height.value.value,
|
|
158
159
|
displayAspectWidth: displayWidth
|
|
159
|
-
? displayWidth.
|
|
160
|
-
: width.
|
|
160
|
+
? displayWidth.value.value
|
|
161
|
+
: width.value.value,
|
|
161
162
|
rotation: 0,
|
|
162
163
|
};
|
|
163
164
|
}
|
|
164
|
-
if (trackType.
|
|
165
|
+
if ((0, track_entry_1.trackTypeToString)(trackType.value.value) === 'audio') {
|
|
165
166
|
const sampleRate = (0, traversal_1.getSampleRate)(track);
|
|
166
167
|
const numberOfChannels = (0, traversal_1.getNumberOfChannels)(track);
|
|
167
168
|
if (sampleRate === null) {
|
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { PossibleEbmlOrUint8Array } from './segments/all-segments';
|
|
2
2
|
export declare const webmPattern: Uint8Array;
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
[key in keyof Struct & Numbers as Struct[key]['name']]: EmblTypes[Struct[key]['type']];
|
|
6
|
-
};
|
|
7
|
-
type SerializeValue<Struct extends Ebml> = Struct extends EbmlWithChildren ? ChildFields<Struct['children']> : Struct extends EbmlWithString ? string : Struct extends EbmlWithUint8 ? number : Struct extends EbmlWithHexString ? string : undefined;
|
|
8
|
-
export declare const makeMatroskaHeader: <Struct extends Ebml>(struct: Struct, fields: SerializeValue<Struct>) => Uint8Array;
|
|
9
|
-
export {};
|
|
3
|
+
export declare const makeMatroskaBytes: (fields: PossibleEbmlOrUint8Array) => Uint8Array;
|
|
4
|
+
export declare const combineUint8Arrays: (arrays: Uint8Array[]) => Uint8Array;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.combineUint8Arrays = exports.makeMatroskaBytes = exports.webmPattern = void 0;
|
|
4
4
|
const ebml_1 = require("./ebml");
|
|
5
5
|
const all_segments_1 = require("./segments/all-segments");
|
|
6
6
|
exports.webmPattern = new Uint8Array([0x1a, 0x45, 0xdf, 0xa3]);
|
|
@@ -12,12 +12,12 @@ const matroskaToHex = (matrId) => {
|
|
|
12
12
|
}
|
|
13
13
|
return numbers;
|
|
14
14
|
};
|
|
15
|
-
function putUintDynamic(number) {
|
|
15
|
+
function putUintDynamic(number, minimumLength) {
|
|
16
16
|
if (number < 0) {
|
|
17
17
|
throw new Error('This function is designed for non-negative integers only.');
|
|
18
18
|
}
|
|
19
19
|
// Calculate the minimum number of bytes needed to store the integer
|
|
20
|
-
const length = Math.ceil(Math.log2(number + 1) / 8);
|
|
20
|
+
const length = Math.max(minimumLength !== null && minimumLength !== void 0 ? minimumLength : 0, Math.ceil(Math.log2(number + 1) / 8));
|
|
21
21
|
const bytes = new Uint8Array(length);
|
|
22
22
|
for (let i = 0; i < length; i++) {
|
|
23
23
|
// Extract each byte from the number
|
|
@@ -25,24 +25,29 @@ function putUintDynamic(number) {
|
|
|
25
25
|
}
|
|
26
26
|
return bytes;
|
|
27
27
|
}
|
|
28
|
-
const makeFromHeaderStructure = (
|
|
28
|
+
const makeFromHeaderStructure = (fields) => {
|
|
29
|
+
if (fields instanceof Uint8Array) {
|
|
30
|
+
return fields;
|
|
31
|
+
}
|
|
29
32
|
const arrays = [];
|
|
33
|
+
const struct = all_segments_1.ebmlMap[(0, all_segments_1.getIdForName)(fields.type)];
|
|
34
|
+
if (struct.type === 'uint8array') {
|
|
35
|
+
return fields.value;
|
|
36
|
+
}
|
|
30
37
|
if (struct.type === 'children') {
|
|
31
|
-
for (const item of
|
|
32
|
-
arrays.push((0, exports.
|
|
33
|
-
// @ts-expect-error
|
|
34
|
-
fields[item.name]));
|
|
38
|
+
for (const item of fields.value) {
|
|
39
|
+
arrays.push((0, exports.makeMatroskaBytes)(item));
|
|
35
40
|
}
|
|
36
|
-
return combineUint8Arrays(arrays);
|
|
41
|
+
return (0, exports.combineUint8Arrays)(arrays);
|
|
37
42
|
}
|
|
38
43
|
if (struct.type === 'string') {
|
|
39
|
-
return new TextEncoder().encode(fields);
|
|
44
|
+
return new TextEncoder().encode(fields.value);
|
|
40
45
|
}
|
|
41
46
|
if (struct.type === 'uint') {
|
|
42
|
-
return putUintDynamic(fields);
|
|
47
|
+
return putUintDynamic(fields.value.value, fields.value.byteLength);
|
|
43
48
|
}
|
|
44
49
|
if (struct.type === 'hex-string') {
|
|
45
|
-
const hex = fields.substring(2);
|
|
50
|
+
const hex = fields.value.substring(2);
|
|
46
51
|
const arr = new Uint8Array(hex.length / 2);
|
|
47
52
|
for (let i = 0; i < hex.length; i += 2) {
|
|
48
53
|
const byte = parseInt(hex.substring(i, i + 2), 16);
|
|
@@ -50,21 +55,38 @@ const makeFromHeaderStructure = (struct, fields) => {
|
|
|
50
55
|
}
|
|
51
56
|
return arr;
|
|
52
57
|
}
|
|
53
|
-
if (struct.type === '
|
|
54
|
-
|
|
58
|
+
if (struct.type === 'float') {
|
|
59
|
+
const value = fields.value;
|
|
60
|
+
if (value.size === '32') {
|
|
61
|
+
const dataView = new DataView(new ArrayBuffer(4));
|
|
62
|
+
dataView.setFloat32(0, value.value);
|
|
63
|
+
return new Uint8Array(dataView.buffer);
|
|
64
|
+
}
|
|
65
|
+
const dataView2 = new DataView(new ArrayBuffer(8));
|
|
66
|
+
dataView2.setFloat64(0, value.value);
|
|
67
|
+
return new Uint8Array(dataView2.buffer);
|
|
55
68
|
}
|
|
56
69
|
throw new Error('Unexpected type');
|
|
57
70
|
};
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
71
|
+
const makeMatroskaBytes = (fields) => {
|
|
72
|
+
if (fields instanceof Uint8Array) {
|
|
73
|
+
return fields;
|
|
74
|
+
}
|
|
75
|
+
const value = makeFromHeaderStructure(fields);
|
|
76
|
+
return (0, exports.combineUint8Arrays)([
|
|
77
|
+
matroskaToHex((0, all_segments_1.getIdForName)(fields.type)),
|
|
78
|
+
(0, ebml_1.getVariableInt)(value.length, fields.minVintWidth),
|
|
63
79
|
value,
|
|
64
80
|
]);
|
|
65
81
|
};
|
|
66
|
-
exports.
|
|
82
|
+
exports.makeMatroskaBytes = makeMatroskaBytes;
|
|
67
83
|
const combineUint8Arrays = (arrays) => {
|
|
84
|
+
if (arrays.length === 0) {
|
|
85
|
+
return new Uint8Array([]);
|
|
86
|
+
}
|
|
87
|
+
if (arrays.length === 1) {
|
|
88
|
+
return arrays[0];
|
|
89
|
+
}
|
|
68
90
|
let totalLength = 0;
|
|
69
91
|
for (const array of arrays) {
|
|
70
92
|
totalLength += array.length;
|
|
@@ -77,3 +99,4 @@ const combineUint8Arrays = (arrays) => {
|
|
|
77
99
|
}
|
|
78
100
|
return result;
|
|
79
101
|
};
|
|
102
|
+
exports.combineUint8Arrays = combineUint8Arrays;
|
|
@@ -1,7 +1,12 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type BufferIterator } from '../../buffer-iterator';
|
|
2
|
+
import type { ParserContext } from '../../parser-context';
|
|
2
3
|
import type { PossibleEbml } from './segments/all-segments';
|
|
3
|
-
type Prettify<T> = {
|
|
4
|
+
export type Prettify<T> = {
|
|
4
5
|
[K in keyof T]: T[K];
|
|
5
6
|
} & {};
|
|
6
|
-
export declare const parseEbml: (iterator: BufferIterator) => Prettify<PossibleEbml
|
|
7
|
-
export {}
|
|
7
|
+
export declare const parseEbml: (iterator: BufferIterator, parserContext: ParserContext) => Promise<Prettify<PossibleEbml>>;
|
|
8
|
+
export declare const postprocessEbml: ({ offset, ebml, parserContext, }: {
|
|
9
|
+
offset: number;
|
|
10
|
+
ebml: Prettify<PossibleEbml>;
|
|
11
|
+
parserContext: ParserContext;
|
|
12
|
+
}) => Promise<Prettify<PossibleEbml>>;
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.parseEbml = void 0;
|
|
3
|
+
exports.postprocessEbml = exports.parseEbml = void 0;
|
|
4
|
+
const add_new_matroska_tracks_1 = require("../../add-new-matroska-tracks");
|
|
5
|
+
const get_sample_from_block_1 = require("./get-sample-from-block");
|
|
6
|
+
const get_track_1 = require("./get-track");
|
|
4
7
|
const all_segments_1 = require("./segments/all-segments");
|
|
5
|
-
const parseEbml = (iterator) => {
|
|
8
|
+
const parseEbml = async (iterator, parserContext) => {
|
|
6
9
|
const hex = iterator.getMatroskaSegmentId();
|
|
7
10
|
if (hex === null) {
|
|
8
11
|
throw new Error('Not enough bytes left to parse EBML - this should not happen');
|
|
@@ -11,36 +14,58 @@ const parseEbml = (iterator) => {
|
|
|
11
14
|
if (!hasInMap) {
|
|
12
15
|
throw new Error(`Don't know how to parse EBML hex ID ${JSON.stringify(hex)}`);
|
|
13
16
|
}
|
|
17
|
+
const off = iterator.counter.getOffset();
|
|
14
18
|
const size = iterator.getVint();
|
|
19
|
+
const minVintWidth = iterator.counter.getOffset() - off;
|
|
15
20
|
if (size === null) {
|
|
16
21
|
throw new Error('Not enough bytes left to parse EBML - this should not happen');
|
|
17
22
|
}
|
|
18
23
|
if (hasInMap.type === 'uint') {
|
|
24
|
+
const beforeUintOffset = iterator.counter.getOffset();
|
|
19
25
|
const value = iterator.getUint(size);
|
|
20
|
-
return {
|
|
26
|
+
return {
|
|
27
|
+
type: hasInMap.name,
|
|
28
|
+
value: {
|
|
29
|
+
value,
|
|
30
|
+
byteLength: iterator.counter.getOffset() - beforeUintOffset,
|
|
31
|
+
},
|
|
32
|
+
minVintWidth,
|
|
33
|
+
};
|
|
21
34
|
}
|
|
22
35
|
if (hasInMap.type === 'string') {
|
|
23
36
|
const value = iterator.getByteString(size);
|
|
24
37
|
return {
|
|
25
38
|
type: hasInMap.name,
|
|
26
39
|
value,
|
|
27
|
-
|
|
40
|
+
minVintWidth,
|
|
28
41
|
};
|
|
29
42
|
}
|
|
30
43
|
if (hasInMap.type === 'float') {
|
|
31
44
|
const value = size === 4 ? iterator.getFloat32() : iterator.getFloat64();
|
|
32
45
|
return {
|
|
33
46
|
type: hasInMap.name,
|
|
34
|
-
value
|
|
35
|
-
|
|
47
|
+
value: {
|
|
48
|
+
value,
|
|
49
|
+
size: size === 4 ? '32' : '64',
|
|
50
|
+
},
|
|
51
|
+
minVintWidth,
|
|
36
52
|
};
|
|
37
53
|
}
|
|
38
|
-
if (hasInMap.type === '
|
|
39
|
-
iterator.discard(size);
|
|
54
|
+
if (hasInMap.type === 'hex-string') {
|
|
40
55
|
return {
|
|
41
56
|
type: hasInMap.name,
|
|
42
|
-
value:
|
|
43
|
-
|
|
57
|
+
value: '0x' +
|
|
58
|
+
[...iterator.getSlice(size)]
|
|
59
|
+
.map((b) => b.toString(16).padStart(2, '0'))
|
|
60
|
+
.join(''),
|
|
61
|
+
minVintWidth,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
if (hasInMap.type === 'uint8array') {
|
|
65
|
+
return {
|
|
66
|
+
type: hasInMap.name,
|
|
67
|
+
value: iterator.getSlice(size),
|
|
68
|
+
minVintWidth,
|
|
44
69
|
};
|
|
45
70
|
}
|
|
46
71
|
if (hasInMap.type === 'children') {
|
|
@@ -48,8 +73,14 @@ const parseEbml = (iterator) => {
|
|
|
48
73
|
const startOffset = iterator.counter.getOffset();
|
|
49
74
|
// eslint-disable-next-line no-constant-condition
|
|
50
75
|
while (true) {
|
|
51
|
-
const
|
|
52
|
-
|
|
76
|
+
const offset = iterator.counter.getOffset();
|
|
77
|
+
const value = await (0, exports.parseEbml)(iterator, parserContext);
|
|
78
|
+
const remapped = await (0, exports.postprocessEbml)({
|
|
79
|
+
offset,
|
|
80
|
+
ebml: value,
|
|
81
|
+
parserContext,
|
|
82
|
+
});
|
|
83
|
+
children.push(remapped);
|
|
53
84
|
const offsetNow = iterator.counter.getOffset();
|
|
54
85
|
if (offsetNow - startOffset > size) {
|
|
55
86
|
throw new Error(`Offset ${offsetNow - startOffset} is larger than the length of the hex ${size}`);
|
|
@@ -58,9 +89,87 @@ const parseEbml = (iterator) => {
|
|
|
58
89
|
break;
|
|
59
90
|
}
|
|
60
91
|
}
|
|
61
|
-
return { type: hasInMap.name, value: children,
|
|
92
|
+
return { type: hasInMap.name, value: children, minVintWidth };
|
|
62
93
|
}
|
|
63
94
|
// @ts-expect-error
|
|
64
95
|
throw new Error(`Unknown segment type ${hasInMap.type}`);
|
|
65
96
|
};
|
|
66
97
|
exports.parseEbml = parseEbml;
|
|
98
|
+
const postprocessEbml = async ({ offset, ebml, parserContext, }) => {
|
|
99
|
+
if (ebml.type === 'TimestampScale') {
|
|
100
|
+
parserContext.parserState.setTimescale(ebml.value.value);
|
|
101
|
+
}
|
|
102
|
+
if (ebml.type === 'TrackEntry') {
|
|
103
|
+
parserContext.parserState.onTrackEntrySegment(ebml);
|
|
104
|
+
const track = (0, get_track_1.getTrack)({
|
|
105
|
+
track: ebml,
|
|
106
|
+
timescale: parserContext.parserState.getTimescale(),
|
|
107
|
+
});
|
|
108
|
+
if (track) {
|
|
109
|
+
await (0, add_new_matroska_tracks_1.registerTrack)({
|
|
110
|
+
state: parserContext.parserState,
|
|
111
|
+
options: parserContext,
|
|
112
|
+
track,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
if (ebml.type === 'Timestamp') {
|
|
117
|
+
parserContext.parserState.setTimestampOffset(offset, ebml.value.value);
|
|
118
|
+
}
|
|
119
|
+
if (ebml.type === 'Block' || ebml.type === 'SimpleBlock') {
|
|
120
|
+
const sample = (0, get_sample_from_block_1.getSampleFromBlock)(ebml, parserContext, offset);
|
|
121
|
+
if (sample.type === 'video-sample' && parserContext.nullifySamples) {
|
|
122
|
+
await parserContext.parserState.onVideoSample(sample.videoSample.trackId, sample.videoSample);
|
|
123
|
+
return {
|
|
124
|
+
type: 'Block',
|
|
125
|
+
value: new Uint8Array([]),
|
|
126
|
+
minVintWidth: ebml.minVintWidth,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
if (sample.type === 'audio-sample' && parserContext.nullifySamples) {
|
|
130
|
+
await parserContext.parserState.onAudioSample(sample.audioSample.trackId, sample.audioSample);
|
|
131
|
+
return {
|
|
132
|
+
type: 'Block',
|
|
133
|
+
value: new Uint8Array([]),
|
|
134
|
+
minVintWidth: ebml.minVintWidth,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
if (sample.type === 'no-sample' && parserContext.nullifySamples) {
|
|
138
|
+
return {
|
|
139
|
+
type: 'Block',
|
|
140
|
+
value: new Uint8Array([]),
|
|
141
|
+
minVintWidth: ebml.minVintWidth,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
if (ebml.type === 'BlockGroup') {
|
|
146
|
+
// Blocks don't have information about keyframes.
|
|
147
|
+
// https://ffmpeg.org/pipermail/ffmpeg-devel/2015-June/173825.html
|
|
148
|
+
// "For Blocks, keyframes is
|
|
149
|
+
// inferred by the absence of ReferenceBlock element (as done by matroskadec).""
|
|
150
|
+
const block = ebml.value.find((c) => c.type === 'SimpleBlock' || c.type === 'Block');
|
|
151
|
+
if (!block || (block.type !== 'SimpleBlock' && block.type !== 'Block')) {
|
|
152
|
+
throw new Error('Expected block segment');
|
|
153
|
+
}
|
|
154
|
+
const hasReferenceBlock = ebml.value.find((c) => c.type === 'ReferenceBlock');
|
|
155
|
+
const sample = block.value.length === 0
|
|
156
|
+
? null
|
|
157
|
+
: (0, get_sample_from_block_1.getSampleFromBlock)(block, parserContext, offset);
|
|
158
|
+
if (sample && sample.type === 'partial-video-sample') {
|
|
159
|
+
const completeFrame = {
|
|
160
|
+
...sample.partialVideoSample,
|
|
161
|
+
type: hasReferenceBlock ? 'delta' : 'key',
|
|
162
|
+
};
|
|
163
|
+
await parserContext.parserState.onVideoSample(sample.partialVideoSample.trackId, completeFrame);
|
|
164
|
+
}
|
|
165
|
+
if (parserContext.nullifySamples) {
|
|
166
|
+
return {
|
|
167
|
+
type: 'BlockGroup',
|
|
168
|
+
value: [],
|
|
169
|
+
minVintWidth: ebml.minVintWidth,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return ebml;
|
|
174
|
+
};
|
|
175
|
+
exports.postprocessEbml = postprocessEbml;
|