@remotion/media-parser 4.0.247 → 4.0.249
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/boxes/avc/key.d.ts +1 -1
- package/dist/boxes/iso-base-media/get-children.d.ts +14 -0
- package/dist/boxes/iso-base-media/get-children.js +39 -0
- package/dist/boxes/iso-base-media/mdat/mdat.d.ts +2 -1
- package/dist/boxes/iso-base-media/mdat/mdat.js +10 -1
- package/dist/boxes/iso-base-media/moov/moov.js +2 -3
- package/dist/boxes/iso-base-media/parse-boxes.d.ts +15 -0
- package/dist/boxes/iso-base-media/parse-boxes.js +129 -0
- package/dist/boxes/iso-base-media/parse-mdat-partially.d.ts +12 -0
- package/dist/boxes/iso-base-media/parse-mdat-partially.js +33 -0
- package/dist/boxes/iso-base-media/process-box.d.ts +2 -21
- package/dist/boxes/iso-base-media/process-box.js +53 -270
- package/dist/boxes/iso-base-media/stsd/mebx.js +2 -3
- package/dist/boxes/iso-base-media/stsd/samples.js +5 -9
- package/dist/boxes/iso-base-media/trak/trak.js +2 -3
- package/dist/boxes/mp3/get-duration.d.ts +2 -0
- package/dist/boxes/mp3/get-duration.js +30 -0
- package/dist/boxes/mp3/get-frame-length.d.ts +13 -0
- package/dist/boxes/mp3/get-frame-length.js +33 -0
- package/dist/boxes/mp3/get-metadata-from-mp3.d.ts +3 -0
- package/dist/boxes/mp3/get-metadata-from-mp3.js +8 -0
- package/dist/boxes/mp3/get-tracks-from-mp3.d.ts +4 -0
- package/dist/boxes/mp3/get-tracks-from-mp3.js +25 -0
- package/dist/boxes/mp3/id3-v1.d.ts +2 -0
- package/dist/boxes/mp3/id3-v1.js +12 -0
- package/dist/boxes/mp3/id3-v2.d.ts +0 -0
- package/dist/boxes/mp3/id3-v2.js +1 -0
- package/dist/boxes/mp3/id3.d.ts +8 -0
- package/dist/boxes/mp3/id3.js +78 -0
- package/dist/boxes/mp3/parse-mp3.d.ts +8 -0
- package/dist/boxes/mp3/parse-mp3.js +57 -0
- package/dist/boxes/mp3/parse-mpeg-header.d.ts +6 -0
- package/dist/boxes/mp3/parse-mpeg-header.js +274 -0
- package/dist/boxes/mp3/samples-per-mpeg-file.d.ts +4 -0
- package/dist/boxes/mp3/samples-per-mpeg-file.js +26 -0
- package/dist/boxes/riff/continue-after-riff-result.d.ts +13 -0
- package/dist/boxes/riff/continue-after-riff-result.js +34 -0
- package/dist/boxes/riff/expect-riff-box.d.ts +3 -1
- package/dist/boxes/riff/expect-riff-box.js +4 -3
- package/dist/boxes/riff/parse-box.d.ts +1 -7
- package/dist/boxes/riff/parse-box.js +4 -120
- package/dist/boxes/riff/parse-list-box.d.ts +3 -1
- package/dist/boxes/riff/parse-list-box.js +4 -3
- package/dist/boxes/riff/parse-riff-body.d.ts +11 -0
- package/dist/boxes/riff/parse-riff-body.js +105 -0
- package/dist/boxes/riff/parse-riff-box.d.ts +3 -1
- package/dist/boxes/riff/parse-riff-box.js +2 -2
- package/dist/boxes/transport-stream/parse-transport-stream.js +30 -41
- package/dist/buffer-iterator.d.ts +6 -0
- package/dist/buffer-iterator.js +21 -0
- package/dist/continue-mdat-routine.d.ts +17 -0
- package/dist/continue-mdat-routine.js +92 -0
- package/dist/emit-available-info.js +38 -24
- package/dist/esm/index.mjs +1820 -1046
- package/dist/file-types/detect-file-type.js +4 -2
- package/dist/get-audio-codec.js +1 -1
- package/dist/get-container.js +5 -1
- package/dist/get-dimensions.d.ts +1 -1
- package/dist/get-dimensions.js +3 -0
- package/dist/get-duration.js +5 -1
- package/dist/get-fields-from-callbacks.js +1 -0
- package/dist/get-fps.js +3 -0
- package/dist/get-is-hdr.js +1 -1
- package/dist/get-keyframes.js +1 -1
- package/dist/get-tracks.d.ts +1 -1
- package/dist/get-tracks.js +10 -3
- package/dist/get-video-codec.js +1 -1
- package/dist/has-all-info.js +4 -3
- package/dist/index.d.ts +20 -2
- package/dist/may-skip-video-data/need-samples-for-fields.js +1 -0
- package/dist/metadata/get-metadata.d.ts +1 -0
- package/dist/metadata/get-metadata.js +16 -1
- package/dist/options.d.ts +12 -5
- package/dist/parse-media.js +48 -43
- package/dist/parse-result.d.ts +16 -1
- package/dist/parse-video.js +9 -10
- package/dist/state/can-skip-tracks.js +1 -0
- package/dist/state/emitted-fields.js +1 -0
- package/dist/state/images.d.ts +9 -0
- package/dist/state/images.js +14 -0
- package/dist/state/mp3.d.ts +11 -0
- package/dist/state/mp3.js +13 -0
- package/dist/state/parser-state.d.ts +13 -2
- package/dist/state/parser-state.js +8 -1
- package/dist/state/sample-callbacks.js +4 -1
- package/dist/state/slow-duration-fps.d.ts +2 -1
- package/dist/state/slow-duration-fps.js +52 -18
- package/dist/throttled-progress.d.ts +14 -0
- package/dist/throttled-progress.js +44 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseId3 = void 0;
|
|
4
|
+
function combine28Bits(a, b, c, d) {
|
|
5
|
+
// Mask each number to ignore first bit (& 0x7F)
|
|
6
|
+
const val1 = a & 0x7f; // 7 bits from first byte
|
|
7
|
+
const val2 = b & 0x7f; // 7 bits from second byte
|
|
8
|
+
const val3 = c & 0x7f; // 7 bits from third byte
|
|
9
|
+
const val4 = d & 0x7f; // 7 bits from fourth byte
|
|
10
|
+
// Combine all values using bitwise operations
|
|
11
|
+
return (val1 << 21) | (val2 << 14) | (val3 << 7) | val4;
|
|
12
|
+
}
|
|
13
|
+
const parseId3 = ({ iterator, structure, state, }) => {
|
|
14
|
+
if (iterator.bytesRemaining() < 9) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
const { returnToCheckpoint } = iterator.startCheckpoint();
|
|
18
|
+
iterator.discard(3);
|
|
19
|
+
const versionMajor = iterator.getUint8();
|
|
20
|
+
const versionMinor = iterator.getUint8();
|
|
21
|
+
const flags = iterator.getUint8();
|
|
22
|
+
const sizeArr = iterator.getSlice(4);
|
|
23
|
+
const size = combine28Bits(sizeArr[0], sizeArr[1], sizeArr[2], sizeArr[3]);
|
|
24
|
+
if (iterator.bytesRemaining() < size) {
|
|
25
|
+
returnToCheckpoint();
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const entries = [];
|
|
29
|
+
const initial = iterator.counter.getOffset();
|
|
30
|
+
while (iterator.counter.getOffset() < size + initial) {
|
|
31
|
+
const name = versionMajor === 3
|
|
32
|
+
? iterator.getByteString(4, true)
|
|
33
|
+
: iterator.getByteString(3, true);
|
|
34
|
+
if (name === '') {
|
|
35
|
+
iterator.discard(size + initial - iterator.counter.getOffset());
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
38
|
+
const s = versionMajor === 3 ? iterator.getUint32() : iterator.getUint24();
|
|
39
|
+
if (versionMajor === 3) {
|
|
40
|
+
iterator.getUint16(); // flags
|
|
41
|
+
}
|
|
42
|
+
let subtract = 0;
|
|
43
|
+
if (!name.startsWith('W')) {
|
|
44
|
+
iterator.getUint8(); // encoding
|
|
45
|
+
subtract += 1;
|
|
46
|
+
}
|
|
47
|
+
if (name === 'APIC') {
|
|
48
|
+
const { discardRest } = iterator.planBytes(s - subtract);
|
|
49
|
+
const mimeType = iterator.readUntilNullTerminator();
|
|
50
|
+
iterator.getUint16(); // picture type
|
|
51
|
+
const description = iterator.readUntilNullTerminator();
|
|
52
|
+
iterator.discard(1);
|
|
53
|
+
const data = discardRest();
|
|
54
|
+
state.images.addImage({
|
|
55
|
+
data,
|
|
56
|
+
description,
|
|
57
|
+
mimeType,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
const information = iterator.getByteString(s - subtract, true);
|
|
62
|
+
entries.push({
|
|
63
|
+
key: name,
|
|
64
|
+
value: information,
|
|
65
|
+
trackId: null,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
structure.boxes.push({
|
|
70
|
+
type: 'id3-header',
|
|
71
|
+
flags,
|
|
72
|
+
size,
|
|
73
|
+
versionMajor,
|
|
74
|
+
versionMinor,
|
|
75
|
+
metatags: entries,
|
|
76
|
+
});
|
|
77
|
+
};
|
|
78
|
+
exports.parseId3 = parseId3;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { BufferIterator } from '../../buffer-iterator';
|
|
2
|
+
import type { Mp3Structure, ParseResult } from '../../parse-result';
|
|
3
|
+
import type { ParserState } from '../../state/parser-state';
|
|
4
|
+
export declare const parseMp3: ({ iterator, structure, state, }: {
|
|
5
|
+
iterator: BufferIterator;
|
|
6
|
+
structure: Mp3Structure;
|
|
7
|
+
state: ParserState;
|
|
8
|
+
}) => Promise<ParseResult>;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseMp3 = void 0;
|
|
4
|
+
const id3_1 = require("./id3");
|
|
5
|
+
const id3_v1_1 = require("./id3-v1");
|
|
6
|
+
const parse_mpeg_header_1 = require("./parse-mpeg-header");
|
|
7
|
+
const parseMp3 = async ({ iterator, structure, state, }) => {
|
|
8
|
+
const continueParsing = () => {
|
|
9
|
+
return (0, exports.parseMp3)({ iterator, structure, state });
|
|
10
|
+
};
|
|
11
|
+
if (iterator.bytesRemaining() === 0) {
|
|
12
|
+
return Promise.resolve({
|
|
13
|
+
status: 'done',
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
if (iterator.bytesRemaining() < 3) {
|
|
17
|
+
return {
|
|
18
|
+
status: 'incomplete',
|
|
19
|
+
skipTo: null,
|
|
20
|
+
continueParsing,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
const { returnToCheckpoint } = iterator.startCheckpoint();
|
|
24
|
+
const bytes = iterator.getSlice(3);
|
|
25
|
+
returnToCheckpoint();
|
|
26
|
+
// ID3 v1
|
|
27
|
+
if (bytes[0] === 0x54 && bytes[1] === 0x41 && bytes[2] === 0x47) {
|
|
28
|
+
(0, id3_v1_1.parseID3V1)(iterator);
|
|
29
|
+
return {
|
|
30
|
+
status: 'incomplete',
|
|
31
|
+
continueParsing,
|
|
32
|
+
skipTo: null,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
// ID3 v2 or v3
|
|
36
|
+
if (bytes[0] === 0x49 && bytes[1] === 0x44 && bytes[2] === 0x33) {
|
|
37
|
+
(0, id3_1.parseId3)({ iterator, structure, state });
|
|
38
|
+
return {
|
|
39
|
+
status: 'incomplete',
|
|
40
|
+
continueParsing,
|
|
41
|
+
skipTo: null,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
if (bytes[0] === 0xff) {
|
|
45
|
+
await (0, parse_mpeg_header_1.parseMpegHeader)({
|
|
46
|
+
iterator,
|
|
47
|
+
state,
|
|
48
|
+
});
|
|
49
|
+
return {
|
|
50
|
+
status: 'incomplete',
|
|
51
|
+
continueParsing,
|
|
52
|
+
skipTo: null,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
throw new Error('Unknown MP3 header ');
|
|
56
|
+
};
|
|
57
|
+
exports.parseMp3 = parseMp3;
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// spec: http://www.mp3-tech.org/programmer/frame_header.html
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.parseMpegHeader = void 0;
|
|
5
|
+
const register_track_1 = require("../../register-track");
|
|
6
|
+
const get_frame_length_1 = require("./get-frame-length");
|
|
7
|
+
const samples_per_mpeg_file_1 = require("./samples-per-mpeg-file");
|
|
8
|
+
function getSamplingFrequency({ bits, mpegVersion, }) {
|
|
9
|
+
const samplingTable = {
|
|
10
|
+
0b00: { MPEG1: 44100, MPEG2: 22050 },
|
|
11
|
+
0b01: { MPEG1: 48000, MPEG2: 24000 },
|
|
12
|
+
0b10: { MPEG1: 32000, MPEG2: 16000 },
|
|
13
|
+
0b11: { MPEG1: 'reserved', MPEG2: 'reserved' },
|
|
14
|
+
};
|
|
15
|
+
const key = `MPEG${mpegVersion}`;
|
|
16
|
+
const value = samplingTable[bits][key];
|
|
17
|
+
if (value === 'reserved') {
|
|
18
|
+
throw new Error('Reserved sampling frequency');
|
|
19
|
+
}
|
|
20
|
+
if (!value) {
|
|
21
|
+
throw new Error('Invalid sampling frequency for MPEG version: ' +
|
|
22
|
+
JSON.stringify({ bits, version: mpegVersion }));
|
|
23
|
+
}
|
|
24
|
+
return value;
|
|
25
|
+
}
|
|
26
|
+
function getBitrateKB({ bits, mpegVersion, level, }) {
|
|
27
|
+
const bitrateTable = {
|
|
28
|
+
0b0000: {
|
|
29
|
+
'V1,L1': 'free',
|
|
30
|
+
'V1,L2': 'free',
|
|
31
|
+
'V1,L3': 'free',
|
|
32
|
+
'V2,L1': 'free',
|
|
33
|
+
'V2,L2&L3': 'free',
|
|
34
|
+
},
|
|
35
|
+
0b0001: { 'V1,L1': 32, 'V1,L2': 32, 'V1,L3': 32, 'V2,L1': 32, 'V2,L2&L3': 8 },
|
|
36
|
+
0b0010: {
|
|
37
|
+
'V1,L1': 64,
|
|
38
|
+
'V1,L2': 48,
|
|
39
|
+
'V1,L3': 40,
|
|
40
|
+
'V2,L1': 48,
|
|
41
|
+
'V2,L2&L3': 16,
|
|
42
|
+
},
|
|
43
|
+
0b0011: {
|
|
44
|
+
'V1,L1': 96,
|
|
45
|
+
'V1,L2': 56,
|
|
46
|
+
'V1,L3': 48,
|
|
47
|
+
'V2,L1': 56,
|
|
48
|
+
'V2,L2&L3': 24,
|
|
49
|
+
},
|
|
50
|
+
0b0100: {
|
|
51
|
+
'V1,L1': 128,
|
|
52
|
+
'V1,L2': 64,
|
|
53
|
+
'V1,L3': 56,
|
|
54
|
+
'V2,L1': 64,
|
|
55
|
+
'V2,L2&L3': 32,
|
|
56
|
+
},
|
|
57
|
+
0b0101: {
|
|
58
|
+
'V1,L1': 160,
|
|
59
|
+
'V1,L2': 80,
|
|
60
|
+
'V1,L3': 64,
|
|
61
|
+
'V2,L1': 80,
|
|
62
|
+
'V2,L2&L3': 40,
|
|
63
|
+
},
|
|
64
|
+
0b0110: {
|
|
65
|
+
'V1,L1': 192,
|
|
66
|
+
'V1,L2': 96,
|
|
67
|
+
'V1,L3': 80,
|
|
68
|
+
'V2,L1': 96,
|
|
69
|
+
'V2,L2&L3': 48,
|
|
70
|
+
},
|
|
71
|
+
0b0111: {
|
|
72
|
+
'V1,L1': 224,
|
|
73
|
+
'V1,L2': 112,
|
|
74
|
+
'V1,L3': 96,
|
|
75
|
+
'V2,L1': 112,
|
|
76
|
+
'V2,L2&L3': 56,
|
|
77
|
+
},
|
|
78
|
+
0b1000: {
|
|
79
|
+
'V1,L1': 256,
|
|
80
|
+
'V1,L2': 128,
|
|
81
|
+
'V1,L3': 112,
|
|
82
|
+
'V2,L1': 128,
|
|
83
|
+
'V2,L2&L3': 64,
|
|
84
|
+
},
|
|
85
|
+
0b1001: {
|
|
86
|
+
'V1,L1': 288,
|
|
87
|
+
'V1,L2': 160,
|
|
88
|
+
'V1,L3': 128,
|
|
89
|
+
'V2,L1': 144,
|
|
90
|
+
'V2,L2&L3': 80,
|
|
91
|
+
},
|
|
92
|
+
0b1010: {
|
|
93
|
+
'V1,L1': 320,
|
|
94
|
+
'V1,L2': 192,
|
|
95
|
+
'V1,L3': 160,
|
|
96
|
+
'V2,L1': 160,
|
|
97
|
+
'V2,L2&L3': 96,
|
|
98
|
+
},
|
|
99
|
+
0b1011: {
|
|
100
|
+
'V1,L1': 352,
|
|
101
|
+
'V1,L2': 224,
|
|
102
|
+
'V1,L3': 192,
|
|
103
|
+
'V2,L1': 176,
|
|
104
|
+
'V2,L2&L3': 112,
|
|
105
|
+
},
|
|
106
|
+
0b1100: {
|
|
107
|
+
'V1,L1': 384,
|
|
108
|
+
'V1,L2': 256,
|
|
109
|
+
'V1,L3': 224,
|
|
110
|
+
'V2,L1': 192,
|
|
111
|
+
'V2,L2&L3': 128,
|
|
112
|
+
},
|
|
113
|
+
0b1101: {
|
|
114
|
+
'V1,L1': 416,
|
|
115
|
+
'V1,L2': 320,
|
|
116
|
+
'V1,L3': 256,
|
|
117
|
+
'V2,L1': 224,
|
|
118
|
+
'V2,L2&L3': 144,
|
|
119
|
+
},
|
|
120
|
+
0b1110: {
|
|
121
|
+
'V1,L1': 448,
|
|
122
|
+
'V1,L2': 384,
|
|
123
|
+
'V1,L3': 320,
|
|
124
|
+
'V2,L1': 256,
|
|
125
|
+
'V2,L2&L3': 160,
|
|
126
|
+
},
|
|
127
|
+
0b1111: {
|
|
128
|
+
'V1,L1': 'bad',
|
|
129
|
+
'V1,L2': 'bad',
|
|
130
|
+
'V1,L3': 'bad',
|
|
131
|
+
'V2,L1': 'bad',
|
|
132
|
+
'V2,L2&L3': 'bad',
|
|
133
|
+
},
|
|
134
|
+
};
|
|
135
|
+
// Determine the correct key based on version and level
|
|
136
|
+
let key;
|
|
137
|
+
if (mpegVersion === 2 && (level === 2 || level === 3)) {
|
|
138
|
+
key = 'V2,L2&L3';
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
key = `V${mpegVersion},L${level}`;
|
|
142
|
+
}
|
|
143
|
+
// Return the corresponding bitrate
|
|
144
|
+
return bitrateTable[bits][key];
|
|
145
|
+
}
|
|
146
|
+
const parseMpegHeader = async ({ iterator, state, }) => {
|
|
147
|
+
const initialOffset = iterator.counter.getOffset();
|
|
148
|
+
if (iterator.bytesRemaining() < 32) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
iterator.startReadingBits();
|
|
152
|
+
for (let i = 0; i < 11; i++) {
|
|
153
|
+
const expectToBe1 = iterator.getBits(1);
|
|
154
|
+
if (expectToBe1 !== 1) {
|
|
155
|
+
throw new Error('Expected 1');
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
const audioVersionId = iterator.getBits(2);
|
|
159
|
+
/**
|
|
160
|
+
* 00 - MPEG Version 2.5 (later extension of MPEG 2)
|
|
161
|
+
01 - reserved
|
|
162
|
+
10 - MPEG Version 2 (ISO/IEC 13818-3)
|
|
163
|
+
11 - MPEG Version 1 (ISO/IEC 11172-3)
|
|
164
|
+
*/
|
|
165
|
+
if (audioVersionId !== 0b11 && audioVersionId !== 0b10) {
|
|
166
|
+
throw new Error('Expected MPEG Version 1 or 2');
|
|
167
|
+
}
|
|
168
|
+
const mpegVersion = audioVersionId === 0b11 ? 1 : 2;
|
|
169
|
+
const layerBits = iterator.getBits(2);
|
|
170
|
+
/**
|
|
171
|
+
* 00 - reserved
|
|
172
|
+
01 - Layer III
|
|
173
|
+
10 - Layer II
|
|
174
|
+
11 - Layer I
|
|
175
|
+
*/
|
|
176
|
+
if (layerBits === 0b00) {
|
|
177
|
+
throw new Error('Expected Layer I, II or III');
|
|
178
|
+
}
|
|
179
|
+
const layer = layerBits === 0b11 ? 1 : layerBits === 0b10 ? 2 : 3;
|
|
180
|
+
const protectionBit = iterator.getBits(1);
|
|
181
|
+
if (protectionBit !== 0b1) {
|
|
182
|
+
throw new Error('Does not support CRC yet');
|
|
183
|
+
}
|
|
184
|
+
const bitrateIndex = iterator.getBits(4);
|
|
185
|
+
const bitrateKbit = getBitrateKB({
|
|
186
|
+
bits: bitrateIndex,
|
|
187
|
+
mpegVersion,
|
|
188
|
+
level: audioVersionId,
|
|
189
|
+
});
|
|
190
|
+
if (bitrateKbit === 'bad') {
|
|
191
|
+
throw new Error('Invalid bitrate');
|
|
192
|
+
}
|
|
193
|
+
if (bitrateKbit === 'free') {
|
|
194
|
+
throw new Error('Free bitrate not supported');
|
|
195
|
+
}
|
|
196
|
+
const samplingFrequencyIndex = iterator.getBits(2);
|
|
197
|
+
const sampleRate = getSamplingFrequency({
|
|
198
|
+
bits: samplingFrequencyIndex,
|
|
199
|
+
mpegVersion,
|
|
200
|
+
});
|
|
201
|
+
const padding = Boolean(iterator.getBits(1));
|
|
202
|
+
iterator.getBits(1); // private bit
|
|
203
|
+
const channelMode = iterator.getBits(2); // channel mode
|
|
204
|
+
iterator.getBits(2); // mode extension
|
|
205
|
+
iterator.getBits(1); // copyright
|
|
206
|
+
iterator.getBits(1); // original
|
|
207
|
+
iterator.getBits(2); // emphasis
|
|
208
|
+
const numberOfChannels = channelMode === 0b11 ? 1 : 2;
|
|
209
|
+
const samplesPerFrame = (0, samples_per_mpeg_file_1.getSamplesPerMpegFrame)({ mpegVersion, layer });
|
|
210
|
+
const frameLength = (0, get_frame_length_1.getMpegFrameLength)({
|
|
211
|
+
bitrateKbit,
|
|
212
|
+
padding,
|
|
213
|
+
samplesPerFrame,
|
|
214
|
+
samplingFrequency: sampleRate,
|
|
215
|
+
layer,
|
|
216
|
+
});
|
|
217
|
+
iterator.stopReadingBits();
|
|
218
|
+
const offsetNow = iterator.counter.getOffset();
|
|
219
|
+
iterator.counter.decrement(offsetNow - initialOffset);
|
|
220
|
+
const data = iterator.getSlice(frameLength);
|
|
221
|
+
if (state.callbacks.tracks.getTracks().length === 0) {
|
|
222
|
+
state.mp3Info.setMp3Info({
|
|
223
|
+
layer,
|
|
224
|
+
mpegVersion,
|
|
225
|
+
sampleRate,
|
|
226
|
+
bitrateKbit,
|
|
227
|
+
startOfMpegStream: initialOffset,
|
|
228
|
+
});
|
|
229
|
+
await (0, register_track_1.registerTrack)({
|
|
230
|
+
container: 'mp3',
|
|
231
|
+
state,
|
|
232
|
+
track: {
|
|
233
|
+
type: 'audio',
|
|
234
|
+
codec: 'mp3',
|
|
235
|
+
codecPrivate: null,
|
|
236
|
+
codecWithoutConfig: 'mp3',
|
|
237
|
+
description: undefined,
|
|
238
|
+
numberOfChannels,
|
|
239
|
+
sampleRate,
|
|
240
|
+
timescale: 1000000,
|
|
241
|
+
trackId: 0,
|
|
242
|
+
trakBox: null,
|
|
243
|
+
},
|
|
244
|
+
});
|
|
245
|
+
state.callbacks.tracks.setIsDone();
|
|
246
|
+
}
|
|
247
|
+
const mp3Info = state.mp3Info.getMp3Info();
|
|
248
|
+
if (!mp3Info) {
|
|
249
|
+
throw new Error('No MP3 info by now');
|
|
250
|
+
}
|
|
251
|
+
const avgLength = (0, get_frame_length_1.getAverageMpegFrameLength)({
|
|
252
|
+
bitrateKbit,
|
|
253
|
+
layer,
|
|
254
|
+
samplesPerFrame,
|
|
255
|
+
samplingFrequency: sampleRate,
|
|
256
|
+
});
|
|
257
|
+
const nthFrame = Math.round((initialOffset - mp3Info.startOfMpegStream) / avgLength);
|
|
258
|
+
const durationInSeconds = samplesPerFrame / sampleRate;
|
|
259
|
+
const timeInSeconds = (nthFrame * samplesPerFrame) / sampleRate;
|
|
260
|
+
const timestamp = Math.round(timeInSeconds * 1000000);
|
|
261
|
+
const duration = Math.round(durationInSeconds * 1000000);
|
|
262
|
+
await state.callbacks.onAudioSample(0, {
|
|
263
|
+
data,
|
|
264
|
+
cts: timestamp,
|
|
265
|
+
dts: timestamp,
|
|
266
|
+
duration,
|
|
267
|
+
offset: initialOffset,
|
|
268
|
+
timescale: 1000000,
|
|
269
|
+
timestamp,
|
|
270
|
+
trackId: 0,
|
|
271
|
+
type: 'key',
|
|
272
|
+
});
|
|
273
|
+
};
|
|
274
|
+
exports.parseMpegHeader = parseMpegHeader;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getSamplesPerMpegFrame = void 0;
|
|
4
|
+
const getSamplesPerMpegFrame = ({ mpegVersion, layer, }) => {
|
|
5
|
+
if (mpegVersion === 1) {
|
|
6
|
+
if (layer === 1) {
|
|
7
|
+
return 384;
|
|
8
|
+
}
|
|
9
|
+
if (layer === 2 || layer === 3) {
|
|
10
|
+
return 1152;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
if (mpegVersion === 2) {
|
|
14
|
+
if (layer === 1) {
|
|
15
|
+
return 384;
|
|
16
|
+
}
|
|
17
|
+
if (layer === 2) {
|
|
18
|
+
return 1152;
|
|
19
|
+
}
|
|
20
|
+
if (layer === 3) {
|
|
21
|
+
return 576;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
throw new Error('Invalid MPEG layer');
|
|
25
|
+
};
|
|
26
|
+
exports.getSamplesPerMpegFrame = getSamplesPerMpegFrame;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { BufferIterator } from '../../buffer-iterator';
|
|
2
|
+
import type { Options, ParseMediaFields } from '../../options';
|
|
3
|
+
import type { ParseResult, RiffStructure } from '../../parse-result';
|
|
4
|
+
import type { ParserState } from '../../state/parser-state';
|
|
5
|
+
import type { RiffResult } from './expect-riff-box';
|
|
6
|
+
export declare const continueAfterRiffBoxResult: ({ result, structure, iterator, maxOffset, state: options, fields, }: {
|
|
7
|
+
result: RiffResult;
|
|
8
|
+
structure: RiffStructure;
|
|
9
|
+
iterator: BufferIterator;
|
|
10
|
+
maxOffset: number;
|
|
11
|
+
state: ParserState;
|
|
12
|
+
fields: Options<ParseMediaFields>;
|
|
13
|
+
}) => Promise<ParseResult>;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.continueAfterRiffBoxResult = void 0;
|
|
4
|
+
const parse_riff_body_1 = require("./parse-riff-body");
|
|
5
|
+
const continueAfterRiffBoxResult = ({ result, structure, iterator, maxOffset, state: options, fields, }) => {
|
|
6
|
+
if (result.type === 'incomplete') {
|
|
7
|
+
return Promise.resolve({
|
|
8
|
+
status: 'incomplete',
|
|
9
|
+
async continueParsing() {
|
|
10
|
+
return Promise.resolve((0, exports.continueAfterRiffBoxResult)({
|
|
11
|
+
result: await result.continueParsing(),
|
|
12
|
+
structure,
|
|
13
|
+
iterator,
|
|
14
|
+
maxOffset,
|
|
15
|
+
state: options,
|
|
16
|
+
fields,
|
|
17
|
+
}));
|
|
18
|
+
},
|
|
19
|
+
segments: structure,
|
|
20
|
+
skipTo: null,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
if (result.type === 'complete' && result.box) {
|
|
24
|
+
structure.boxes.push(result.box);
|
|
25
|
+
}
|
|
26
|
+
return (0, parse_riff_body_1.parseRiffBody)({
|
|
27
|
+
iterator,
|
|
28
|
+
maxOffset,
|
|
29
|
+
state: options,
|
|
30
|
+
structure,
|
|
31
|
+
fields,
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
exports.continueAfterRiffBoxResult = continueAfterRiffBoxResult;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { BufferIterator } from '../../buffer-iterator';
|
|
2
|
+
import type { Options, ParseMediaFields } from '../../options';
|
|
2
3
|
import type { RiffStructure } from '../../parse-result';
|
|
3
4
|
import type { ParserState } from '../../state/parser-state';
|
|
4
5
|
import type { RiffBox } from './riff-box';
|
|
@@ -10,8 +11,9 @@ export type RiffResult = {
|
|
|
10
11
|
box: RiffBox | null;
|
|
11
12
|
skipTo: number | null;
|
|
12
13
|
};
|
|
13
|
-
export declare const expectRiffBox: ({ iterator, state, structure, }: {
|
|
14
|
+
export declare const expectRiffBox: ({ iterator, state, structure, fields, }: {
|
|
14
15
|
iterator: BufferIterator;
|
|
15
16
|
state: ParserState;
|
|
16
17
|
structure: RiffStructure;
|
|
18
|
+
fields: Options<ParseMediaFields>;
|
|
17
19
|
}) => Promise<RiffResult>;
|
|
@@ -4,13 +4,13 @@ exports.expectRiffBox = void 0;
|
|
|
4
4
|
const is_movi_1 = require("./is-movi");
|
|
5
5
|
const parse_movi_1 = require("./parse-movi");
|
|
6
6
|
const parse_riff_box_1 = require("./parse-riff-box");
|
|
7
|
-
const expectRiffBox = async ({ iterator, state, structure, }) => {
|
|
7
|
+
const expectRiffBox = async ({ iterator, state, structure, fields, }) => {
|
|
8
8
|
// Need at least 16 bytes to read LIST,size,movi,size
|
|
9
9
|
if (iterator.bytesRemaining() < 16) {
|
|
10
10
|
return {
|
|
11
11
|
type: 'incomplete',
|
|
12
12
|
continueParsing() {
|
|
13
|
-
return (0, exports.expectRiffBox)({ structure, iterator, state });
|
|
13
|
+
return (0, exports.expectRiffBox)({ structure, iterator, state, fields });
|
|
14
14
|
},
|
|
15
15
|
};
|
|
16
16
|
}
|
|
@@ -30,7 +30,7 @@ const expectRiffBox = async ({ iterator, state, structure, }) => {
|
|
|
30
30
|
return {
|
|
31
31
|
type: 'incomplete',
|
|
32
32
|
continueParsing: () => {
|
|
33
|
-
return (0, exports.expectRiffBox)({ structure, iterator, state });
|
|
33
|
+
return (0, exports.expectRiffBox)({ structure, iterator, state, fields });
|
|
34
34
|
},
|
|
35
35
|
};
|
|
36
36
|
}
|
|
@@ -42,6 +42,7 @@ const expectRiffBox = async ({ iterator, state, structure, }) => {
|
|
|
42
42
|
size: ckSize,
|
|
43
43
|
boxes: structure.boxes,
|
|
44
44
|
state,
|
|
45
|
+
fields,
|
|
45
46
|
}),
|
|
46
47
|
skipTo: null,
|
|
47
48
|
};
|
|
@@ -1,13 +1,7 @@
|
|
|
1
1
|
import type { BufferIterator } from '../../buffer-iterator';
|
|
2
2
|
import type { Options, ParseMediaFields } from '../../options';
|
|
3
|
-
import type { ParseResult
|
|
3
|
+
import type { ParseResult } from '../../parse-result';
|
|
4
4
|
import type { ParserState } from '../../state/parser-state';
|
|
5
|
-
export declare const parseRiffBody: ({ iterator, structure, maxOffset, state, }: {
|
|
6
|
-
iterator: BufferIterator;
|
|
7
|
-
structure: RiffStructure;
|
|
8
|
-
maxOffset: number;
|
|
9
|
-
state: ParserState;
|
|
10
|
-
}) => Promise<ParseResult>;
|
|
11
5
|
export declare const parseRiff: ({ iterator, state, fields, }: {
|
|
12
6
|
iterator: BufferIterator;
|
|
13
7
|
state: ParserState;
|