music-metadata 7.12.4 → 8.0.0
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 +47 -31
- package/lib/ParserFactory.js +37 -41
- package/lib/aiff/AiffParser.js +25 -17
- package/lib/aiff/AiffToken.js +13 -12
- package/lib/apev2/APEv2Parser.js +29 -32
- package/lib/apev2/APEv2TagMapper.js +2 -6
- package/lib/apev2/APEv2Token.js +13 -19
- package/lib/asf/AsfObject.js +42 -56
- package/lib/asf/AsfParser.js +15 -19
- package/lib/asf/AsfTagMapper.js +2 -6
- package/lib/asf/AsfUtil.js +4 -7
- package/lib/asf/GUID.js +1 -4
- package/lib/common/BasicParser.js +1 -5
- package/lib/common/CaseInsensitiveTagMap.js +2 -6
- package/lib/common/CombinedTagMapper.js +20 -24
- package/lib/common/FourCC.js +3 -6
- package/lib/common/GenericTagMapper.js +2 -6
- package/lib/common/GenericTagTypes.js +5 -10
- package/lib/common/MetadataCollector.js +20 -25
- package/lib/common/RandomFileReader.js +2 -6
- package/lib/common/RandomUint8ArrayReader.js +1 -5
- package/lib/common/Util.js +11 -25
- package/lib/core.js +18 -28
- package/lib/dsdiff/DsdiffParser.js +24 -28
- package/lib/dsdiff/DsdiffToken.js +4 -7
- package/lib/dsf/DsfChunk.js +8 -11
- package/lib/dsf/DsfParser.js +13 -17
- package/lib/flac/FlacParser.js +22 -26
- package/lib/id3v1/ID3v1Parser.js +16 -21
- package/lib/id3v1/ID3v1TagMap.js +2 -6
- package/lib/id3v2/AbstractID3Parser.js +13 -17
- package/lib/id3v2/FrameParser.js +12 -17
- package/lib/id3v2/ID3v22TagMapper.js +4 -8
- package/lib/id3v2/ID3v24TagMapper.js +5 -9
- package/lib/id3v2/ID3v2Parser.js +10 -14
- package/lib/id3v2/ID3v2Token.js +9 -12
- package/lib/iff/index.js +4 -7
- package/lib/index.js +14 -44
- package/lib/lyrics3/Lyrics3.js +3 -7
- package/lib/matroska/MatroskaDtd.js +111 -114
- package/lib/matroska/MatroskaParser.js +20 -24
- package/lib/matroska/MatroskaTagMapper.js +2 -6
- package/lib/matroska/types.js +6 -9
- package/lib/mp4/Atom.js +4 -8
- package/lib/mp4/AtomToken.js +29 -44
- package/lib/mp4/MP4Parser.js +12 -16
- package/lib/mp4/MP4TagMapper.js +4 -8
- package/lib/mpeg/ExtendedLameHeader.js +6 -9
- package/lib/mpeg/MpegParser.js +17 -21
- package/lib/mpeg/ReplayGainDataFormat.js +2 -5
- package/lib/mpeg/XingTag.js +9 -13
- package/lib/musepack/index.js +10 -12
- package/lib/musepack/sv7/BitReader.js +2 -6
- package/lib/musepack/sv7/MpcSv7Parser.js +9 -13
- package/lib/musepack/sv7/StreamVersion7.js +3 -6
- package/lib/musepack/sv8/MpcSv8Parser.js +9 -13
- package/lib/musepack/sv8/StreamVersion8.js +5 -9
- package/lib/ogg/Ogg.js +1 -2
- package/lib/ogg/OggParser.js +19 -24
- package/lib/ogg/opus/Opus.js +2 -6
- package/lib/ogg/opus/OpusParser.js +4 -8
- package/lib/ogg/speex/Speex.js +3 -6
- package/lib/ogg/speex/SpeexParser.js +5 -9
- package/lib/ogg/theora/Theora.js +2 -5
- package/lib/ogg/theora/TheoraParser.js +5 -9
- package/lib/ogg/vorbis/Vorbis.js +6 -10
- package/lib/ogg/vorbis/VorbisDecoder.js +2 -6
- package/lib/ogg/vorbis/VorbisParser.js +18 -22
- package/lib/ogg/vorbis/VorbisTagMapper.js +3 -7
- package/lib/riff/RiffChunk.js +3 -7
- package/lib/riff/RiffInfoTagMap.js +4 -8
- package/lib/type.js +1 -5
- package/lib/wav/BwfChunk.js +8 -11
- package/lib/wav/WaveChunk.js +4 -9
- package/lib/wav/WaveParser.js +17 -21
- package/lib/wavpack/WavPackParser.js +17 -21
- package/lib/wavpack/WavPackToken.js +4 -8
- package/package.json +34 -44
- package/lib/ParserFactory.d.ts +0 -48
- package/lib/aiff/AiffParser.d.ts +0 -14
- package/lib/aiff/AiffToken.d.ts +0 -22
- package/lib/apev2/APEv2Parser.d.ts +0 -30
- package/lib/apev2/APEv2TagMapper.d.ts +0 -4
- package/lib/apev2/APEv2Token.d.ts +0 -100
- package/lib/asf/AsfObject.d.ts +0 -319
- package/lib/asf/AsfParser.d.ts +0 -17
- package/lib/asf/AsfTagMapper.d.ts +0 -7
- package/lib/asf/AsfUtil.d.ts +0 -13
- package/lib/asf/GUID.d.ts +0 -84
- package/lib/common/BasicParser.d.ts +0 -17
- package/lib/common/CaseInsensitiveTagMap.d.ts +0 -10
- package/lib/common/CombinedTagMapper.d.ts +0 -19
- package/lib/common/FourCC.d.ts +0 -6
- package/lib/common/GenericTagMapper.d.ts +0 -51
- package/lib/common/GenericTagTypes.d.ts +0 -33
- package/lib/common/MetadataCollector.d.ts +0 -76
- package/lib/common/RandomFileReader.d.ts +0 -22
- package/lib/common/RandomUint8ArrayReader.d.ts +0 -18
- package/lib/common/Util.d.ts +0 -57
- package/lib/core.d.ts +0 -48
- package/lib/dsdiff/DsdiffParser.d.ts +0 -14
- package/lib/dsdiff/DsdiffToken.d.ts +0 -9
- package/lib/dsf/DsfChunk.d.ts +0 -86
- package/lib/dsf/DsfParser.d.ts +0 -9
- package/lib/flac/FlacParser.d.ts +0 -28
- package/lib/id3v1/ID3v1Parser.d.ts +0 -13
- package/lib/id3v1/ID3v1TagMap.d.ts +0 -4
- package/lib/id3v2/AbstractID3Parser.d.ts +0 -17
- package/lib/id3v2/FrameParser.d.ts +0 -31
- package/lib/id3v2/ID3v22TagMapper.d.ts +0 -9
- package/lib/id3v2/ID3v24TagMapper.d.ts +0 -14
- package/lib/id3v2/ID3v2Parser.d.ts +0 -28
- package/lib/id3v2/ID3v2Token.d.ts +0 -73
- package/lib/iff/index.d.ts +0 -33
- package/lib/index.d.ts +0 -45
- package/lib/lyrics3/Lyrics3.d.ts +0 -3
- package/lib/matroska/MatroskaDtd.d.ts +0 -8
- package/lib/matroska/MatroskaParser.d.ts +0 -37
- package/lib/matroska/MatroskaTagMapper.d.ts +0 -4
- package/lib/matroska/types.d.ts +0 -175
- package/lib/mp4/Atom.d.ts +0 -16
- package/lib/mp4/AtomToken.d.ts +0 -395
- package/lib/mp4/MP4Parser.d.ts +0 -30
- package/lib/mp4/MP4TagMapper.d.ts +0 -5
- package/lib/mpeg/ExtendedLameHeader.d.ts +0 -27
- package/lib/mpeg/MpegParser.d.ts +0 -49
- package/lib/mpeg/ReplayGainDataFormat.d.ts +0 -55
- package/lib/mpeg/XingTag.d.ts +0 -45
- package/lib/musepack/index.d.ts +0 -5
- package/lib/musepack/sv7/BitReader.d.ts +0 -13
- package/lib/musepack/sv7/MpcSv7Parser.d.ts +0 -8
- package/lib/musepack/sv7/StreamVersion7.d.ts +0 -28
- package/lib/musepack/sv8/MpcSv8Parser.d.ts +0 -6
- package/lib/musepack/sv8/StreamVersion8.d.ts +0 -40
- package/lib/ogg/Ogg.d.ts +0 -72
- package/lib/ogg/OggParser.d.ts +0 -23
- package/lib/ogg/opus/Opus.d.ts +0 -48
- package/lib/ogg/opus/OpusParser.d.ts +0 -25
- package/lib/ogg/speex/Speex.d.ts +0 -36
- package/lib/ogg/speex/SpeexParser.d.ts +0 -22
- package/lib/ogg/theora/Theora.d.ts +0 -20
- package/lib/ogg/theora/TheoraParser.d.ts +0 -28
- package/lib/ogg/vorbis/Vorbis.d.ts +0 -69
- package/lib/ogg/vorbis/VorbisDecoder.d.ts +0 -12
- package/lib/ogg/vorbis/VorbisParser.d.ts +0 -36
- package/lib/ogg/vorbis/VorbisTagMapper.d.ts +0 -7
- package/lib/riff/RiffChunk.d.ts +0 -16
- package/lib/riff/RiffInfoTagMap.d.ts +0 -10
- package/lib/type.d.ts +0 -592
- package/lib/wav/BwfChunk.d.ts +0 -17
- package/lib/wav/WaveChunk.d.ts +0 -64
- package/lib/wav/WaveParser.d.ts +0 -24
- package/lib/wavpack/WavPackParser.d.ts +0 -14
- package/lib/wavpack/WavPackToken.d.ts +0 -64
package/lib/mp4/AtomToken.js
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const FourCC_1 = require("../common/FourCC");
|
|
7
|
-
const debug = (0, debug_1.default)('music-metadata:parser:MP4:atom');
|
|
8
|
-
exports.Header = {
|
|
1
|
+
import * as Token from 'token-types';
|
|
2
|
+
import initDebug from 'debug';
|
|
3
|
+
import { FourCcToken } from '../common/FourCC.js';
|
|
4
|
+
const debug = initDebug('music-metadata:parser:MP4:atom');
|
|
5
|
+
export const Header = {
|
|
9
6
|
len: 8,
|
|
10
7
|
get: (buf, off) => {
|
|
11
8
|
const length = Token.UINT32_BE.get(buf, off);
|
|
@@ -18,14 +15,14 @@ exports.Header = {
|
|
|
18
15
|
},
|
|
19
16
|
put: (buf, off, hdr) => {
|
|
20
17
|
Token.UINT32_BE.put(buf, off, Number(hdr.length));
|
|
21
|
-
return
|
|
18
|
+
return FourCcToken.put(buf, off + 4, hdr.name);
|
|
22
19
|
}
|
|
23
20
|
};
|
|
24
21
|
/**
|
|
25
22
|
* Ref: https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFChap1/qtff1.html#//apple_ref/doc/uid/TP40000939-CH203-38190
|
|
26
23
|
*/
|
|
27
|
-
|
|
28
|
-
|
|
24
|
+
export const ExtendedSize = Token.UINT64_BE;
|
|
25
|
+
export const ftyp = {
|
|
29
26
|
len: 4,
|
|
30
27
|
get: (buf, off) => {
|
|
31
28
|
return {
|
|
@@ -33,7 +30,7 @@ exports.ftyp = {
|
|
|
33
30
|
};
|
|
34
31
|
}
|
|
35
32
|
};
|
|
36
|
-
|
|
33
|
+
export const tkhd = {
|
|
37
34
|
len: 4,
|
|
38
35
|
get: (buf, off) => {
|
|
39
36
|
return {
|
|
@@ -44,7 +41,7 @@ exports.tkhd = {
|
|
|
44
41
|
/**
|
|
45
42
|
* Token: Movie Header Atom
|
|
46
43
|
*/
|
|
47
|
-
|
|
44
|
+
export const mhdr = {
|
|
48
45
|
len: 8,
|
|
49
46
|
get: (buf, off) => {
|
|
50
47
|
return {
|
|
@@ -59,7 +56,7 @@ exports.mhdr = {
|
|
|
59
56
|
* In some cases these atoms are longer then the sum of the described fields.
|
|
60
57
|
* Issue: https://github.com/Borewit/music-metadata/issues/120
|
|
61
58
|
*/
|
|
62
|
-
class FixedLengthAtom {
|
|
59
|
+
export class FixedLengthAtom {
|
|
63
60
|
/**
|
|
64
61
|
*
|
|
65
62
|
* @param {number} len Length as specified in the size field
|
|
@@ -75,7 +72,6 @@ class FixedLengthAtom {
|
|
|
75
72
|
}
|
|
76
73
|
}
|
|
77
74
|
}
|
|
78
|
-
exports.FixedLengthAtom = FixedLengthAtom;
|
|
79
75
|
/**
|
|
80
76
|
* Timestamp stored in seconds since Mac Epoch (1 January 1904)
|
|
81
77
|
*/
|
|
@@ -92,7 +88,7 @@ const SecondsSinceMacEpoch = {
|
|
|
92
88
|
* - https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html#//apple_ref/doc/uid/TP40000939-CH204-SW34
|
|
93
89
|
* - https://wiki.multimedia.cx/index.php/QuickTime_container#mdhd
|
|
94
90
|
*/
|
|
95
|
-
class MdhdAtom extends FixedLengthAtom {
|
|
91
|
+
export class MdhdAtom extends FixedLengthAtom {
|
|
96
92
|
constructor(len) {
|
|
97
93
|
super(len, 24, 'mdhd');
|
|
98
94
|
this.len = len;
|
|
@@ -110,11 +106,10 @@ class MdhdAtom extends FixedLengthAtom {
|
|
|
110
106
|
};
|
|
111
107
|
}
|
|
112
108
|
}
|
|
113
|
-
exports.MdhdAtom = MdhdAtom;
|
|
114
109
|
/**
|
|
115
110
|
* Token: Movie Header Atom
|
|
116
111
|
*/
|
|
117
|
-
class MvhdAtom extends FixedLengthAtom {
|
|
112
|
+
export class MvhdAtom extends FixedLengthAtom {
|
|
118
113
|
constructor(len) {
|
|
119
114
|
super(len, 100, 'mvhd');
|
|
120
115
|
this.len = len;
|
|
@@ -141,11 +136,10 @@ class MvhdAtom extends FixedLengthAtom {
|
|
|
141
136
|
};
|
|
142
137
|
}
|
|
143
138
|
}
|
|
144
|
-
exports.MvhdAtom = MvhdAtom;
|
|
145
139
|
/**
|
|
146
140
|
* Data Atom Structure
|
|
147
141
|
*/
|
|
148
|
-
class DataAtom {
|
|
142
|
+
export class DataAtom {
|
|
149
143
|
constructor(len) {
|
|
150
144
|
this.len = len;
|
|
151
145
|
}
|
|
@@ -160,12 +154,11 @@ class DataAtom {
|
|
|
160
154
|
};
|
|
161
155
|
}
|
|
162
156
|
}
|
|
163
|
-
exports.DataAtom = DataAtom;
|
|
164
157
|
/**
|
|
165
158
|
* Data Atom Structure
|
|
166
159
|
* Ref: https://developer.apple.com/library/content/documentation/QuickTime/QTFF/Metadata/Metadata.html#//apple_ref/doc/uid/TP40000939-CH1-SW31
|
|
167
160
|
*/
|
|
168
|
-
class NameAtom {
|
|
161
|
+
export class NameAtom {
|
|
169
162
|
constructor(len) {
|
|
170
163
|
this.len = len;
|
|
171
164
|
}
|
|
@@ -177,12 +170,11 @@ class NameAtom {
|
|
|
177
170
|
};
|
|
178
171
|
}
|
|
179
172
|
}
|
|
180
|
-
exports.NameAtom = NameAtom;
|
|
181
173
|
/**
|
|
182
174
|
* Track Header Atoms structure
|
|
183
175
|
* Ref: https://developer.apple.com/library/content/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html#//apple_ref/doc/uid/TP40000939-CH204-25550
|
|
184
176
|
*/
|
|
185
|
-
class TrackHeaderAtom {
|
|
177
|
+
export class TrackHeaderAtom {
|
|
186
178
|
constructor(len) {
|
|
187
179
|
this.len = len;
|
|
188
180
|
}
|
|
@@ -202,7 +194,6 @@ class TrackHeaderAtom {
|
|
|
202
194
|
};
|
|
203
195
|
}
|
|
204
196
|
}
|
|
205
|
-
exports.TrackHeaderAtom = TrackHeaderAtom;
|
|
206
197
|
/**
|
|
207
198
|
* Atom: Sample Description Atom ('stsd')
|
|
208
199
|
* Ref: https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html#//apple_ref/doc/uid/TP40000939-CH204-25691
|
|
@@ -227,7 +218,7 @@ class SampleDescriptionTable {
|
|
|
227
218
|
}
|
|
228
219
|
get(buf, off) {
|
|
229
220
|
return {
|
|
230
|
-
dataFormat:
|
|
221
|
+
dataFormat: FourCcToken.get(buf, off),
|
|
231
222
|
dataReferenceIndex: Token.UINT16_BE.get(buf, off + 10),
|
|
232
223
|
description: new Token.Uint8ArrayType(this.len - 12).get(buf, off + 12)
|
|
233
224
|
};
|
|
@@ -237,7 +228,7 @@ class SampleDescriptionTable {
|
|
|
237
228
|
* Atom: Sample-description Atom ('stsd')
|
|
238
229
|
* Ref: https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html#//apple_ref/doc/uid/TP40000939-CH204-25691
|
|
239
230
|
*/
|
|
240
|
-
class StsdAtom {
|
|
231
|
+
export class StsdAtom {
|
|
241
232
|
constructor(len) {
|
|
242
233
|
this.len = len;
|
|
243
234
|
}
|
|
@@ -257,12 +248,11 @@ class StsdAtom {
|
|
|
257
248
|
};
|
|
258
249
|
}
|
|
259
250
|
}
|
|
260
|
-
exports.StsdAtom = StsdAtom;
|
|
261
251
|
/**
|
|
262
252
|
* Common Sound Sample Description (version & revision)
|
|
263
253
|
* Ref: https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFChap3/qtff3.html#//apple_ref/doc/uid/TP40000939-CH205-57317
|
|
264
254
|
*/
|
|
265
|
-
|
|
255
|
+
export const SoundSampleDescriptionVersion = {
|
|
266
256
|
len: 8,
|
|
267
257
|
get(buf, off) {
|
|
268
258
|
return {
|
|
@@ -276,7 +266,7 @@ exports.SoundSampleDescriptionVersion = {
|
|
|
276
266
|
* Sound Sample Description (Version 0)
|
|
277
267
|
* Ref: https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFChap3/qtff3.html#//apple_ref/doc/uid/TP40000939-CH205-130736
|
|
278
268
|
*/
|
|
279
|
-
|
|
269
|
+
export const SoundSampleDescriptionV0 = {
|
|
280
270
|
len: 12,
|
|
281
271
|
get(buf, off) {
|
|
282
272
|
return {
|
|
@@ -303,7 +293,7 @@ class SimpleTableAtom {
|
|
|
303
293
|
};
|
|
304
294
|
}
|
|
305
295
|
}
|
|
306
|
-
|
|
296
|
+
export const TimeToSampleToken = {
|
|
307
297
|
len: 8,
|
|
308
298
|
get(buf, off) {
|
|
309
299
|
return {
|
|
@@ -317,14 +307,13 @@ exports.TimeToSampleToken = {
|
|
|
317
307
|
* Store duration information for a media’s samples.
|
|
318
308
|
* Ref: https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html#//apple_ref/doc/uid/TP40000939-CH204-25696
|
|
319
309
|
*/
|
|
320
|
-
class SttsAtom extends SimpleTableAtom {
|
|
310
|
+
export class SttsAtom extends SimpleTableAtom {
|
|
321
311
|
constructor(len) {
|
|
322
|
-
super(len,
|
|
312
|
+
super(len, TimeToSampleToken);
|
|
323
313
|
this.len = len;
|
|
324
314
|
}
|
|
325
315
|
}
|
|
326
|
-
|
|
327
|
-
exports.SampleToChunkToken = {
|
|
316
|
+
export const SampleToChunkToken = {
|
|
328
317
|
len: 12,
|
|
329
318
|
get(buf, off) {
|
|
330
319
|
return {
|
|
@@ -338,18 +327,17 @@ exports.SampleToChunkToken = {
|
|
|
338
327
|
* Sample-to-Chunk ('stsc') atom interface
|
|
339
328
|
* Ref: https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html#//apple_ref/doc/uid/TP40000939-CH204-25706
|
|
340
329
|
*/
|
|
341
|
-
class StscAtom extends SimpleTableAtom {
|
|
330
|
+
export class StscAtom extends SimpleTableAtom {
|
|
342
331
|
constructor(len) {
|
|
343
|
-
super(len,
|
|
332
|
+
super(len, SampleToChunkToken);
|
|
344
333
|
this.len = len;
|
|
345
334
|
}
|
|
346
335
|
}
|
|
347
|
-
exports.StscAtom = StscAtom;
|
|
348
336
|
/**
|
|
349
337
|
* Sample-size ('stsz') atom
|
|
350
338
|
* Ref: https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html#//apple_ref/doc/uid/TP40000939-CH204-25710
|
|
351
339
|
*/
|
|
352
|
-
class StszAtom {
|
|
340
|
+
export class StszAtom {
|
|
353
341
|
constructor(len) {
|
|
354
342
|
this.len = len;
|
|
355
343
|
}
|
|
@@ -364,22 +352,20 @@ class StszAtom {
|
|
|
364
352
|
};
|
|
365
353
|
}
|
|
366
354
|
}
|
|
367
|
-
exports.StszAtom = StszAtom;
|
|
368
355
|
/**
|
|
369
356
|
* Chunk offset atom, 'stco'
|
|
370
357
|
* Ref: https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html#//apple_ref/doc/uid/TP40000939-CH204-25715
|
|
371
358
|
*/
|
|
372
|
-
class StcoAtom extends SimpleTableAtom {
|
|
359
|
+
export class StcoAtom extends SimpleTableAtom {
|
|
373
360
|
constructor(len) {
|
|
374
361
|
super(len, Token.INT32_BE);
|
|
375
362
|
this.len = len;
|
|
376
363
|
}
|
|
377
364
|
}
|
|
378
|
-
exports.StcoAtom = StcoAtom;
|
|
379
365
|
/**
|
|
380
366
|
* Token used to decode text-track from 'mdat' atom (raw data stream)
|
|
381
367
|
*/
|
|
382
|
-
class ChapterText {
|
|
368
|
+
export class ChapterText {
|
|
383
369
|
constructor(len) {
|
|
384
370
|
this.len = len;
|
|
385
371
|
}
|
|
@@ -389,7 +375,6 @@ class ChapterText {
|
|
|
389
375
|
return str.get(buf, off + 2);
|
|
390
376
|
}
|
|
391
377
|
}
|
|
392
|
-
exports.ChapterText = ChapterText;
|
|
393
378
|
function readTokenTable(buf, token, off, remainingLen, numberOfEntries) {
|
|
394
379
|
debug(`remainingLen=${remainingLen}, numberOfEntries=${numberOfEntries} * token-len=${token.len}`);
|
|
395
380
|
if (remainingLen === 0)
|
package/lib/mp4/MP4Parser.js
CHANGED
|
@@ -1,14 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const
|
|
9
|
-
const Atom_1 = require("./Atom");
|
|
10
|
-
const AtomToken = require("./AtomToken");
|
|
11
|
-
const debug = (0, debug_1.default)('music-metadata:parser:MP4');
|
|
1
|
+
import initDebug from 'debug';
|
|
2
|
+
import * as Token from 'token-types';
|
|
3
|
+
import { BasicParser } from '../common/BasicParser.js';
|
|
4
|
+
import { Genres } from '../id3v1/ID3v1Parser.js';
|
|
5
|
+
import { Atom } from './Atom.js';
|
|
6
|
+
import * as AtomToken from './AtomToken.js';
|
|
7
|
+
import { TrackType } from '../type.js';
|
|
8
|
+
const debug = initDebug('music-metadata:parser:MP4');
|
|
12
9
|
const tagFormat = 'iTunes';
|
|
13
10
|
const encoderDict = {
|
|
14
11
|
raw: {
|
|
@@ -90,7 +87,7 @@ function distinct(value, index, self) {
|
|
|
90
87
|
* https://github.com/sergiomb2/libmp4v2/wiki/iTunesMetadata
|
|
91
88
|
* https://wiki.multimedia.cx/index.php/QuickTime_container
|
|
92
89
|
*/
|
|
93
|
-
class MP4Parser extends
|
|
90
|
+
export class MP4Parser extends BasicParser {
|
|
94
91
|
constructor() {
|
|
95
92
|
super(...arguments);
|
|
96
93
|
this.atomParsers = {
|
|
@@ -233,7 +230,7 @@ class MP4Parser extends BasicParser_1.BasicParser {
|
|
|
233
230
|
this.addWarning(errMsg);
|
|
234
231
|
break;
|
|
235
232
|
}
|
|
236
|
-
const rootAtom = await
|
|
233
|
+
const rootAtom = await Atom.readAtom(this.tokenizer, (atom, remaining) => this.handleAtom(atom, remaining), null, remainingFileSize);
|
|
237
234
|
remainingFileSize -= rootAtom.header.length === BigInt(0) ? remainingFileSize : Number(rootAtom.header.length);
|
|
238
235
|
}
|
|
239
236
|
// Post process metadata
|
|
@@ -253,7 +250,7 @@ class MP4Parser extends BasicParser_1.BasicParser {
|
|
|
253
250
|
if (ssd.description) {
|
|
254
251
|
const { description } = ssd;
|
|
255
252
|
if (description.sampleRate > 0) {
|
|
256
|
-
streamInfo.type =
|
|
253
|
+
streamInfo.type = TrackType.audio;
|
|
257
254
|
streamInfo.audio = {
|
|
258
255
|
samplingFrequency: description.sampleRate,
|
|
259
256
|
bitDepth: description.sampleSize,
|
|
@@ -368,7 +365,7 @@ class MP4Parser extends BasicParser_1.BasicParser {
|
|
|
368
365
|
break;
|
|
369
366
|
case 'gnre':
|
|
370
367
|
const genreInt = Token.UINT8.get(dataAtom.value, 1);
|
|
371
|
-
const genreStr =
|
|
368
|
+
const genreStr = Genres[genreInt - 1];
|
|
372
369
|
// console.log(" %s[data] = %s", tagKey, genreStr);
|
|
373
370
|
this.addTag(tagKey, genreStr);
|
|
374
371
|
break;
|
|
@@ -508,4 +505,3 @@ class MP4Parser extends BasicParser_1.BasicParser {
|
|
|
508
505
|
return stcTable[stcTable.length - 1].samplesPerChunk;
|
|
509
506
|
}
|
|
510
507
|
}
|
|
511
|
-
exports.MP4Parser = MP4Parser;
|
package/lib/mp4/MP4TagMapper.js
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.MP4TagMapper = exports.tagType = void 0;
|
|
4
|
-
const CaseInsensitiveTagMap_1 = require("../common/CaseInsensitiveTagMap");
|
|
1
|
+
import { CaseInsensitiveTagMap } from '../common/CaseInsensitiveTagMap.js';
|
|
5
2
|
/**
|
|
6
3
|
* Ref: https://github.com/sergiomb2/libmp4v2/wiki/iTunesMetadata
|
|
7
4
|
*/
|
|
@@ -106,11 +103,10 @@ const mp4TagMap = {
|
|
|
106
103
|
shwm: 'showMovement',
|
|
107
104
|
stik: 'stik'
|
|
108
105
|
};
|
|
109
|
-
|
|
110
|
-
class MP4TagMapper extends
|
|
106
|
+
export const tagType = 'iTunes';
|
|
107
|
+
export class MP4TagMapper extends CaseInsensitiveTagMap {
|
|
111
108
|
constructor() {
|
|
112
|
-
super([
|
|
109
|
+
super([tagType], mp4TagMap);
|
|
113
110
|
}
|
|
114
111
|
}
|
|
115
|
-
exports.MP4TagMapper = MP4TagMapper;
|
|
116
112
|
//# sourceMappingURL=MP4TagMapper.js.map
|
|
@@ -1,18 +1,15 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* Extended Lame Header
|
|
4
3
|
*/
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const common = require("../common/Util");
|
|
9
|
-
const ReplayGainDataFormat_1 = require("./ReplayGainDataFormat");
|
|
4
|
+
import * as Token from 'token-types';
|
|
5
|
+
import * as common from '../common/Util.js';
|
|
6
|
+
import { ReplayGain } from './ReplayGainDataFormat.js';
|
|
10
7
|
/**
|
|
11
8
|
* Info Tag
|
|
12
9
|
* @link http://gabriel.mp3-tech.org/mp3infotag.html
|
|
13
10
|
* @link https://github.com/quodlibet/mutagen/blob/abd58ee58772224334a18817c3fb31103572f70e/mutagen/mp3/_util.py#L112
|
|
14
11
|
*/
|
|
15
|
-
|
|
12
|
+
export const ExtendedLameHeader = {
|
|
16
13
|
len: 27,
|
|
17
14
|
get: (buf, off) => {
|
|
18
15
|
const track_peak = Token.UINT32_BE.get(buf, off + 2);
|
|
@@ -21,8 +18,8 @@ exports.ExtendedLameHeader = {
|
|
|
21
18
|
vbr_method: common.getBitAllignedNumber(buf, off, 4, 4),
|
|
22
19
|
lowpass_filter: 100 * Token.UINT8.get(buf, off + 1),
|
|
23
20
|
track_peak: track_peak === 0 ? undefined : track_peak / Math.pow(2, 23),
|
|
24
|
-
track_gain:
|
|
25
|
-
album_gain:
|
|
21
|
+
track_gain: ReplayGain.get(buf, 6),
|
|
22
|
+
album_gain: ReplayGain.get(buf, 8),
|
|
26
23
|
music_length: Token.UINT32_BE.get(buf, off + 20),
|
|
27
24
|
music_crc: Token.UINT8.get(buf, off + 24),
|
|
28
25
|
header_crc: Token.UINT16_BE.get(buf, off + 24)
|
package/lib/mpeg/MpegParser.js
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const
|
|
8
|
-
const AbstractID3Parser_1 = require("../id3v2/AbstractID3Parser");
|
|
9
|
-
const XingTag_1 = require("./XingTag");
|
|
10
|
-
const debug = (0, debug_1.default)('music-metadata:parser:mpeg');
|
|
1
|
+
import * as Token from 'token-types';
|
|
2
|
+
import { EndOfStreamError } from 'strtok3/core';
|
|
3
|
+
import initDebug from 'debug';
|
|
4
|
+
import * as common from '../common/Util.js';
|
|
5
|
+
import { AbstractID3Parser } from '../id3v2/AbstractID3Parser.js';
|
|
6
|
+
import { InfoTagHeaderTag, LameEncoderVersion, readXingHeader } from './XingTag.js';
|
|
7
|
+
const debug = initDebug('music-metadata:parser:mpeg');
|
|
11
8
|
/**
|
|
12
9
|
* Cache buffer size used for searching synchronization preabmle
|
|
13
10
|
*/
|
|
@@ -206,7 +203,7 @@ const FrameHeader = {
|
|
|
206
203
|
function getVbrCodecProfile(vbrScale) {
|
|
207
204
|
return 'V' + Math.floor((100 - vbrScale) / 10);
|
|
208
205
|
}
|
|
209
|
-
class MpegParser extends
|
|
206
|
+
export class MpegParser extends AbstractID3Parser {
|
|
210
207
|
constructor() {
|
|
211
208
|
super(...arguments);
|
|
212
209
|
this.frameCount = 0;
|
|
@@ -234,7 +231,7 @@ class MpegParser extends AbstractID3Parser_1.AbstractID3Parser {
|
|
|
234
231
|
}
|
|
235
232
|
}
|
|
236
233
|
catch (err) {
|
|
237
|
-
if (err instanceof
|
|
234
|
+
if (err instanceof EndOfStreamError) {
|
|
238
235
|
debug(`End-of-stream`);
|
|
239
236
|
if (this.calculateEofDuration) {
|
|
240
237
|
const numberOfSamples = this.frameCount * this.samplesPerFrame;
|
|
@@ -276,7 +273,7 @@ class MpegParser extends AbstractID3Parser_1.AbstractID3Parser {
|
|
|
276
273
|
let bo = 0;
|
|
277
274
|
this.syncPeek.len = await this.tokenizer.peekBuffer(this.syncPeek.buf, { length: maxPeekLen, mayBeLess: true });
|
|
278
275
|
if (this.syncPeek.len <= 163) {
|
|
279
|
-
throw new
|
|
276
|
+
throw new EndOfStreamError();
|
|
280
277
|
}
|
|
281
278
|
while (true) {
|
|
282
279
|
if (gotFirstSync && (this.syncPeek.buf[bo] & 0xE0) === 0xE0) {
|
|
@@ -297,7 +294,7 @@ class MpegParser extends AbstractID3Parser_1.AbstractID3Parser {
|
|
|
297
294
|
bo = this.syncPeek.buf.indexOf(MpegFrameHeader.SyncByte1, bo);
|
|
298
295
|
if (bo === -1) {
|
|
299
296
|
if (this.syncPeek.len < this.syncPeek.buf.length) {
|
|
300
|
-
throw new
|
|
297
|
+
throw new EndOfStreamError();
|
|
301
298
|
}
|
|
302
299
|
await this.tokenizer.ignore(this.syncPeek.len);
|
|
303
300
|
break; // continue with next buffer
|
|
@@ -437,8 +434,8 @@ class MpegParser extends AbstractID3Parser_1.AbstractID3Parser {
|
|
|
437
434
|
return;
|
|
438
435
|
}
|
|
439
436
|
async readXtraInfoHeader() {
|
|
440
|
-
const headerTag = await this.tokenizer.readToken(
|
|
441
|
-
this.offset +=
|
|
437
|
+
const headerTag = await this.tokenizer.readToken(InfoTagHeaderTag);
|
|
438
|
+
this.offset += InfoTagHeaderTag.len; // 12
|
|
442
439
|
switch (headerTag) {
|
|
443
440
|
case 'Info':
|
|
444
441
|
this.metadata.setFormat('codecProfile', 'CBR');
|
|
@@ -452,9 +449,9 @@ class MpegParser extends AbstractID3Parser_1.AbstractID3Parser {
|
|
|
452
449
|
// ToDo: ???
|
|
453
450
|
break;
|
|
454
451
|
case 'LAME':
|
|
455
|
-
const version = await this.tokenizer.readToken(
|
|
456
|
-
if (this.frame_size >= this.offset +
|
|
457
|
-
this.offset +=
|
|
452
|
+
const version = await this.tokenizer.readToken(LameEncoderVersion);
|
|
453
|
+
if (this.frame_size >= this.offset + LameEncoderVersion.len) {
|
|
454
|
+
this.offset += LameEncoderVersion.len;
|
|
458
455
|
this.metadata.setFormat('tool', 'LAME ' + version);
|
|
459
456
|
await this.skipFrameData(this.frame_size - this.offset);
|
|
460
457
|
return null;
|
|
@@ -481,7 +478,7 @@ class MpegParser extends AbstractID3Parser_1.AbstractID3Parser {
|
|
|
481
478
|
*/
|
|
482
479
|
async readXingInfoHeader() {
|
|
483
480
|
const offset = this.tokenizer.position;
|
|
484
|
-
const infoTag = await
|
|
481
|
+
const infoTag = await readXingHeader(this.tokenizer);
|
|
485
482
|
this.offset += this.tokenizer.position - offset;
|
|
486
483
|
if (infoTag.lame) {
|
|
487
484
|
this.metadata.setFormat('tool', 'LAME ' + common.stripNulls(infoTag.lame.version));
|
|
@@ -521,4 +518,3 @@ class MpegParser extends AbstractID3Parser_1.AbstractID3Parser {
|
|
|
521
518
|
});
|
|
522
519
|
}
|
|
523
520
|
}
|
|
524
|
-
exports.MpegParser = MpegParser;
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ReplayGain = void 0;
|
|
4
|
-
const common = require("../common/Util");
|
|
1
|
+
import * as common from '../common/Util.js';
|
|
5
2
|
/**
|
|
6
3
|
* https://github.com/Borewit/music-metadata/wiki/Replay-Gain-Data-Format#name-code
|
|
7
4
|
*/
|
|
@@ -51,7 +48,7 @@ var ReplayGainOriginator;
|
|
|
51
48
|
*
|
|
52
49
|
* https://github.com/Borewit/music-metadata/wiki/Replay-Gain-Data-Format
|
|
53
50
|
*/
|
|
54
|
-
|
|
51
|
+
export const ReplayGain = {
|
|
55
52
|
len: 2,
|
|
56
53
|
get: (buf, off) => {
|
|
57
54
|
const gain_type = common.getBitAllignedNumber(buf, off, 0, 3);
|
package/lib/mpeg/XingTag.js
CHANGED
|
@@ -1,24 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const Token = require("token-types");
|
|
5
|
-
const util = require("../common/Util");
|
|
6
|
-
const ExtendedLameHeader_1 = require("./ExtendedLameHeader");
|
|
1
|
+
import * as Token from 'token-types';
|
|
2
|
+
import * as util from '../common/Util.js';
|
|
3
|
+
import { ExtendedLameHeader } from './ExtendedLameHeader.js';
|
|
7
4
|
/**
|
|
8
5
|
* Info Tag: Xing, LAME
|
|
9
6
|
*/
|
|
10
|
-
|
|
7
|
+
export const InfoTagHeaderTag = new Token.StringType(4, 'ascii');
|
|
11
8
|
/**
|
|
12
9
|
* LAME TAG value
|
|
13
10
|
* Did not find any official documentation for this
|
|
14
11
|
* Value e.g.: "3.98.4"
|
|
15
12
|
*/
|
|
16
|
-
|
|
13
|
+
export const LameEncoderVersion = new Token.StringType(6, 'ascii');
|
|
17
14
|
/**
|
|
18
15
|
* Info Tag
|
|
19
16
|
* Ref: http://gabriel.mp3-tech.org/mp3infotag.html
|
|
20
17
|
*/
|
|
21
|
-
|
|
18
|
+
export const XingHeaderFlags = {
|
|
22
19
|
len: 4,
|
|
23
20
|
get: (buf, off) => {
|
|
24
21
|
return {
|
|
@@ -33,8 +30,8 @@ exports.XingHeaderFlags = {
|
|
|
33
30
|
// * XING Header Tag
|
|
34
31
|
// * Ref: http://gabriel.mp3-tech.org/mp3infotag.html
|
|
35
32
|
// */
|
|
36
|
-
async function readXingHeader(tokenizer) {
|
|
37
|
-
const flags = await tokenizer.readToken(
|
|
33
|
+
export async function readXingHeader(tokenizer) {
|
|
34
|
+
const flags = await tokenizer.readToken(XingHeaderFlags);
|
|
38
35
|
const xingInfoTag = {};
|
|
39
36
|
if (flags.frames) {
|
|
40
37
|
xingInfoTag.numFrames = await tokenizer.readToken(Token.UINT32_BE);
|
|
@@ -60,10 +57,9 @@ async function readXingHeader(tokenizer) {
|
|
|
60
57
|
const majorMinorVersion = xingInfoTag.lame.version.match(/\d+.\d+/g)[0]; // e.g. 3.97
|
|
61
58
|
const version = majorMinorVersion.split('.').map(n => parseInt(n, 10));
|
|
62
59
|
if (version[0] >= 3 && version[1] >= 90) {
|
|
63
|
-
xingInfoTag.lame.extended = await tokenizer.readToken(
|
|
60
|
+
xingInfoTag.lame.extended = await tokenizer.readToken(ExtendedLameHeader);
|
|
64
61
|
}
|
|
65
62
|
}
|
|
66
63
|
}
|
|
67
64
|
return xingInfoTag;
|
|
68
65
|
}
|
|
69
|
-
exports.readXingHeader = readXingHeader;
|
package/lib/musepack/index.js
CHANGED
|
@@ -1,24 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
const debug = (0, debug_1.default)('music-metadata:parser:musepack');
|
|
9
|
-
class MusepackParser extends AbstractID3Parser_1.AbstractID3Parser {
|
|
1
|
+
import initDebug from 'debug';
|
|
2
|
+
import * as Token from 'token-types';
|
|
3
|
+
import { AbstractID3Parser } from '../id3v2/AbstractID3Parser.js';
|
|
4
|
+
import { MpcSv8Parser } from './sv8/MpcSv8Parser.js';
|
|
5
|
+
import { MpcSv7Parser } from './sv7/MpcSv7Parser.js';
|
|
6
|
+
const debug = initDebug('music-metadata:parser:musepack');
|
|
7
|
+
class MusepackParser extends AbstractID3Parser {
|
|
10
8
|
async postId3v2Parse() {
|
|
11
9
|
const signature = await this.tokenizer.peekToken(new Token.StringType(3, 'binary'));
|
|
12
10
|
let mpcParser;
|
|
13
11
|
switch (signature) {
|
|
14
12
|
case 'MP+': {
|
|
15
13
|
debug('Musepack stream-version 7');
|
|
16
|
-
mpcParser = new
|
|
14
|
+
mpcParser = new MpcSv7Parser();
|
|
17
15
|
break;
|
|
18
16
|
}
|
|
19
17
|
case 'MPC': {
|
|
20
18
|
debug('Musepack stream-version 8');
|
|
21
|
-
mpcParser = new
|
|
19
|
+
mpcParser = new MpcSv8Parser();
|
|
22
20
|
break;
|
|
23
21
|
}
|
|
24
22
|
default: {
|
|
@@ -29,4 +27,4 @@ class MusepackParser extends AbstractID3Parser_1.AbstractID3Parser {
|
|
|
29
27
|
return mpcParser.parse();
|
|
30
28
|
}
|
|
31
29
|
}
|
|
32
|
-
|
|
30
|
+
export default MusepackParser;
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.BitReader = void 0;
|
|
4
|
-
const Token = require("token-types");
|
|
5
|
-
class BitReader {
|
|
1
|
+
import * as Token from 'token-types';
|
|
2
|
+
export class BitReader {
|
|
6
3
|
constructor(tokenizer) {
|
|
7
4
|
this.tokenizer = tokenizer;
|
|
8
5
|
this.pos = 0;
|
|
@@ -51,4 +48,3 @@ class BitReader {
|
|
|
51
48
|
return this.read(remainder);
|
|
52
49
|
}
|
|
53
50
|
}
|
|
54
|
-
exports.BitReader = BitReader;
|
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
const SV7 = require("./StreamVersion7");
|
|
9
|
-
const debug = (0, debug_1.default)('music-metadata:parser:musepack');
|
|
10
|
-
class MpcSv7Parser extends BasicParser_1.BasicParser {
|
|
1
|
+
import initDebug from 'debug';
|
|
2
|
+
import { BasicParser } from '../../common/BasicParser.js';
|
|
3
|
+
import { APEv2Parser } from '../../apev2/APEv2Parser.js';
|
|
4
|
+
import { BitReader } from './BitReader.js';
|
|
5
|
+
import * as SV7 from './StreamVersion7.js';
|
|
6
|
+
const debug = initDebug('music-metadata:parser:musepack');
|
|
7
|
+
export class MpcSv7Parser extends BasicParser {
|
|
11
8
|
constructor() {
|
|
12
9
|
super(...arguments);
|
|
13
10
|
this.audioLength = 0;
|
|
@@ -23,13 +20,13 @@ class MpcSv7Parser extends BasicParser_1.BasicParser {
|
|
|
23
20
|
this.metadata.setFormat('numberOfSamples', numberOfSamples);
|
|
24
21
|
this.duration = numberOfSamples / header.sampleFrequency;
|
|
25
22
|
this.metadata.setFormat('duration', this.duration);
|
|
26
|
-
this.bitreader = new
|
|
23
|
+
this.bitreader = new BitReader(this.tokenizer);
|
|
27
24
|
this.metadata.setFormat('numberOfChannels', header.midSideStereo || header.intensityStereo ? 2 : 1);
|
|
28
25
|
const version = await this.bitreader.read(8);
|
|
29
26
|
this.metadata.setFormat('codec', (version / 100).toFixed(2));
|
|
30
27
|
await this.skipAudioData(header.frameCount);
|
|
31
28
|
debug(`End of audio stream, switching to APEv2, offset=${this.tokenizer.position}`);
|
|
32
|
-
return
|
|
29
|
+
return APEv2Parser.tryParseApeHeader(this.metadata, this.tokenizer, this.options);
|
|
33
30
|
}
|
|
34
31
|
async skipAudioData(frameCount) {
|
|
35
32
|
while (frameCount-- > 0) {
|
|
@@ -43,4 +40,3 @@ class MpcSv7Parser extends BasicParser_1.BasicParser {
|
|
|
43
40
|
this.metadata.setFormat('bitrate', this.audioLength / this.duration);
|
|
44
41
|
}
|
|
45
42
|
}
|
|
46
|
-
exports.MpcSv7Parser = MpcSv7Parser;
|
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.Header = void 0;
|
|
4
|
-
const Token = require("token-types");
|
|
5
|
-
const util = require("../../common/Util");
|
|
1
|
+
import * as Token from 'token-types';
|
|
2
|
+
import * as util from '../../common/Util.js';
|
|
6
3
|
/**
|
|
7
4
|
* BASIC STRUCTURE
|
|
8
5
|
*/
|
|
9
|
-
|
|
6
|
+
export const Header = {
|
|
10
7
|
len: 6 * 4,
|
|
11
8
|
get: (buf, off) => {
|
|
12
9
|
const header = {
|