music-metadata 11.8.1 → 11.8.3

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.
@@ -47,7 +47,7 @@ export class ParserFactory {
47
47
  musepackParserLoader,
48
48
  dsfParserLoader,
49
49
  dsdiffParserLoader
50
- ].forEach(parser => this.registerParser(parser));
50
+ ].forEach(parser => { this.registerParser(parser); });
51
51
  }
52
52
  registerParser(parser) {
53
53
  this.parsers.push(parser);
@@ -5,7 +5,7 @@ import * as util from '../common/Util.js';
5
5
  import { BasicParser } from '../common/BasicParser.js';
6
6
  import { DataType, DescriptorParser, Header, TagFooter, TagItemHeader } from './APEv2Token.js';
7
7
  import { makeUnexpectedFileContentError } from '../ParseError.js';
8
- import { TextDecoder } from '@kayahr/text-encoding';
8
+ import { textDecode } from '@borewit/text-codec';
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 = new TextDecoder('utf-8').decode(picData.slice(0, zero));
135
+ const description = textDecode(picData.slice(0, zero), 'utf-8');
136
136
  const data = picData.slice(zero + 1);
137
137
  await this.metadata.addTag(tagFormat, key, {
138
138
  description,
@@ -1,4 +1,4 @@
1
- import { TextDecoder, TextEncoder } from '@kayahr/text-encoding';
1
+ import { textDecode, textEncode } from '@borewit/text-codec';
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 = new TextDecoder('latin1').decode(buf.slice(off, off + FourCcToken.len));
12
+ const id = textDecode(buf.slice(off, off + FourCcToken.len), 'latin1');
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 = new TextEncoder('latin1').encode(id);
19
+ const str = textEncode(id, 'latin1');
20
20
  if (str.length !== 4)
21
21
  throw new InternalParserError('Invalid length');
22
22
  buffer.set(str, offset);
@@ -51,4 +51,3 @@ export declare function dbToRatio(dB: number): number;
51
51
  * @param value string holding a ratio like '0.034' or '-7.54 dB'
52
52
  */
53
53
  export declare function toRatio(value: string): IRatio | undefined;
54
- export declare function uint8ArrayToHex(array: Uint8Array): string;
@@ -129,7 +129,6 @@ export function dbToRatio(dB) {
129
129
  */
130
130
  export function toRatio(value) {
131
131
  const ps = value.split(' ').map(p => p.trim().toLowerCase());
132
- // @ts-ignore
133
132
  if (ps.length >= 1) {
134
133
  const v = Number.parseFloat(ps[0]);
135
134
  return ps.length === 2 && ps[1] === 'db' ? {
@@ -141,13 +140,3 @@ export function toRatio(value) {
141
140
  };
142
141
  }
143
142
  }
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
- }
@@ -3,7 +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
+ import { textDecode } from '@borewit/text-codec';
7
7
  const debug = initDebug('music-metadata:parser:ID3v1');
8
8
  /**
9
9
  * ID3v1 Genre mappings
@@ -131,7 +131,7 @@ export async function hasID3v1Header(tokenizer) {
131
131
  const position = tokenizer.position;
132
132
  await tokenizer.readBuffer(tag, { position: tokenizer.fileInfo.size - 128 });
133
133
  tokenizer.setPosition(position); // Restore tokenizer position
134
- return new TextDecoder('latin1').decode(tag) === 'TAG';
134
+ return textDecode(tag, 'latin1') === 'TAG';
135
135
  }
136
136
  return false;
137
137
  }
@@ -2,8 +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';
6
- const asciiDecoder = new TextDecoder('ascii');
5
+ import { textDecode } from '@borewit/text-codec';
7
6
  export class ID3v2Parser {
8
7
  constructor() {
9
8
  this.tokenizer = undefined;
@@ -150,7 +149,7 @@ export class ID3v2Parser {
150
149
  switch (majorVer) {
151
150
  case 2:
152
151
  header = {
153
- id: asciiDecoder.decode(uint8Array.slice(0, 3)),
152
+ id: textDecode(uint8Array.slice(0, 3), 'ascii'),
154
153
  length: Token.UINT24_BE.get(uint8Array, 3)
155
154
  };
156
155
  if (!header.id.match(/[A-Z0-9]{3}/g)) {
@@ -160,7 +159,7 @@ export class ID3v2Parser {
160
159
  case 3:
161
160
  case 4:
162
161
  header = {
163
- id: asciiDecoder.decode(uint8Array.slice(0, 4)),
162
+ id: textDecode(uint8Array.slice(0, 4), 'ascii'),
164
163
  length: (majorVer === 4 ? UINT32SYNCSAFE : Token.UINT32_BE).get(uint8Array, 4),
165
164
  flags: ID3v2Parser.readFrameFlags(uint8Array.slice(8, 10))
166
165
  };
@@ -1,4 +1,4 @@
1
- import { TextDecoder } from '@kayahr/text-encoding';
1
+ import { textDecode } from '@borewit/text-codec';
2
2
  export const endTag2 = 'LYRICS200';
3
3
  export async function getLyricsHeaderLength(tokenizer) {
4
4
  const fileSize = tokenizer.fileInfo.size;
@@ -7,7 +7,7 @@ export async function getLyricsHeaderLength(tokenizer) {
7
7
  const position = tokenizer.position;
8
8
  await tokenizer.readBuffer(buf, { position: fileSize - 143 });
9
9
  tokenizer.setPosition(position); // Restore position
10
- const txt = new TextDecoder('latin1').decode(buf);
10
+ const txt = textDecode(buf, 'latin1');
11
11
  const tag = txt.slice(6);
12
12
  if (tag === endTag2) {
13
13
  return Number.parseInt(txt.slice(0, 6), 10) + 15;
@@ -6,8 +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 } from '../common/Util.js';
10
- import { TextDecoder } from '@kayahr/text-encoding';
9
+ import { uint8ArrayToHex } from 'uint8array-extras';
10
+ import { textDecode } from '@borewit/text-codec';
11
11
  const debug = initDebug('music-metadata:parser:MP4');
12
12
  const tagFormat = 'iTunes';
13
13
  const encoderDict = {
@@ -354,7 +354,7 @@ export class MP4Parser extends BasicParser {
354
354
  }
355
355
  default: {
356
356
  const uint8Array = await this.tokenizer.readToken(new Token.Uint8ArrayType(payLoadLength));
357
- this.addWarning(`Unsupported meta-item: ${tagKey}[${child.header.name}] => value=${uint8ArrayToHex(uint8Array)} ascii=${new TextDecoder('ascii').decode(uint8Array)}`);
357
+ this.addWarning(`Unsupported meta-item: ${tagKey}[${child.header.name}] => value=${uint8ArrayToHex(uint8Array)} ascii=${textDecode(uint8Array, 'ascii')}`);
358
358
  }
359
359
  }
360
360
  }, metaAtom.getPayloadLength(0));
@@ -385,7 +385,7 @@ export class MP4Parser extends BasicParser {
385
385
  break;
386
386
  }
387
387
  case 'rate': {
388
- const rate = new TextDecoder('ascii').decode(dataAtom.value);
388
+ const rate = textDecode(dataAtom.value, 'ascii');
389
389
  await this.addTag(tagKey, rate);
390
390
  break;
391
391
  }
@@ -395,7 +395,7 @@ export class MP4Parser extends BasicParser {
395
395
  break;
396
396
  case 1: // UTF-8: Without any count or NULL terminator
397
397
  case 18: // Unknown: Found in m4b in combination with a '©gen' tag
398
- await this.addTag(tagKey, new TextDecoder('utf-8').decode(dataAtom.value));
398
+ await this.addTag(tagKey, textDecode(dataAtom.value));
399
399
  break;
400
400
  case 13: // JPEG
401
401
  if (this.options.skipCovers)
@@ -433,7 +433,7 @@ export class MP4Parser extends BasicParser {
433
433
  }
434
434
  }
435
435
  async parseTrackBox(trakBox) {
436
- // @ts-ignore
436
+ // @ts-expect-error
437
437
  const track = {
438
438
  media: {},
439
439
  fragments: []
@@ -1,6 +1,6 @@
1
1
  import * as Token from 'token-types';
2
2
  import * as util from '../../common/Util.js';
3
- import { TextDecoder } from '@kayahr/text-encoding';
3
+ import { textDecode } from '@borewit/text-codec';
4
4
  /**
5
5
  * BASIC STRUCTURE
6
6
  */
@@ -9,7 +9,7 @@ export const Header = {
9
9
  get: (buf, off) => {
10
10
  const header = {
11
11
  // word 0
12
- signature: new TextDecoder('latin1').decode(buf.subarray(off, off + 3)),
12
+ signature: textDecode(buf.subarray(off, off + 3), 'latin1'),
13
13
  // versionIndex number * 1000 (3.81 = 3810) (remember that 4-byte alignment causes this to take 4-bytes)
14
14
  streamMinorVersion: util.getBitAllignedNumber(buf, off + 3, 0, 4),
15
15
  streamMajorVersion: util.getBitAllignedNumber(buf, off + 3, 4, 4),
@@ -1,5 +1,5 @@
1
1
  import * as Token from 'token-types';
2
- import { TextDecoder } from '@kayahr/text-encoding';
2
+ import { textDecode } from '@borewit/text-codec';
3
3
  export class VorbisDecoder {
4
4
  constructor(data, offset) {
5
5
  this.data = data;
@@ -12,7 +12,7 @@ export class VorbisDecoder {
12
12
  }
13
13
  readStringUtf8() {
14
14
  const len = this.readInt32();
15
- const value = new TextDecoder('utf-8').decode(this.data.subarray(this.offset, this.offset + len));
15
+ const value = textDecode(this.data.subarray(this.offset, this.offset + len), 'utf-8');
16
16
  this.offset += len;
17
17
  return value;
18
18
  }
@@ -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 '../common/Util.js';
7
+ import { uint8ArrayToHex } from 'uint8array-extras';
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,149 @@
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
- }
1
+ {
2
+ "name": "music-metadata",
3
+ "description": "Music metadata parser for Node.js, supporting virtual any audio and tag format.",
4
+ "version": "11.8.3",
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
+ "@borewit/text-codec": "^0.2.0",
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.1",
117
+ "uint8array-extras": "^1.4.1"
118
+ },
119
+ "devDependencies": {
120
+ "@biomejs/biome": "2.2.0",
121
+ "@types/chai": "^5.2.2",
122
+ "@types/chai-as-promised": "^8.0.2",
123
+ "@types/content-type": "^1.1.9",
124
+ "@types/debug": "^4.1.12",
125
+ "@types/media-typer": "^1.1.3",
126
+ "@types/mocha": "^10.0.10",
127
+ "@types/node": "^24.2.1",
128
+ "c8": "^10.1.3",
129
+ "chai": "^5.2.1",
130
+ "chai-as-promised": "^8.0.1",
131
+ "del-cli": "^6.0.0",
132
+ "mime": "^4.0.7",
133
+ "mocha": "^11.7.1",
134
+ "node-readable-to-web-readable-stream": "^0.4.2",
135
+ "remark-cli": "^12.0.1",
136
+ "remark-preset-lint-consistent": "^6.0.1",
137
+ "ts-node": "^10.9.2",
138
+ "typescript": "^5.9.2"
139
+ },
140
+ "engines": {
141
+ "node": ">=18"
142
+ },
143
+ "repository": "github:Borewit/music-metadata",
144
+ "license": "MIT",
145
+ "bugs": {
146
+ "url": "https://github.com/Borewit/music-metadata/issues"
147
+ },
148
+ "packageManager": "yarn@4.9.2"
149
+ }