music-metadata 10.0.0 → 10.1.0

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.
Files changed (121) hide show
  1. package/README.md +4 -3
  2. package/lib/ParserFactory.d.ts +20 -28
  3. package/lib/ParserFactory.js +204 -207
  4. package/lib/aiff/AiffParser.js +20 -18
  5. package/lib/aiff/AiffToken.d.ts +14 -2
  6. package/lib/aiff/AiffToken.js +12 -0
  7. package/lib/apev2/APEv2Parser.d.ts +4 -4
  8. package/lib/apev2/APEv2Parser.js +20 -12
  9. package/lib/apev2/APEv2Token.d.ts +2 -4
  10. package/lib/apev2/APEv2Token.js +1 -4
  11. package/lib/asf/AsfObject.d.ts +7 -16
  12. package/lib/asf/AsfObject.js +8 -34
  13. package/lib/asf/AsfParser.js +17 -10
  14. package/lib/asf/AsfTagMapper.d.ts +1 -1
  15. package/lib/asf/AsfTagMapper.js +3 -2
  16. package/lib/asf/AsfUtil.d.ts +3 -11
  17. package/lib/asf/AsfUtil.js +29 -30
  18. package/lib/asf/GUID.js +6 -9
  19. package/lib/common/BasicParser.d.ts +4 -4
  20. package/lib/common/BasicParser.js +6 -0
  21. package/lib/common/CaseInsensitiveTagMap.d.ts +1 -1
  22. package/lib/common/CombinedTagMapper.d.ts +5 -5
  23. package/lib/common/CombinedTagMapper.js +1 -1
  24. package/lib/common/FourCC.d.ts +1 -1
  25. package/lib/common/GenericTagMapper.d.ts +8 -8
  26. package/lib/common/GenericTagMapper.js +4 -4
  27. package/lib/common/GenericTagTypes.d.ts +5 -4
  28. package/lib/common/GenericTagTypes.js +2 -2
  29. package/lib/common/MetadataCollector.d.ts +9 -9
  30. package/lib/common/MetadataCollector.js +24 -17
  31. package/lib/common/RandomFileReader.d.ts +1 -1
  32. package/lib/common/RandomFileReader.js +1 -1
  33. package/lib/common/RandomUint8ArrayReader.d.ts +1 -1
  34. package/lib/common/Util.d.ts +2 -6
  35. package/lib/common/Util.js +9 -11
  36. package/lib/core.d.ts +7 -9
  37. package/lib/core.js +10 -7
  38. package/lib/dsdiff/DsdiffParser.js +26 -14
  39. package/lib/dsdiff/DsdiffToken.d.ts +2 -2
  40. package/lib/dsdiff/DsdiffToken.js +1 -0
  41. package/lib/dsf/DsfChunk.js +1 -0
  42. package/lib/dsf/DsfParser.js +4 -2
  43. package/lib/flac/FlacParser.d.ts +3 -3
  44. package/lib/flac/FlacParser.js +9 -12
  45. package/lib/id3v1/ID3v1Parser.d.ts +1 -1
  46. package/lib/id3v1/ID3v1Parser.js +7 -4
  47. package/lib/id3v2/AbstractID3Parser.d.ts +1 -1
  48. package/lib/id3v2/AbstractID3Parser.js +2 -1
  49. package/lib/id3v2/FrameParser.d.ts +28 -3
  50. package/lib/id3v2/FrameParser.js +50 -28
  51. package/lib/id3v2/ID3v22TagMapper.d.ts +1 -1
  52. package/lib/id3v2/ID3v24TagMapper.d.ts +2 -1
  53. package/lib/id3v2/ID3v24TagMapper.js +23 -16
  54. package/lib/id3v2/ID3v2Parser.d.ts +2 -2
  55. package/lib/id3v2/ID3v2Parser.js +19 -8
  56. package/lib/iff/index.js +1 -0
  57. package/lib/index.d.ts +5 -6
  58. package/lib/index.js +7 -8
  59. package/lib/lyrics3/Lyrics3.d.ts +1 -1
  60. package/lib/lyrics3/Lyrics3.js +1 -1
  61. package/lib/matroska/MatroskaDtd.d.ts +1 -1
  62. package/lib/matroska/MatroskaDtd.js +139 -138
  63. package/lib/matroska/MatroskaParser.d.ts +4 -4
  64. package/lib/matroska/MatroskaParser.js +12 -12
  65. package/lib/matroska/types.d.ts +6 -4
  66. package/lib/mp4/Atom.d.ts +3 -3
  67. package/lib/mp4/Atom.js +4 -7
  68. package/lib/mp4/AtomToken.js +2 -1
  69. package/lib/mp4/MP4Parser.js +29 -20
  70. package/lib/mp4/MP4TagMapper.d.ts +2 -2
  71. package/lib/mp4/MP4TagMapper.js +1 -1
  72. package/lib/mpeg/ExtendedLameHeader.d.ts +4 -4
  73. package/lib/mpeg/ExtendedLameHeader.js +2 -1
  74. package/lib/mpeg/MpegParser.d.ts +1 -1
  75. package/lib/mpeg/MpegParser.js +145 -96
  76. package/lib/mpeg/ReplayGainDataFormat.d.ts +1 -1
  77. package/lib/mpeg/ReplayGainDataFormat.js +1 -0
  78. package/lib/mpeg/XingTag.d.ts +4 -4
  79. package/lib/mpeg/XingTag.js +5 -4
  80. package/lib/musepack/index.js +1 -0
  81. package/lib/musepack/sv7/BitReader.js +14 -17
  82. package/lib/musepack/sv7/MpcSv7Parser.js +6 -1
  83. package/lib/musepack/sv7/StreamVersion7.js +1 -0
  84. package/lib/musepack/sv8/MpcSv8Parser.js +6 -2
  85. package/lib/musepack/sv8/StreamVersion8.d.ts +1 -1
  86. package/lib/musepack/sv8/StreamVersion8.js +1 -0
  87. package/lib/ogg/Ogg.d.ts +1 -1
  88. package/lib/ogg/Ogg.js +1 -0
  89. package/lib/ogg/OggParser.d.ts +3 -3
  90. package/lib/ogg/OggParser.js +25 -16
  91. package/lib/ogg/opus/Opus.d.ts +1 -1
  92. package/lib/ogg/opus/Opus.js +1 -0
  93. package/lib/ogg/opus/OpusParser.d.ts +4 -4
  94. package/lib/ogg/opus/OpusParser.js +2 -0
  95. package/lib/ogg/speex/Speex.js +1 -0
  96. package/lib/ogg/speex/SpeexParser.d.ts +4 -4
  97. package/lib/ogg/speex/SpeexParser.js +1 -0
  98. package/lib/ogg/theora/Theora.js +1 -0
  99. package/lib/ogg/theora/TheoraParser.d.ts +4 -4
  100. package/lib/ogg/theora/TheoraParser.js +1 -0
  101. package/lib/ogg/vorbis/Vorbis.d.ts +3 -3
  102. package/lib/ogg/vorbis/Vorbis.js +22 -11
  103. package/lib/ogg/vorbis/VorbisDecoder.d.ts +1 -1
  104. package/lib/ogg/vorbis/VorbisDecoder.js +1 -0
  105. package/lib/ogg/vorbis/VorbisParser.d.ts +4 -4
  106. package/lib/ogg/vorbis/VorbisParser.js +3 -2
  107. package/lib/ogg/vorbis/VorbisTagMapper.d.ts +2 -2
  108. package/lib/ogg/vorbis/VorbisTagMapper.js +2 -2
  109. package/lib/riff/RiffChunk.d.ts +3 -3
  110. package/lib/riff/RiffChunk.js +1 -0
  111. package/lib/riff/RiffInfoTagMap.d.ts +1 -1
  112. package/lib/type.d.ts +35 -25
  113. package/lib/wav/BwfChunk.js +1 -0
  114. package/lib/wav/WaveChunk.d.ts +1 -1
  115. package/lib/wav/WaveChunk.js +1 -0
  116. package/lib/wav/WaveParser.js +27 -17
  117. package/lib/wavpack/WavPackParser.d.ts +1 -1
  118. package/lib/wavpack/WavPackParser.js +22 -13
  119. package/lib/wavpack/WavPackToken.d.ts +13 -17
  120. package/lib/wavpack/WavPackToken.js +22 -23
  121. package/package.json +15 -28
@@ -2,7 +2,7 @@ import * as Token from 'token-types';
2
2
  import { APEv2Parser } from '../apev2/APEv2Parser.js';
3
3
  import { FourCcToken } from '../common/FourCC.js';
4
4
  import { BasicParser } from '../common/BasicParser.js';
5
- import { WavPack } from './WavPackToken.js';
5
+ import { BlockHeaderToken, MetadataIdToken } from './WavPackToken.js';
6
6
  import initDebug from 'debug';
7
7
  import { uint8ArrayToHex } from 'uint8array-extras';
8
8
  const debug = initDebug('music-metadata:parser:WavPack');
@@ -10,6 +10,10 @@ const debug = initDebug('music-metadata:parser:WavPack');
10
10
  * WavPack Parser
11
11
  */
12
12
  export class WavPackParser extends BasicParser {
13
+ constructor() {
14
+ super(...arguments);
15
+ this.audioDataSize = 0;
16
+ }
13
17
  async parse() {
14
18
  this.audioDataSize = 0;
15
19
  // First parse all WavPack blocks
@@ -22,10 +26,10 @@ export class WavPackParser extends BasicParser {
22
26
  const blockId = await this.tokenizer.peekToken(FourCcToken);
23
27
  if (blockId !== 'wvpk')
24
28
  break;
25
- const header = await this.tokenizer.readToken(WavPack.BlockHeaderToken);
29
+ const header = await this.tokenizer.readToken(BlockHeaderToken);
26
30
  if (header.BlockID !== 'wvpk')
27
31
  throw new Error('Invalid WavPack Block-ID');
28
- debug(`WavPack header blockIndex=${header.blockIndex}, len=${WavPack.BlockHeaderToken.len}`);
32
+ debug(`WavPack header blockIndex=${header.blockIndex}, len=${BlockHeaderToken.len}`);
29
33
  if (header.blockIndex === 0 && !this.metadata.format.container) {
30
34
  this.metadata.setFormat('container', 'WavPack');
31
35
  this.metadata.setFormat('lossless', !header.flags.isHybrid);
@@ -40,22 +44,25 @@ export class WavPackParser extends BasicParser {
40
44
  this.metadata.setFormat('numberOfSamples', header.totalSamples);
41
45
  this.metadata.setFormat('codec', header.flags.isDSD ? 'DSD' : 'PCM');
42
46
  }
43
- const ignoreBytes = header.blockSize - (WavPack.BlockHeaderToken.len - 8);
47
+ const ignoreBytes = header.blockSize - (BlockHeaderToken.len - 8);
44
48
  await (header.blockIndex === 0 ? this.parseMetadataSubBlock(header, ignoreBytes) : this.tokenizer.ignore(ignoreBytes));
45
49
  if (header.blockSamples > 0) {
46
50
  this.audioDataSize += header.blockSize; // Count audio data for bit-rate calculation
47
51
  }
48
- } while (!this.tokenizer.fileInfo.size || this.tokenizer.fileInfo.size - this.tokenizer.position >= WavPack.BlockHeaderToken.len);
49
- this.metadata.setFormat('bitrate', this.audioDataSize * 8 / this.metadata.format.duration);
52
+ } while (!this.tokenizer.fileInfo.size || this.tokenizer.fileInfo.size - this.tokenizer.position >= BlockHeaderToken.len);
53
+ if (this.metadata.format.duration) {
54
+ this.metadata.setFormat('bitrate', this.audioDataSize * 8 / this.metadata.format.duration);
55
+ }
50
56
  }
51
57
  /**
52
58
  * Ref: http://www.wavpack.com/WavPack5FileFormat.pdf, 3.0 Metadata Sub-blocks
53
59
  * @param header Header
54
- * @param remainingLength
60
+ * @param remainingLength Remaining length
55
61
  */
56
62
  async parseMetadataSubBlock(header, remainingLength) {
57
- while (remainingLength > WavPack.MetadataIdToken.len) {
58
- const id = await this.tokenizer.readToken(WavPack.MetadataIdToken);
63
+ let remaining = remainingLength;
64
+ while (remaining > MetadataIdToken.len) {
65
+ const id = await this.tokenizer.readToken(MetadataIdToken);
59
66
  const dataSizeInWords = await this.tokenizer.readNumber(id.largeBlock ? Token.UINT24_LE : Token.UINT8);
60
67
  const data = new Uint8Array(dataSizeInWords * 2 - (id.isOddSize ? 1 : 0));
61
68
  await this.tokenizer.readBuffer(data);
@@ -63,7 +70,7 @@ export class WavPackParser extends BasicParser {
63
70
  switch (id.functionId) {
64
71
  case 0x0: // ID_DUMMY: could be used to pad WavPack blocks
65
72
  break;
66
- case 0xe: // ID_DSD_BLOCK
73
+ case 0xe: { // ID_DSD_BLOCK
67
74
  debug('ID_DSD_BLOCK');
68
75
  // https://github.com/dbry/WavPack/issues/71#issuecomment-483094813
69
76
  const mp = 1 << Token.UINT8.get(data, 0);
@@ -73,6 +80,7 @@ export class WavPackParser extends BasicParser {
73
80
  this.metadata.setFormat('sampleRate', samplingRate);
74
81
  this.metadata.setFormat('duration', header.totalSamples / samplingRate);
75
82
  break;
83
+ }
76
84
  case 0x24: // ID_ALT_TRAILER: maybe used to embed original ID3 tag header
77
85
  debug('ID_ALT_TRAILER: trailer for non-wav files');
78
86
  break;
@@ -86,12 +94,13 @@ export class WavPackParser extends BasicParser {
86
94
  debug(`Ignore unsupported meta-sub-block-id functionId=0x${id.functionId.toString(16)}`);
87
95
  break;
88
96
  }
89
- remainingLength -= WavPack.MetadataIdToken.len + (id.largeBlock ? Token.UINT24_LE.len : Token.UINT8.len) + dataSizeInWords * 2;
90
- debug(`remainingLength=${remainingLength}`);
97
+ remaining -= MetadataIdToken.len + (id.largeBlock ? Token.UINT24_LE.len : Token.UINT8.len) + dataSizeInWords * 2;
98
+ debug(`remainingLength=${remaining}`);
91
99
  if (id.isOddSize)
92
100
  this.tokenizer.ignore(1);
93
101
  }
94
- if (remainingLength !== 0)
102
+ if (remaining !== 0)
95
103
  throw new Error('metadata-sub-block should fit it remaining length');
96
104
  }
97
105
  }
106
+ //# sourceMappingURL=WavPackParser.js.map
@@ -45,20 +45,16 @@ export interface IMetadataId {
45
45
  */
46
46
  largeBlock: boolean;
47
47
  }
48
- export declare class WavPack {
49
- /**
50
- * WavPack Block Header
51
- *
52
- * 32-byte little-endian header at the front of every WavPack block
53
- *
54
- * Ref: http://www.wavpack.com/WavPack5FileFormat.pdf (page 2/6: 2.0 "Block Header")
55
- */
56
- static BlockHeaderToken: IGetToken<IBlockHeader>;
57
- /**
58
- * 3.0 Metadata Sub-Blocks
59
- * Ref: http://www.wavpack.com/WavPack5FileFormat.pdf (page 4/6: 3.0 "Metadata Sub-Block")
60
- */
61
- static MetadataIdToken: IGetToken<IMetadataId>;
62
- private static isBitSet;
63
- private static getBitAllignedNumber;
64
- }
48
+ /**
49
+ * WavPack Block Header
50
+ *
51
+ * 32-byte little-endian header at the front of every WavPack block
52
+ *
53
+ * Ref: http://www.wavpack.com/WavPack5FileFormat.pdf (page 2/6: 2.0 "Block Header")
54
+ */
55
+ export declare const BlockHeaderToken: IGetToken<IBlockHeader>;
56
+ /**
57
+ * 3.0 Metadata Sub-Blocks
58
+ * Ref: http://www.wavpack.com/WavPack5FileFormat.pdf (page 4/6: 3.0 "Metadata Sub-Block")
59
+ */
60
+ export declare const MetadataIdToken: IGetToken<IMetadataId>;
@@ -2,14 +2,6 @@ import * as Token from 'token-types';
2
2
  import { FourCcToken } from '../common/FourCC.js';
3
3
  const SampleRates = [6000, 8000, 9600, 11025, 12000, 16000, 22050, 24000, 32000, 44100,
4
4
  48000, 64000, 88200, 96000, 192000, -1];
5
- export class WavPack {
6
- static isBitSet(flags, bitOffset) {
7
- return WavPack.getBitAllignedNumber(flags, bitOffset, 1) === 1;
8
- }
9
- static getBitAllignedNumber(flags, bitOffset, len) {
10
- return (flags >>> bitOffset) & (0xffffffff >>> (32 - len));
11
- }
12
- }
13
5
  /**
14
6
  * WavPack Block Header
15
7
  *
@@ -17,7 +9,7 @@ export class WavPack {
17
9
  *
18
10
  * Ref: http://www.wavpack.com/WavPack5FileFormat.pdf (page 2/6: 2.0 "Block Header")
19
11
  */
20
- WavPack.BlockHeaderToken = {
12
+ export const BlockHeaderToken = {
21
13
  len: 32,
22
14
  get: (buf, off) => {
23
15
  const flags = Token.UINT32_LE.get(buf, off + 24);
@@ -36,15 +28,15 @@ WavPack.BlockHeaderToken = {
36
28
  blockSamples: Token.UINT32_LE.get(buf, off + 20),
37
29
  // various flags for id and decoding
38
30
  flags: {
39
- bitsPerSample: (1 + WavPack.getBitAllignedNumber(flags, 0, 2)) * 8,
40
- isMono: WavPack.isBitSet(flags, 2),
41
- isHybrid: WavPack.isBitSet(flags, 3),
42
- isJointStereo: WavPack.isBitSet(flags, 4),
43
- crossChannel: WavPack.isBitSet(flags, 5),
44
- hybridNoiseShaping: WavPack.isBitSet(flags, 6),
45
- floatingPoint: WavPack.isBitSet(flags, 7),
46
- samplingRate: SampleRates[WavPack.getBitAllignedNumber(flags, 23, 4)],
47
- isDSD: WavPack.isBitSet(flags, 31)
31
+ bitsPerSample: (1 + getBitAllignedNumber(flags, 0, 2)) * 8,
32
+ isMono: isBitSet(flags, 2),
33
+ isHybrid: isBitSet(flags, 3),
34
+ isJointStereo: isBitSet(flags, 4),
35
+ crossChannel: isBitSet(flags, 5),
36
+ hybridNoiseShaping: isBitSet(flags, 6),
37
+ floatingPoint: isBitSet(flags, 7),
38
+ samplingRate: SampleRates[getBitAllignedNumber(flags, 23, 4)],
39
+ isDSD: isBitSet(flags, 31)
48
40
  },
49
41
  // crc for actual decoded data
50
42
  crc: new Token.Uint8ArrayType(4).get(buf, off + 28)
@@ -59,14 +51,21 @@ WavPack.BlockHeaderToken = {
59
51
  * 3.0 Metadata Sub-Blocks
60
52
  * Ref: http://www.wavpack.com/WavPack5FileFormat.pdf (page 4/6: 3.0 "Metadata Sub-Block")
61
53
  */
62
- WavPack.MetadataIdToken = {
54
+ export const MetadataIdToken = {
63
55
  len: 1,
64
56
  get: (buf, off) => {
65
57
  return {
66
- functionId: WavPack.getBitAllignedNumber(buf[off], 0, 6), // functionId overlaps with isOptional flag
67
- isOptional: WavPack.isBitSet(buf[off], 5),
68
- isOddSize: WavPack.isBitSet(buf[off], 6),
69
- largeBlock: WavPack.isBitSet(buf[off], 7)
58
+ functionId: getBitAllignedNumber(buf[off], 0, 6), // functionId overlaps with isOptional flag
59
+ isOptional: isBitSet(buf[off], 5),
60
+ isOddSize: isBitSet(buf[off], 6),
61
+ largeBlock: isBitSet(buf[off], 7)
70
62
  };
71
63
  }
72
64
  };
65
+ function isBitSet(flags, bitOffset) {
66
+ return getBitAllignedNumber(flags, bitOffset, 1) === 1;
67
+ }
68
+ function getBitAllignedNumber(flags, bitOffset, len) {
69
+ return (flags >>> bitOffset) & (0xffffffff >>> (32 - len));
70
+ }
71
+ //# sourceMappingURL=WavPackToken.js.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "music-metadata",
3
3
  "description": "Music metadata parser for Node.js, supporting virtual any audio and tag format.",
4
- "version": "10.0.0",
4
+ "version": "10.1.0",
5
5
  "author": {
6
6
  "name": "Borewit",
7
7
  "url": "https://github.com/Borewit"
@@ -83,54 +83,41 @@
83
83
  "compile-src": "tsc -p lib",
84
84
  "compile-test": "tsc -p test",
85
85
  "compile-doc": "tsc -p doc-gen",
86
- "compile": "npm run compile-src && npm run compile-test && npm run compile-doc",
87
- "eslint": "eslint lib test doc-gen",
88
- "lint-md": "remark -u preset-lint-markdown-style-guide .",
89
- "lint": "npm run lint-md && npm run eslint",
86
+ "compile": "yarn run compile-src && yarn compile-test && yarn compile-doc",
87
+ "lint-ts": "biome check",
88
+ "lint-md": "yarn run remark -u preset-lint-markdown-style-guide .",
89
+ "lint": "yarn run lint-ts && yarn run lint-md",
90
90
  "test": "mocha",
91
- "build": "npm run clean && npm run compile && npm run doc-gen",
92
- "start": "npm-run-all compile lint cover-test",
93
- "test-coverage": "c8 npm run test",
91
+ "build": "yarn run clean && yarn compile && yarn run doc-gen",
92
+ "test-coverage": "c8 yarn run test",
94
93
  "send-codacy": "c8 report --reporter=text-lcov | codacy-coverage",
95
- "doc-gen": "node doc-gen/gen.js"
94
+ "doc-gen": "yarn node doc-gen/gen.js"
96
95
  },
97
96
  "dependencies": {
98
97
  "@tokenizer/token": "^0.3.0",
99
98
  "content-type": "^1.0.5",
100
99
  "debug": "^4.3.4",
101
- "file-type": "^19.2.0",
100
+ "file-type": "^19.4.0",
102
101
  "media-typer": "^1.1.0",
103
- "strtok3": "^8.0.0",
102
+ "strtok3": "^8.0.5",
104
103
  "token-types": "^6.0.0",
105
104
  "uint8array-extras": "^1.4.0"
106
105
  },
107
106
  "devDependencies": {
108
- "@eslint/compat": "^1.1.1",
109
- "@eslint/eslintrc": "^3.1.0",
110
- "@eslint/js": "^9.7.0",
107
+ "@biomejs/biome": "1.8.3",
111
108
  "@types/chai": "^4.3.16",
112
109
  "@types/chai-as-promised": "^7.1.8",
110
+ "@types/content-type": "^1.1.8",
113
111
  "@types/debug": "^4.1.12",
114
- "@types/file-type": "^10.9.1",
112
+ "@types/media-typer": "^1.1.3",
115
113
  "@types/mocha": "^10.0.7",
116
- "@types/node": "^20.14.11",
117
- "@typescript-eslint/eslint-plugin": "^7.16.1",
118
- "@typescript-eslint/parser": "^7.16.1",
114
+ "@types/node": "^22.2.0",
119
115
  "c8": "^10.1.2",
120
116
  "chai": "^5.1.1",
121
117
  "chai-as-promised": "^8.0.0",
122
118
  "del-cli": "^5.1.0",
123
- "eslint": "^9.7.0",
124
- "eslint-config-prettier": "^9.1.0",
125
- "eslint-import-resolver-typescript": "^3.6.1",
126
- "eslint-plugin-import": "^2.29.1",
127
- "eslint-plugin-jsdoc": "^48.7.0",
128
- "eslint-plugin-node": "^11.1.0",
129
- "eslint-plugin-unicorn": "^54.0.0",
130
- "globals": "^15.8.0",
131
119
  "mime": "^4.0.4",
132
- "mocha": "^10.6.0",
133
- "npm-run-all": "^4.1.5",
120
+ "mocha": "^10.7.3",
134
121
  "prettier": "^3.3.3",
135
122
  "remark-cli": "^12.0.1",
136
123
  "remark-preset-lint-markdown-style-guide": "^6.0.0",