agdi 3.3.6 → 3.3.8
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/README.md +13 -0
- package/dist/APEv2Parser-EU45AV6X.js +14 -0
- package/dist/AiffParser-FOX7GQ42.js +189 -0
- package/dist/AsfParser-HD5CSGIO.js +610 -0
- package/dist/DsdiffParser-OJREDMBI.js +188 -0
- package/dist/DsfParser-2YL4ARJ7.js +110 -0
- package/dist/FlacParser-IVV4RYF6.js +15 -0
- package/dist/MP4Parser-NLX4A2YN.js +1140 -0
- package/dist/MatroskaParser-4OEK43GF.js +654 -0
- package/dist/MpegParser-PXKEUF2B.js +642 -0
- package/dist/MusepackParser-54QGYRLY.js +322 -0
- package/dist/OggParser-KRV5QCGZ.js +435 -0
- package/dist/WavPackParser-XPZSQFVS.js +203 -0
- package/dist/WaveParser-27IS2RAI.js +294 -0
- package/dist/chunk-2B4QMSZW.js +311 -0
- package/dist/chunk-3JKZUGPJ.js +70 -0
- package/dist/chunk-4VNS5WPM.js +42 -0
- package/dist/chunk-65JVFJ3X.js +729 -0
- package/dist/chunk-6OKLAJRQ.js +0 -0
- package/dist/chunk-AGSFUVRG.js +439 -0
- package/dist/chunk-GD35BJSH.js +177 -0
- package/dist/chunk-HNLU36CC.js +702 -0
- package/dist/{chunk-M2FF7ETI.js → chunk-J6OLLWVT.js} +1 -1
- package/dist/chunk-LREP5CZP.js +146 -0
- package/dist/chunk-M54HVABG.js +34 -0
- package/dist/{chunk-S45VXJEO.js → chunk-OPFFFAQC.js} +19 -1
- package/dist/chunk-VGOIHW7D.js +1529 -0
- package/dist/chunk-YIHDW7JC.js +314 -0
- package/dist/config-D3QBUN2Y.js +13 -0
- package/dist/{config-ZFU7TSU2.js → config-K2XM6D4Z.js} +3 -2
- package/dist/{event-bus-Q3WCETQQ.js → event-bus-MO5SFUME.js} +1 -0
- package/dist/index.js +3966 -1203
- package/dist/lib-2XISBYT3.js +144950 -0
- package/dist/lib-HCGLI2GJ.js +4161 -0
- package/dist/{telemetry-service-OHU5NKON.js → telemetry-service-76YPOPDM.js} +8 -4
- package/package.json +5 -2
|
@@ -0,0 +1,435 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BlockHeader,
|
|
3
|
+
BlockStreamInfo,
|
|
4
|
+
BlockType,
|
|
5
|
+
FlacParser,
|
|
6
|
+
VorbisPictureToken,
|
|
7
|
+
VorbisStream
|
|
8
|
+
} from "./chunk-AGSFUVRG.js";
|
|
9
|
+
import "./chunk-3JKZUGPJ.js";
|
|
10
|
+
import "./chunk-65JVFJ3X.js";
|
|
11
|
+
import "./chunk-2B4QMSZW.js";
|
|
12
|
+
import {
|
|
13
|
+
FourCcToken
|
|
14
|
+
} from "./chunk-YIHDW7JC.js";
|
|
15
|
+
import {
|
|
16
|
+
EndOfStreamError
|
|
17
|
+
} from "./chunk-HNLU36CC.js";
|
|
18
|
+
import "./chunk-LREP5CZP.js";
|
|
19
|
+
import {
|
|
20
|
+
getBit,
|
|
21
|
+
trimRightNull
|
|
22
|
+
} from "./chunk-GD35BJSH.js";
|
|
23
|
+
import {
|
|
24
|
+
BasicParser,
|
|
25
|
+
INT32_LE,
|
|
26
|
+
StringType,
|
|
27
|
+
UINT16_BE,
|
|
28
|
+
UINT16_LE,
|
|
29
|
+
UINT24_BE,
|
|
30
|
+
UINT32_LE,
|
|
31
|
+
UINT64_LE,
|
|
32
|
+
UINT8,
|
|
33
|
+
Uint8ArrayType,
|
|
34
|
+
makeUnexpectedFileContentError,
|
|
35
|
+
require_src
|
|
36
|
+
} from "./chunk-VGOIHW7D.js";
|
|
37
|
+
import {
|
|
38
|
+
__toESM
|
|
39
|
+
} from "./chunk-4VNS5WPM.js";
|
|
40
|
+
|
|
41
|
+
// ../../node_modules/.pnpm/music-metadata@11.12.0/node_modules/music-metadata/lib/ogg/OggParser.js
|
|
42
|
+
var import_debug4 = __toESM(require_src(), 1);
|
|
43
|
+
|
|
44
|
+
// ../../node_modules/.pnpm/music-metadata@11.12.0/node_modules/music-metadata/lib/ogg/opus/Opus.js
|
|
45
|
+
var OpusContentError = class extends makeUnexpectedFileContentError("Opus") {
|
|
46
|
+
};
|
|
47
|
+
var IdHeader = class {
|
|
48
|
+
constructor(len) {
|
|
49
|
+
if (len < 19) {
|
|
50
|
+
throw new OpusContentError("ID-header-page 0 should be at least 19 bytes long");
|
|
51
|
+
}
|
|
52
|
+
this.len = len;
|
|
53
|
+
}
|
|
54
|
+
get(buf, off) {
|
|
55
|
+
return {
|
|
56
|
+
magicSignature: new StringType(8, "ascii").get(buf, off + 0),
|
|
57
|
+
version: UINT8.get(buf, off + 8),
|
|
58
|
+
channelCount: UINT8.get(buf, off + 9),
|
|
59
|
+
preSkip: UINT16_LE.get(buf, off + 10),
|
|
60
|
+
inputSampleRate: UINT32_LE.get(buf, off + 12),
|
|
61
|
+
outputGain: UINT16_LE.get(buf, off + 16),
|
|
62
|
+
channelMapping: UINT8.get(buf, off + 18)
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
// ../../node_modules/.pnpm/music-metadata@11.12.0/node_modules/music-metadata/lib/ogg/opus/OpusStream.js
|
|
68
|
+
var OpusStream = class extends VorbisStream {
|
|
69
|
+
constructor(metadata, options, tokenizer) {
|
|
70
|
+
super(metadata, options);
|
|
71
|
+
this.idHeader = null;
|
|
72
|
+
this.lastPos = -1;
|
|
73
|
+
this.tokenizer = tokenizer;
|
|
74
|
+
this.durationOnLastPage = true;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Parse first Opus Ogg page
|
|
78
|
+
* @param {IPageHeader} header
|
|
79
|
+
* @param {Uint8Array} pageData
|
|
80
|
+
*/
|
|
81
|
+
parseFirstPage(_header, pageData) {
|
|
82
|
+
this.metadata.setFormat("codec", "Opus");
|
|
83
|
+
this.idHeader = new IdHeader(pageData.length).get(pageData, 0);
|
|
84
|
+
if (this.idHeader.magicSignature !== "OpusHead")
|
|
85
|
+
throw new OpusContentError("Illegal ogg/Opus magic-signature");
|
|
86
|
+
this.metadata.setFormat("sampleRate", this.idHeader.inputSampleRate);
|
|
87
|
+
this.metadata.setFormat("numberOfChannels", this.idHeader.channelCount);
|
|
88
|
+
this.metadata.setAudioOnly();
|
|
89
|
+
}
|
|
90
|
+
async parseFullPage(pageData) {
|
|
91
|
+
const magicSignature = new StringType(8, "ascii").get(pageData, 0);
|
|
92
|
+
switch (magicSignature) {
|
|
93
|
+
case "OpusTags":
|
|
94
|
+
await this.parseUserCommentList(pageData, 8);
|
|
95
|
+
this.lastPos = this.tokenizer.position - pageData.length;
|
|
96
|
+
break;
|
|
97
|
+
default:
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
calculateDuration(enfOfStream) {
|
|
102
|
+
if (this.lastPageHeader && (enfOfStream || this.lastPageHeader.headerType.lastPage) && this.metadata.format.sampleRate && this.lastPageHeader.absoluteGranulePosition >= 0) {
|
|
103
|
+
const pos_48bit = this.lastPageHeader.absoluteGranulePosition - this.idHeader.preSkip;
|
|
104
|
+
this.metadata.setFormat("numberOfSamples", pos_48bit);
|
|
105
|
+
this.metadata.setFormat("duration", pos_48bit / 48e3);
|
|
106
|
+
if (this.lastPos !== -1 && this.tokenizer.fileInfo.size && this.metadata.format.duration) {
|
|
107
|
+
const dataSize = this.tokenizer.fileInfo.size - this.lastPos;
|
|
108
|
+
this.metadata.setFormat("bitrate", 8 * dataSize / this.metadata.format.duration);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
// ../../node_modules/.pnpm/music-metadata@11.12.0/node_modules/music-metadata/lib/ogg/speex/SpeexStream.js
|
|
115
|
+
var import_debug = __toESM(require_src(), 1);
|
|
116
|
+
|
|
117
|
+
// ../../node_modules/.pnpm/music-metadata@11.12.0/node_modules/music-metadata/lib/ogg/speex/Speex.js
|
|
118
|
+
var Header = {
|
|
119
|
+
len: 80,
|
|
120
|
+
get: (buf, off) => {
|
|
121
|
+
return {
|
|
122
|
+
speex: new StringType(8, "ascii").get(buf, off + 0),
|
|
123
|
+
version: trimRightNull(new StringType(20, "ascii").get(buf, off + 8)),
|
|
124
|
+
version_id: INT32_LE.get(buf, off + 28),
|
|
125
|
+
header_size: INT32_LE.get(buf, off + 32),
|
|
126
|
+
rate: INT32_LE.get(buf, off + 36),
|
|
127
|
+
mode: INT32_LE.get(buf, off + 40),
|
|
128
|
+
mode_bitstream_version: INT32_LE.get(buf, off + 44),
|
|
129
|
+
nb_channels: INT32_LE.get(buf, off + 48),
|
|
130
|
+
bitrate: INT32_LE.get(buf, off + 52),
|
|
131
|
+
frame_size: INT32_LE.get(buf, off + 56),
|
|
132
|
+
vbr: INT32_LE.get(buf, off + 60),
|
|
133
|
+
frames_per_packet: INT32_LE.get(buf, off + 64),
|
|
134
|
+
extra_headers: INT32_LE.get(buf, off + 68),
|
|
135
|
+
reserved1: INT32_LE.get(buf, off + 72),
|
|
136
|
+
reserved2: INT32_LE.get(buf, off + 76)
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
// ../../node_modules/.pnpm/music-metadata@11.12.0/node_modules/music-metadata/lib/ogg/speex/SpeexStream.js
|
|
142
|
+
var debug = (0, import_debug.default)("music-metadata:parser:ogg:speex");
|
|
143
|
+
var SpeexStream = class extends VorbisStream {
|
|
144
|
+
constructor(metadata, options, _tokenizer) {
|
|
145
|
+
super(metadata, options);
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Parse first Speex Ogg page
|
|
149
|
+
* @param {IPageHeader} header
|
|
150
|
+
* @param {Uint8Array} pageData
|
|
151
|
+
*/
|
|
152
|
+
parseFirstPage(_header, pageData) {
|
|
153
|
+
debug("First Ogg/Speex page");
|
|
154
|
+
const speexHeader = Header.get(pageData, 0);
|
|
155
|
+
this.metadata.setFormat("codec", `Speex ${speexHeader.version}`);
|
|
156
|
+
this.metadata.setFormat("numberOfChannels", speexHeader.nb_channels);
|
|
157
|
+
this.metadata.setFormat("sampleRate", speexHeader.rate);
|
|
158
|
+
if (speexHeader.bitrate !== -1) {
|
|
159
|
+
this.metadata.setFormat("bitrate", speexHeader.bitrate);
|
|
160
|
+
}
|
|
161
|
+
this.metadata.setAudioOnly();
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
// ../../node_modules/.pnpm/music-metadata@11.12.0/node_modules/music-metadata/lib/ogg/theora/TheoraStream.js
|
|
166
|
+
var import_debug2 = __toESM(require_src(), 1);
|
|
167
|
+
|
|
168
|
+
// ../../node_modules/.pnpm/music-metadata@11.12.0/node_modules/music-metadata/lib/ogg/theora/Theora.js
|
|
169
|
+
var IdentificationHeader = {
|
|
170
|
+
len: 42,
|
|
171
|
+
get: (buf, off) => {
|
|
172
|
+
return {
|
|
173
|
+
id: new StringType(7, "ascii").get(buf, off),
|
|
174
|
+
vmaj: UINT8.get(buf, off + 7),
|
|
175
|
+
vmin: UINT8.get(buf, off + 8),
|
|
176
|
+
vrev: UINT8.get(buf, off + 9),
|
|
177
|
+
vmbw: UINT16_BE.get(buf, off + 10),
|
|
178
|
+
vmbh: UINT16_BE.get(buf, off + 17),
|
|
179
|
+
nombr: UINT24_BE.get(buf, off + 37),
|
|
180
|
+
nqual: UINT8.get(buf, off + 40)
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
// ../../node_modules/.pnpm/music-metadata@11.12.0/node_modules/music-metadata/lib/ogg/theora/TheoraStream.js
|
|
186
|
+
var debug2 = (0, import_debug2.default)("music-metadata:parser:ogg:theora");
|
|
187
|
+
var TheoraStream = class {
|
|
188
|
+
constructor(metadata, _options, _tokenizer) {
|
|
189
|
+
this.durationOnLastPage = false;
|
|
190
|
+
this.metadata = metadata;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Vorbis 1 parser
|
|
194
|
+
* @param header Ogg Page Header
|
|
195
|
+
* @param pageData Page data
|
|
196
|
+
*/
|
|
197
|
+
async parsePage(header, pageData) {
|
|
198
|
+
if (header.headerType.firstPage) {
|
|
199
|
+
await this.parseFirstPage(header, pageData);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
calculateDuration() {
|
|
203
|
+
debug2("duration calculation not implemented");
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Parse first Theora Ogg page. the initial identification header packet
|
|
207
|
+
*/
|
|
208
|
+
async parseFirstPage(_header, pageData) {
|
|
209
|
+
debug2("First Ogg/Theora page");
|
|
210
|
+
this.metadata.setFormat("codec", "Theora");
|
|
211
|
+
const idHeader = IdentificationHeader.get(pageData, 0);
|
|
212
|
+
this.metadata.setFormat("bitrate", idHeader.nombr);
|
|
213
|
+
this.metadata.setFormat("hasVideo", true);
|
|
214
|
+
}
|
|
215
|
+
flush() {
|
|
216
|
+
return Promise.resolve();
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
// ../../node_modules/.pnpm/music-metadata@11.12.0/node_modules/music-metadata/lib/ogg/OggToken.js
|
|
221
|
+
var PageHeader = {
|
|
222
|
+
len: 27,
|
|
223
|
+
get: (buf, off) => {
|
|
224
|
+
return {
|
|
225
|
+
capturePattern: new StringType(4, "latin1").get(buf, off),
|
|
226
|
+
version: UINT8.get(buf, off + 4),
|
|
227
|
+
headerType: {
|
|
228
|
+
continued: getBit(buf, off + 5, 0),
|
|
229
|
+
firstPage: getBit(buf, off + 5, 1),
|
|
230
|
+
lastPage: getBit(buf, off + 5, 2)
|
|
231
|
+
},
|
|
232
|
+
// packet_flag: Token.UINT8.get(buf, off + 5),
|
|
233
|
+
absoluteGranulePosition: Number(UINT64_LE.get(buf, off + 6)),
|
|
234
|
+
streamSerialNumber: UINT32_LE.get(buf, off + 14),
|
|
235
|
+
pageSequenceNo: UINT32_LE.get(buf, off + 18),
|
|
236
|
+
pageChecksum: UINT32_LE.get(buf, off + 22),
|
|
237
|
+
page_segments: UINT8.get(buf, off + 26)
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
};
|
|
241
|
+
var SegmentTable = class _SegmentTable {
|
|
242
|
+
static sum(buf, off, len) {
|
|
243
|
+
const dv = new DataView(buf.buffer, 0);
|
|
244
|
+
let s = 0;
|
|
245
|
+
for (let i = off; i < off + len; ++i) {
|
|
246
|
+
s += dv.getUint8(i);
|
|
247
|
+
}
|
|
248
|
+
return s;
|
|
249
|
+
}
|
|
250
|
+
constructor(header) {
|
|
251
|
+
this.len = header.page_segments;
|
|
252
|
+
}
|
|
253
|
+
get(buf, off) {
|
|
254
|
+
return {
|
|
255
|
+
totalPageSize: _SegmentTable.sum(buf, off, this.len)
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
// ../../node_modules/.pnpm/music-metadata@11.12.0/node_modules/music-metadata/lib/ogg/flac/FlacStream.js
|
|
261
|
+
var import_debug3 = __toESM(require_src(), 1);
|
|
262
|
+
var debug3 = (0, import_debug3.default)("music-metadata:parser:ogg:theora");
|
|
263
|
+
var FlacStream = class {
|
|
264
|
+
constructor(metadata, options, tokenizer) {
|
|
265
|
+
this.durationOnLastPage = false;
|
|
266
|
+
this.metadata = metadata;
|
|
267
|
+
this.options = options;
|
|
268
|
+
this.tokenizer = tokenizer;
|
|
269
|
+
this.flacParser = new FlacParser(this.metadata, this.tokenizer, options);
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Vorbis 1 parser
|
|
273
|
+
* @param header Ogg Page Header
|
|
274
|
+
* @param pageData Page data
|
|
275
|
+
*/
|
|
276
|
+
async parsePage(header, pageData) {
|
|
277
|
+
if (header.headerType.firstPage) {
|
|
278
|
+
await this.parseFirstPage(header, pageData);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
calculateDuration() {
|
|
282
|
+
debug3("duration calculation not implemented");
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Parse first Theora Ogg page. the initial identification header packet
|
|
286
|
+
*/
|
|
287
|
+
async parseFirstPage(_header, pageData) {
|
|
288
|
+
debug3("First Ogg/FLAC page");
|
|
289
|
+
const fourCC = await FourCcToken.get(pageData, 9);
|
|
290
|
+
if (fourCC.toString() !== "fLaC") {
|
|
291
|
+
throw new Error("Invalid FLAC preamble");
|
|
292
|
+
}
|
|
293
|
+
const blockHeader = await BlockHeader.get(pageData, 13);
|
|
294
|
+
await this.parseDataBlock(blockHeader, pageData.subarray(13 + BlockHeader.len));
|
|
295
|
+
}
|
|
296
|
+
async parseDataBlock(blockHeader, pageData) {
|
|
297
|
+
debug3(`blockHeader type=${blockHeader.type}, length=${blockHeader.length}`);
|
|
298
|
+
switch (blockHeader.type) {
|
|
299
|
+
case BlockType.STREAMINFO: {
|
|
300
|
+
const streamInfo = BlockStreamInfo.get(pageData, 0);
|
|
301
|
+
return this.flacParser.processsStreamInfo(streamInfo);
|
|
302
|
+
}
|
|
303
|
+
case BlockType.PADDING:
|
|
304
|
+
break;
|
|
305
|
+
case BlockType.APPLICATION:
|
|
306
|
+
break;
|
|
307
|
+
case BlockType.SEEKTABLE:
|
|
308
|
+
break;
|
|
309
|
+
case BlockType.VORBIS_COMMENT:
|
|
310
|
+
return this.flacParser.parseComment(pageData);
|
|
311
|
+
case BlockType.PICTURE:
|
|
312
|
+
if (!this.options.skipCovers) {
|
|
313
|
+
const picture = new VorbisPictureToken(pageData.length).get(pageData, 0);
|
|
314
|
+
return this.flacParser.addPictureTag(picture);
|
|
315
|
+
}
|
|
316
|
+
break;
|
|
317
|
+
default:
|
|
318
|
+
this.metadata.addWarning(`Unknown block type: ${blockHeader.type}`);
|
|
319
|
+
}
|
|
320
|
+
return this.tokenizer.ignore(blockHeader.length).then();
|
|
321
|
+
}
|
|
322
|
+
flush() {
|
|
323
|
+
return Promise.resolve();
|
|
324
|
+
}
|
|
325
|
+
};
|
|
326
|
+
|
|
327
|
+
// ../../node_modules/.pnpm/music-metadata@11.12.0/node_modules/music-metadata/lib/ogg/OggParser.js
|
|
328
|
+
var OggContentError = class extends makeUnexpectedFileContentError("Ogg") {
|
|
329
|
+
};
|
|
330
|
+
var debug4 = (0, import_debug4.default)("music-metadata:parser:ogg");
|
|
331
|
+
var OggStream = class {
|
|
332
|
+
constructor(metadata, streamSerial, options) {
|
|
333
|
+
this.pageNumber = 0;
|
|
334
|
+
this.closed = false;
|
|
335
|
+
this.metadata = metadata;
|
|
336
|
+
this.streamSerial = streamSerial;
|
|
337
|
+
this.options = options;
|
|
338
|
+
}
|
|
339
|
+
async parsePage(tokenizer, header) {
|
|
340
|
+
this.pageNumber = header.pageSequenceNo;
|
|
341
|
+
debug4("serial=%s page#=%s, Ogg.id=%s", header.streamSerialNumber, header.pageSequenceNo, header.capturePattern);
|
|
342
|
+
const segmentTable = await tokenizer.readToken(new SegmentTable(header));
|
|
343
|
+
debug4("totalPageSize=%s", segmentTable.totalPageSize);
|
|
344
|
+
const pageData = await tokenizer.readToken(new Uint8ArrayType(segmentTable.totalPageSize));
|
|
345
|
+
debug4("firstPage=%s, lastPage=%s, continued=%s", header.headerType.firstPage, header.headerType.lastPage, header.headerType.continued);
|
|
346
|
+
if (header.headerType.firstPage) {
|
|
347
|
+
this.metadata.setFormat("container", "Ogg");
|
|
348
|
+
const idData = pageData.subarray(0, 7);
|
|
349
|
+
const asciiId = Array.from(idData).filter((b) => b >= 32 && b <= 126).map((b) => String.fromCharCode(b)).join("");
|
|
350
|
+
switch (asciiId) {
|
|
351
|
+
case "vorbis":
|
|
352
|
+
debug4(`Set Ogg stream serial ${header.streamSerialNumber}, codec=Vorbis`);
|
|
353
|
+
this.pageConsumer = new VorbisStream(this.metadata, this.options);
|
|
354
|
+
break;
|
|
355
|
+
case "OpusHea":
|
|
356
|
+
debug4("Set page consumer to Ogg/Opus");
|
|
357
|
+
this.pageConsumer = new OpusStream(this.metadata, this.options, tokenizer);
|
|
358
|
+
break;
|
|
359
|
+
case "Speex ":
|
|
360
|
+
debug4("Set page consumer to Ogg/Speex");
|
|
361
|
+
this.pageConsumer = new SpeexStream(this.metadata, this.options, tokenizer);
|
|
362
|
+
break;
|
|
363
|
+
case "fishead":
|
|
364
|
+
case "theora":
|
|
365
|
+
debug4("Set page consumer to Ogg/Theora");
|
|
366
|
+
this.pageConsumer = new TheoraStream(this.metadata, this.options, tokenizer);
|
|
367
|
+
break;
|
|
368
|
+
case "FLAC":
|
|
369
|
+
debug4("Set page consumer to Vorbis");
|
|
370
|
+
this.pageConsumer = new FlacStream(this.metadata, this.options, tokenizer);
|
|
371
|
+
break;
|
|
372
|
+
default:
|
|
373
|
+
throw new OggContentError(`Ogg codec not recognized (id=${asciiId}`);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
if (header.headerType.lastPage) {
|
|
377
|
+
this.closed = true;
|
|
378
|
+
}
|
|
379
|
+
if (this.pageConsumer) {
|
|
380
|
+
await this.pageConsumer.parsePage(header, pageData);
|
|
381
|
+
} else
|
|
382
|
+
throw new Error("pageConsumer should be initialized");
|
|
383
|
+
}
|
|
384
|
+
};
|
|
385
|
+
var OggParser = class extends BasicParser {
|
|
386
|
+
constructor() {
|
|
387
|
+
super(...arguments);
|
|
388
|
+
this.streams = /* @__PURE__ */ new Map();
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* Parse page
|
|
392
|
+
* @returns {Promise<void>}
|
|
393
|
+
*/
|
|
394
|
+
async parse() {
|
|
395
|
+
this.streams = /* @__PURE__ */ new Map();
|
|
396
|
+
let enfOfStream = false;
|
|
397
|
+
let header;
|
|
398
|
+
try {
|
|
399
|
+
do {
|
|
400
|
+
header = await this.tokenizer.readToken(PageHeader);
|
|
401
|
+
if (header.capturePattern !== "OggS")
|
|
402
|
+
throw new OggContentError("Invalid Ogg capture pattern");
|
|
403
|
+
let stream = this.streams.get(header.streamSerialNumber);
|
|
404
|
+
if (!stream) {
|
|
405
|
+
stream = new OggStream(this.metadata, header.streamSerialNumber, this.options);
|
|
406
|
+
this.streams.set(header.streamSerialNumber, stream);
|
|
407
|
+
}
|
|
408
|
+
await stream.parsePage(this.tokenizer, header);
|
|
409
|
+
if (stream.pageNumber > 12 && !(this.options.duration && [...this.streams.values()].find((stream2) => stream2.pageConsumer?.durationOnLastPage))) {
|
|
410
|
+
debug4("Stop processing Ogg stream");
|
|
411
|
+
break;
|
|
412
|
+
}
|
|
413
|
+
} while (![...this.streams.values()].every((item) => item.closed));
|
|
414
|
+
} catch (err) {
|
|
415
|
+
if (err instanceof EndOfStreamError) {
|
|
416
|
+
debug4("Reached end-of-stream");
|
|
417
|
+
enfOfStream = true;
|
|
418
|
+
} else if (err instanceof OggContentError) {
|
|
419
|
+
this.metadata.addWarning(`Corrupt Ogg content at ${this.tokenizer.position}`);
|
|
420
|
+
} else
|
|
421
|
+
throw err;
|
|
422
|
+
}
|
|
423
|
+
for (const stream of this.streams.values()) {
|
|
424
|
+
if (!stream.closed) {
|
|
425
|
+
this.metadata.addWarning(`End-of-stream reached before reaching last page in Ogg stream serial=${stream.streamSerial}`);
|
|
426
|
+
await stream.pageConsumer?.flush();
|
|
427
|
+
}
|
|
428
|
+
stream.pageConsumer?.calculateDuration(enfOfStream);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
};
|
|
432
|
+
export {
|
|
433
|
+
OggContentError,
|
|
434
|
+
OggParser
|
|
435
|
+
};
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import {
|
|
2
|
+
FourCcToken,
|
|
3
|
+
tryParseApeHeader
|
|
4
|
+
} from "./chunk-YIHDW7JC.js";
|
|
5
|
+
import "./chunk-HNLU36CC.js";
|
|
6
|
+
import {
|
|
7
|
+
uint8ArrayToHex
|
|
8
|
+
} from "./chunk-GD35BJSH.js";
|
|
9
|
+
import {
|
|
10
|
+
BasicParser,
|
|
11
|
+
UINT16_LE,
|
|
12
|
+
UINT24_LE,
|
|
13
|
+
UINT32_LE,
|
|
14
|
+
UINT8,
|
|
15
|
+
Uint8ArrayType,
|
|
16
|
+
makeUnexpectedFileContentError,
|
|
17
|
+
require_src
|
|
18
|
+
} from "./chunk-VGOIHW7D.js";
|
|
19
|
+
import {
|
|
20
|
+
__toESM
|
|
21
|
+
} from "./chunk-4VNS5WPM.js";
|
|
22
|
+
|
|
23
|
+
// ../../node_modules/.pnpm/music-metadata@11.12.0/node_modules/music-metadata/lib/wavpack/WavPackToken.js
|
|
24
|
+
var SampleRates = [
|
|
25
|
+
6e3,
|
|
26
|
+
8e3,
|
|
27
|
+
9600,
|
|
28
|
+
11025,
|
|
29
|
+
12e3,
|
|
30
|
+
16e3,
|
|
31
|
+
22050,
|
|
32
|
+
24e3,
|
|
33
|
+
32e3,
|
|
34
|
+
44100,
|
|
35
|
+
48e3,
|
|
36
|
+
64e3,
|
|
37
|
+
88200,
|
|
38
|
+
96e3,
|
|
39
|
+
192e3,
|
|
40
|
+
-1
|
|
41
|
+
];
|
|
42
|
+
var BlockHeaderToken = {
|
|
43
|
+
len: 32,
|
|
44
|
+
get: (buf, off) => {
|
|
45
|
+
const flags = UINT32_LE.get(buf, off + 24);
|
|
46
|
+
const res = {
|
|
47
|
+
// should equal 'wvpk'
|
|
48
|
+
BlockID: FourCcToken.get(buf, off),
|
|
49
|
+
// 0x402 to 0x410 are valid for decode
|
|
50
|
+
blockSize: UINT32_LE.get(buf, off + 4),
|
|
51
|
+
// 0x402 (1026) to 0x410 are valid for decode
|
|
52
|
+
version: UINT16_LE.get(buf, off + 8),
|
|
53
|
+
// 40-bit total samples for entire file (if block_index == 0 and a value of -1 indicates an unknown length)
|
|
54
|
+
totalSamples: (
|
|
55
|
+
/* replace with bigint? (Token.UINT8.get(buf, off + 11) << 32) + */
|
|
56
|
+
UINT32_LE.get(buf, off + 12)
|
|
57
|
+
),
|
|
58
|
+
// 40-bit block_index
|
|
59
|
+
blockIndex: (
|
|
60
|
+
/* replace with bigint? (Token.UINT8.get(buf, off + 10) << 32) + */
|
|
61
|
+
UINT32_LE.get(buf, off + 16)
|
|
62
|
+
),
|
|
63
|
+
// 40-bit total samples for entire file (if block_index == 0 and a value of -1 indicates an unknown length)
|
|
64
|
+
blockSamples: UINT32_LE.get(buf, off + 20),
|
|
65
|
+
// various flags for id and decoding
|
|
66
|
+
flags: {
|
|
67
|
+
bitsPerSample: (1 + getBitAllignedNumber(flags, 0, 2)) * 8,
|
|
68
|
+
isMono: isBitSet(flags, 2),
|
|
69
|
+
isHybrid: isBitSet(flags, 3),
|
|
70
|
+
isJointStereo: isBitSet(flags, 4),
|
|
71
|
+
crossChannel: isBitSet(flags, 5),
|
|
72
|
+
hybridNoiseShaping: isBitSet(flags, 6),
|
|
73
|
+
floatingPoint: isBitSet(flags, 7),
|
|
74
|
+
samplingRate: SampleRates[getBitAllignedNumber(flags, 23, 4)],
|
|
75
|
+
isDSD: isBitSet(flags, 31)
|
|
76
|
+
},
|
|
77
|
+
// crc for actual decoded data
|
|
78
|
+
crc: new Uint8ArrayType(4).get(buf, off + 28)
|
|
79
|
+
};
|
|
80
|
+
if (res.flags.isDSD) {
|
|
81
|
+
res.totalSamples *= 8;
|
|
82
|
+
}
|
|
83
|
+
return res;
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
var MetadataIdToken = {
|
|
87
|
+
len: 1,
|
|
88
|
+
get: (buf, off) => {
|
|
89
|
+
return {
|
|
90
|
+
functionId: getBitAllignedNumber(buf[off], 0, 6),
|
|
91
|
+
// functionId overlaps with isOptional flag
|
|
92
|
+
isOptional: isBitSet(buf[off], 5),
|
|
93
|
+
isOddSize: isBitSet(buf[off], 6),
|
|
94
|
+
largeBlock: isBitSet(buf[off], 7)
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
function isBitSet(flags, bitOffset) {
|
|
99
|
+
return getBitAllignedNumber(flags, bitOffset, 1) === 1;
|
|
100
|
+
}
|
|
101
|
+
function getBitAllignedNumber(flags, bitOffset, len) {
|
|
102
|
+
return flags >>> bitOffset & 4294967295 >>> 32 - len;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// ../../node_modules/.pnpm/music-metadata@11.12.0/node_modules/music-metadata/lib/wavpack/WavPackParser.js
|
|
106
|
+
var import_debug = __toESM(require_src(), 1);
|
|
107
|
+
var debug = (0, import_debug.default)("music-metadata:parser:WavPack");
|
|
108
|
+
var WavPackContentError = class extends makeUnexpectedFileContentError("WavPack") {
|
|
109
|
+
};
|
|
110
|
+
var WavPackParser = class extends BasicParser {
|
|
111
|
+
constructor() {
|
|
112
|
+
super(...arguments);
|
|
113
|
+
this.audioDataSize = 0;
|
|
114
|
+
}
|
|
115
|
+
async parse() {
|
|
116
|
+
this.metadata.setAudioOnly();
|
|
117
|
+
this.audioDataSize = 0;
|
|
118
|
+
await this.parseWavPackBlocks();
|
|
119
|
+
return tryParseApeHeader(this.metadata, this.tokenizer, this.options);
|
|
120
|
+
}
|
|
121
|
+
async parseWavPackBlocks() {
|
|
122
|
+
do {
|
|
123
|
+
const blockId = await this.tokenizer.peekToken(FourCcToken);
|
|
124
|
+
if (blockId !== "wvpk")
|
|
125
|
+
break;
|
|
126
|
+
const header = await this.tokenizer.readToken(BlockHeaderToken);
|
|
127
|
+
if (header.BlockID !== "wvpk")
|
|
128
|
+
throw new WavPackContentError("Invalid WavPack Block-ID");
|
|
129
|
+
debug(`WavPack header blockIndex=${header.blockIndex}, len=${BlockHeaderToken.len}`);
|
|
130
|
+
if (header.blockIndex === 0 && !this.metadata.format.container) {
|
|
131
|
+
this.metadata.setFormat("container", "WavPack");
|
|
132
|
+
this.metadata.setFormat("lossless", !header.flags.isHybrid);
|
|
133
|
+
this.metadata.setFormat("bitsPerSample", header.flags.bitsPerSample);
|
|
134
|
+
if (!header.flags.isDSD) {
|
|
135
|
+
this.metadata.setFormat("sampleRate", header.flags.samplingRate);
|
|
136
|
+
this.metadata.setFormat("duration", header.totalSamples / header.flags.samplingRate);
|
|
137
|
+
}
|
|
138
|
+
this.metadata.setFormat("numberOfChannels", header.flags.isMono ? 1 : 2);
|
|
139
|
+
this.metadata.setFormat("numberOfSamples", header.totalSamples);
|
|
140
|
+
this.metadata.setFormat("codec", header.flags.isDSD ? "DSD" : "PCM");
|
|
141
|
+
}
|
|
142
|
+
const ignoreBytes = header.blockSize - (BlockHeaderToken.len - 8);
|
|
143
|
+
await (header.blockIndex === 0 ? this.parseMetadataSubBlock(header, ignoreBytes) : this.tokenizer.ignore(ignoreBytes));
|
|
144
|
+
if (header.blockSamples > 0) {
|
|
145
|
+
this.audioDataSize += header.blockSize;
|
|
146
|
+
}
|
|
147
|
+
} while (!this.tokenizer.fileInfo.size || this.tokenizer.fileInfo.size - this.tokenizer.position >= BlockHeaderToken.len);
|
|
148
|
+
if (this.metadata.format.duration) {
|
|
149
|
+
this.metadata.setFormat("bitrate", this.audioDataSize * 8 / this.metadata.format.duration);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Ref: http://www.wavpack.com/WavPack5FileFormat.pdf, 3.0 Metadata Sub-blocks
|
|
154
|
+
* @param header Header
|
|
155
|
+
* @param remainingLength Remaining length
|
|
156
|
+
*/
|
|
157
|
+
async parseMetadataSubBlock(header, remainingLength) {
|
|
158
|
+
let remaining = remainingLength;
|
|
159
|
+
while (remaining > MetadataIdToken.len) {
|
|
160
|
+
const id = await this.tokenizer.readToken(MetadataIdToken);
|
|
161
|
+
const dataSizeInWords = await this.tokenizer.readNumber(id.largeBlock ? UINT24_LE : UINT8);
|
|
162
|
+
const data = new Uint8Array(dataSizeInWords * 2 - (id.isOddSize ? 1 : 0));
|
|
163
|
+
await this.tokenizer.readBuffer(data);
|
|
164
|
+
debug(`Metadata Sub-Blocks functionId=0x${id.functionId.toString(16)}, id.largeBlock=${id.largeBlock},data-size=${data.length}`);
|
|
165
|
+
switch (id.functionId) {
|
|
166
|
+
case 0:
|
|
167
|
+
break;
|
|
168
|
+
case 14: {
|
|
169
|
+
debug("ID_DSD_BLOCK");
|
|
170
|
+
const mp = 1 << UINT8.get(data, 0);
|
|
171
|
+
const samplingRate = header.flags.samplingRate * mp * 8;
|
|
172
|
+
if (!header.flags.isDSD)
|
|
173
|
+
throw new WavPackContentError("Only expect DSD block if DSD-flag is set");
|
|
174
|
+
this.metadata.setFormat("sampleRate", samplingRate);
|
|
175
|
+
this.metadata.setFormat("duration", header.totalSamples / samplingRate);
|
|
176
|
+
break;
|
|
177
|
+
}
|
|
178
|
+
case 36:
|
|
179
|
+
debug("ID_ALT_TRAILER: trailer for non-wav files");
|
|
180
|
+
break;
|
|
181
|
+
case 38:
|
|
182
|
+
this.metadata.setFormat("audioMD5", data);
|
|
183
|
+
break;
|
|
184
|
+
case 47:
|
|
185
|
+
debug(`ID_BLOCK_CHECKSUM: checksum=${uint8ArrayToHex(data)}`);
|
|
186
|
+
break;
|
|
187
|
+
default:
|
|
188
|
+
debug(`Ignore unsupported meta-sub-block-id functionId=0x${id.functionId.toString(16)}`);
|
|
189
|
+
break;
|
|
190
|
+
}
|
|
191
|
+
remaining -= MetadataIdToken.len + (id.largeBlock ? UINT24_LE.len : UINT8.len) + dataSizeInWords * 2;
|
|
192
|
+
debug(`remainingLength=${remaining}`);
|
|
193
|
+
if (id.isOddSize)
|
|
194
|
+
this.tokenizer.ignore(1);
|
|
195
|
+
}
|
|
196
|
+
if (remaining !== 0)
|
|
197
|
+
throw new WavPackContentError("metadata-sub-block should fit it remaining length");
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
export {
|
|
201
|
+
WavPackContentError,
|
|
202
|
+
WavPackParser
|
|
203
|
+
};
|