@agentdocumentformat/cli 0.7.2
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/LICENSE +21 -0
- package/README.md +45 -0
- package/dist/adf.mjs +162 -0
- package/dist/chunks/APEv2Parser-2CNNHMXV.mjs +22 -0
- package/dist/chunks/AiffParser-7BR4RL6G.mjs +162 -0
- package/dist/chunks/App-L5L37JI5.mjs +16747 -0
- package/dist/chunks/AsfParser-VVRSLFOM.mjs +538 -0
- package/dist/chunks/DsdiffParser-CMD4AX7A.mjs +156 -0
- package/dist/chunks/DsfParser-UOGZDS2M.mjs +94 -0
- package/dist/chunks/FlacParser-HB3T3CD4.mjs +23 -0
- package/dist/chunks/MP4Parser-66HBRUSX.mjs +973 -0
- package/dist/chunks/MatroskaParser-J3HUIMEW.mjs +579 -0
- package/dist/chunks/MpegParser-YW6LIUEW.mjs +442 -0
- package/dist/chunks/MusepackParser-PAUSXP7D.mjs +252 -0
- package/dist/chunks/OggParser-NUBV3GWC.mjs +359 -0
- package/dist/chunks/WavPackParser-WQAGT7TC.mjs +171 -0
- package/dist/chunks/WaveParser-EWLQVDX4.mjs +238 -0
- package/dist/chunks/adf-schema-JRU2BTOG.mjs +62 -0
- package/dist/chunks/build-QF5W473T.mjs +60 -0
- package/dist/chunks/chatgpt-subscription-BQGWYZXE.mjs +23 -0
- package/dist/chunks/chunk-2DIECGFL.mjs +6 -0
- package/dist/chunks/chunk-2NAP2ZF7.mjs +60 -0
- package/dist/chunks/chunk-3AT7IIP7.mjs +25696 -0
- package/dist/chunks/chunk-3GNIDM53.mjs +35 -0
- package/dist/chunks/chunk-3M4ZPOA3.mjs +1477 -0
- package/dist/chunks/chunk-4MQPTCXY.mjs +510 -0
- package/dist/chunks/chunk-5PO5PKRV.mjs +366 -0
- package/dist/chunks/chunk-5QU5VY7N.mjs +52 -0
- package/dist/chunks/chunk-5W7KES6P.mjs +436 -0
- package/dist/chunks/chunk-62NE4LG4.mjs +61 -0
- package/dist/chunks/chunk-64OKE4X3.mjs +45 -0
- package/dist/chunks/chunk-6GJ4QHRI.mjs +1278 -0
- package/dist/chunks/chunk-6VQEXLE2.mjs +144 -0
- package/dist/chunks/chunk-6XUV6EK6.mjs +41 -0
- package/dist/chunks/chunk-776TSXEP.mjs +43 -0
- package/dist/chunks/chunk-7CV2SA3H.mjs +285 -0
- package/dist/chunks/chunk-7MTRVW2U.mjs +3103 -0
- package/dist/chunks/chunk-7N2R2VCG.mjs +1434 -0
- package/dist/chunks/chunk-7T2YMTWL.mjs +374 -0
- package/dist/chunks/chunk-7XYNI52E.mjs +149 -0
- package/dist/chunks/chunk-APHX6HSV.mjs +7731 -0
- package/dist/chunks/chunk-APRU6PHC.mjs +40 -0
- package/dist/chunks/chunk-AUYKRQPJ.mjs +499 -0
- package/dist/chunks/chunk-DXWDD5XJ.mjs +136 -0
- package/dist/chunks/chunk-EWL5FG4I.mjs +39 -0
- package/dist/chunks/chunk-EYX2YLJW.mjs +117 -0
- package/dist/chunks/chunk-F5ELW46V.mjs +27 -0
- package/dist/chunks/chunk-G426FACA.mjs +49 -0
- package/dist/chunks/chunk-GEKSJHIV.mjs +2472 -0
- package/dist/chunks/chunk-HBUENVQL.mjs +570 -0
- package/dist/chunks/chunk-HPVFJYXR.mjs +112 -0
- package/dist/chunks/chunk-HWLWPXQ7.mjs +721 -0
- package/dist/chunks/chunk-I2HJYHFT.mjs +665 -0
- package/dist/chunks/chunk-I3UYSITV.mjs +68 -0
- package/dist/chunks/chunk-IC4JDZCI.mjs +3864 -0
- package/dist/chunks/chunk-IHDDCZBS.mjs +112 -0
- package/dist/chunks/chunk-IIGMZHQQ.mjs +10416 -0
- package/dist/chunks/chunk-KWFOS5WC.mjs +41 -0
- package/dist/chunks/chunk-LAZIXV2F.mjs +5290 -0
- package/dist/chunks/chunk-LFMB4PAA.mjs +10814 -0
- package/dist/chunks/chunk-M2RX3S2T.mjs +49 -0
- package/dist/chunks/chunk-M3WPIJYM.mjs +65 -0
- package/dist/chunks/chunk-NBTUWMGP.mjs +263 -0
- package/dist/chunks/chunk-NGK6PVSF.mjs +2676 -0
- package/dist/chunks/chunk-NZ7JTHEO.mjs +85 -0
- package/dist/chunks/chunk-OQN33RGQ.mjs +52 -0
- package/dist/chunks/chunk-RIX34QHC.mjs +2935 -0
- package/dist/chunks/chunk-SGUTYISF.mjs +16 -0
- package/dist/chunks/chunk-SLJ5L7PY.mjs +1473 -0
- package/dist/chunks/chunk-SLUKGXKH.mjs +68 -0
- package/dist/chunks/chunk-TMT32MXT.mjs +419 -0
- package/dist/chunks/chunk-UYY5M2PB.mjs +151 -0
- package/dist/chunks/chunk-VAUOM3IN.mjs +298 -0
- package/dist/chunks/chunk-VMHTYDH4.mjs +172 -0
- package/dist/chunks/chunk-VZS54AA5.mjs +200 -0
- package/dist/chunks/chunk-WFQUVXML.mjs +295 -0
- package/dist/chunks/chunk-X34PDRUH.mjs +809 -0
- package/dist/chunks/chunk-XNPZBLYL.mjs +33 -0
- package/dist/chunks/chunk-XX7OSWTO.mjs +157 -0
- package/dist/chunks/chunk-XYTWGHFS.mjs +600 -0
- package/dist/chunks/chunk-XYV3VCIX.mjs +336 -0
- package/dist/chunks/chunk-Y5ZLKFLE.mjs +1469 -0
- package/dist/chunks/chunk-ZJKXHM4Q.mjs +230 -0
- package/dist/chunks/cli-TCMBNZF6.mjs +1030 -0
- package/dist/chunks/commands-DTEKM4ZL.mjs +20 -0
- package/dist/chunks/daemon-ZC3FZ2P4.mjs +112449 -0
- package/dist/chunks/daemon-control-WDX7PMTC.mjs +300 -0
- package/dist/chunks/daemon-token-WRSULP7G.mjs +23 -0
- package/dist/chunks/devtools-H7CI2ZVG.mjs +85 -0
- package/dist/chunks/discord-IWDQJA7A.mjs +70588 -0
- package/dist/chunks/dist-C57KYFS2.mjs +4952 -0
- package/dist/chunks/dist-I3XBAGDL.mjs +11 -0
- package/dist/chunks/email-V4Q4VJON.mjs +58679 -0
- package/dist/chunks/environment-NX277MQG.mjs +15 -0
- package/dist/chunks/grok-subscription-4PYX7TBF.mjs +19 -0
- package/dist/chunks/layout-EPJQNFAI.mjs +22 -0
- package/dist/chunks/lib-N7FCZWKH.mjs +4038 -0
- package/dist/chunks/open-OTQDGDH5.mjs +36 -0
- package/dist/chunks/parser-JVY2PWSM.mjs +19 -0
- package/dist/chunks/pipeline-executor-BHBSJX2K.mjs +19 -0
- package/dist/chunks/react-IUIDQ5LX.mjs +11 -0
- package/dist/chunks/screen-54BUTYCW.mjs +27 -0
- package/dist/chunks/slack-3L5QTDZX.mjs +8113 -0
- package/dist/chunks/store-WR7TZJZS.mjs +32 -0
- package/dist/chunks/telegram-5ISVFBV3.mjs +14918 -0
- package/dist/chunks/terminal-O5WO7C5U.mjs +48 -0
- package/dist/chunks/theme-NORU4J74.mjs +20 -0
- package/dist/chunks/themes-F2FKU7CP.mjs +23 -0
- package/dist/chunks/token-6G3HCMNX.mjs +54 -0
- package/dist/chunks/token-util-UXYSDQIW.mjs +12 -0
- package/dist/chunks/tui-ODVYUIMT.mjs +197 -0
- package/dist/chunks/welcome-XHXFV7SH.mjs +32 -0
- package/dist/chunks/whatsapp-XSAMNGPJ.mjs +85412 -0
- package/dist/chunks/xterm-headless-YF53XWXE.mjs +3353 -0
- package/package.json +53 -0
- package/resources/wasm/coreutils.LICENSE +18 -0
- package/resources/wasm/coreutils.wasm +0 -0
|
@@ -0,0 +1,442 @@
|
|
|
1
|
+
import { createRequire as __adfCreateRequire } from 'node:module';
|
|
2
|
+
import { fileURLToPath as __adfFileURLToPath } from 'node:url';
|
|
3
|
+
import { dirname as __adfDirname } from 'node:path';
|
|
4
|
+
const require = __adfCreateRequire(import.meta.url);
|
|
5
|
+
const __filename = __adfFileURLToPath(import.meta.url);
|
|
6
|
+
const __dirname = __adfDirname(__filename);
|
|
7
|
+
import {
|
|
8
|
+
AbstractID3Parser
|
|
9
|
+
} from "./chunk-62NE4LG4.mjs";
|
|
10
|
+
import "./chunk-XYTWGHFS.mjs";
|
|
11
|
+
import "./chunk-VAUOM3IN.mjs";
|
|
12
|
+
import "./chunk-DXWDD5XJ.mjs";
|
|
13
|
+
import "./chunk-NBTUWMGP.mjs";
|
|
14
|
+
import {
|
|
15
|
+
getBitAllignedNumber,
|
|
16
|
+
isBitSet,
|
|
17
|
+
stripNulls
|
|
18
|
+
} from "./chunk-XX7OSWTO.mjs";
|
|
19
|
+
import {
|
|
20
|
+
EndOfStreamError
|
|
21
|
+
} from "./chunk-HBUENVQL.mjs";
|
|
22
|
+
import {
|
|
23
|
+
INT16_BE,
|
|
24
|
+
StringType,
|
|
25
|
+
UINT16_BE,
|
|
26
|
+
UINT32_BE,
|
|
27
|
+
UINT8,
|
|
28
|
+
Uint8ArrayType,
|
|
29
|
+
makeUnexpectedFileContentError
|
|
30
|
+
} from "./chunk-I2HJYHFT.mjs";
|
|
31
|
+
import {
|
|
32
|
+
require_src
|
|
33
|
+
} from "./chunk-AUYKRQPJ.mjs";
|
|
34
|
+
import "./chunk-NZ7JTHEO.mjs";
|
|
35
|
+
import {
|
|
36
|
+
__toESM
|
|
37
|
+
} from "./chunk-M2RX3S2T.mjs";
|
|
38
|
+
|
|
39
|
+
// node_modules/music-metadata/lib/mpeg/MpegParser.js
|
|
40
|
+
var import_debug = __toESM(require_src(), 1);
|
|
41
|
+
|
|
42
|
+
// node_modules/music-metadata/lib/mpeg/ReplayGainDataFormat.js
|
|
43
|
+
var ReplayGain = {
|
|
44
|
+
len: 2,
|
|
45
|
+
get: (buf, off) => {
|
|
46
|
+
let gain_type = getBitAllignedNumber(buf, off, 0, 3), sign = getBitAllignedNumber(buf, off, 6, 1), gain_adj = getBitAllignedNumber(buf, off, 7, 9) / 10;
|
|
47
|
+
if (gain_type > 0)
|
|
48
|
+
return {
|
|
49
|
+
type: getBitAllignedNumber(buf, off, 0, 3),
|
|
50
|
+
origin: getBitAllignedNumber(buf, off, 3, 3),
|
|
51
|
+
adjustment: sign ? -gain_adj : gain_adj
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
// node_modules/music-metadata/lib/mpeg/ExtendedLameHeader.js
|
|
57
|
+
var ExtendedLameHeader = {
|
|
58
|
+
len: 27,
|
|
59
|
+
get: (buf, off) => {
|
|
60
|
+
let track_peak = UINT32_BE.get(buf, off + 2);
|
|
61
|
+
return {
|
|
62
|
+
revision: getBitAllignedNumber(buf, off, 0, 4),
|
|
63
|
+
vbr_method: getBitAllignedNumber(buf, off, 4, 4),
|
|
64
|
+
lowpass_filter: 100 * UINT8.get(buf, off + 1),
|
|
65
|
+
track_peak: track_peak === 0 ? null : track_peak / 2 ** 23,
|
|
66
|
+
track_gain: ReplayGain.get(buf, 6),
|
|
67
|
+
album_gain: ReplayGain.get(buf, 8),
|
|
68
|
+
music_length: UINT32_BE.get(buf, off + 20),
|
|
69
|
+
music_crc: UINT8.get(buf, off + 24),
|
|
70
|
+
header_crc: UINT16_BE.get(buf, off + 24)
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
// node_modules/music-metadata/lib/mpeg/XingTag.js
|
|
76
|
+
var InfoTagHeaderTag = new StringType(4, "ascii"), LameEncoderVersion = new StringType(6, "ascii"), XingHeaderFlags = {
|
|
77
|
+
len: 4,
|
|
78
|
+
get: (buf, off) => ({
|
|
79
|
+
frames: isBitSet(buf, off, 31),
|
|
80
|
+
bytes: isBitSet(buf, off, 30),
|
|
81
|
+
toc: isBitSet(buf, off, 29),
|
|
82
|
+
vbrScale: isBitSet(buf, off, 28)
|
|
83
|
+
})
|
|
84
|
+
};
|
|
85
|
+
async function readXingHeader(tokenizer) {
|
|
86
|
+
let flags = await tokenizer.readToken(XingHeaderFlags), xingInfoTag = { numFrames: null, streamSize: null, vbrScale: null };
|
|
87
|
+
if (flags.frames && (xingInfoTag.numFrames = await tokenizer.readToken(UINT32_BE)), flags.bytes && (xingInfoTag.streamSize = await tokenizer.readToken(UINT32_BE)), flags.toc && (xingInfoTag.toc = new Uint8Array(100), await tokenizer.readBuffer(xingInfoTag.toc)), flags.vbrScale && (xingInfoTag.vbrScale = await tokenizer.readToken(UINT32_BE)), await tokenizer.peekToken(new StringType(4, "ascii")) === "LAME") {
|
|
88
|
+
await tokenizer.ignore(4), xingInfoTag.lame = {
|
|
89
|
+
version: await tokenizer.readToken(new StringType(5, "ascii"))
|
|
90
|
+
};
|
|
91
|
+
let match = xingInfoTag.lame.version.match(/\d+.\d+/g);
|
|
92
|
+
if (match !== null) {
|
|
93
|
+
let version = match[0].split(".").map((n) => Number.parseInt(n, 10));
|
|
94
|
+
version[0] >= 3 && version[1] >= 90 && (xingInfoTag.lame.extended = await tokenizer.readToken(ExtendedLameHeader));
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return xingInfoTag;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// node_modules/music-metadata/lib/mpeg/MpegParser.js
|
|
101
|
+
var debug = (0, import_debug.default)("music-metadata:parser:mpeg"), MpegContentError = class extends makeUnexpectedFileContentError("MPEG") {
|
|
102
|
+
}, maxPeekLen = 1024, MPEG4 = {
|
|
103
|
+
/**
|
|
104
|
+
* Audio Object Types
|
|
105
|
+
*/
|
|
106
|
+
AudioObjectTypes: [
|
|
107
|
+
"AAC Main",
|
|
108
|
+
"AAC LC",
|
|
109
|
+
// Low Complexity
|
|
110
|
+
"AAC SSR",
|
|
111
|
+
// Scalable Sample Rate
|
|
112
|
+
"AAC LTP"
|
|
113
|
+
// Long Term Prediction
|
|
114
|
+
],
|
|
115
|
+
/**
|
|
116
|
+
* Sampling Frequencies
|
|
117
|
+
* https://wiki.multimedia.cx/index.php/MPEG-4_Audio#Sampling_Frequencies
|
|
118
|
+
*/
|
|
119
|
+
SamplingFrequencies: [
|
|
120
|
+
96e3,
|
|
121
|
+
88200,
|
|
122
|
+
64e3,
|
|
123
|
+
48e3,
|
|
124
|
+
44100,
|
|
125
|
+
32e3,
|
|
126
|
+
24e3,
|
|
127
|
+
22050,
|
|
128
|
+
16e3,
|
|
129
|
+
12e3,
|
|
130
|
+
11025,
|
|
131
|
+
8e3,
|
|
132
|
+
7350,
|
|
133
|
+
null,
|
|
134
|
+
null,
|
|
135
|
+
null
|
|
136
|
+
]
|
|
137
|
+
/**
|
|
138
|
+
* Channel Configurations
|
|
139
|
+
*/
|
|
140
|
+
}, MPEG4_ChannelConfigurations = [
|
|
141
|
+
void 0,
|
|
142
|
+
["front-center"],
|
|
143
|
+
["front-left", "front-right"],
|
|
144
|
+
["front-center", "front-left", "front-right"],
|
|
145
|
+
["front-center", "front-left", "front-right", "back-center"],
|
|
146
|
+
["front-center", "front-left", "front-right", "back-left", "back-right"],
|
|
147
|
+
["front-center", "front-left", "front-right", "back-left", "back-right", "LFE-channel"],
|
|
148
|
+
["front-center", "front-left", "front-right", "side-left", "side-right", "back-left", "back-right", "LFE-channel"]
|
|
149
|
+
], MpegFrameHeader = class _MpegFrameHeader {
|
|
150
|
+
constructor(buf, off) {
|
|
151
|
+
this.bitrateIndex = null, this.sampRateFreqIndex = null, this.padding = null, this.privateBit = null, this.channelModeIndex = null, this.modeExtension = null, this.isOriginalMedia = null, this.version = null, this.bitrate = null, this.samplingRate = null, this.frameLength = 0, this.versionIndex = getBitAllignedNumber(buf, off + 1, 3, 2), this.layer = _MpegFrameHeader.LayerDescription[getBitAllignedNumber(buf, off + 1, 5, 2)], this.versionIndex > 1 && this.layer === 0 ? this.parseAdtsHeader(buf, off) : this.parseMpegHeader(buf, off), this.isProtectedByCRC = !isBitSet(buf, off + 1, 7);
|
|
152
|
+
}
|
|
153
|
+
calcDuration(numFrames) {
|
|
154
|
+
return this.samplingRate == null ? null : numFrames * this.calcSamplesPerFrame() / this.samplingRate;
|
|
155
|
+
}
|
|
156
|
+
calcSamplesPerFrame() {
|
|
157
|
+
return _MpegFrameHeader.samplesInFrameTable[this.version === 1 ? 0 : 1][this.layer];
|
|
158
|
+
}
|
|
159
|
+
calculateSideInfoLength() {
|
|
160
|
+
if (this.layer !== 3)
|
|
161
|
+
return 2;
|
|
162
|
+
if (this.channelModeIndex === 3) {
|
|
163
|
+
if (this.version === 1)
|
|
164
|
+
return 17;
|
|
165
|
+
if (this.version === 2 || this.version === 2.5)
|
|
166
|
+
return 9;
|
|
167
|
+
} else {
|
|
168
|
+
if (this.version === 1)
|
|
169
|
+
return 32;
|
|
170
|
+
if (this.version === 2 || this.version === 2.5)
|
|
171
|
+
return 17;
|
|
172
|
+
}
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
175
|
+
calcSlotSize() {
|
|
176
|
+
return [null, 4, 1, 1][this.layer];
|
|
177
|
+
}
|
|
178
|
+
parseMpegHeader(buf, off) {
|
|
179
|
+
this.container = "MPEG", this.bitrateIndex = getBitAllignedNumber(buf, off + 2, 0, 4), this.sampRateFreqIndex = getBitAllignedNumber(buf, off + 2, 4, 2), this.padding = isBitSet(buf, off + 2, 6), this.privateBit = isBitSet(buf, off + 2, 7), this.channelModeIndex = getBitAllignedNumber(buf, off + 3, 0, 2), this.modeExtension = getBitAllignedNumber(buf, off + 3, 2, 2), this.isCopyrighted = isBitSet(buf, off + 3, 4), this.isOriginalMedia = isBitSet(buf, off + 3, 5), this.emphasis = getBitAllignedNumber(buf, off + 3, 7, 2), this.version = _MpegFrameHeader.VersionID[this.versionIndex], this.channelMode = _MpegFrameHeader.ChannelMode[this.channelModeIndex], this.codec = `MPEG ${this.version} Layer ${this.layer}`;
|
|
180
|
+
let bitrateInKbps = this.calcBitrate();
|
|
181
|
+
if (!bitrateInKbps)
|
|
182
|
+
throw new MpegContentError("Cannot determine bit-rate");
|
|
183
|
+
if (this.bitrate = bitrateInKbps * 1e3, this.samplingRate = this.calcSamplingRate(), this.samplingRate == null)
|
|
184
|
+
throw new MpegContentError("Cannot determine sampling-rate");
|
|
185
|
+
}
|
|
186
|
+
parseAdtsHeader(buf, off) {
|
|
187
|
+
debug("layer=0 => ADTS"), this.version = this.versionIndex === 2 ? 4 : 2, this.container = `ADTS/MPEG-${this.version}`;
|
|
188
|
+
let profileIndex = getBitAllignedNumber(buf, off + 2, 0, 2);
|
|
189
|
+
this.codec = "AAC", this.codecProfile = MPEG4.AudioObjectTypes[profileIndex], debug(`MPEG-4 audio-codec=${this.codec}`);
|
|
190
|
+
let samplingFrequencyIndex = getBitAllignedNumber(buf, off + 2, 2, 4);
|
|
191
|
+
this.samplingRate = MPEG4.SamplingFrequencies[samplingFrequencyIndex], debug(`sampling-rate=${this.samplingRate}`);
|
|
192
|
+
let channelIndex = getBitAllignedNumber(buf, off + 2, 7, 3);
|
|
193
|
+
this.mp4ChannelConfig = MPEG4_ChannelConfigurations[channelIndex], debug(`channel-config=${this.mp4ChannelConfig ? this.mp4ChannelConfig.join("+") : "?"}`), this.frameLength = getBitAllignedNumber(buf, off + 3, 6, 2) << 11;
|
|
194
|
+
}
|
|
195
|
+
calcBitrate() {
|
|
196
|
+
if (this.bitrateIndex === 0 || // free
|
|
197
|
+
this.bitrateIndex === 15)
|
|
198
|
+
return null;
|
|
199
|
+
if (this.version && this.bitrateIndex) {
|
|
200
|
+
let codecIndex = 10 * Math.floor(this.version) + this.layer;
|
|
201
|
+
return _MpegFrameHeader.bitrate_index[this.bitrateIndex][codecIndex];
|
|
202
|
+
}
|
|
203
|
+
return null;
|
|
204
|
+
}
|
|
205
|
+
calcSamplingRate() {
|
|
206
|
+
return this.sampRateFreqIndex === 3 || this.version === null || this.sampRateFreqIndex == null ? null : _MpegFrameHeader.sampling_rate_freq_index[this.version][this.sampRateFreqIndex];
|
|
207
|
+
}
|
|
208
|
+
};
|
|
209
|
+
MpegFrameHeader.SyncByte1 = 255;
|
|
210
|
+
MpegFrameHeader.SyncByte2 = 224;
|
|
211
|
+
MpegFrameHeader.VersionID = [2.5, null, 2, 1];
|
|
212
|
+
MpegFrameHeader.LayerDescription = [0, 3, 2, 1];
|
|
213
|
+
MpegFrameHeader.ChannelMode = ["stereo", "joint_stereo", "dual_channel", "mono"];
|
|
214
|
+
MpegFrameHeader.bitrate_index = {
|
|
215
|
+
1: { 11: 32, 12: 32, 13: 32, 21: 32, 22: 8, 23: 8 },
|
|
216
|
+
2: { 11: 64, 12: 48, 13: 40, 21: 48, 22: 16, 23: 16 },
|
|
217
|
+
3: { 11: 96, 12: 56, 13: 48, 21: 56, 22: 24, 23: 24 },
|
|
218
|
+
4: { 11: 128, 12: 64, 13: 56, 21: 64, 22: 32, 23: 32 },
|
|
219
|
+
5: { 11: 160, 12: 80, 13: 64, 21: 80, 22: 40, 23: 40 },
|
|
220
|
+
6: { 11: 192, 12: 96, 13: 80, 21: 96, 22: 48, 23: 48 },
|
|
221
|
+
7: { 11: 224, 12: 112, 13: 96, 21: 112, 22: 56, 23: 56 },
|
|
222
|
+
8: { 11: 256, 12: 128, 13: 112, 21: 128, 22: 64, 23: 64 },
|
|
223
|
+
9: { 11: 288, 12: 160, 13: 128, 21: 144, 22: 80, 23: 80 },
|
|
224
|
+
10: { 11: 320, 12: 192, 13: 160, 21: 160, 22: 96, 23: 96 },
|
|
225
|
+
11: { 11: 352, 12: 224, 13: 192, 21: 176, 22: 112, 23: 112 },
|
|
226
|
+
12: { 11: 384, 12: 256, 13: 224, 21: 192, 22: 128, 23: 128 },
|
|
227
|
+
13: { 11: 416, 12: 320, 13: 256, 21: 224, 22: 144, 23: 144 },
|
|
228
|
+
14: { 11: 448, 12: 384, 13: 320, 21: 256, 22: 160, 23: 160 }
|
|
229
|
+
};
|
|
230
|
+
MpegFrameHeader.sampling_rate_freq_index = {
|
|
231
|
+
1: { 0: 44100, 1: 48e3, 2: 32e3 },
|
|
232
|
+
2: { 0: 22050, 1: 24e3, 2: 16e3 },
|
|
233
|
+
2.5: { 0: 11025, 1: 12e3, 2: 8e3 }
|
|
234
|
+
};
|
|
235
|
+
MpegFrameHeader.samplesInFrameTable = [
|
|
236
|
+
/* Layer I II III */
|
|
237
|
+
[0, 384, 1152, 1152],
|
|
238
|
+
// MPEG-1
|
|
239
|
+
[0, 384, 1152, 576]
|
|
240
|
+
// MPEG-2(.5
|
|
241
|
+
];
|
|
242
|
+
var FrameHeader = {
|
|
243
|
+
len: 4,
|
|
244
|
+
get: (buf, off) => new MpegFrameHeader(buf, off)
|
|
245
|
+
};
|
|
246
|
+
function getVbrCodecProfile(vbrScale) {
|
|
247
|
+
return `V${Math.floor((100 - vbrScale) / 10)}`;
|
|
248
|
+
}
|
|
249
|
+
var MpegParser = class extends AbstractID3Parser {
|
|
250
|
+
constructor() {
|
|
251
|
+
super(...arguments), this.frameCount = 0, this.syncFrameCount = -1, this.totalDataLength = 0, this.bitrates = [], this.offset = 0, this.frame_size = 0, this.calculateEofDuration = !1, this.samplesPerFrame = null, this.buf_frame_header = new Uint8Array(4), this.mpegOffset = null, this.syncPeek = {
|
|
252
|
+
buf: new Uint8Array(maxPeekLen),
|
|
253
|
+
len: 0
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Called after ID3 headers have been parsed
|
|
258
|
+
*/
|
|
259
|
+
async postId3v2Parse() {
|
|
260
|
+
this.metadata.setFormat("lossless", !1), this.metadata.setAudioOnly();
|
|
261
|
+
try {
|
|
262
|
+
let quit = !1;
|
|
263
|
+
for (; !quit; )
|
|
264
|
+
await this.sync(), quit = await this.parseCommonMpegHeader();
|
|
265
|
+
} catch (err) {
|
|
266
|
+
if (err instanceof EndOfStreamError) {
|
|
267
|
+
if (debug("End-of-stream"), this.calculateEofDuration && this.samplesPerFrame !== null) {
|
|
268
|
+
let numberOfSamples = this.frameCount * this.samplesPerFrame;
|
|
269
|
+
if (this.metadata.setFormat("numberOfSamples", numberOfSamples), this.metadata.format.sampleRate) {
|
|
270
|
+
let duration = numberOfSamples / this.metadata.format.sampleRate;
|
|
271
|
+
debug(`Calculate duration at EOF: ${duration} sec.`, duration), this.metadata.setFormat("duration", duration);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
} else
|
|
275
|
+
throw err;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Called after file has been fully parsed, this allows, if present, to exclude the ID3v1.1 header length
|
|
280
|
+
*/
|
|
281
|
+
finalize() {
|
|
282
|
+
let format = this.metadata.format, hasID3v1 = !!this.metadata.native.ID3v1;
|
|
283
|
+
if (this.mpegOffset !== null) {
|
|
284
|
+
if (format.duration && this.tokenizer.fileInfo.size) {
|
|
285
|
+
let mpegSize = this.tokenizer.fileInfo.size - this.mpegOffset - (hasID3v1 ? 128 : 0);
|
|
286
|
+
format.codecProfile && format.codecProfile[0] === "V" && this.metadata.setFormat("bitrate", mpegSize * 8 / format.duration);
|
|
287
|
+
}
|
|
288
|
+
if (this.tokenizer.fileInfo.size && format.codecProfile === "CBR") {
|
|
289
|
+
let mpegSize = this.tokenizer.fileInfo.size - this.mpegOffset - (hasID3v1 ? 128 : 0);
|
|
290
|
+
if (this.frame_size !== null && this.samplesPerFrame !== null) {
|
|
291
|
+
let numberOfSamples = Math.round(mpegSize / this.frame_size) * this.samplesPerFrame;
|
|
292
|
+
if (this.metadata.setFormat("numberOfSamples", numberOfSamples), format.sampleRate && !format.duration) {
|
|
293
|
+
let duration = numberOfSamples / format.sampleRate;
|
|
294
|
+
debug("Calculate CBR duration based on file size: %s", duration), this.metadata.setFormat("duration", duration);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
async sync() {
|
|
301
|
+
let gotFirstSync = !1;
|
|
302
|
+
for (; ; ) {
|
|
303
|
+
let bo = 0;
|
|
304
|
+
if (this.syncPeek.len = await this.tokenizer.peekBuffer(this.syncPeek.buf, { length: maxPeekLen, mayBeLess: !0 }), this.syncPeek.len <= 163)
|
|
305
|
+
throw new EndOfStreamError();
|
|
306
|
+
for (; ; ) {
|
|
307
|
+
if (gotFirstSync && (this.syncPeek.buf[bo] & 224) === 224) {
|
|
308
|
+
this.buf_frame_header[0] = MpegFrameHeader.SyncByte1, this.buf_frame_header[1] = this.syncPeek.buf[bo], await this.tokenizer.ignore(bo), debug(`Sync at offset=${this.tokenizer.position - 1}, frameCount=${this.frameCount}`), this.syncFrameCount === this.frameCount && (debug(`Re-synced MPEG stream, frameCount=${this.frameCount}`), this.frameCount = 0, this.frame_size = 0), this.syncFrameCount = this.frameCount;
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
if (gotFirstSync = !1, bo = this.syncPeek.buf.indexOf(MpegFrameHeader.SyncByte1, bo), bo === -1) {
|
|
312
|
+
if (this.syncPeek.len < this.syncPeek.buf.length)
|
|
313
|
+
throw new EndOfStreamError();
|
|
314
|
+
await this.tokenizer.ignore(this.syncPeek.len);
|
|
315
|
+
break;
|
|
316
|
+
}
|
|
317
|
+
++bo, gotFirstSync = !0;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Combined ADTS & MPEG (MP2 & MP3) header handling
|
|
323
|
+
* @return {Promise<boolean>} true if parser should quit
|
|
324
|
+
*/
|
|
325
|
+
async parseCommonMpegHeader() {
|
|
326
|
+
this.frameCount === 0 && (this.mpegOffset = this.tokenizer.position - 1), await this.tokenizer.peekBuffer(this.buf_frame_header.subarray(1), { length: 3 });
|
|
327
|
+
let header;
|
|
328
|
+
try {
|
|
329
|
+
header = FrameHeader.get(this.buf_frame_header, 0);
|
|
330
|
+
} catch (err) {
|
|
331
|
+
if (await this.tokenizer.ignore(1), err instanceof Error)
|
|
332
|
+
return this.metadata.addWarning(`Parse error: ${err.message}`), !1;
|
|
333
|
+
throw err;
|
|
334
|
+
}
|
|
335
|
+
return await this.tokenizer.ignore(3), this.metadata.setFormat("container", header.container), this.metadata.setFormat("codec", header.codec), this.metadata.setFormat("lossless", !1), this.metadata.setFormat("sampleRate", header.samplingRate), this.frameCount++, header.version !== null && header.version >= 2 && header.layer === 0 ? this.parseAdts(header) : this.parseAudioFrameHeader(header);
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* @return {Promise<boolean>} true if parser should quit
|
|
339
|
+
*/
|
|
340
|
+
async parseAudioFrameHeader(header) {
|
|
341
|
+
this.metadata.setFormat("numberOfChannels", header.channelMode === "mono" ? 1 : 2), this.metadata.setFormat("bitrate", header.bitrate), this.frameCount < 20 * 1e4 && debug("offset=%s MP%s bitrate=%s sample-rate=%s", this.tokenizer.position - 4, header.layer, header.bitrate, header.samplingRate);
|
|
342
|
+
let slot_size = header.calcSlotSize();
|
|
343
|
+
if (slot_size === null)
|
|
344
|
+
throw new MpegContentError("invalid slot_size");
|
|
345
|
+
let samples_per_frame = header.calcSamplesPerFrame();
|
|
346
|
+
debug(`samples_per_frame=${samples_per_frame}`);
|
|
347
|
+
let bps = samples_per_frame / 8;
|
|
348
|
+
if (header.bitrate !== null && header.samplingRate != null) {
|
|
349
|
+
let fsize = bps * header.bitrate / header.samplingRate + (header.padding ? slot_size : 0);
|
|
350
|
+
this.frame_size = Math.floor(fsize);
|
|
351
|
+
}
|
|
352
|
+
if (this.audioFrameHeader = header, header.bitrate !== null && this.bitrates.push(header.bitrate), this.frameCount === 1)
|
|
353
|
+
return this.offset = FrameHeader.len, await this.skipSideInformation(), !1;
|
|
354
|
+
if (this.frameCount === 4) {
|
|
355
|
+
if (this.areAllSame(this.bitrates)) {
|
|
356
|
+
if (this.samplesPerFrame = samples_per_frame, this.metadata.setFormat("codecProfile", "CBR"), this.tokenizer.fileInfo.size)
|
|
357
|
+
return !0;
|
|
358
|
+
} else if (this.metadata.format.duration)
|
|
359
|
+
return !0;
|
|
360
|
+
if (!this.options.duration)
|
|
361
|
+
return !0;
|
|
362
|
+
}
|
|
363
|
+
return this.options.duration && this.frameCount === 4 && (this.samplesPerFrame = samples_per_frame, this.calculateEofDuration = !0), this.offset = 4, header.isProtectedByCRC ? (await this.parseCrc(), !1) : (await this.skipSideInformation(), !1);
|
|
364
|
+
}
|
|
365
|
+
async parseAdts(header) {
|
|
366
|
+
let buf = new Uint8Array(3);
|
|
367
|
+
if (await this.tokenizer.readBuffer(buf), header.frameLength += getBitAllignedNumber(buf, 0, 0, 11), this.totalDataLength += header.frameLength, this.samplesPerFrame = 1024, header.samplingRate !== null) {
|
|
368
|
+
let framesPerSec = header.samplingRate / this.samplesPerFrame, bitrate = 8 * (this.frameCount === 0 ? 0 : this.totalDataLength / this.frameCount) * framesPerSec + 0.5;
|
|
369
|
+
this.metadata.setFormat("bitrate", bitrate), debug(`frame-count=${this.frameCount}, size=${header.frameLength} bytes, bit-rate=${bitrate}`);
|
|
370
|
+
}
|
|
371
|
+
if (await this.tokenizer.ignore(header.frameLength > 7 ? header.frameLength - 7 : 1), this.frameCount === 3)
|
|
372
|
+
if (this.metadata.setFormat("codecProfile", header.codecProfile), header.mp4ChannelConfig && this.metadata.setFormat("numberOfChannels", header.mp4ChannelConfig.length), this.options.duration)
|
|
373
|
+
this.calculateEofDuration = !0;
|
|
374
|
+
else
|
|
375
|
+
return !0;
|
|
376
|
+
return !1;
|
|
377
|
+
}
|
|
378
|
+
async parseCrc() {
|
|
379
|
+
return await this.tokenizer.ignore(INT16_BE.len), this.offset += INT16_BE.len, this.skipSideInformation();
|
|
380
|
+
}
|
|
381
|
+
async skipSideInformation() {
|
|
382
|
+
if (this.audioFrameHeader) {
|
|
383
|
+
let sideinfo_length = this.audioFrameHeader.calculateSideInfoLength();
|
|
384
|
+
if (sideinfo_length !== null) {
|
|
385
|
+
await this.tokenizer.readToken(new Uint8ArrayType(sideinfo_length)), this.offset += sideinfo_length, await this.readXtraInfoHeader();
|
|
386
|
+
return;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
async readXtraInfoHeader() {
|
|
391
|
+
let headerTag = await this.tokenizer.readToken(InfoTagHeaderTag);
|
|
392
|
+
switch (this.offset += InfoTagHeaderTag.len, headerTag) {
|
|
393
|
+
case "Info":
|
|
394
|
+
return this.metadata.setFormat("codecProfile", "CBR"), this.readXingInfoHeader();
|
|
395
|
+
case "Xing": {
|
|
396
|
+
let infoTag = await this.readXingInfoHeader();
|
|
397
|
+
if (infoTag.vbrScale !== null) {
|
|
398
|
+
let codecProfile = getVbrCodecProfile(infoTag.vbrScale);
|
|
399
|
+
this.metadata.setFormat("codecProfile", codecProfile);
|
|
400
|
+
}
|
|
401
|
+
return null;
|
|
402
|
+
}
|
|
403
|
+
case "Xtra":
|
|
404
|
+
break;
|
|
405
|
+
case "LAME": {
|
|
406
|
+
let version = await this.tokenizer.readToken(LameEncoderVersion);
|
|
407
|
+
if (this.frame_size !== null && this.frame_size >= this.offset + LameEncoderVersion.len)
|
|
408
|
+
return this.offset += LameEncoderVersion.len, this.metadata.setFormat("tool", `LAME ${version}`), await this.skipFrameData(this.frame_size - this.offset), null;
|
|
409
|
+
this.metadata.addWarning("Corrupt LAME header");
|
|
410
|
+
break;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
let frameDataLeft = this.frame_size - this.offset;
|
|
414
|
+
return frameDataLeft < 0 ? this.metadata.addWarning(`Frame ${this.frameCount}corrupt: negative frameDataLeft`) : await this.skipFrameData(frameDataLeft), null;
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* Ref: http://gabriel.mp3-tech.org/mp3infotag.html
|
|
418
|
+
* @returns {Promise<string>}
|
|
419
|
+
*/
|
|
420
|
+
async readXingInfoHeader() {
|
|
421
|
+
let offset = this.tokenizer.position, infoTag = await readXingHeader(this.tokenizer);
|
|
422
|
+
if (this.offset += this.tokenizer.position - offset, infoTag.lame && (this.metadata.setFormat("tool", `LAME ${stripNulls(infoTag.lame.version)}`), infoTag.lame.extended && (this.metadata.setFormat("trackPeakLevel", infoTag.lame.extended.track_peak), infoTag.lame.extended.track_gain && this.metadata.setFormat("trackGain", infoTag.lame.extended.track_gain.adjustment), infoTag.lame.extended.album_gain && this.metadata.setFormat("albumGain", infoTag.lame.extended.album_gain.adjustment), this.metadata.setFormat("duration", infoTag.lame.extended.music_length / 1e3))), infoTag.streamSize && this.audioFrameHeader && infoTag.numFrames !== null) {
|
|
423
|
+
let duration = this.audioFrameHeader.calcDuration(infoTag.numFrames);
|
|
424
|
+
return this.metadata.setFormat("duration", duration), debug("Get duration from Xing header: %s", this.metadata.format.duration), infoTag;
|
|
425
|
+
}
|
|
426
|
+
let frameDataLeft = this.frame_size - this.offset;
|
|
427
|
+
return await this.skipFrameData(frameDataLeft), infoTag;
|
|
428
|
+
}
|
|
429
|
+
async skipFrameData(frameDataLeft) {
|
|
430
|
+
if (frameDataLeft < 0)
|
|
431
|
+
throw new MpegContentError("frame-data-left cannot be negative");
|
|
432
|
+
await this.tokenizer.ignore(frameDataLeft);
|
|
433
|
+
}
|
|
434
|
+
areAllSame(array) {
|
|
435
|
+
let first = array[0];
|
|
436
|
+
return array.every((element) => element === first);
|
|
437
|
+
}
|
|
438
|
+
};
|
|
439
|
+
export {
|
|
440
|
+
MpegContentError,
|
|
441
|
+
MpegParser
|
|
442
|
+
};
|