music-metadata 7.11.6 → 7.11.9
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 +3 -1
- package/lib/ParserFactory.d.ts +0 -1
- package/lib/ParserFactory.js +9 -8
- package/lib/aiff/AiffParser.d.ts +2 -3
- package/lib/aiff/AiffParser.js +2 -3
- package/lib/apev2/APEv2Parser.js +1 -2
- package/lib/apev2/APEv2Token.d.ts +5 -5
- package/lib/asf/AsfParser.d.ts +5 -5
- package/lib/asf/AsfParser.js +7 -7
- package/lib/asf/GUID.d.ts +14 -16
- package/lib/asf/GUID.js +13 -15
- package/lib/common/CombinedTagMapper.d.ts +3 -3
- package/lib/common/CombinedTagMapper.js +1 -1
- package/lib/common/GenericTagMapper.d.ts +2 -2
- package/lib/common/GenericTagMapper.js +2 -2
- package/lib/common/MetadataCollector.js +2 -2
- package/lib/common/Util.d.ts +5 -4
- package/lib/common/Util.js +12 -24
- package/lib/dsdiff/DsdiffParser.d.ts +1 -1
- package/lib/dsdiff/DsdiffParser.js +1 -1
- package/lib/dsf/DsfParser.d.ts +1 -1
- package/lib/dsf/DsfParser.js +1 -1
- package/lib/flac/FlacParser.d.ts +1 -1
- package/lib/flac/FlacParser.js +12 -12
- package/lib/id3v1/ID3v1Parser.js +39 -39
- package/lib/id3v2/AbstractID3Parser.d.ts +1 -1
- package/lib/id3v2/AbstractID3Parser.js +3 -3
- package/lib/id3v2/FrameParser.js +7 -1
- package/lib/id3v2/ID3v24TagMapper.d.ts +2 -2
- package/lib/id3v2/ID3v24TagMapper.js +2 -2
- package/lib/id3v2/ID3v2Parser.d.ts +3 -3
- package/lib/id3v2/ID3v2Parser.js +5 -15
- package/lib/iff/index.d.ts +2 -2
- package/lib/matroska/MatroskaDtd.d.ts +1 -1
- package/lib/matroska/MatroskaDtd.js +1 -1
- package/lib/matroska/MatroskaParser.js +9 -9
- package/lib/matroska/types.d.ts +2 -2
- package/lib/matroska/types.js +1 -0
- package/lib/mp4/AtomToken.d.ts +6 -6
- package/lib/mp4/AtomToken.js +2 -2
- package/lib/mp4/MP4Parser.js +3 -3
- package/lib/mpeg/MpegParser.d.ts +1 -1
- package/lib/mpeg/MpegParser.js +4 -9
- package/lib/musepack/index.d.ts +1 -1
- package/lib/musepack/index.js +1 -1
- package/lib/ogg/speex/SpeexParser.d.ts +2 -2
- package/lib/ogg/speex/SpeexParser.js +2 -2
- package/lib/ogg/theora/TheoraParser.d.ts +1 -1
- package/lib/ogg/theora/TheoraParser.js +1 -1
- package/lib/ogg/vorbis/Vorbis.d.ts +1 -11
- package/lib/type.d.ts +2 -9
- package/lib/type.js +2 -10
- package/lib/wav/BwfChunk.d.ts +17 -0
- package/lib/wav/BwfChunk.js +28 -0
- package/lib/wav/WaveParser.d.ts +3 -3
- package/lib/wav/WaveParser.js +15 -3
- package/lib/wavpack/WavPackParser.js +1 -7
- package/lib/wavpack/WavPackToken.d.ts +2 -2
- package/lib/wavpack/WavPackToken.js +1 -1
- package/package.json +22 -14
package/README.md
CHANGED
|
@@ -26,6 +26,7 @@ Supports any common audio and tagging format.
|
|
|
26
26
|
| AAC | ADTS / Advanced Audio Coding | [:link:](https://en.wikipedia.org/wiki/Advanced_Audio_Coding) | <img src="https://svgshare.com/i/UT8.svg" width="40" alt="AAC logo"> |
|
|
27
27
|
| APE | Monkey's Audio | [:link:](https://wikipedia.org/wiki/Monkey's_Audio) | <img src="https://foreverhits.files.wordpress.com/2015/05/ape_audio.jpg" width="40" alt="Monkey's Audio logo"> |
|
|
28
28
|
| ASF | Advanced Systems Format | [:link:](https://wikipedia.org/wiki/Advanced_Systems_Format) | |
|
|
29
|
+
| BWF | Broadcast Wave Format | [:link:](https://en.wikipedia.org/wiki/Broadcast_Wave_Format) | |
|
|
29
30
|
| DSDIFF | Philips DSDIFF | [:link:](https://wikipedia.org/wiki/Direct_Stream_Digital) | <img src="https://upload.wikimedia.org/wikipedia/commons/b/bc/DSDlogo.svg" width="80" alt="DSD logo"> |
|
|
30
31
|
| DSF | Sony's DSD Stream File | [:link:](https://wikipedia.org/wiki/Direct_Stream_Digital) | <img src="https://upload.wikimedia.org/wikipedia/commons/b/bc/DSDlogo.svg" width="80" alt="DSD logo"> |
|
|
31
32
|
| FLAC | Free Lossless Audio Codec | [:link:](https://wikipedia.org/wiki/FLAC) | <img src="https://upload.wikimedia.org/wikipedia/commons/a/a2/FLAC_logo_vector.svg" width="80" alt="FLAC logo"> |
|
|
@@ -70,9 +71,10 @@ Support for encoding / format details:
|
|
|
70
71
|
|
|
71
72
|
|
|
72
73
|
## Online demo's
|
|
73
|
-
* [<img src="https://
|
|
74
|
+
* [<img src="https://raw.githubusercontent.com/Borewit/audio-tag-analyzer/master/src/assets/icon/audio-tag-analyzer.svg" width="40">Audio Tag Analyzer](https://audio-tag-analyzer.netlify.com/)
|
|
74
75
|
* [<img src="https://cdn.sanity.io/images/3do82whm/next/ba8c847f13a5fa39d88f8bc9b7846b7886531b18-2500x2500.svg" width="40"> Webamp](https://webamp.org/)
|
|
75
76
|
|
|
77
|
+
|
|
76
78
|
## Compatibility
|
|
77
79
|
|
|
78
80
|
The JavaScript in runtime is compliant with [ECMAScript 2017 (ES8)](https://en.wikipedia.org/wiki/ECMAScript#8th_Edition_-_ECMAScript_2017).
|
package/lib/ParserFactory.d.ts
CHANGED
|
@@ -39,7 +39,6 @@ export declare class ParserFactory {
|
|
|
39
39
|
*/
|
|
40
40
|
static getParserIdForExtension(filePath: string): ParserType;
|
|
41
41
|
static loadParser(moduleName: ParserType): Promise<ITokenParser>;
|
|
42
|
-
private static _parse;
|
|
43
42
|
private static getExtension;
|
|
44
43
|
/**
|
|
45
44
|
* @param httpContentType - HTTP Content-Type, extension, path or filename
|
package/lib/ParserFactory.js
CHANGED
|
@@ -31,6 +31,13 @@ function parseHttpContentType(contentType) {
|
|
|
31
31
|
};
|
|
32
32
|
}
|
|
33
33
|
exports.parseHttpContentType = parseHttpContentType;
|
|
34
|
+
async function parse(tokenizer, parserId, opts = {}) {
|
|
35
|
+
// Parser found, execute parser
|
|
36
|
+
const parser = await ParserFactory.loadParser(parserId);
|
|
37
|
+
const metadata = new MetadataCollector_1.MetadataCollector(opts);
|
|
38
|
+
await parser.init(metadata, tokenizer, opts).parse();
|
|
39
|
+
return metadata.toCommonMetadata();
|
|
40
|
+
}
|
|
34
41
|
class ParserFactory {
|
|
35
42
|
/**
|
|
36
43
|
* Parse metadata from tokenizer
|
|
@@ -69,7 +76,7 @@ class ParserFactory {
|
|
|
69
76
|
}
|
|
70
77
|
}
|
|
71
78
|
// Parser found, execute parser
|
|
72
|
-
return
|
|
79
|
+
return parse(tokenizer, parserId, opts);
|
|
73
80
|
}
|
|
74
81
|
/**
|
|
75
82
|
* @param filePath - Path, filename or extension to audio file
|
|
@@ -114,6 +121,7 @@ class ParserFactory {
|
|
|
114
121
|
case '.aifc':
|
|
115
122
|
return 'aiff';
|
|
116
123
|
case '.wav':
|
|
124
|
+
case '.bwf': // Broadcast Wave Format
|
|
117
125
|
return 'riff';
|
|
118
126
|
case '.wv':
|
|
119
127
|
case '.wvp':
|
|
@@ -153,13 +161,6 @@ class ParserFactory {
|
|
|
153
161
|
throw new Error(`Unknown parser type: ${moduleName}`);
|
|
154
162
|
}
|
|
155
163
|
}
|
|
156
|
-
static async _parse(tokenizer, parserId, opts = {}) {
|
|
157
|
-
// Parser found, execute parser
|
|
158
|
-
const parser = await ParserFactory.loadParser(parserId);
|
|
159
|
-
const metadata = new MetadataCollector_1.MetadataCollector(opts);
|
|
160
|
-
await parser.init(metadata, tokenizer, opts).parse();
|
|
161
|
-
return metadata.toCommonMetadata();
|
|
162
|
-
}
|
|
163
164
|
static getExtension(fname) {
|
|
164
165
|
const i = fname.lastIndexOf('.');
|
|
165
166
|
return i === -1 ? '' : fname.slice(i);
|
package/lib/aiff/AiffParser.d.ts
CHANGED
|
@@ -4,9 +4,8 @@ import * as iff from '../iff';
|
|
|
4
4
|
* AIFF - Audio Interchange File Format
|
|
5
5
|
*
|
|
6
6
|
* Ref:
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/AIFF/AIFF.html
|
|
7
|
+
* - http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/AIFF/AIFF.html
|
|
8
|
+
* - http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/AIFF/Docs/AIFF-1.3.pdf
|
|
10
9
|
*/
|
|
11
10
|
export declare class AIFFParser extends BasicParser {
|
|
12
11
|
private isCompressed;
|
package/lib/aiff/AiffParser.js
CHANGED
|
@@ -14,9 +14,8 @@ const debug = initDebug('music-metadata:parser:aiff');
|
|
|
14
14
|
* AIFF - Audio Interchange File Format
|
|
15
15
|
*
|
|
16
16
|
* Ref:
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/AIFF/AIFF.html
|
|
17
|
+
* - http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/AIFF/AIFF.html
|
|
18
|
+
* - http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/AIFF/Docs/AIFF-1.3.pdf
|
|
20
19
|
*/
|
|
21
20
|
class AIFFParser extends BasicParser_1.BasicParser {
|
|
22
21
|
async parse() {
|
package/lib/apev2/APEv2Parser.js
CHANGED
|
@@ -106,10 +106,9 @@ class APEv2Parser extends BasicParser_1.BasicParser {
|
|
|
106
106
|
await this.tokenizer.ignore(1);
|
|
107
107
|
bytesRemaining -= key.length + 1;
|
|
108
108
|
switch (tagItemHeader.flags.dataType) {
|
|
109
|
-
case APEv2Token_1.DataType.text_utf8: { // utf-8
|
|
109
|
+
case APEv2Token_1.DataType.text_utf8: { // utf-8 text-string
|
|
110
110
|
const value = await this.tokenizer.readToken(new token_types_1.StringType(tagItemHeader.size, 'utf8'));
|
|
111
111
|
const values = value.split(/\x00/g);
|
|
112
|
-
/*jshint loopfunc:true */
|
|
113
112
|
for (const val of values) {
|
|
114
113
|
this.metadata.addTag(tagFormat, key, val);
|
|
115
114
|
}
|
|
@@ -3,12 +3,12 @@ import { IGetToken } from 'strtok3/lib/core';
|
|
|
3
3
|
/**
|
|
4
4
|
* APETag versionIndex history / supported formats
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
6
|
+
* 1.0 (1000) - Original APE tag spec. Fully supported by this code.
|
|
7
|
+
* 2.0 (2000) - Refined APE tag spec (better streaming support, UTF StringEncoding). Fully supported by this code.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
9
|
+
* Notes:
|
|
10
|
+
* - also supports reading of ID3v1.1 tags
|
|
11
|
+
* - all saving done in the APE Tag format using CURRENT_APE_TAG_VERSION
|
|
12
12
|
*
|
|
13
13
|
* APE File Format Overview: (pieces in order -- only valid for the latest versionIndex APE files)
|
|
14
14
|
*
|
package/lib/asf/AsfParser.d.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { BasicParser } from '../common/BasicParser';
|
|
2
2
|
/**
|
|
3
3
|
* Windows Media Metadata Usage Guidelines
|
|
4
|
-
*
|
|
4
|
+
* - Ref: https://msdn.microsoft.com/en-us/library/ms867702.aspx
|
|
5
5
|
*
|
|
6
6
|
* Ref:
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
7
|
+
* - https://tools.ietf.org/html/draft-fleischman-asf-01
|
|
8
|
+
* - https://hwiegman.home.xs4all.nl/fileformats/asf/ASF_Specification.pdf
|
|
9
|
+
* - http://drang.s4.xrea.com/program/tips/id3tag/wmp/index.html
|
|
10
|
+
* - https://msdn.microsoft.com/en-us/library/windows/desktop/ee663575(v=vs.85).aspx
|
|
11
11
|
*/
|
|
12
12
|
export declare class AsfParser extends BasicParser {
|
|
13
13
|
parse(): Promise<void>;
|
package/lib/asf/AsfParser.js
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.AsfParser = void 0;
|
|
4
|
-
const
|
|
4
|
+
const initDebug = require("debug");
|
|
5
5
|
const type_1 = require("../type");
|
|
6
6
|
const GUID_1 = require("./GUID");
|
|
7
7
|
const AsfObject = require("./AsfObject");
|
|
8
8
|
const BasicParser_1 = require("../common/BasicParser");
|
|
9
|
-
const debug =
|
|
9
|
+
const debug = initDebug('music-metadata:parser:ASF');
|
|
10
10
|
const headerType = 'asf';
|
|
11
11
|
/**
|
|
12
12
|
* Windows Media Metadata Usage Guidelines
|
|
13
|
-
*
|
|
13
|
+
* - Ref: https://msdn.microsoft.com/en-us/library/ms867702.aspx
|
|
14
14
|
*
|
|
15
15
|
* Ref:
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
16
|
+
* - https://tools.ietf.org/html/draft-fleischman-asf-01
|
|
17
|
+
* - https://hwiegman.home.xs4all.nl/fileformats/asf/ASF_Specification.pdf
|
|
18
|
+
* - http://drang.s4.xrea.com/program/tips/id3tag/wmp/index.html
|
|
19
|
+
* - https://msdn.microsoft.com/en-us/library/windows/desktop/ee663575(v=vs.85).aspx
|
|
20
20
|
*/
|
|
21
21
|
class AsfParser extends BasicParser_1.BasicParser {
|
|
22
22
|
async parse() {
|
package/lib/asf/GUID.d.ts
CHANGED
|
@@ -1,19 +1,17 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
/**
|
|
3
3
|
* Ref:
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* - https://tools.ietf.org/html/draft-fleischman-asf-01, Appendix A: ASF GUIDs
|
|
5
|
+
* - http://drang.s4.xrea.com/program/tips/id3tag/wmp/10_asf_guids.html
|
|
6
|
+
* - http://drang.s4.xrea.com/program/tips/id3tag/wmp/index.html
|
|
7
|
+
* - http://drang.s4.xrea.com/program/tips/id3tag/wmp/10_asf_guids.html
|
|
7
8
|
*
|
|
8
|
-
*
|
|
9
|
+
* ASF File Structure:
|
|
10
|
+
* - https://msdn.microsoft.com/en-us/library/windows/desktop/ee663575(v=vs.85).aspx
|
|
9
11
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* ASF GUIDs:
|
|
14
|
-
* http://drang.s4.xrea.com/program/tips/id3tag/wmp/10_asf_guids.html
|
|
15
|
-
*
|
|
16
|
-
* https://github.com/dji-sdk/FFmpeg/blob/master/libavformat/asf.c
|
|
12
|
+
* ASF GUIDs:
|
|
13
|
+
* - http://drang.s4.xrea.com/program/tips/id3tag/wmp/10_asf_guids.html
|
|
14
|
+
* - https://github.com/dji-sdk/FFmpeg/blob/master/libavformat/asf.c
|
|
17
15
|
*/
|
|
18
16
|
export default class GUID {
|
|
19
17
|
str: string;
|
|
@@ -65,19 +63,19 @@ export default class GUID {
|
|
|
65
63
|
* Decode GUID in format like "B503BF5F-2EA9-CF11-8EE3-00C00C205365"
|
|
66
64
|
* @param objectId Binary GUID
|
|
67
65
|
* @param offset Read offset in bytes, default 0
|
|
68
|
-
* @returns
|
|
66
|
+
* @returns GUID as dashed hexadecimal representation
|
|
69
67
|
*/
|
|
70
68
|
static decode(objectId: Buffer, offset?: number): string;
|
|
71
69
|
/**
|
|
72
70
|
* Decode stream type
|
|
73
|
-
* @param
|
|
74
|
-
* @returns
|
|
71
|
+
* @param mediaType Media type GUID
|
|
72
|
+
* @returns Media type
|
|
75
73
|
*/
|
|
76
|
-
static decodeMediaType(mediaType: GUID):
|
|
74
|
+
static decodeMediaType(mediaType: GUID): 'audio' | 'video' | 'command' | 'degradable-jpeg' | 'file-transfer' | 'binary' | undefined;
|
|
77
75
|
/**
|
|
78
76
|
* Encode GUID
|
|
79
77
|
* @param guid GUID like: "B503BF5F-2EA9-CF11-8EE3-00C00C205365"
|
|
80
|
-
* @returns
|
|
78
|
+
* @returns Encoded Binary GUID
|
|
81
79
|
*/
|
|
82
80
|
static encode(str: string): Buffer;
|
|
83
81
|
constructor(str: string);
|
package/lib/asf/GUID.js
CHANGED
|
@@ -2,19 +2,17 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
/**
|
|
4
4
|
* Ref:
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* - https://tools.ietf.org/html/draft-fleischman-asf-01, Appendix A: ASF GUIDs
|
|
6
|
+
* - http://drang.s4.xrea.com/program/tips/id3tag/wmp/10_asf_guids.html
|
|
7
|
+
* - http://drang.s4.xrea.com/program/tips/id3tag/wmp/index.html
|
|
8
|
+
* - http://drang.s4.xrea.com/program/tips/id3tag/wmp/10_asf_guids.html
|
|
8
9
|
*
|
|
9
|
-
*
|
|
10
|
+
* ASF File Structure:
|
|
11
|
+
* - https://msdn.microsoft.com/en-us/library/windows/desktop/ee663575(v=vs.85).aspx
|
|
10
12
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* ASF GUIDs:
|
|
15
|
-
* http://drang.s4.xrea.com/program/tips/id3tag/wmp/10_asf_guids.html
|
|
16
|
-
*
|
|
17
|
-
* https://github.com/dji-sdk/FFmpeg/blob/master/libavformat/asf.c
|
|
13
|
+
* ASF GUIDs:
|
|
14
|
+
* - http://drang.s4.xrea.com/program/tips/id3tag/wmp/10_asf_guids.html
|
|
15
|
+
* - https://github.com/dji-sdk/FFmpeg/blob/master/libavformat/asf.c
|
|
18
16
|
*/
|
|
19
17
|
class GUID {
|
|
20
18
|
constructor(str) {
|
|
@@ -27,7 +25,7 @@ class GUID {
|
|
|
27
25
|
* Decode GUID in format like "B503BF5F-2EA9-CF11-8EE3-00C00C205365"
|
|
28
26
|
* @param objectId Binary GUID
|
|
29
27
|
* @param offset Read offset in bytes, default 0
|
|
30
|
-
* @returns
|
|
28
|
+
* @returns GUID as dashed hexadecimal representation
|
|
31
29
|
*/
|
|
32
30
|
static decode(objectId, offset = 0) {
|
|
33
31
|
const guid = objectId.readUInt32LE(offset).toString(16) + "-" +
|
|
@@ -39,8 +37,8 @@ class GUID {
|
|
|
39
37
|
}
|
|
40
38
|
/**
|
|
41
39
|
* Decode stream type
|
|
42
|
-
* @param
|
|
43
|
-
* @returns
|
|
40
|
+
* @param mediaType Media type GUID
|
|
41
|
+
* @returns Media type
|
|
44
42
|
*/
|
|
45
43
|
static decodeMediaType(mediaType) {
|
|
46
44
|
switch (mediaType.str) {
|
|
@@ -55,7 +53,7 @@ class GUID {
|
|
|
55
53
|
/**
|
|
56
54
|
* Encode GUID
|
|
57
55
|
* @param guid GUID like: "B503BF5F-2EA9-CF11-8EE3-00C00C205365"
|
|
58
|
-
* @returns
|
|
56
|
+
* @returns Encoded Binary GUID
|
|
59
57
|
*/
|
|
60
58
|
static encode(str) {
|
|
61
59
|
const bin = Buffer.alloc(16);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { IGenericTag, TagType } from
|
|
2
|
-
import { IGenericTagMapper } from
|
|
3
|
-
import { ITag } from
|
|
1
|
+
import { IGenericTag, TagType } from './GenericTagTypes';
|
|
2
|
+
import { IGenericTagMapper } from './GenericTagMapper';
|
|
3
|
+
import { ITag } from '../type';
|
|
4
4
|
import { INativeMetadataCollector } from './MetadataCollector';
|
|
5
5
|
export declare class CombinedTagMapper {
|
|
6
6
|
tagMappers: {
|
|
@@ -40,7 +40,7 @@ class CombinedTagMapper {
|
|
|
40
40
|
if (tagMapper) {
|
|
41
41
|
return this.tagMappers[tagType].mapGenericTag(tag, warnings);
|
|
42
42
|
}
|
|
43
|
-
throw new Error(
|
|
43
|
+
throw new Error('No generic tag mapper defined for tag-format: ' + tagType);
|
|
44
44
|
}
|
|
45
45
|
registerTagMapper(genericTagMapper) {
|
|
46
46
|
for (const tagType of genericTagMapper.tagTypes) {
|
|
@@ -44,8 +44,8 @@ export declare class CommonTagMapper implements IGenericTagMapper {
|
|
|
44
44
|
protected getCommonName(tag: string): generic.GenericTagId;
|
|
45
45
|
/**
|
|
46
46
|
* Handle post mapping exceptions / correction
|
|
47
|
-
* @param
|
|
48
|
-
* @param
|
|
47
|
+
* @param tag Tag e.g. {"©alb", "Buena Vista Social Club")
|
|
48
|
+
* @param warnings Used to register warnings
|
|
49
49
|
*/
|
|
50
50
|
protected postMap(tag: ITag, warnings: IWarningCollector): void;
|
|
51
51
|
}
|
|
@@ -44,8 +44,8 @@ class CommonTagMapper {
|
|
|
44
44
|
}
|
|
45
45
|
/**
|
|
46
46
|
* Handle post mapping exceptions / correction
|
|
47
|
-
* @param
|
|
48
|
-
* @param
|
|
47
|
+
* @param tag Tag e.g. {"©alb", "Buena Vista Social Club")
|
|
48
|
+
* @param warnings Used to register warnings
|
|
49
49
|
*/
|
|
50
50
|
postMap(tag, warnings) {
|
|
51
51
|
return;
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.joinArtists = exports.MetadataCollector = void 0;
|
|
4
4
|
const type_1 = require("../type");
|
|
5
|
-
const
|
|
5
|
+
const initDebug = require("debug");
|
|
6
6
|
const GenericTagTypes_1 = require("./GenericTagTypes");
|
|
7
7
|
const CombinedTagMapper_1 = require("./CombinedTagMapper");
|
|
8
8
|
const GenericTagMapper_1 = require("./GenericTagMapper");
|
|
9
9
|
const Util_1 = require("./Util");
|
|
10
10
|
const FileType = require("file-type/core");
|
|
11
|
-
const debug =
|
|
11
|
+
const debug = initDebug('music-metadata:collector');
|
|
12
12
|
const TagPriority = ['matroska', 'APEv2', 'vorbis', 'ID3v2.4', 'ID3v2.3', 'ID3v2.2', 'exif', 'asf', 'iTunes', 'ID3v1'];
|
|
13
13
|
/**
|
|
14
14
|
* Provided to the parser to uodate the metadata result.
|
package/lib/common/Util.d.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import { IRatio } from '../type';
|
|
3
3
|
export declare type StringEncoding = 'ascii' | 'utf8' | 'utf16le' | 'ucs2' | 'base64url' | 'latin1' | 'hex';
|
|
4
|
+
export interface ITextEncoding {
|
|
5
|
+
encoding: StringEncoding;
|
|
6
|
+
bom?: boolean;
|
|
7
|
+
}
|
|
4
8
|
export declare function getBit(buf: Uint8Array, off: number, bit: number): boolean;
|
|
5
9
|
/**
|
|
6
10
|
* Found delimiting zero in uint8Array
|
|
@@ -13,10 +17,7 @@ export declare function getBit(buf: Uint8Array, off: number, bit: number): boole
|
|
|
13
17
|
export declare function findZero(uint8Array: Uint8Array, start: number, end: number, encoding?: StringEncoding): number;
|
|
14
18
|
export declare function trimRightNull(x: string): string;
|
|
15
19
|
/**
|
|
16
|
-
*
|
|
17
|
-
* @param buffer Decoder input data
|
|
18
|
-
* @param encoding 'utf16le' | 'utf16' | 'utf8' | 'iso-8859-1'
|
|
19
|
-
* @return {string}
|
|
20
|
+
* Decode string
|
|
20
21
|
*/
|
|
21
22
|
export declare function decodeString(buffer: Buffer, encoding: StringEncoding): string;
|
|
22
23
|
export declare function stripNulls(str: string): string;
|
package/lib/common/Util.js
CHANGED
|
@@ -50,28 +50,21 @@ function swapBytes(uint8Array) {
|
|
|
50
50
|
return uint8Array;
|
|
51
51
|
}
|
|
52
52
|
/**
|
|
53
|
-
*
|
|
54
|
-
* @param buffer Decoder input data
|
|
55
|
-
* @param encoding 'utf16le' | 'utf16' | 'utf8' | 'iso-8859-1'
|
|
56
|
-
* @return {string}
|
|
53
|
+
* Decode string
|
|
57
54
|
*/
|
|
58
55
|
function decodeString(buffer, encoding) {
|
|
59
56
|
// annoying workaround for a double BOM issue
|
|
60
57
|
// https://github.com/leetreveil/musicmetadata/issues/84
|
|
61
|
-
let offset = 0;
|
|
62
58
|
if (buffer[0] === 0xFF && buffer[1] === 0xFE) { // little endian
|
|
63
|
-
|
|
64
|
-
offset = 2;
|
|
65
|
-
}
|
|
66
|
-
else if (buffer[2] === 0xFE && buffer[3] === 0xFF) {
|
|
67
|
-
offset = 2; // Clear double BOM
|
|
68
|
-
}
|
|
59
|
+
return decodeString(buffer.subarray(2), encoding);
|
|
69
60
|
}
|
|
70
61
|
else if (encoding === 'utf16le' && buffer[0] === 0xFE && buffer[1] === 0xFF) {
|
|
71
62
|
// BOM, indicating big endian decoding
|
|
63
|
+
if ((buffer.length & 1) !== 0)
|
|
64
|
+
throw new Error('Expected even number of octets for 16-bit unicode string');
|
|
72
65
|
return decodeString(swapBytes(buffer), encoding);
|
|
73
66
|
}
|
|
74
|
-
return buffer.toString(encoding
|
|
67
|
+
return buffer.toString(encoding);
|
|
75
68
|
}
|
|
76
69
|
exports.decodeString = decodeString;
|
|
77
70
|
function stripNulls(str) {
|
|
@@ -152,18 +145,13 @@ function toRatio(value) {
|
|
|
152
145
|
// @ts-ignore
|
|
153
146
|
if (ps.length >= 1) {
|
|
154
147
|
const v = parseFloat(ps[0]);
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
return {
|
|
163
|
-
dB: ratioToDb(v),
|
|
164
|
-
ratio: v
|
|
165
|
-
};
|
|
166
|
-
}
|
|
148
|
+
return ps.length === 2 && ps[1] === 'db' ? {
|
|
149
|
+
dB: v,
|
|
150
|
+
ratio: dbToRatio(v)
|
|
151
|
+
} : {
|
|
152
|
+
dB: ratioToDb(v),
|
|
153
|
+
ratio: v
|
|
154
|
+
};
|
|
167
155
|
}
|
|
168
156
|
}
|
|
169
157
|
exports.toRatio = toRatio;
|
|
@@ -3,7 +3,7 @@ import { BasicParser } from '../common/BasicParser';
|
|
|
3
3
|
* DSDIFF - Direct Stream Digital Interchange File Format (Phillips)
|
|
4
4
|
*
|
|
5
5
|
* Ref:
|
|
6
|
-
*
|
|
6
|
+
* - http://www.sonicstudio.com/pdf/dsd/DSDIFF_1.5_Spec.pdf
|
|
7
7
|
*/
|
|
8
8
|
export declare class DsdiffParser extends BasicParser {
|
|
9
9
|
parse(): Promise<void>;
|
|
@@ -13,7 +13,7 @@ const debug = initDebug('music-metadata:parser:aiff');
|
|
|
13
13
|
* DSDIFF - Direct Stream Digital Interchange File Format (Phillips)
|
|
14
14
|
*
|
|
15
15
|
* Ref:
|
|
16
|
-
*
|
|
16
|
+
* - http://www.sonicstudio.com/pdf/dsd/DSDIFF_1.5_Spec.pdf
|
|
17
17
|
*/
|
|
18
18
|
class DsdiffParser extends BasicParser_1.BasicParser {
|
|
19
19
|
async parse() {
|
package/lib/dsf/DsfParser.d.ts
CHANGED
|
@@ -4,6 +4,6 @@ import { AbstractID3Parser } from '../id3v2/AbstractID3Parser';
|
|
|
4
4
|
* Ref: https://dsd-guide.com/sites/default/files/white-papers/DSFFileFormatSpec_E.pdf
|
|
5
5
|
*/
|
|
6
6
|
export declare class DsfParser extends AbstractID3Parser {
|
|
7
|
-
|
|
7
|
+
postId3v2Parse(): Promise<void>;
|
|
8
8
|
private parseChunks;
|
|
9
9
|
}
|
package/lib/dsf/DsfParser.js
CHANGED
|
@@ -11,7 +11,7 @@ const debug = _debug('music-metadata:parser:DSF');
|
|
|
11
11
|
* Ref: https://dsd-guide.com/sites/default/files/white-papers/DSFFileFormatSpec_E.pdf
|
|
12
12
|
*/
|
|
13
13
|
class DsfParser extends AbstractID3Parser_1.AbstractID3Parser {
|
|
14
|
-
async
|
|
14
|
+
async postId3v2Parse() {
|
|
15
15
|
const p0 = this.tokenizer.position; // mark start position, normally 0
|
|
16
16
|
const chunkHeader = await this.tokenizer.readToken(DsfChunk_1.ChunkHeader);
|
|
17
17
|
if (chunkHeader.id !== 'DSD ')
|
package/lib/flac/FlacParser.d.ts
CHANGED
|
@@ -13,7 +13,7 @@ export declare class FlacParser extends AbstractID3Parser {
|
|
|
13
13
|
* @param {IOptions} options Parsing options
|
|
14
14
|
*/
|
|
15
15
|
init(metadata: INativeMetadataCollector, tokenizer: ITokenizer, options: IOptions): ITokenParser;
|
|
16
|
-
|
|
16
|
+
postId3v2Parse(): Promise<void>;
|
|
17
17
|
private parseDataBlock;
|
|
18
18
|
/**
|
|
19
19
|
* Parse STREAMINFO
|
package/lib/flac/FlacParser.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.FlacParser = void 0;
|
|
4
|
-
const
|
|
5
|
-
const
|
|
4
|
+
const token_types_1 = require("token-types");
|
|
5
|
+
const initDebug = require("debug");
|
|
6
6
|
const util = require("../common/Util");
|
|
7
7
|
const Vorbis_1 = require("../ogg/vorbis/Vorbis");
|
|
8
8
|
const AbstractID3Parser_1 = require("../id3v2/AbstractID3Parser");
|
|
9
9
|
const FourCC_1 = require("../common/FourCC");
|
|
10
10
|
const VorbisParser_1 = require("../ogg/vorbis/VorbisParser");
|
|
11
11
|
const VorbisDecoder_1 = require("../ogg/vorbis/VorbisDecoder");
|
|
12
|
-
const debug =
|
|
12
|
+
const debug = initDebug('music-metadata:parser:FLAC');
|
|
13
13
|
/**
|
|
14
14
|
* FLAC supports up to 128 kinds of metadata blocks; currently the following are defined:
|
|
15
15
|
* ref: https://xiph.org/flac/format.html#metadata_block
|
|
@@ -40,7 +40,7 @@ class FlacParser extends AbstractID3Parser_1.AbstractID3Parser {
|
|
|
40
40
|
this.vorbisParser = new VorbisParser_1.VorbisParser(metadata, options);
|
|
41
41
|
return this;
|
|
42
42
|
}
|
|
43
|
-
async
|
|
43
|
+
async postId3v2Parse() {
|
|
44
44
|
const fourCC = await this.tokenizer.readToken(FourCC_1.FourCcToken);
|
|
45
45
|
if (fourCC.toString() !== 'fLaC') {
|
|
46
46
|
throw new Error('Invalid FLAC preamble');
|
|
@@ -103,7 +103,7 @@ class FlacParser extends AbstractID3Parser_1.AbstractID3Parser {
|
|
|
103
103
|
* Ref: https://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-640004.2.3
|
|
104
104
|
*/
|
|
105
105
|
async parseComment(dataLen) {
|
|
106
|
-
const data = await this.tokenizer.readToken(new
|
|
106
|
+
const data = await this.tokenizer.readToken(new token_types_1.Uint8ArrayType(dataLen));
|
|
107
107
|
const decoder = new VorbisDecoder_1.VorbisDecoder(data, 0);
|
|
108
108
|
decoder.readStringUtf8(); // vendor (skip)
|
|
109
109
|
const commentListLength = decoder.readInt32();
|
|
@@ -131,7 +131,7 @@ Metadata.BlockHeader = {
|
|
|
131
131
|
return {
|
|
132
132
|
lastBlock: util.getBit(buf, off, 7),
|
|
133
133
|
type: util.getBitAllignedNumber(buf, off, 1, 7),
|
|
134
|
-
length:
|
|
134
|
+
length: token_types_1.UINT24_BE.get(buf, off + 1)
|
|
135
135
|
};
|
|
136
136
|
}
|
|
137
137
|
};
|
|
@@ -144,20 +144,20 @@ Metadata.BlockStreamInfo = {
|
|
|
144
144
|
get: (buf, off) => {
|
|
145
145
|
return {
|
|
146
146
|
// The minimum block size (in samples) used in the stream.
|
|
147
|
-
minimumBlockSize:
|
|
147
|
+
minimumBlockSize: token_types_1.UINT16_BE.get(buf, off),
|
|
148
148
|
// The maximum block size (in samples) used in the stream.
|
|
149
149
|
// (Minimum blocksize == maximum blocksize) implies a fixed-blocksize stream.
|
|
150
|
-
maximumBlockSize:
|
|
150
|
+
maximumBlockSize: token_types_1.UINT16_BE.get(buf, off + 2) / 1000,
|
|
151
151
|
// The minimum frame size (in bytes) used in the stream.
|
|
152
152
|
// May be 0 to imply the value is not known.
|
|
153
|
-
minimumFrameSize:
|
|
153
|
+
minimumFrameSize: token_types_1.UINT24_BE.get(buf, off + 4),
|
|
154
154
|
// The maximum frame size (in bytes) used in the stream.
|
|
155
155
|
// May be 0 to imply the value is not known.
|
|
156
|
-
maximumFrameSize:
|
|
156
|
+
maximumFrameSize: token_types_1.UINT24_BE.get(buf, off + 7),
|
|
157
157
|
// Sample rate in Hz. Though 20 bits are available,
|
|
158
158
|
// the maximum sample rate is limited by the structure of frame headers to 655350Hz.
|
|
159
159
|
// Also, a value of 0 is invalid.
|
|
160
|
-
sampleRate:
|
|
160
|
+
sampleRate: token_types_1.UINT24_BE.get(buf, off + 10) >> 4,
|
|
161
161
|
// probably slower: sampleRate: common.getBitAllignedNumber(buf, off + 10, 0, 20),
|
|
162
162
|
// (number of channels)-1. FLAC supports from 1 to 8 channels
|
|
163
163
|
channels: util.getBitAllignedNumber(buf, off + 12, 4, 3) + 1,
|
|
@@ -169,7 +169,7 @@ Metadata.BlockStreamInfo = {
|
|
|
169
169
|
// A value of zero here means the number of total samples is unknown.
|
|
170
170
|
totalSamples: util.getBitAllignedNumber(buf, off + 13, 4, 36),
|
|
171
171
|
// the MD5 hash of the file (see notes for usage... it's a littly tricky)
|
|
172
|
-
fileMD5: new
|
|
172
|
+
fileMD5: new token_types_1.Uint8ArrayType(16).get(buf, off + 18)
|
|
173
173
|
};
|
|
174
174
|
}
|
|
175
175
|
};
|