music-metadata 11.7.3 → 11.8.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/LICENSE.txt +9 -9
- package/README.md +874 -873
- package/lib/apev2/APEv2Parser.js +2 -2
- package/lib/common/FourCC.js +3 -3
- package/lib/common/Util.d.ts +1 -0
- package/lib/common/Util.js +10 -0
- package/lib/id3v1/ID3v1Parser.js +1 -0
- package/lib/id3v2/ID3v2Parser.js +1 -0
- package/lib/lyrics3/Lyrics3.js +1 -0
- package/lib/mp4/MP4Parser.js +3 -2
- package/lib/musepack/sv7/StreamVersion7.js +1 -0
- package/lib/ogg/vorbis/VorbisDecoder.js +1 -0
- package/lib/wavpack/WavPackParser.js +1 -1
- package/package.json +148 -148
package/lib/apev2/APEv2Parser.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import initDebug from 'debug';
|
|
2
2
|
import * as strtok3 from 'strtok3';
|
|
3
3
|
import { StringType } from 'token-types';
|
|
4
|
-
import { uint8ArrayToString } from 'uint8array-extras';
|
|
5
4
|
import * as util from '../common/Util.js';
|
|
6
5
|
import { BasicParser } from '../common/BasicParser.js';
|
|
7
6
|
import { DataType, DescriptorParser, Header, TagFooter, TagItemHeader } from './APEv2Token.js';
|
|
8
7
|
import { makeUnexpectedFileContentError } from '../ParseError.js';
|
|
8
|
+
import { TextDecoder } from '@kayahr/text-encoding';
|
|
9
9
|
const debug = initDebug('music-metadata:parser:APEv2');
|
|
10
10
|
const tagFormat = 'APEv2';
|
|
11
11
|
const preamble = 'APETAGEX';
|
|
@@ -132,7 +132,7 @@ export class APEv2Parser extends BasicParser {
|
|
|
132
132
|
const picData = new Uint8Array(tagItemHeader.size);
|
|
133
133
|
await this.tokenizer.readBuffer(picData);
|
|
134
134
|
zero = util.findZero(picData, 0, picData.length);
|
|
135
|
-
const description =
|
|
135
|
+
const description = new TextDecoder('utf-8').decode(picData.slice(0, zero));
|
|
136
136
|
const data = picData.slice(zero + 1);
|
|
137
137
|
await this.metadata.addTag(tagFormat, key, {
|
|
138
138
|
description,
|
package/lib/common/FourCC.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { TextDecoder, TextEncoder } from '@kayahr/text-encoding';
|
|
2
2
|
import * as util from './Util.js';
|
|
3
3
|
import { InternalParserError, FieldDecodingError } from '../ParseError.js';
|
|
4
4
|
const validFourCC = /^[\x21-\x7e©][\x20-\x7e\x00()]{3}/;
|
|
@@ -9,14 +9,14 @@ const validFourCC = /^[\x21-\x7e©][\x20-\x7e\x00()]{3}/;
|
|
|
9
9
|
export const FourCcToken = {
|
|
10
10
|
len: 4,
|
|
11
11
|
get: (buf, off) => {
|
|
12
|
-
const id =
|
|
12
|
+
const id = new TextDecoder('latin1').decode(buf.slice(off, off + FourCcToken.len));
|
|
13
13
|
if (!id.match(validFourCC)) {
|
|
14
14
|
throw new FieldDecodingError(`FourCC contains invalid characters: ${util.a2hex(id)} "${id}"`);
|
|
15
15
|
}
|
|
16
16
|
return id;
|
|
17
17
|
},
|
|
18
18
|
put: (buffer, offset, id) => {
|
|
19
|
-
const str =
|
|
19
|
+
const str = new TextEncoder('latin1').encode(id);
|
|
20
20
|
if (str.length !== 4)
|
|
21
21
|
throw new InternalParserError('Invalid length');
|
|
22
22
|
buffer.set(str, offset);
|
package/lib/common/Util.d.ts
CHANGED
package/lib/common/Util.js
CHANGED
|
@@ -141,3 +141,13 @@ export function toRatio(value) {
|
|
|
141
141
|
};
|
|
142
142
|
}
|
|
143
143
|
}
|
|
144
|
+
const byteToHexLookupTable = Array.from({ length: 256 }, (_, index) => index.toString(16).padStart(2, '0'));
|
|
145
|
+
export function uint8ArrayToHex(array) {
|
|
146
|
+
// Concatenating a string is faster than using an array.
|
|
147
|
+
let hexString = '';
|
|
148
|
+
// eslint-disable-next-line unicorn/no-for-loop -- Max performance is critical.
|
|
149
|
+
for (let index = 0; index < array.length; index++) {
|
|
150
|
+
hexString += byteToHexLookupTable[array[index]];
|
|
151
|
+
}
|
|
152
|
+
return hexString;
|
|
153
|
+
}
|
package/lib/id3v1/ID3v1Parser.js
CHANGED
|
@@ -3,6 +3,7 @@ import { StringType, UINT8 } from 'token-types';
|
|
|
3
3
|
import * as util from '../common/Util.js';
|
|
4
4
|
import { BasicParser } from '../common/BasicParser.js';
|
|
5
5
|
import { APEv2Parser } from '../apev2/APEv2Parser.js';
|
|
6
|
+
import { TextDecoder } from '@kayahr/text-encoding';
|
|
6
7
|
const debug = initDebug('music-metadata:parser:ID3v1');
|
|
7
8
|
/**
|
|
8
9
|
* ID3v1 Genre mappings
|
package/lib/id3v2/ID3v2Parser.js
CHANGED
|
@@ -2,6 +2,7 @@ import * as Token from 'token-types';
|
|
|
2
2
|
import * as util from '../common/Util.js';
|
|
3
3
|
import { FrameParser, Id3v2ContentError } from './FrameParser.js';
|
|
4
4
|
import { ExtendedHeader, ID3v2Header, UINT32SYNCSAFE } from './ID3v2Token.js';
|
|
5
|
+
import { TextDecoder } from '@kayahr/text-encoding';
|
|
5
6
|
const asciiDecoder = new TextDecoder('ascii');
|
|
6
7
|
export class ID3v2Parser {
|
|
7
8
|
constructor() {
|
package/lib/lyrics3/Lyrics3.js
CHANGED
package/lib/mp4/MP4Parser.js
CHANGED
|
@@ -6,7 +6,8 @@ import { Atom } from './Atom.js';
|
|
|
6
6
|
import * as AtomToken from './AtomToken.js';
|
|
7
7
|
import { ChapterTrackReferenceBox, Mp4ContentError, } from './AtomToken.js';
|
|
8
8
|
import { TrackType } from '../type.js';
|
|
9
|
-
import { uint8ArrayToHex
|
|
9
|
+
import { uint8ArrayToHex } from '../common/Util.js';
|
|
10
|
+
import { TextDecoder } from '@kayahr/text-encoding';
|
|
10
11
|
const debug = initDebug('music-metadata:parser:MP4');
|
|
11
12
|
const tagFormat = 'iTunes';
|
|
12
13
|
const encoderDict = {
|
|
@@ -353,7 +354,7 @@ export class MP4Parser extends BasicParser {
|
|
|
353
354
|
}
|
|
354
355
|
default: {
|
|
355
356
|
const uint8Array = await this.tokenizer.readToken(new Token.Uint8ArrayType(payLoadLength));
|
|
356
|
-
this.addWarning(`Unsupported meta-item: ${tagKey}[${child.header.name}] => value=${uint8ArrayToHex(uint8Array)} ascii=${
|
|
357
|
+
this.addWarning(`Unsupported meta-item: ${tagKey}[${child.header.name}] => value=${uint8ArrayToHex(uint8Array)} ascii=${new TextDecoder('ascii').decode(uint8Array)}`);
|
|
357
358
|
}
|
|
358
359
|
}
|
|
359
360
|
}, metaAtom.getPayloadLength(0));
|
|
@@ -4,7 +4,7 @@ import { FourCcToken } from '../common/FourCC.js';
|
|
|
4
4
|
import { BasicParser } from '../common/BasicParser.js';
|
|
5
5
|
import { BlockHeaderToken, MetadataIdToken } from './WavPackToken.js';
|
|
6
6
|
import initDebug from 'debug';
|
|
7
|
-
import { uint8ArrayToHex } from '
|
|
7
|
+
import { uint8ArrayToHex } from '../common/Util.js';
|
|
8
8
|
import { makeUnexpectedFileContentError } from '../ParseError.js';
|
|
9
9
|
const debug = initDebug('music-metadata:parser:WavPack');
|
|
10
10
|
export class WavPackContentError extends makeUnexpectedFileContentError('WavPack') {
|
package/package.json
CHANGED
|
@@ -1,148 +1,148 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "music-metadata",
|
|
3
|
-
"description": "Music metadata parser for Node.js, supporting virtual any audio and tag format.",
|
|
4
|
-
"version": "11.
|
|
5
|
-
"author": {
|
|
6
|
-
"name": "Borewit",
|
|
7
|
-
"url": "https://github.com/Borewit"
|
|
8
|
-
},
|
|
9
|
-
"funding": [
|
|
10
|
-
{
|
|
11
|
-
"type": "github",
|
|
12
|
-
"url": "https://github.com/sponsors/Borewit"
|
|
13
|
-
},
|
|
14
|
-
{
|
|
15
|
-
"type": "buymeacoffee",
|
|
16
|
-
"url": "https://buymeacoffee.com/borewit"
|
|
17
|
-
}
|
|
18
|
-
],
|
|
19
|
-
"sideEffects": false,
|
|
20
|
-
"type": "module",
|
|
21
|
-
"exports": {
|
|
22
|
-
"node": {
|
|
23
|
-
"import": "./lib/index.js",
|
|
24
|
-
"module-sync": "./lib/index.js",
|
|
25
|
-
"types": "./lib/index.d.ts"
|
|
26
|
-
},
|
|
27
|
-
"default": {
|
|
28
|
-
"import": "./lib/core.js",
|
|
29
|
-
"module-sync": "./lib/core.js",
|
|
30
|
-
"types": "./lib/core.d.ts"
|
|
31
|
-
}
|
|
32
|
-
},
|
|
33
|
-
"types": "lib/index.d.ts",
|
|
34
|
-
"files": [
|
|
35
|
-
"lib/**/*.js",
|
|
36
|
-
"lib/**/*.d.ts"
|
|
37
|
-
],
|
|
38
|
-
"keywords": [
|
|
39
|
-
"music",
|
|
40
|
-
"metadata",
|
|
41
|
-
"meta",
|
|
42
|
-
"audio",
|
|
43
|
-
"tag",
|
|
44
|
-
"tags",
|
|
45
|
-
"duration",
|
|
46
|
-
"MusicBrainz",
|
|
47
|
-
"Discogs",
|
|
48
|
-
"Picard",
|
|
49
|
-
"ID3",
|
|
50
|
-
"ID3v1",
|
|
51
|
-
"ID3v2",
|
|
52
|
-
"m4a",
|
|
53
|
-
"m4b",
|
|
54
|
-
"mp3",
|
|
55
|
-
"mp4",
|
|
56
|
-
"Vorbis",
|
|
57
|
-
"ogg",
|
|
58
|
-
"flac",
|
|
59
|
-
"Matroska",
|
|
60
|
-
"WebM",
|
|
61
|
-
"EBML",
|
|
62
|
-
"asf",
|
|
63
|
-
"wma",
|
|
64
|
-
"wmv",
|
|
65
|
-
"ape",
|
|
66
|
-
"MonkeyAudio",
|
|
67
|
-
"aiff",
|
|
68
|
-
"wav",
|
|
69
|
-
"WavPack",
|
|
70
|
-
"Opus",
|
|
71
|
-
"speex",
|
|
72
|
-
"musepack",
|
|
73
|
-
"mpc",
|
|
74
|
-
"dsd",
|
|
75
|
-
"dsf",
|
|
76
|
-
"mpc",
|
|
77
|
-
"dff",
|
|
78
|
-
"dsdiff",
|
|
79
|
-
"aac",
|
|
80
|
-
"adts",
|
|
81
|
-
"length",
|
|
82
|
-
"chapter",
|
|
83
|
-
"info",
|
|
84
|
-
"parse",
|
|
85
|
-
"parser",
|
|
86
|
-
"bwf",
|
|
87
|
-
"slt",
|
|
88
|
-
"lyrics"
|
|
89
|
-
],
|
|
90
|
-
"scripts": {
|
|
91
|
-
"clean": "del-cli 'lib/**/*.js' 'lib/**/*.js.map' 'lib/**/*.d.ts' 'test/**/*.js' 'test/**/*.js.map' 'test/**/*.js' 'test/**/*.js.map' 'doc-gen/**/*.js' 'doc-gen/**/*.js.map'",
|
|
92
|
-
"compile-src": "tsc -p lib --sourceMap false",
|
|
93
|
-
"compile-test": "tsc -p test",
|
|
94
|
-
"compile-doc": "tsc -p doc-gen",
|
|
95
|
-
"compile": "yarn run compile-src && yarn compile-test && yarn compile-doc",
|
|
96
|
-
"lint:ts": "biome check",
|
|
97
|
-
"lint:md": "yarn run remark -u remark-preset-lint-consistent .",
|
|
98
|
-
"lint": "yarn run lint:ts && yarn run lint:md",
|
|
99
|
-
"test": "mocha",
|
|
100
|
-
"build": "yarn run clean && yarn compile && yarn run doc-gen",
|
|
101
|
-
"prepublishOnly": "yarn run build",
|
|
102
|
-
"test-coverage": "c8 yarn run test",
|
|
103
|
-
"send-codacy": "c8 report --reporter=text-lcov | codacy-coverage",
|
|
104
|
-
"doc-gen": "yarn node doc-gen/gen.js",
|
|
105
|
-
"typecheck": "tsc --project ./lib/tsconfig.json --noEmit && tsc --project ./test/tsconfig.json --noEmit",
|
|
106
|
-
"update-biome": "yarn add -D --exact @biomejs/biome && npx @biomejs/biome migrate --write"
|
|
107
|
-
},
|
|
108
|
-
"dependencies": {
|
|
109
|
-
"@
|
|
110
|
-
"
|
|
111
|
-
"
|
|
112
|
-
"
|
|
113
|
-
"
|
|
114
|
-
"
|
|
115
|
-
"
|
|
116
|
-
"
|
|
117
|
-
},
|
|
118
|
-
"devDependencies": {
|
|
119
|
-
"@biomejs/biome": "2.1.
|
|
120
|
-
"@types/chai": "^5.2.2",
|
|
121
|
-
"@types/chai-as-promised": "^8.0.2",
|
|
122
|
-
"@types/content-type": "^1.1.9",
|
|
123
|
-
"@types/debug": "^4.1.12",
|
|
124
|
-
"@types/media-typer": "^1.1.3",
|
|
125
|
-
"@types/mocha": "^10.0.10",
|
|
126
|
-
"@types/node": "^24.1
|
|
127
|
-
"c8": "^10.1.3",
|
|
128
|
-
"chai": "^5.2.1",
|
|
129
|
-
"chai-as-promised": "^8.0.1",
|
|
130
|
-
"del-cli": "^6.0.0",
|
|
131
|
-
"mime": "^4.0.7",
|
|
132
|
-
"mocha": "^11.7.1",
|
|
133
|
-
"node-readable-to-web-readable-stream": "^0.4.2",
|
|
134
|
-
"remark-cli": "^12.0.1",
|
|
135
|
-
"remark-preset-lint-consistent": "^6.0.1",
|
|
136
|
-
"ts-node": "^10.9.2",
|
|
137
|
-
"typescript": "^5.
|
|
138
|
-
},
|
|
139
|
-
"engines": {
|
|
140
|
-
"node": ">=18"
|
|
141
|
-
},
|
|
142
|
-
"repository": "github:Borewit/music-metadata",
|
|
143
|
-
"license": "MIT",
|
|
144
|
-
"bugs": {
|
|
145
|
-
"url": "https://github.com/Borewit/music-metadata/issues"
|
|
146
|
-
},
|
|
147
|
-
"packageManager": "yarn@4.9.2"
|
|
148
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "music-metadata",
|
|
3
|
+
"description": "Music metadata parser for Node.js, supporting virtual any audio and tag format.",
|
|
4
|
+
"version": "11.8.1",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "Borewit",
|
|
7
|
+
"url": "https://github.com/Borewit"
|
|
8
|
+
},
|
|
9
|
+
"funding": [
|
|
10
|
+
{
|
|
11
|
+
"type": "github",
|
|
12
|
+
"url": "https://github.com/sponsors/Borewit"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"type": "buymeacoffee",
|
|
16
|
+
"url": "https://buymeacoffee.com/borewit"
|
|
17
|
+
}
|
|
18
|
+
],
|
|
19
|
+
"sideEffects": false,
|
|
20
|
+
"type": "module",
|
|
21
|
+
"exports": {
|
|
22
|
+
"node": {
|
|
23
|
+
"import": "./lib/index.js",
|
|
24
|
+
"module-sync": "./lib/index.js",
|
|
25
|
+
"types": "./lib/index.d.ts"
|
|
26
|
+
},
|
|
27
|
+
"default": {
|
|
28
|
+
"import": "./lib/core.js",
|
|
29
|
+
"module-sync": "./lib/core.js",
|
|
30
|
+
"types": "./lib/core.d.ts"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"types": "lib/index.d.ts",
|
|
34
|
+
"files": [
|
|
35
|
+
"lib/**/*.js",
|
|
36
|
+
"lib/**/*.d.ts"
|
|
37
|
+
],
|
|
38
|
+
"keywords": [
|
|
39
|
+
"music",
|
|
40
|
+
"metadata",
|
|
41
|
+
"meta",
|
|
42
|
+
"audio",
|
|
43
|
+
"tag",
|
|
44
|
+
"tags",
|
|
45
|
+
"duration",
|
|
46
|
+
"MusicBrainz",
|
|
47
|
+
"Discogs",
|
|
48
|
+
"Picard",
|
|
49
|
+
"ID3",
|
|
50
|
+
"ID3v1",
|
|
51
|
+
"ID3v2",
|
|
52
|
+
"m4a",
|
|
53
|
+
"m4b",
|
|
54
|
+
"mp3",
|
|
55
|
+
"mp4",
|
|
56
|
+
"Vorbis",
|
|
57
|
+
"ogg",
|
|
58
|
+
"flac",
|
|
59
|
+
"Matroska",
|
|
60
|
+
"WebM",
|
|
61
|
+
"EBML",
|
|
62
|
+
"asf",
|
|
63
|
+
"wma",
|
|
64
|
+
"wmv",
|
|
65
|
+
"ape",
|
|
66
|
+
"MonkeyAudio",
|
|
67
|
+
"aiff",
|
|
68
|
+
"wav",
|
|
69
|
+
"WavPack",
|
|
70
|
+
"Opus",
|
|
71
|
+
"speex",
|
|
72
|
+
"musepack",
|
|
73
|
+
"mpc",
|
|
74
|
+
"dsd",
|
|
75
|
+
"dsf",
|
|
76
|
+
"mpc",
|
|
77
|
+
"dff",
|
|
78
|
+
"dsdiff",
|
|
79
|
+
"aac",
|
|
80
|
+
"adts",
|
|
81
|
+
"length",
|
|
82
|
+
"chapter",
|
|
83
|
+
"info",
|
|
84
|
+
"parse",
|
|
85
|
+
"parser",
|
|
86
|
+
"bwf",
|
|
87
|
+
"slt",
|
|
88
|
+
"lyrics"
|
|
89
|
+
],
|
|
90
|
+
"scripts": {
|
|
91
|
+
"clean": "del-cli 'lib/**/*.js' 'lib/**/*.js.map' 'lib/**/*.d.ts' 'test/**/*.js' 'test/**/*.js.map' 'test/**/*.js' 'test/**/*.js.map' 'doc-gen/**/*.js' 'doc-gen/**/*.js.map'",
|
|
92
|
+
"compile-src": "tsc -p lib --sourceMap false",
|
|
93
|
+
"compile-test": "tsc -p test",
|
|
94
|
+
"compile-doc": "tsc -p doc-gen",
|
|
95
|
+
"compile": "yarn run compile-src && yarn compile-test && yarn compile-doc",
|
|
96
|
+
"lint:ts": "biome check",
|
|
97
|
+
"lint:md": "yarn run remark -u remark-preset-lint-consistent .",
|
|
98
|
+
"lint": "yarn run lint:ts && yarn run lint:md",
|
|
99
|
+
"test": "mocha",
|
|
100
|
+
"build": "yarn run clean && yarn compile && yarn run doc-gen",
|
|
101
|
+
"prepublishOnly": "yarn run build",
|
|
102
|
+
"test-coverage": "c8 yarn run test",
|
|
103
|
+
"send-codacy": "c8 report --reporter=text-lcov | codacy-coverage",
|
|
104
|
+
"doc-gen": "yarn node doc-gen/gen.js",
|
|
105
|
+
"typecheck": "tsc --project ./lib/tsconfig.json --noEmit && tsc --project ./test/tsconfig.json --noEmit",
|
|
106
|
+
"update-biome": "yarn add -D --exact @biomejs/biome && npx @biomejs/biome migrate --write"
|
|
107
|
+
},
|
|
108
|
+
"dependencies": {
|
|
109
|
+
"@kayahr/text-encoding": "^2.0.1",
|
|
110
|
+
"@tokenizer/token": "^0.3.0",
|
|
111
|
+
"content-type": "^1.0.5",
|
|
112
|
+
"debug": "^4.4.1",
|
|
113
|
+
"file-type": "^21.0.0",
|
|
114
|
+
"media-typer": "^1.1.0",
|
|
115
|
+
"strtok3": "^10.3.4",
|
|
116
|
+
"token-types": "^6.1.0"
|
|
117
|
+
},
|
|
118
|
+
"devDependencies": {
|
|
119
|
+
"@biomejs/biome": "2.1.4",
|
|
120
|
+
"@types/chai": "^5.2.2",
|
|
121
|
+
"@types/chai-as-promised": "^8.0.2",
|
|
122
|
+
"@types/content-type": "^1.1.9",
|
|
123
|
+
"@types/debug": "^4.1.12",
|
|
124
|
+
"@types/media-typer": "^1.1.3",
|
|
125
|
+
"@types/mocha": "^10.0.10",
|
|
126
|
+
"@types/node": "^24.2.1",
|
|
127
|
+
"c8": "^10.1.3",
|
|
128
|
+
"chai": "^5.2.1",
|
|
129
|
+
"chai-as-promised": "^8.0.1",
|
|
130
|
+
"del-cli": "^6.0.0",
|
|
131
|
+
"mime": "^4.0.7",
|
|
132
|
+
"mocha": "^11.7.1",
|
|
133
|
+
"node-readable-to-web-readable-stream": "^0.4.2",
|
|
134
|
+
"remark-cli": "^12.0.1",
|
|
135
|
+
"remark-preset-lint-consistent": "^6.0.1",
|
|
136
|
+
"ts-node": "^10.9.2",
|
|
137
|
+
"typescript": "^5.9.2"
|
|
138
|
+
},
|
|
139
|
+
"engines": {
|
|
140
|
+
"node": ">=18"
|
|
141
|
+
},
|
|
142
|
+
"repository": "github:Borewit/music-metadata",
|
|
143
|
+
"license": "MIT",
|
|
144
|
+
"bugs": {
|
|
145
|
+
"url": "https://github.com/Borewit/music-metadata/issues"
|
|
146
|
+
},
|
|
147
|
+
"packageManager": "yarn@4.9.2"
|
|
148
|
+
}
|