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
package/lib/browser.js
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import initDebug from 'debug';
|
|
2
|
+
import { ReadableWebToNodeStream } from 'readable-web-to-node-stream';
|
|
3
|
+
import * as mm from './core.js';
|
|
4
|
+
export { parseBuffer, parseFromTokenizer, orderTags, ratingToStars, selectCover } from './core.js';
|
|
5
|
+
const debug = initDebug('music-metadata-browser:main');
|
|
6
|
+
/**
|
|
7
|
+
* Parse audio Stream
|
|
8
|
+
* @param stream - ReadableStream
|
|
9
|
+
* @param contentType - MIME-Type
|
|
10
|
+
* @param options - Parsing options
|
|
11
|
+
* @returns Metadata
|
|
12
|
+
*/
|
|
13
|
+
export const parseNodeStream = mm.parseStream;
|
|
14
|
+
/**
|
|
15
|
+
* Parse Web API ReadableStream: https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream
|
|
16
|
+
* @param stream - ReadableStream (web stream according WTWG Streams Standard)
|
|
17
|
+
* @param fileInfo FileInfo object or MIME-Type
|
|
18
|
+
* @param options - Parsing options
|
|
19
|
+
* @returns Metadata
|
|
20
|
+
*/
|
|
21
|
+
export async function parseReadableStream(stream, fileInfo, options) {
|
|
22
|
+
const ns = new ReadableWebToNodeStream(stream);
|
|
23
|
+
const res = await parseNodeStream(ns, typeof fileInfo === 'string' ? { mimeType: fileInfo } : fileInfo, options);
|
|
24
|
+
await ns.close();
|
|
25
|
+
return res;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Parse Web API File
|
|
29
|
+
* @param blob - Blob to parse
|
|
30
|
+
* @param options - Parsing options
|
|
31
|
+
* @returns Metadata
|
|
32
|
+
*/
|
|
33
|
+
export async function parseBlob(blob, options) {
|
|
34
|
+
const fileInfo = { mimeType: blob.type, size: blob.size };
|
|
35
|
+
if (blob instanceof File) {
|
|
36
|
+
fileInfo.path = blob.name;
|
|
37
|
+
}
|
|
38
|
+
const stream = blob.stream ? blob.stream() : convertBlobToReadableStream(blob);
|
|
39
|
+
return parseReadableStream(stream, { mimeType: blob.type, size: blob.size }, options);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Convert Blob to ReadableStream
|
|
43
|
+
* Fallback for Safari versions < 14.1
|
|
44
|
+
* @param blob
|
|
45
|
+
*/
|
|
46
|
+
function convertBlobToReadableStream(blob) {
|
|
47
|
+
const fileReader = new FileReader();
|
|
48
|
+
return new ReadableStream({
|
|
49
|
+
start(controller) {
|
|
50
|
+
// The following function handles each data chunk
|
|
51
|
+
fileReader.onloadend = event => {
|
|
52
|
+
let data = event.target.result;
|
|
53
|
+
if (data instanceof ArrayBuffer) {
|
|
54
|
+
data = new Uint8Array(data);
|
|
55
|
+
}
|
|
56
|
+
controller.enqueue(data);
|
|
57
|
+
controller.close();
|
|
58
|
+
};
|
|
59
|
+
fileReader.onerror = error => {
|
|
60
|
+
controller.close();
|
|
61
|
+
};
|
|
62
|
+
fileReader.onabort = error => {
|
|
63
|
+
controller.close();
|
|
64
|
+
};
|
|
65
|
+
fileReader.readAsArrayBuffer(blob);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Parse fetched file, using the Web Fetch API
|
|
71
|
+
* @param audioTrackUrl - URL to download the audio track from
|
|
72
|
+
* @param options - Parsing options
|
|
73
|
+
* @returns Metadata
|
|
74
|
+
*/
|
|
75
|
+
export async function fetchFromUrl(audioTrackUrl, options) {
|
|
76
|
+
const response = await fetch(audioTrackUrl);
|
|
77
|
+
const fileInfo = {
|
|
78
|
+
size: parseInt(response.headers.get('Content-Length'), 10),
|
|
79
|
+
mimeType: response.headers.get('Content-Type')
|
|
80
|
+
};
|
|
81
|
+
if (response.ok) {
|
|
82
|
+
if (response.body) {
|
|
83
|
+
const res = await parseReadableStream(response.body, fileInfo, options);
|
|
84
|
+
debug('Closing HTTP-readable-stream...');
|
|
85
|
+
if (!response.body.locked) { // Prevent error in Firefox
|
|
86
|
+
await response.body.cancel();
|
|
87
|
+
}
|
|
88
|
+
debug('HTTP-readable-stream closed.');
|
|
89
|
+
return res;
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
// Fall back on Blob
|
|
93
|
+
return parseBlob(await response.blob(), options);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
throw new Error(`HTTP error status=${response.status}: ${response.statusText}`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { ITokenizer } from 'strtok3/
|
|
2
|
-
import { ITokenParser } from '../ParserFactory';
|
|
3
|
-
import { IOptions, IPrivateOptions } from '../type';
|
|
4
|
-
import { INativeMetadataCollector } from './MetadataCollector';
|
|
1
|
+
import { ITokenizer } from 'strtok3/core';
|
|
2
|
+
import { ITokenParser } from '../ParserFactory.js';
|
|
3
|
+
import { IOptions, IPrivateOptions } from '../type.js';
|
|
4
|
+
import { INativeMetadataCollector } from './MetadataCollector.js';
|
|
5
5
|
export declare abstract class BasicParser implements ITokenParser {
|
|
6
6
|
protected metadata: INativeMetadataCollector;
|
|
7
7
|
protected tokenizer: ITokenizer;
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.BasicParser = void 0;
|
|
4
|
-
class BasicParser {
|
|
1
|
+
export class BasicParser {
|
|
5
2
|
/**
|
|
6
3
|
* Initialize parser with output (metadata), input (tokenizer) & parsing options (options).
|
|
7
4
|
* @param {INativeMetadataCollector} metadata Output
|
|
@@ -15,4 +12,3 @@ class BasicParser {
|
|
|
15
12
|
return this;
|
|
16
13
|
}
|
|
17
14
|
}
|
|
18
|
-
exports.BasicParser = BasicParser;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { INativeTagMap, TagType } from './GenericTagTypes';
|
|
2
|
-
import { CommonTagMapper } from './GenericTagMapper';
|
|
1
|
+
import { INativeTagMap, TagType } from './GenericTagTypes.js';
|
|
2
|
+
import { CommonTagMapper } from './GenericTagMapper.js';
|
|
3
3
|
export declare class CaseInsensitiveTagMap extends CommonTagMapper {
|
|
4
4
|
constructor(tagTypes: TagType[], tagMap: INativeTagMap);
|
|
5
5
|
/**
|
|
6
6
|
* @tag Native header tag
|
|
7
7
|
* @return common tag name (alias)
|
|
8
8
|
*/
|
|
9
|
-
protected getCommonName(tag: string): import("./GenericTagTypes").GenericTagId;
|
|
9
|
+
protected getCommonName(tag: string): import("./GenericTagTypes.js").GenericTagId;
|
|
10
10
|
}
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.CaseInsensitiveTagMap = void 0;
|
|
4
|
-
const GenericTagMapper_1 = require("./GenericTagMapper");
|
|
5
|
-
class CaseInsensitiveTagMap extends GenericTagMapper_1.CommonTagMapper {
|
|
1
|
+
import { CommonTagMapper } from './GenericTagMapper.js';
|
|
2
|
+
export class CaseInsensitiveTagMap extends CommonTagMapper {
|
|
6
3
|
constructor(tagTypes, tagMap) {
|
|
7
4
|
const upperCaseMap = {};
|
|
8
5
|
for (const tag of Object.keys(tagMap)) {
|
|
@@ -18,5 +15,4 @@ class CaseInsensitiveTagMap extends GenericTagMapper_1.CommonTagMapper {
|
|
|
18
15
|
return this.tagMap[tag.toUpperCase()];
|
|
19
16
|
}
|
|
20
17
|
}
|
|
21
|
-
exports.CaseInsensitiveTagMap = CaseInsensitiveTagMap;
|
|
22
18
|
//# sourceMappingURL=CaseInsensitiveTagMap.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { IGenericTag, TagType } from './GenericTagTypes';
|
|
2
|
-
import { IGenericTagMapper } from './GenericTagMapper';
|
|
3
|
-
import { ITag } from '../type';
|
|
4
|
-
import { INativeMetadataCollector } from './MetadataCollector';
|
|
1
|
+
import { IGenericTag, TagType } from './GenericTagTypes.js';
|
|
2
|
+
import { IGenericTagMapper } from './GenericTagMapper.js';
|
|
3
|
+
import { ITag } from '../type.js';
|
|
4
|
+
import { INativeMetadataCollector } from './MetadataCollector.js';
|
|
5
5
|
export declare class CombinedTagMapper {
|
|
6
6
|
tagMappers: {
|
|
7
7
|
[index: string]: IGenericTagMapper;
|
|
@@ -1,29 +1,26 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const RiffInfoTagMap_1 = require("../riff/RiffInfoTagMap");
|
|
12
|
-
const MatroskaTagMapper_1 = require("../matroska/MatroskaTagMapper");
|
|
13
|
-
class CombinedTagMapper {
|
|
1
|
+
import { ID3v1TagMapper } from '../id3v1/ID3v1TagMap.js';
|
|
2
|
+
import { ID3v24TagMapper } from '../id3v2/ID3v24TagMapper.js';
|
|
3
|
+
import { AsfTagMapper } from '../asf/AsfTagMapper.js';
|
|
4
|
+
import { ID3v22TagMapper } from '../id3v2/ID3v22TagMapper.js';
|
|
5
|
+
import { APEv2TagMapper } from '../apev2/APEv2TagMapper.js';
|
|
6
|
+
import { MP4TagMapper } from '../mp4/MP4TagMapper.js';
|
|
7
|
+
import { VorbisTagMapper } from '../ogg/vorbis/VorbisTagMapper.js';
|
|
8
|
+
import { RiffInfoTagMapper } from '../riff/RiffInfoTagMap.js';
|
|
9
|
+
import { MatroskaTagMapper } from '../matroska/MatroskaTagMapper.js';
|
|
10
|
+
export class CombinedTagMapper {
|
|
14
11
|
constructor() {
|
|
15
12
|
this.tagMappers = {};
|
|
16
13
|
[
|
|
17
|
-
new
|
|
18
|
-
new
|
|
19
|
-
new
|
|
20
|
-
new
|
|
21
|
-
new
|
|
22
|
-
new
|
|
23
|
-
new
|
|
24
|
-
new
|
|
25
|
-
new
|
|
26
|
-
new
|
|
14
|
+
new ID3v1TagMapper(),
|
|
15
|
+
new ID3v22TagMapper(),
|
|
16
|
+
new ID3v24TagMapper(),
|
|
17
|
+
new MP4TagMapper(),
|
|
18
|
+
new MP4TagMapper(),
|
|
19
|
+
new VorbisTagMapper(),
|
|
20
|
+
new APEv2TagMapper(),
|
|
21
|
+
new AsfTagMapper(),
|
|
22
|
+
new RiffInfoTagMapper(),
|
|
23
|
+
new MatroskaTagMapper()
|
|
27
24
|
].forEach(mapper => {
|
|
28
25
|
this.registerTagMapper(mapper);
|
|
29
26
|
});
|
|
@@ -48,5 +45,4 @@ class CombinedTagMapper {
|
|
|
48
45
|
}
|
|
49
46
|
}
|
|
50
47
|
}
|
|
51
|
-
exports.CombinedTagMapper = CombinedTagMapper;
|
|
52
48
|
//# sourceMappingURL=CombinedTagMapper.js.map
|
package/lib/common/FourCC.d.ts
CHANGED
package/lib/common/FourCC.js
CHANGED
|
@@ -1,16 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.FourCcToken = void 0;
|
|
4
|
-
const util = require("./Util");
|
|
1
|
+
import * as util from './Util.js';
|
|
5
2
|
const validFourCC = /^[\x21-\x7e©][\x20-\x7e\x00()]{3}/;
|
|
6
3
|
/**
|
|
7
4
|
* Token for read FourCC
|
|
8
5
|
* Ref: https://en.wikipedia.org/wiki/FourCC
|
|
9
6
|
*/
|
|
10
|
-
|
|
7
|
+
export const FourCcToken = {
|
|
11
8
|
len: 4,
|
|
12
9
|
get: (buf, off) => {
|
|
13
|
-
const id = buf.toString('binary', off, off +
|
|
10
|
+
const id = buf.toString('binary', off, off + FourCcToken.len);
|
|
14
11
|
switch (id) {
|
|
15
12
|
default:
|
|
16
13
|
if (!id.match(validFourCC)) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import * as generic from './GenericTagTypes';
|
|
2
|
-
import { ITag } from '../type';
|
|
3
|
-
import { INativeMetadataCollector, IWarningCollector } from './MetadataCollector';
|
|
1
|
+
import * as generic from './GenericTagTypes.js';
|
|
2
|
+
import { ITag } from '../type.js';
|
|
3
|
+
import { INativeMetadataCollector, IWarningCollector } from './MetadataCollector.js';
|
|
4
4
|
export interface IGenericTagMapper {
|
|
5
5
|
/**
|
|
6
6
|
* Which tagType it able to map to the generic mapping format
|
|
@@ -38,7 +38,7 @@ export declare class CommonTagMapper implements IGenericTagMapper {
|
|
|
38
38
|
mapGenericTag(tag: ITag, warnings: IWarningCollector): generic.IGenericTag;
|
|
39
39
|
/**
|
|
40
40
|
* Convert native tag key to common tag key
|
|
41
|
-
* @tag
|
|
41
|
+
* @param tag Native header tag
|
|
42
42
|
* @return common tag name (alias)
|
|
43
43
|
*/
|
|
44
44
|
protected getCommonName(tag: string): generic.GenericTagId;
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.CommonTagMapper = void 0;
|
|
4
|
-
class CommonTagMapper {
|
|
1
|
+
export class CommonTagMapper {
|
|
5
2
|
constructor(tagTypes, tagMap) {
|
|
6
3
|
this.tagTypes = tagTypes;
|
|
7
4
|
this.tagMap = tagMap;
|
|
@@ -36,7 +33,7 @@ class CommonTagMapper {
|
|
|
36
33
|
}
|
|
37
34
|
/**
|
|
38
35
|
* Convert native tag key to common tag key
|
|
39
|
-
* @tag
|
|
36
|
+
* @param tag Native header tag
|
|
40
37
|
* @return common tag name (alias)
|
|
41
38
|
*/
|
|
42
39
|
getCommonName(tag) {
|
|
@@ -51,6 +48,5 @@ class CommonTagMapper {
|
|
|
51
48
|
return;
|
|
52
49
|
}
|
|
53
50
|
}
|
|
54
|
-
exports.CommonTagMapper = CommonTagMapper;
|
|
55
51
|
CommonTagMapper.maxRatingScore = 1;
|
|
56
52
|
//# sourceMappingURL=GenericTagMapper.js.map
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.isUnique = exports.isSingleton = exports.commonTags = void 0;
|
|
4
|
-
exports.commonTags = {
|
|
1
|
+
export const commonTags = {
|
|
5
2
|
year: { multiple: false },
|
|
6
3
|
track: { multiple: false },
|
|
7
4
|
disk: { multiple: false },
|
|
@@ -117,16 +114,14 @@ exports.commonTags = {
|
|
|
117
114
|
* @param alias Name of common tag
|
|
118
115
|
* @returns {boolean|*} true if given alias is mapped as a singleton', otherwise false
|
|
119
116
|
*/
|
|
120
|
-
function isSingleton(alias) {
|
|
121
|
-
return
|
|
117
|
+
export function isSingleton(alias) {
|
|
118
|
+
return commonTags.hasOwnProperty(alias) && !commonTags[alias].multiple;
|
|
122
119
|
}
|
|
123
|
-
exports.isSingleton = isSingleton;
|
|
124
120
|
/**
|
|
125
121
|
* @param alias Common (generic) tag
|
|
126
122
|
* @returns {boolean|*} true if given alias is a singleton or explicitly marked as unique
|
|
127
123
|
*/
|
|
128
|
-
function isUnique(alias) {
|
|
129
|
-
return !
|
|
124
|
+
export function isUnique(alias) {
|
|
125
|
+
return !commonTags[alias].multiple || commonTags[alias].unique;
|
|
130
126
|
}
|
|
131
|
-
exports.isUnique = isUnique;
|
|
132
127
|
//# sourceMappingURL=GenericTagTypes.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { FormatId, IAudioMetadata, ICommonTagsResult, IFormat, INativeTags, IOptions, IQualityInformation, ITrackInfo } from '../type';
|
|
2
|
-
import { IGenericTag, TagType } from './GenericTagTypes';
|
|
1
|
+
import { FormatId, IAudioMetadata, ICommonTagsResult, IFormat, INativeTags, IOptions, IQualityInformation, ITrackInfo } from '../type.js';
|
|
2
|
+
import { IGenericTag, TagType } from './GenericTagTypes.js';
|
|
3
3
|
/**
|
|
4
4
|
* Combines all generic-tag-mappers for each tag type
|
|
5
5
|
*/
|
|
@@ -1,20 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const
|
|
9
|
-
const Util_1 = require("./Util");
|
|
10
|
-
const FileType = require("file-type/core");
|
|
11
|
-
const debug = (0, debug_1.default)('music-metadata:collector');
|
|
1
|
+
import { TrackType } from '../type.js';
|
|
2
|
+
import initDebug from 'debug';
|
|
3
|
+
import { isSingleton, isUnique } from './GenericTagTypes.js';
|
|
4
|
+
import { CombinedTagMapper } from './CombinedTagMapper.js';
|
|
5
|
+
import { CommonTagMapper } from './GenericTagMapper.js';
|
|
6
|
+
import { toRatio } from './Util.js';
|
|
7
|
+
import { fileTypeFromBuffer } from 'file-type';
|
|
8
|
+
const debug = initDebug('music-metadata:collector');
|
|
12
9
|
const TagPriority = ['matroska', 'APEv2', 'vorbis', 'ID3v2.4', 'ID3v2.3', 'ID3v2.2', 'exif', 'asf', 'iTunes', 'ID3v1'];
|
|
13
10
|
/**
|
|
14
11
|
* Provided to the parser to uodate the metadata result.
|
|
15
12
|
* Responsible for triggering async updates
|
|
16
13
|
*/
|
|
17
|
-
class MetadataCollector {
|
|
14
|
+
export class MetadataCollector {
|
|
18
15
|
constructor(opts) {
|
|
19
16
|
this.opts = opts;
|
|
20
17
|
this.format = {
|
|
@@ -38,7 +35,7 @@ class MetadataCollector {
|
|
|
38
35
|
* Maps a tag type to a priority
|
|
39
36
|
*/
|
|
40
37
|
this.originPriority = {};
|
|
41
|
-
this.tagMapper = new
|
|
38
|
+
this.tagMapper = new CombinedTagMapper();
|
|
42
39
|
let priority = 1;
|
|
43
40
|
for (const tagType of TagPriority) {
|
|
44
41
|
this.originPriority[tagType] = priority++;
|
|
@@ -53,7 +50,7 @@ class MetadataCollector {
|
|
|
53
50
|
return Object.keys(this.native).length > 0;
|
|
54
51
|
}
|
|
55
52
|
addStreamInfo(streamInfo) {
|
|
56
|
-
debug(`streamInfo: type=${
|
|
53
|
+
debug(`streamInfo: type=${TrackType[streamInfo.type]}, codec=${streamInfo.codecName}`);
|
|
57
54
|
this.format.trackInfo.push(streamInfo);
|
|
58
55
|
}
|
|
59
56
|
setFormat(key, value) {
|
|
@@ -111,19 +108,19 @@ class MetadataCollector {
|
|
|
111
108
|
});
|
|
112
109
|
return;
|
|
113
110
|
case 'totaltracks':
|
|
114
|
-
this.common.track.of =
|
|
111
|
+
this.common.track.of = CommonTagMapper.toIntOrNull(tag.value);
|
|
115
112
|
return;
|
|
116
113
|
case 'totaldiscs':
|
|
117
|
-
this.common.disk.of =
|
|
114
|
+
this.common.disk.of = CommonTagMapper.toIntOrNull(tag.value);
|
|
118
115
|
return;
|
|
119
116
|
case 'movementTotal':
|
|
120
|
-
this.common.movementIndex.of =
|
|
117
|
+
this.common.movementIndex.of = CommonTagMapper.toIntOrNull(tag.value);
|
|
121
118
|
return;
|
|
122
119
|
case 'track':
|
|
123
120
|
case 'disk':
|
|
124
121
|
case 'movementIndex':
|
|
125
122
|
const of = this.common[tag.id].of; // store of value, maybe maybe overwritten
|
|
126
|
-
this.common[tag.id] =
|
|
123
|
+
this.common[tag.id] = CommonTagMapper.normalizeTrack(tag.value);
|
|
127
124
|
this.common[tag.id].of = of != null ? of : this.common[tag.id].of;
|
|
128
125
|
return;
|
|
129
126
|
case 'bpm':
|
|
@@ -149,7 +146,7 @@ class MetadataCollector {
|
|
|
149
146
|
case 'replaygain_track_peak':
|
|
150
147
|
case 'replaygain_album_gain':
|
|
151
148
|
case 'replaygain_album_peak':
|
|
152
|
-
tag.value =
|
|
149
|
+
tag.value = toRatio(tag.value);
|
|
153
150
|
break;
|
|
154
151
|
case 'replaygain_track_minmax':
|
|
155
152
|
tag.value = tag.value.split(',').map(v => parseInt(v, 10));
|
|
@@ -197,7 +194,7 @@ class MetadataCollector {
|
|
|
197
194
|
async postFixPicture(picture) {
|
|
198
195
|
if (picture.data && picture.data.length > 0) {
|
|
199
196
|
if (!picture.format) {
|
|
200
|
-
const fileType = await
|
|
197
|
+
const fileType = await fileTypeFromBuffer(picture.data);
|
|
201
198
|
if (fileType) {
|
|
202
199
|
picture.format = fileType.mime;
|
|
203
200
|
}
|
|
@@ -232,7 +229,7 @@ class MetadataCollector {
|
|
|
232
229
|
debug(`common.${tag.id} = ${tag.value}`);
|
|
233
230
|
const prio0 = this.commonOrigin[tag.id] || 1000;
|
|
234
231
|
const prio1 = this.originPriority[tagType];
|
|
235
|
-
if (
|
|
232
|
+
if (isSingleton(tag.id)) {
|
|
236
233
|
if (prio1 <= prio0) {
|
|
237
234
|
this.common[tag.id] = tag.value;
|
|
238
235
|
this.commonOrigin[tag.id] = prio1;
|
|
@@ -243,7 +240,7 @@ class MetadataCollector {
|
|
|
243
240
|
}
|
|
244
241
|
else {
|
|
245
242
|
if (prio1 === prio0) {
|
|
246
|
-
if (!
|
|
243
|
+
if (!isUnique(tag.id) || this.common[tag.id].indexOf(tag.value) === -1) {
|
|
247
244
|
this.common[tag.id].push(tag.value);
|
|
248
245
|
}
|
|
249
246
|
else {
|
|
@@ -265,12 +262,10 @@ class MetadataCollector {
|
|
|
265
262
|
// ToDo: trigger metadata event
|
|
266
263
|
}
|
|
267
264
|
}
|
|
268
|
-
|
|
269
|
-
function joinArtists(artists) {
|
|
265
|
+
export function joinArtists(artists) {
|
|
270
266
|
if (artists.length > 2) {
|
|
271
267
|
return artists.slice(0, artists.length - 1).join(', ') + ' & ' + artists[artists.length - 1];
|
|
272
268
|
}
|
|
273
269
|
return artists.join(' & ');
|
|
274
270
|
}
|
|
275
|
-
exports.joinArtists = joinArtists;
|
|
276
271
|
//# sourceMappingURL=MetadataCollector.js.map
|
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.RandomFileReader = void 0;
|
|
4
|
-
const fs = require("fs");
|
|
1
|
+
import * as fs from 'fs';
|
|
5
2
|
/**
|
|
6
3
|
* Provides abstract file access via the IRandomRead interface
|
|
7
4
|
*/
|
|
8
|
-
class RandomFileReader {
|
|
5
|
+
export class RandomFileReader {
|
|
9
6
|
constructor(fileHandle, filePath, fileSize) {
|
|
10
7
|
this.fileHandle = fileHandle;
|
|
11
8
|
this.filePath = filePath;
|
|
@@ -31,4 +28,3 @@ class RandomFileReader {
|
|
|
31
28
|
return new RandomFileReader(fileHandle, filePath, fileSize);
|
|
32
29
|
}
|
|
33
30
|
}
|
|
34
|
-
exports.RandomFileReader = RandomFileReader;
|
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.RandomUint8ArrayReader = void 0;
|
|
4
1
|
/**
|
|
5
2
|
* Provides abstract Uint8Array access via the IRandomRead interface
|
|
6
3
|
*/
|
|
7
|
-
class RandomUint8ArrayReader {
|
|
4
|
+
export class RandomUint8ArrayReader {
|
|
8
5
|
constructor(uint8Array) {
|
|
9
6
|
this.uint8Array = uint8Array;
|
|
10
7
|
this.fileSize = uint8Array.length;
|
|
@@ -22,4 +19,3 @@ class RandomUint8ArrayReader {
|
|
|
22
19
|
return length;
|
|
23
20
|
}
|
|
24
21
|
}
|
|
25
|
-
exports.RandomUint8ArrayReader = RandomUint8ArrayReader;
|
package/lib/common/Util.d.ts
CHANGED
package/lib/common/Util.js
CHANGED
|
@@ -1,10 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.toRatio = exports.dbToRatio = exports.ratioToDb = exports.a2hex = exports.isBitSet = exports.getBitAllignedNumber = exports.stripNulls = exports.decodeString = exports.trimRightNull = exports.findZero = exports.getBit = void 0;
|
|
4
|
-
function getBit(buf, off, bit) {
|
|
1
|
+
export function getBit(buf, off, bit) {
|
|
5
2
|
return (buf[off] & (1 << bit)) !== 0;
|
|
6
3
|
}
|
|
7
|
-
exports.getBit = getBit;
|
|
8
4
|
/**
|
|
9
5
|
* Found delimiting zero in uint8Array
|
|
10
6
|
* @param uint8Array Uint8Array to find the zero delimiter in
|
|
@@ -13,7 +9,7 @@ exports.getBit = getBit;
|
|
|
13
9
|
* @param encoding The string encoding used
|
|
14
10
|
* @return Absolute position on uint8Array where zero found
|
|
15
11
|
*/
|
|
16
|
-
function findZero(uint8Array, start, end, encoding) {
|
|
12
|
+
export function findZero(uint8Array, start, end, encoding) {
|
|
17
13
|
let i = start;
|
|
18
14
|
if (encoding === 'utf16le') {
|
|
19
15
|
while (uint8Array[i] !== 0 || uint8Array[i + 1] !== 0) {
|
|
@@ -32,12 +28,10 @@ function findZero(uint8Array, start, end, encoding) {
|
|
|
32
28
|
return i;
|
|
33
29
|
}
|
|
34
30
|
}
|
|
35
|
-
|
|
36
|
-
function trimRightNull(x) {
|
|
31
|
+
export function trimRightNull(x) {
|
|
37
32
|
const pos0 = x.indexOf('\0');
|
|
38
33
|
return pos0 === -1 ? x : x.substr(0, pos0);
|
|
39
34
|
}
|
|
40
|
-
exports.trimRightNull = trimRightNull;
|
|
41
35
|
function swapBytes(uint8Array) {
|
|
42
36
|
const l = uint8Array.length;
|
|
43
37
|
if ((l & 1) !== 0)
|
|
@@ -52,7 +46,7 @@ function swapBytes(uint8Array) {
|
|
|
52
46
|
/**
|
|
53
47
|
* Decode string
|
|
54
48
|
*/
|
|
55
|
-
function decodeString(uint8Array, encoding) {
|
|
49
|
+
export function decodeString(uint8Array, encoding) {
|
|
56
50
|
// annoying workaround for a double BOM issue
|
|
57
51
|
// https://github.com/leetreveil/musicmetadata/issues/84
|
|
58
52
|
if (uint8Array[0] === 0xFF && uint8Array[1] === 0xFE) { // little endian
|
|
@@ -66,13 +60,11 @@ function decodeString(uint8Array, encoding) {
|
|
|
66
60
|
}
|
|
67
61
|
return Buffer.from(uint8Array).toString(encoding);
|
|
68
62
|
}
|
|
69
|
-
|
|
70
|
-
function stripNulls(str) {
|
|
63
|
+
export function stripNulls(str) {
|
|
71
64
|
str = str.replace(/^\x00+/g, '');
|
|
72
65
|
str = str.replace(/\x00+$/g, '');
|
|
73
66
|
return str;
|
|
74
67
|
}
|
|
75
|
-
exports.stripNulls = stripNulls;
|
|
76
68
|
/**
|
|
77
69
|
* Read bit-aligned number start from buffer
|
|
78
70
|
* Total offset in bits = byteOffset * 8 + bitOffset
|
|
@@ -82,7 +74,7 @@ exports.stripNulls = stripNulls;
|
|
|
82
74
|
* @param len Length of number in bits
|
|
83
75
|
* @return Decoded bit aligned number
|
|
84
76
|
*/
|
|
85
|
-
function getBitAllignedNumber(source, byteOffset, bitOffset, len) {
|
|
77
|
+
export function getBitAllignedNumber(source, byteOffset, bitOffset, len) {
|
|
86
78
|
const byteOff = byteOffset + ~~(bitOffset / 8);
|
|
87
79
|
const bitOff = bitOffset % 8;
|
|
88
80
|
let value = source[byteOff];
|
|
@@ -98,7 +90,6 @@ function getBitAllignedNumber(source, byteOffset, bitOffset, len) {
|
|
|
98
90
|
}
|
|
99
91
|
return value;
|
|
100
92
|
}
|
|
101
|
-
exports.getBitAllignedNumber = getBitAllignedNumber;
|
|
102
93
|
/**
|
|
103
94
|
* Read bit-aligned number start from buffer
|
|
104
95
|
* Total offset in bits = byteOffset * 8 + bitOffset
|
|
@@ -107,11 +98,10 @@ exports.getBitAllignedNumber = getBitAllignedNumber;
|
|
|
107
98
|
* @param bitOffset Starting offset in bits: 0 = most significant bit, 7 is the least significant bit
|
|
108
99
|
* @return True if bit is set
|
|
109
100
|
*/
|
|
110
|
-
function isBitSet(source, byteOffset, bitOffset) {
|
|
101
|
+
export function isBitSet(source, byteOffset, bitOffset) {
|
|
111
102
|
return getBitAllignedNumber(source, byteOffset, bitOffset, 1) === 1;
|
|
112
103
|
}
|
|
113
|
-
|
|
114
|
-
function a2hex(str) {
|
|
104
|
+
export function a2hex(str) {
|
|
115
105
|
const arr = [];
|
|
116
106
|
for (let i = 0, l = str.length; i < l; i++) {
|
|
117
107
|
const hex = Number(str.charCodeAt(i)).toString(16);
|
|
@@ -119,28 +109,25 @@ function a2hex(str) {
|
|
|
119
109
|
}
|
|
120
110
|
return arr.join(' ');
|
|
121
111
|
}
|
|
122
|
-
exports.a2hex = a2hex;
|
|
123
112
|
/**
|
|
124
113
|
* Convert power ratio to DB
|
|
125
114
|
* ratio: [0..1]
|
|
126
115
|
*/
|
|
127
|
-
function ratioToDb(ratio) {
|
|
116
|
+
export function ratioToDb(ratio) {
|
|
128
117
|
return 10 * Math.log10(ratio);
|
|
129
118
|
}
|
|
130
|
-
exports.ratioToDb = ratioToDb;
|
|
131
119
|
/**
|
|
132
120
|
* Convert dB to ratio
|
|
133
121
|
* db Decibels
|
|
134
122
|
*/
|
|
135
|
-
function dbToRatio(dB) {
|
|
123
|
+
export function dbToRatio(dB) {
|
|
136
124
|
return Math.pow(10, dB / 10);
|
|
137
125
|
}
|
|
138
|
-
exports.dbToRatio = dbToRatio;
|
|
139
126
|
/**
|
|
140
127
|
* Convert replay gain to ratio and Decibel
|
|
141
128
|
* @param value string holding a ratio like '0.034' or '-7.54 dB'
|
|
142
129
|
*/
|
|
143
|
-
function toRatio(value) {
|
|
130
|
+
export function toRatio(value) {
|
|
144
131
|
const ps = value.split(' ').map(p => p.trim().toLowerCase());
|
|
145
132
|
// @ts-ignore
|
|
146
133
|
if (ps.length >= 1) {
|
|
@@ -154,5 +141,4 @@ function toRatio(value) {
|
|
|
154
141
|
};
|
|
155
142
|
}
|
|
156
143
|
}
|
|
157
|
-
exports.toRatio = toRatio;
|
|
158
144
|
//# sourceMappingURL=Util.js.map
|