music-metadata 7.12.5 → 8.0.1
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.d.ts +3 -3
- package/lib/ParserFactory.js +37 -41
- package/lib/aiff/AiffParser.d.ts +2 -2
- package/lib/aiff/AiffParser.js +25 -17
- package/lib/aiff/AiffToken.d.ts +3 -2
- package/lib/aiff/AiffToken.js +13 -12
- package/lib/apev2/APEv2Parser.d.ts +5 -5
- package/lib/apev2/APEv2Parser.js +29 -32
- package/lib/apev2/APEv2TagMapper.d.ts +1 -1
- package/lib/apev2/APEv2TagMapper.js +2 -6
- package/lib/apev2/APEv2Token.d.ts +1 -1
- package/lib/apev2/APEv2Token.js +13 -19
- package/lib/asf/AsfObject.d.ts +5 -4
- package/lib/asf/AsfObject.js +42 -56
- package/lib/asf/AsfParser.d.ts +1 -1
- package/lib/asf/AsfParser.js +15 -19
- package/lib/asf/AsfTagMapper.d.ts +2 -2
- package/lib/asf/AsfTagMapper.js +2 -6
- package/lib/asf/AsfUtil.d.ts +3 -2
- package/lib/asf/AsfUtil.js +4 -7
- package/lib/asf/GUID.d.ts +1 -1
- package/lib/asf/GUID.js +1 -4
- package/lib/browser.js +99 -0
- package/lib/common/BasicParser.d.ts +4 -4
- package/lib/common/BasicParser.js +1 -5
- package/lib/common/CaseInsensitiveTagMap.d.ts +3 -3
- package/lib/common/CaseInsensitiveTagMap.js +2 -6
- package/lib/common/CombinedTagMapper.d.ts +4 -4
- package/lib/common/CombinedTagMapper.js +20 -24
- package/lib/common/FourCC.d.ts +1 -1
- package/lib/common/FourCC.js +3 -6
- package/lib/common/GenericTagMapper.d.ts +4 -4
- package/lib/common/GenericTagMapper.js +2 -6
- package/lib/common/GenericTagTypes.js +5 -10
- package/lib/common/MetadataCollector.d.ts +2 -2
- package/lib/common/MetadataCollector.js +20 -25
- package/lib/common/RandomFileReader.d.ts +2 -2
- package/lib/common/RandomFileReader.js +2 -6
- package/lib/common/RandomUint8ArrayReader.d.ts +1 -1
- package/lib/common/RandomUint8ArrayReader.js +1 -5
- package/lib/common/Util.d.ts +1 -1
- package/lib/common/Util.js +11 -25
- package/lib/core.d.ts +4 -4
- package/lib/core.js +18 -28
- package/lib/dsdiff/DsdiffParser.d.ts +1 -1
- package/lib/dsdiff/DsdiffParser.js +24 -28
- package/lib/dsdiff/DsdiffToken.d.ts +3 -3
- package/lib/dsdiff/DsdiffToken.js +4 -7
- package/lib/dsf/DsfChunk.d.ts +1 -1
- package/lib/dsf/DsfChunk.js +8 -11
- package/lib/dsf/DsfParser.d.ts +1 -1
- package/lib/dsf/DsfParser.js +13 -17
- package/lib/flac/FlacParser.d.ts +5 -5
- package/lib/flac/FlacParser.js +22 -26
- package/lib/id3v1/ID3v1Parser.d.ts +2 -2
- package/lib/id3v1/ID3v1Parser.js +16 -21
- package/lib/id3v1/ID3v1TagMap.d.ts +1 -1
- package/lib/id3v1/ID3v1TagMap.js +2 -6
- package/lib/id3v2/AbstractID3Parser.d.ts +2 -2
- package/lib/id3v2/AbstractID3Parser.js +13 -17
- package/lib/id3v2/FrameParser.d.ts +2 -2
- package/lib/id3v2/FrameParser.js +12 -17
- package/lib/id3v2/ID3v22TagMapper.d.ts +2 -2
- package/lib/id3v2/ID3v22TagMapper.js +4 -8
- package/lib/id3v2/ID3v24TagMapper.d.ts +3 -3
- package/lib/id3v2/ID3v24TagMapper.js +5 -9
- package/lib/id3v2/ID3v2Parser.d.ts +3 -3
- package/lib/id3v2/ID3v2Parser.js +10 -14
- package/lib/id3v2/ID3v2Token.d.ts +2 -2
- package/lib/id3v2/ID3v2Token.js +9 -12
- package/lib/iff/index.d.ts +1 -1
- package/lib/iff/index.js +4 -7
- package/lib/index.d.ts +4 -28
- package/lib/index.js +14 -44
- package/lib/lyrics3/Lyrics3.d.ts +1 -1
- package/lib/lyrics3/Lyrics3.js +3 -7
- package/lib/matroska/MatroskaDtd.d.ts +1 -1
- package/lib/matroska/MatroskaDtd.js +111 -114
- package/lib/matroska/MatroskaParser.d.ts +5 -5
- package/lib/matroska/MatroskaParser.js +20 -24
- package/lib/matroska/MatroskaTagMapper.d.ts +1 -1
- package/lib/matroska/MatroskaTagMapper.js +2 -6
- package/lib/matroska/types.d.ts +1 -1
- package/lib/matroska/types.js +6 -9
- package/lib/mp4/Atom.d.ts +2 -2
- package/lib/mp4/Atom.js +4 -8
- package/lib/mp4/AtomToken.d.ts +2 -2
- package/lib/mp4/AtomToken.js +29 -44
- package/lib/mp4/MP4Parser.d.ts +2 -2
- package/lib/mp4/MP4Parser.js +12 -16
- package/lib/mp4/MP4TagMapper.d.ts +1 -1
- package/lib/mp4/MP4TagMapper.js +4 -8
- package/lib/mpeg/ExtendedLameHeader.d.ts +2 -2
- package/lib/mpeg/ExtendedLameHeader.js +6 -9
- package/lib/mpeg/MpegParser.d.ts +1 -1
- package/lib/mpeg/MpegParser.js +17 -21
- package/lib/mpeg/ReplayGainDataFormat.d.ts +1 -1
- package/lib/mpeg/ReplayGainDataFormat.js +2 -5
- package/lib/mpeg/XingTag.d.ts +3 -3
- package/lib/mpeg/XingTag.js +9 -13
- package/lib/musepack/index.d.ts +1 -1
- package/lib/musepack/index.js +10 -12
- package/lib/musepack/sv7/BitReader.d.ts +1 -1
- package/lib/musepack/sv7/BitReader.js +2 -6
- package/lib/musepack/sv7/MpcSv7Parser.d.ts +1 -1
- package/lib/musepack/sv7/MpcSv7Parser.js +9 -13
- package/lib/musepack/sv7/StreamVersion7.d.ts +1 -1
- package/lib/musepack/sv7/StreamVersion7.js +3 -6
- package/lib/musepack/sv8/MpcSv8Parser.d.ts +1 -1
- package/lib/musepack/sv8/MpcSv8Parser.js +9 -13
- package/lib/musepack/sv8/StreamVersion8.d.ts +1 -1
- package/lib/musepack/sv8/StreamVersion8.js +5 -9
- package/lib/ogg/Ogg.js +1 -2
- package/lib/ogg/OggParser.d.ts +3 -3
- package/lib/ogg/OggParser.js +19 -24
- package/lib/ogg/opus/Opus.d.ts +1 -1
- package/lib/ogg/opus/Opus.js +2 -6
- package/lib/ogg/opus/OpusParser.d.ts +6 -6
- package/lib/ogg/opus/OpusParser.js +4 -8
- package/lib/ogg/speex/Speex.d.ts +1 -1
- package/lib/ogg/speex/Speex.js +3 -6
- package/lib/ogg/speex/SpeexParser.d.ts +6 -6
- package/lib/ogg/speex/SpeexParser.js +5 -9
- package/lib/ogg/theora/Theora.d.ts +1 -1
- package/lib/ogg/theora/Theora.js +2 -5
- package/lib/ogg/theora/TheoraParser.d.ts +5 -5
- package/lib/ogg/theora/TheoraParser.js +5 -9
- package/lib/ogg/vorbis/Vorbis.d.ts +3 -3
- package/lib/ogg/vorbis/Vorbis.js +6 -10
- package/lib/ogg/vorbis/VorbisDecoder.js +2 -6
- package/lib/ogg/vorbis/VorbisParser.d.ts +11 -11
- package/lib/ogg/vorbis/VorbisParser.js +18 -22
- package/lib/ogg/vorbis/VorbisTagMapper.d.ts +2 -2
- package/lib/ogg/vorbis/VorbisTagMapper.js +3 -7
- package/lib/riff/RiffChunk.d.ts +3 -3
- package/lib/riff/RiffChunk.js +3 -7
- package/lib/riff/RiffInfoTagMap.d.ts +2 -2
- package/lib/riff/RiffInfoTagMap.js +4 -8
- package/lib/type.d.ts +6 -5
- package/lib/type.js +1 -5
- package/lib/wav/BwfChunk.d.ts +1 -1
- package/lib/wav/BwfChunk.js +8 -11
- package/lib/wav/WaveChunk.d.ts +3 -3
- package/lib/wav/WaveChunk.js +4 -9
- package/lib/wav/WaveParser.d.ts +2 -2
- package/lib/wav/WaveParser.js +17 -21
- package/lib/wavpack/WavPackParser.d.ts +1 -1
- package/lib/wavpack/WavPackParser.js +17 -21
- package/lib/wavpack/WavPackToken.d.ts +1 -1
- package/lib/wavpack/WavPackToken.js +4 -8
- package/package.json +29 -41
|
@@ -1,16 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const
|
|
6
|
-
const VorbisDecoder_1 = require("./VorbisDecoder");
|
|
7
|
-
const Vorbis_1 = require("./Vorbis");
|
|
8
|
-
const debug = (0, debug_1.default)('music-metadata:parser:ogg:vorbis1');
|
|
1
|
+
import * as Token from 'token-types';
|
|
2
|
+
import debugInit from 'debug';
|
|
3
|
+
import { VorbisDecoder } from './VorbisDecoder.js';
|
|
4
|
+
import { CommonHeader, IdentificationHeader, VorbisPictureToken } from './Vorbis.js';
|
|
5
|
+
const debug = debugInit('music-metadata:parser:ogg:vorbis1');
|
|
9
6
|
/**
|
|
10
7
|
* Vorbis 1 Parser.
|
|
11
8
|
* Used by OggParser
|
|
12
9
|
*/
|
|
13
|
-
class VorbisParser {
|
|
10
|
+
export class VorbisParser {
|
|
14
11
|
constructor(metadata, options) {
|
|
15
12
|
this.metadata = metadata;
|
|
16
13
|
this.options = options;
|
|
@@ -28,7 +25,7 @@ class VorbisParser {
|
|
|
28
25
|
else {
|
|
29
26
|
if (header.headerType.continued) {
|
|
30
27
|
if (this.pageSegments.length === 0) {
|
|
31
|
-
throw new Error(
|
|
28
|
+
throw new Error('Cannot continue on previous page');
|
|
32
29
|
}
|
|
33
30
|
this.pageSegments.push(pageData);
|
|
34
31
|
}
|
|
@@ -50,7 +47,7 @@ class VorbisParser {
|
|
|
50
47
|
this.parseFullPage(Buffer.concat(this.pageSegments));
|
|
51
48
|
}
|
|
52
49
|
parseUserComment(pageData, offset) {
|
|
53
|
-
const decoder = new
|
|
50
|
+
const decoder = new VorbisDecoder(pageData, offset);
|
|
54
51
|
const tag = decoder.parseUserComment();
|
|
55
52
|
this.addTag(tag.key, tag.value);
|
|
56
53
|
return tag.len;
|
|
@@ -61,7 +58,7 @@ class VorbisParser {
|
|
|
61
58
|
debug(`Ignore picture`);
|
|
62
59
|
return;
|
|
63
60
|
}
|
|
64
|
-
value =
|
|
61
|
+
value = VorbisPictureToken.fromBase64(value);
|
|
65
62
|
debug(`Push picture: id=${id}, format=${value.format}`);
|
|
66
63
|
}
|
|
67
64
|
else {
|
|
@@ -78,33 +75,33 @@ class VorbisParser {
|
|
|
78
75
|
}
|
|
79
76
|
/**
|
|
80
77
|
* Parse first Ogg/Vorbis page
|
|
81
|
-
* @param
|
|
82
|
-
* @param
|
|
78
|
+
* @param header
|
|
79
|
+
* @param pageData
|
|
83
80
|
*/
|
|
84
81
|
parseFirstPage(header, pageData) {
|
|
85
82
|
this.metadata.setFormat('codec', 'Vorbis I');
|
|
86
|
-
debug(
|
|
83
|
+
debug('Parse first page');
|
|
87
84
|
// Parse Vorbis common header
|
|
88
|
-
const commonHeader =
|
|
85
|
+
const commonHeader = CommonHeader.get(pageData, 0);
|
|
89
86
|
if (commonHeader.vorbis !== 'vorbis')
|
|
90
87
|
throw new Error('Metadata does not look like Vorbis');
|
|
91
88
|
if (commonHeader.packetType === 1) {
|
|
92
|
-
const idHeader =
|
|
89
|
+
const idHeader = IdentificationHeader.get(pageData, CommonHeader.len);
|
|
93
90
|
this.metadata.setFormat('sampleRate', idHeader.sampleRate);
|
|
94
91
|
this.metadata.setFormat('bitrate', idHeader.bitrateNominal);
|
|
95
92
|
this.metadata.setFormat('numberOfChannels', idHeader.channelMode);
|
|
96
|
-
debug(
|
|
93
|
+
debug('sample-rate=%s[hz], bitrate=%s[b/s], channel-mode=%s', idHeader.sampleRate, idHeader.bitrateNominal, idHeader.channelMode);
|
|
97
94
|
}
|
|
98
95
|
else
|
|
99
96
|
throw new Error('First Ogg page should be type 1: the identification header');
|
|
100
97
|
}
|
|
101
98
|
parseFullPage(pageData) {
|
|
102
99
|
// New page
|
|
103
|
-
const commonHeader =
|
|
104
|
-
debug(
|
|
100
|
+
const commonHeader = CommonHeader.get(pageData, 0);
|
|
101
|
+
debug('Parse full page: type=%s, byteLength=%s', commonHeader.packetType, pageData.byteLength);
|
|
105
102
|
switch (commonHeader.packetType) {
|
|
106
103
|
case 3: // type 3: comment header
|
|
107
|
-
return this.parseUserCommentList(pageData,
|
|
104
|
+
return this.parseUserCommentList(pageData, CommonHeader.len);
|
|
108
105
|
case 1: // type 1: the identification header
|
|
109
106
|
case 5: // type 5: setup header type
|
|
110
107
|
break; // ignore
|
|
@@ -125,4 +122,3 @@ class VorbisParser {
|
|
|
125
122
|
}
|
|
126
123
|
}
|
|
127
124
|
}
|
|
128
|
-
exports.VorbisParser = VorbisParser;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { CommonTagMapper } from '../../common/GenericTagMapper';
|
|
2
|
-
import { IRating, ITag } from '../../type';
|
|
1
|
+
import { CommonTagMapper } from '../../common/GenericTagMapper.js';
|
|
2
|
+
import { IRating, ITag } from '../../type.js';
|
|
3
3
|
export declare class VorbisTagMapper extends CommonTagMapper {
|
|
4
4
|
static toRating(email: string, rating: string): IRating;
|
|
5
5
|
constructor();
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.VorbisTagMapper = void 0;
|
|
4
|
-
const GenericTagMapper_1 = require("../../common/GenericTagMapper");
|
|
1
|
+
import { CommonTagMapper } from '../../common/GenericTagMapper.js';
|
|
5
2
|
/**
|
|
6
3
|
* Vorbis tag mappings
|
|
7
4
|
*
|
|
@@ -111,11 +108,11 @@ const vorbisTagMap = {
|
|
|
111
108
|
REPLAYGAIN_ALBUM_MINMAX: 'replaygain_album_minmax',
|
|
112
109
|
REPLAYGAIN_UNDO: 'replaygain_undo'
|
|
113
110
|
};
|
|
114
|
-
class VorbisTagMapper extends
|
|
111
|
+
export class VorbisTagMapper extends CommonTagMapper {
|
|
115
112
|
static toRating(email, rating) {
|
|
116
113
|
return {
|
|
117
114
|
source: email ? email.toLowerCase() : email,
|
|
118
|
-
rating: parseFloat(rating) *
|
|
115
|
+
rating: parseFloat(rating) * CommonTagMapper.maxRatingScore
|
|
119
116
|
};
|
|
120
117
|
}
|
|
121
118
|
constructor() {
|
|
@@ -129,5 +126,4 @@ class VorbisTagMapper extends GenericTagMapper_1.CommonTagMapper {
|
|
|
129
126
|
}
|
|
130
127
|
}
|
|
131
128
|
}
|
|
132
|
-
exports.VorbisTagMapper = VorbisTagMapper;
|
|
133
129
|
//# sourceMappingURL=VorbisTagMapper.js.map
|
package/lib/riff/RiffChunk.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { IGetToken } from 'strtok3/
|
|
2
|
-
import { IChunkHeader } from '../iff';
|
|
3
|
-
export { IChunkHeader } from '../iff';
|
|
1
|
+
import { IGetToken } from 'strtok3/core';
|
|
2
|
+
import { IChunkHeader } from '../iff/index.js';
|
|
3
|
+
export { IChunkHeader } from '../iff/index.js';
|
|
4
4
|
/**
|
|
5
5
|
* Common RIFF chunk header
|
|
6
6
|
*/
|
package/lib/riff/RiffChunk.js
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ListInfoTagValue = exports.Header = void 0;
|
|
4
|
-
const Token = require("token-types");
|
|
1
|
+
import * as Token from 'token-types';
|
|
5
2
|
/**
|
|
6
3
|
* Common RIFF chunk header
|
|
7
4
|
*/
|
|
8
|
-
|
|
5
|
+
export const Header = {
|
|
9
6
|
len: 8,
|
|
10
7
|
get: (buf, off) => {
|
|
11
8
|
return {
|
|
@@ -19,7 +16,7 @@ exports.Header = {
|
|
|
19
16
|
/**
|
|
20
17
|
* Token to parse RIFF-INFO tag value
|
|
21
18
|
*/
|
|
22
|
-
class ListInfoTagValue {
|
|
19
|
+
export class ListInfoTagValue {
|
|
23
20
|
constructor(tagHeader) {
|
|
24
21
|
this.tagHeader = tagHeader;
|
|
25
22
|
this.len = tagHeader.chunkSize;
|
|
@@ -29,4 +26,3 @@ class ListInfoTagValue {
|
|
|
29
26
|
return new Token.StringType(this.tagHeader.chunkSize, 'ascii').get(buf, off);
|
|
30
27
|
}
|
|
31
28
|
}
|
|
32
|
-
exports.ListInfoTagValue = ListInfoTagValue;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { INativeTagMap } from '../common/GenericTagTypes';
|
|
2
|
-
import { CommonTagMapper } from '../common/GenericTagMapper';
|
|
1
|
+
import { INativeTagMap } from '../common/GenericTagTypes.js';
|
|
2
|
+
import { CommonTagMapper } from '../common/GenericTagMapper.js';
|
|
3
3
|
/**
|
|
4
4
|
* RIFF Info Tags; part of the EXIF 2.3
|
|
5
5
|
* Ref: http://owl.phy.queensu.ca/~phil/exiftool/TagNames/RIFF.html#Info
|
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.RiffInfoTagMapper = exports.riffInfoTagMap = void 0;
|
|
4
|
-
const GenericTagMapper_1 = require("../common/GenericTagMapper");
|
|
1
|
+
import { CommonTagMapper } from '../common/GenericTagMapper.js';
|
|
5
2
|
/**
|
|
6
3
|
* RIFF Info Tags; part of the EXIF 2.3
|
|
7
4
|
* Ref: http://owl.phy.queensu.ca/~phil/exiftool/TagNames/RIFF.html#Info
|
|
8
5
|
*/
|
|
9
|
-
|
|
6
|
+
export const riffInfoTagMap = {
|
|
10
7
|
IART: 'artist',
|
|
11
8
|
ICRD: 'date',
|
|
12
9
|
INAM: 'title',
|
|
@@ -29,10 +26,9 @@ exports.riffInfoTagMap = {
|
|
|
29
26
|
IMED: 'media',
|
|
30
27
|
IRPD: 'album' // Product, where the file was intended for
|
|
31
28
|
};
|
|
32
|
-
class RiffInfoTagMapper extends
|
|
29
|
+
export class RiffInfoTagMapper extends CommonTagMapper {
|
|
33
30
|
constructor() {
|
|
34
|
-
super(['exif'],
|
|
31
|
+
super(['exif'], riffInfoTagMap);
|
|
35
32
|
}
|
|
36
33
|
}
|
|
37
|
-
exports.RiffInfoTagMapper = RiffInfoTagMapper;
|
|
38
34
|
//# sourceMappingURL=RiffInfoTagMap.js.map
|
package/lib/type.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
1
|
+
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
+
import { Buffer } from 'node:buffer';
|
|
3
|
+
import { GenericTagId, TagType } from './common/GenericTagTypes.js';
|
|
4
|
+
import { IFooter } from './apev2/APEv2Token.js';
|
|
5
|
+
import { TrackType } from './matroska/types.js';
|
|
6
|
+
export { TrackType } from './matroska/types.js';
|
|
6
7
|
/**
|
|
7
8
|
* Attached picture, typically used for cover art
|
|
8
9
|
*/
|
package/lib/type.js
CHANGED
|
@@ -1,6 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.TrackType = void 0;
|
|
4
|
-
var types_1 = require("./matroska/types");
|
|
5
|
-
Object.defineProperty(exports, "TrackType", { enumerable: true, get: function () { return types_1.TrackType; } });
|
|
1
|
+
export { TrackType } from './matroska/types.js';
|
|
6
2
|
//# sourceMappingURL=type.js.map
|
package/lib/wav/BwfChunk.d.ts
CHANGED
package/lib/wav/BwfChunk.js
CHANGED
|
@@ -1,21 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.BroadcastAudioExtensionChunk = void 0;
|
|
4
|
-
const Token = require("token-types");
|
|
5
|
-
const Util_1 = require("../common/Util");
|
|
1
|
+
import * as Token from 'token-types';
|
|
2
|
+
import { stripNulls } from '../common/Util.js';
|
|
6
3
|
/**
|
|
7
4
|
* Broadcast Audio Extension Chunk
|
|
8
5
|
* Ref: https://tech.ebu.ch/docs/tech/tech3285.pdf
|
|
9
6
|
*/
|
|
10
|
-
|
|
7
|
+
export const BroadcastAudioExtensionChunk = {
|
|
11
8
|
len: 420,
|
|
12
9
|
get: (uint8array, off) => {
|
|
13
10
|
return {
|
|
14
|
-
description:
|
|
15
|
-
originator:
|
|
16
|
-
originatorReference:
|
|
17
|
-
originationDate:
|
|
18
|
-
originationTime:
|
|
11
|
+
description: stripNulls(new Token.StringType(256, 'ascii').get(uint8array, off)).trim(),
|
|
12
|
+
originator: stripNulls(new Token.StringType(32, 'ascii').get(uint8array, off + 256)).trim(),
|
|
13
|
+
originatorReference: stripNulls(new Token.StringType(32, 'ascii').get(uint8array, off + 288)).trim(),
|
|
14
|
+
originationDate: stripNulls(new Token.StringType(10, 'ascii').get(uint8array, off + 320)).trim(),
|
|
15
|
+
originationTime: stripNulls(new Token.StringType(8, 'ascii').get(uint8array, off + 330)).trim(),
|
|
19
16
|
timeReferenceLow: Token.UINT32_LE.get(uint8array, off + 338),
|
|
20
17
|
timeReferenceHigh: Token.UINT32_LE.get(uint8array, off + 342),
|
|
21
18
|
version: Token.UINT16_LE.get(uint8array, off + 346),
|
package/lib/wav/WaveChunk.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
|
-
import { IGetToken } from 'strtok3/
|
|
3
|
-
import { IChunkHeader } from '../iff';
|
|
1
|
+
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
+
import { IGetToken } from 'strtok3/core';
|
|
3
|
+
import { IChunkHeader } from '../iff/index.js';
|
|
4
4
|
/**
|
|
5
5
|
* Ref: https://msdn.microsoft.com/en-us/library/windows/desktop/dd317599(v=vs.85).aspx
|
|
6
6
|
*/
|
package/lib/wav/WaveChunk.js
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.FactChunk = exports.Format = exports.WaveFormat = void 0;
|
|
4
1
|
/**
|
|
5
2
|
* Ref: https://msdn.microsoft.com/en-us/library/windows/desktop/dd317599(v=vs.85).aspx
|
|
6
3
|
*/
|
|
7
|
-
var WaveFormat;
|
|
4
|
+
export var WaveFormat;
|
|
8
5
|
(function (WaveFormat) {
|
|
9
6
|
WaveFormat[WaveFormat["PCM"] = 1] = "PCM";
|
|
10
7
|
// MPEG-4 and AAC Audio Types
|
|
@@ -21,12 +18,12 @@ var WaveFormat;
|
|
|
21
18
|
WaveFormat[WaveFormat["DRM"] = 9] = "DRM";
|
|
22
19
|
WaveFormat[WaveFormat["DTS2"] = 8193] = "DTS2";
|
|
23
20
|
WaveFormat[WaveFormat["MPEG"] = 80] = "MPEG";
|
|
24
|
-
})(WaveFormat =
|
|
21
|
+
})(WaveFormat = WaveFormat || (WaveFormat = {}));
|
|
25
22
|
/**
|
|
26
23
|
* format chunk; chunk-id is "fmt "
|
|
27
24
|
* http://soundfile.sapp.org/doc/WaveFormat/
|
|
28
25
|
*/
|
|
29
|
-
class Format {
|
|
26
|
+
export class Format {
|
|
30
27
|
constructor(header) {
|
|
31
28
|
if (header.chunkSize < 16)
|
|
32
29
|
throw new Error('Invalid chunk size');
|
|
@@ -43,13 +40,12 @@ class Format {
|
|
|
43
40
|
};
|
|
44
41
|
}
|
|
45
42
|
}
|
|
46
|
-
exports.Format = Format;
|
|
47
43
|
/**
|
|
48
44
|
* Fact chunk; chunk-id is "fact"
|
|
49
45
|
* http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/WAVE.html
|
|
50
46
|
* http://www.recordingblogs.com/wiki/fact-chunk-of-a-wave-file
|
|
51
47
|
*/
|
|
52
|
-
class FactChunk {
|
|
48
|
+
export class FactChunk {
|
|
53
49
|
constructor(header) {
|
|
54
50
|
if (header.chunkSize < 4) {
|
|
55
51
|
throw new Error('Invalid fact chunk size.');
|
|
@@ -62,4 +58,3 @@ class FactChunk {
|
|
|
62
58
|
};
|
|
63
59
|
}
|
|
64
60
|
}
|
|
65
|
-
exports.FactChunk = FactChunk;
|
package/lib/wav/WaveParser.d.ts
CHANGED
package/lib/wav/WaveParser.js
CHANGED
|
@@ -1,17 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const
|
|
12
|
-
const BasicParser_1 = require("../common/BasicParser");
|
|
13
|
-
const BwfChunk_1 = require("../wav/BwfChunk");
|
|
14
|
-
const debug = (0, debug_1.default)('music-metadata:parser:RIFF');
|
|
1
|
+
import * as strtok3 from 'strtok3/core';
|
|
2
|
+
import * as Token from 'token-types';
|
|
3
|
+
import initDebug from 'debug';
|
|
4
|
+
import * as riff from '../riff/RiffChunk.js';
|
|
5
|
+
import * as WaveChunk from './../wav/WaveChunk.js';
|
|
6
|
+
import { ID3v2Parser } from '../id3v2/ID3v2Parser.js';
|
|
7
|
+
import * as util from '../common/Util.js';
|
|
8
|
+
import { FourCcToken } from '../common/FourCC.js';
|
|
9
|
+
import { BasicParser } from '../common/BasicParser.js';
|
|
10
|
+
import { BroadcastAudioExtensionChunk } from '../wav/BwfChunk.js';
|
|
11
|
+
const debug = initDebug('music-metadata:parser:RIFF');
|
|
15
12
|
/**
|
|
16
13
|
* Resource Interchange File Format (RIFF) Parser
|
|
17
14
|
*
|
|
@@ -23,7 +20,7 @@ const debug = (0, debug_1.default)('music-metadata:parser:RIFF');
|
|
|
23
20
|
*
|
|
24
21
|
* ToDo: Split WAVE part from RIFF parser
|
|
25
22
|
*/
|
|
26
|
-
class WaveParser extends
|
|
23
|
+
export class WaveParser extends BasicParser {
|
|
27
24
|
async parse() {
|
|
28
25
|
const riffHeader = await this.tokenizer.readToken(riff.Header);
|
|
29
26
|
debug(`pos=${this.tokenizer.position}, parse: chunkID=${riffHeader.chunkID}`);
|
|
@@ -36,11 +33,11 @@ class WaveParser extends BasicParser_1.BasicParser {
|
|
|
36
33
|
});
|
|
37
34
|
}
|
|
38
35
|
async parseRiffChunk(chunkSize) {
|
|
39
|
-
const type = await this.tokenizer.readToken(
|
|
36
|
+
const type = await this.tokenizer.readToken(FourCcToken);
|
|
40
37
|
this.metadata.setFormat('container', type);
|
|
41
38
|
switch (type) {
|
|
42
39
|
case 'WAVE':
|
|
43
|
-
return this.readWaveChunk(chunkSize -
|
|
40
|
+
return this.readWaveChunk(chunkSize - FourCcToken.len);
|
|
44
41
|
default:
|
|
45
42
|
throw new Error(`Unsupported RIFF format: RIFF/${type}`);
|
|
46
43
|
}
|
|
@@ -80,7 +77,7 @@ class WaveParser extends BasicParser_1.BasicParser {
|
|
|
80
77
|
case 'ID3 ': // The way Mp3Tags stores ID3 meta-data
|
|
81
78
|
const id3_data = await this.tokenizer.readToken(new Token.Uint8ArrayType(header.chunkSize));
|
|
82
79
|
const rst = strtok3.fromBuffer(id3_data);
|
|
83
|
-
await new
|
|
80
|
+
await new ID3v2Parser().parse(this.metadata, rst, this.options);
|
|
84
81
|
break;
|
|
85
82
|
case 'data': // PCM-data
|
|
86
83
|
if (this.metadata.format.lossless !== false) {
|
|
@@ -103,11 +100,11 @@ class WaveParser extends BasicParser_1.BasicParser {
|
|
|
103
100
|
await this.tokenizer.ignore(header.chunkSize);
|
|
104
101
|
break;
|
|
105
102
|
case 'bext': // Broadcast Audio Extension chunk https://tech.ebu.ch/docs/tech/tech3285.pdf
|
|
106
|
-
const bext = await this.tokenizer.readToken(
|
|
103
|
+
const bext = await this.tokenizer.readToken(BroadcastAudioExtensionChunk);
|
|
107
104
|
Object.keys(bext).forEach(key => {
|
|
108
105
|
this.metadata.addTag('exif', 'bext.' + key, bext[key]);
|
|
109
106
|
});
|
|
110
|
-
const bextRemaining = header.chunkSize -
|
|
107
|
+
const bextRemaining = header.chunkSize - BroadcastAudioExtensionChunk.len;
|
|
111
108
|
await this.tokenizer.ignore(bextRemaining);
|
|
112
109
|
break;
|
|
113
110
|
case '\x00\x00\x00\x00': // padding ??
|
|
@@ -155,4 +152,3 @@ class WaveParser extends BasicParser_1.BasicParser {
|
|
|
155
152
|
this.metadata.addTag('exif', id, value);
|
|
156
153
|
}
|
|
157
154
|
}
|
|
158
|
-
exports.WaveParser = WaveParser;
|
|
@@ -1,33 +1,30 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const
|
|
8
|
-
const WavPackToken_1 = require("./WavPackToken");
|
|
9
|
-
const debug_1 = require("debug");
|
|
10
|
-
const debug = (0, debug_1.default)('music-metadata:parser:WavPack');
|
|
1
|
+
import * as Token from 'token-types';
|
|
2
|
+
import { APEv2Parser } from '../apev2/APEv2Parser.js';
|
|
3
|
+
import { FourCcToken } from '../common/FourCC.js';
|
|
4
|
+
import { BasicParser } from '../common/BasicParser.js';
|
|
5
|
+
import { WavPack } from './WavPackToken.js';
|
|
6
|
+
import initDebug from 'debug';
|
|
7
|
+
const debug = initDebug('music-metadata:parser:WavPack');
|
|
11
8
|
/**
|
|
12
9
|
* WavPack Parser
|
|
13
10
|
*/
|
|
14
|
-
class WavPackParser extends
|
|
11
|
+
export class WavPackParser extends BasicParser {
|
|
15
12
|
async parse() {
|
|
16
13
|
this.audioDataSize = 0;
|
|
17
14
|
// First parse all WavPack blocks
|
|
18
15
|
await this.parseWavPackBlocks();
|
|
19
16
|
// try to parse APEv2 header
|
|
20
|
-
return
|
|
17
|
+
return APEv2Parser.tryParseApeHeader(this.metadata, this.tokenizer, this.options);
|
|
21
18
|
}
|
|
22
19
|
async parseWavPackBlocks() {
|
|
23
20
|
do {
|
|
24
|
-
const blockId = await this.tokenizer.peekToken(
|
|
21
|
+
const blockId = await this.tokenizer.peekToken(FourCcToken);
|
|
25
22
|
if (blockId !== 'wvpk')
|
|
26
23
|
break;
|
|
27
|
-
const header = await this.tokenizer.readToken(
|
|
24
|
+
const header = await this.tokenizer.readToken(WavPack.BlockHeaderToken);
|
|
28
25
|
if (header.BlockID !== 'wvpk')
|
|
29
26
|
throw new Error('Invalid WavPack Block-ID');
|
|
30
|
-
debug(`WavPack header blockIndex=${header.blockIndex}, len=${
|
|
27
|
+
debug(`WavPack header blockIndex=${header.blockIndex}, len=${WavPack.BlockHeaderToken.len}`);
|
|
31
28
|
if (header.blockIndex === 0 && !this.metadata.format.container) {
|
|
32
29
|
this.metadata.setFormat('container', 'WavPack');
|
|
33
30
|
this.metadata.setFormat('lossless', !header.flags.isHybrid);
|
|
@@ -42,12 +39,12 @@ class WavPackParser extends BasicParser_1.BasicParser {
|
|
|
42
39
|
this.metadata.setFormat('numberOfSamples', header.totalSamples);
|
|
43
40
|
this.metadata.setFormat('codec', header.flags.isDSD ? 'DSD' : 'PCM');
|
|
44
41
|
}
|
|
45
|
-
const ignoreBytes = header.blockSize - (
|
|
42
|
+
const ignoreBytes = header.blockSize - (WavPack.BlockHeaderToken.len - 8);
|
|
46
43
|
await (header.blockIndex === 0 ? this.parseMetadataSubBlock(header, ignoreBytes) : this.tokenizer.ignore(ignoreBytes));
|
|
47
44
|
if (header.blockSamples > 0) {
|
|
48
45
|
this.audioDataSize += header.blockSize; // Count audio data for bit-rate calculation
|
|
49
46
|
}
|
|
50
|
-
} while (!this.tokenizer.fileInfo.size || this.tokenizer.fileInfo.size - this.tokenizer.position >=
|
|
47
|
+
} while (!this.tokenizer.fileInfo.size || this.tokenizer.fileInfo.size - this.tokenizer.position >= WavPack.BlockHeaderToken.len);
|
|
51
48
|
this.metadata.setFormat('bitrate', this.audioDataSize * 8 / this.metadata.format.duration);
|
|
52
49
|
}
|
|
53
50
|
/**
|
|
@@ -55,8 +52,8 @@ class WavPackParser extends BasicParser_1.BasicParser {
|
|
|
55
52
|
* @param remainingLength
|
|
56
53
|
*/
|
|
57
54
|
async parseMetadataSubBlock(header, remainingLength) {
|
|
58
|
-
while (remainingLength >
|
|
59
|
-
const id = await this.tokenizer.readToken(
|
|
55
|
+
while (remainingLength > WavPack.MetadataIdToken.len) {
|
|
56
|
+
const id = await this.tokenizer.readToken(WavPack.MetadataIdToken);
|
|
60
57
|
const dataSizeInWords = await this.tokenizer.readNumber(id.largeBlock ? Token.UINT24_LE : Token.UINT8);
|
|
61
58
|
const data = Buffer.alloc(dataSizeInWords * 2 - (id.isOddSize ? 1 : 0));
|
|
62
59
|
await this.tokenizer.readBuffer(data);
|
|
@@ -87,7 +84,7 @@ class WavPackParser extends BasicParser_1.BasicParser {
|
|
|
87
84
|
debug(`Ignore unsupported meta-sub-block-id functionId=0x${id.functionId.toString(16)}`);
|
|
88
85
|
break;
|
|
89
86
|
}
|
|
90
|
-
remainingLength -=
|
|
87
|
+
remainingLength -= WavPack.MetadataIdToken.len + (id.largeBlock ? Token.UINT24_LE.len : Token.UINT8.len) + dataSizeInWords * 2;
|
|
91
88
|
debug(`remainingLength=${remainingLength}`);
|
|
92
89
|
if (id.isOddSize)
|
|
93
90
|
this.tokenizer.ignore(1);
|
|
@@ -96,4 +93,3 @@ class WavPackParser extends BasicParser_1.BasicParser {
|
|
|
96
93
|
throw new Error('metadata-sub-block should fit it remaining length');
|
|
97
94
|
}
|
|
98
95
|
}
|
|
99
|
-
exports.WavPackParser = WavPackParser;
|
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.WavPack = void 0;
|
|
4
|
-
const Token = require("token-types");
|
|
5
|
-
const FourCC_1 = require("../common/FourCC");
|
|
1
|
+
import * as Token from 'token-types';
|
|
2
|
+
import { FourCcToken } from '../common/FourCC.js';
|
|
6
3
|
const SampleRates = [6000, 8000, 9600, 11025, 12000, 16000, 22050, 24000, 32000, 44100,
|
|
7
4
|
48000, 64000, 88200, 96000, 192000, -1];
|
|
8
|
-
class WavPack {
|
|
5
|
+
export class WavPack {
|
|
9
6
|
static isBitSet(flags, bitOffset) {
|
|
10
7
|
return WavPack.getBitAllignedNumber(flags, bitOffset, 1) === 1;
|
|
11
8
|
}
|
|
@@ -13,7 +10,6 @@ class WavPack {
|
|
|
13
10
|
return (flags >>> bitOffset) & (0xffffffff >>> (32 - len));
|
|
14
11
|
}
|
|
15
12
|
}
|
|
16
|
-
exports.WavPack = WavPack;
|
|
17
13
|
/**
|
|
18
14
|
* WavPack Block Header
|
|
19
15
|
*
|
|
@@ -27,7 +23,7 @@ WavPack.BlockHeaderToken = {
|
|
|
27
23
|
const flags = Token.UINT32_LE.get(buf, off + 24);
|
|
28
24
|
const res = {
|
|
29
25
|
// should equal 'wvpk'
|
|
30
|
-
BlockID:
|
|
26
|
+
BlockID: FourCcToken.get(buf, off),
|
|
31
27
|
// 0x402 to 0x410 are valid for decode
|
|
32
28
|
blockSize: Token.UINT32_LE.get(buf, off + 4),
|
|
33
29
|
// 0x402 (1026) to 0x410 are valid for decode
|