music-metadata 10.0.1 → 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 (122) hide show
  1. package/LICENSE.txt +9 -9
  2. package/README.md +520 -520
  3. package/lib/ParserFactory.d.ts +20 -28
  4. package/lib/ParserFactory.js +204 -207
  5. package/lib/aiff/AiffParser.js +20 -18
  6. package/lib/aiff/AiffToken.d.ts +14 -2
  7. package/lib/aiff/AiffToken.js +12 -0
  8. package/lib/apev2/APEv2Parser.d.ts +4 -4
  9. package/lib/apev2/APEv2Parser.js +12 -10
  10. package/lib/apev2/APEv2Token.d.ts +2 -4
  11. package/lib/apev2/APEv2Token.js +0 -3
  12. package/lib/asf/AsfObject.d.ts +7 -16
  13. package/lib/asf/AsfObject.js +8 -34
  14. package/lib/asf/AsfParser.js +17 -10
  15. package/lib/asf/AsfTagMapper.d.ts +1 -1
  16. package/lib/asf/AsfTagMapper.js +3 -2
  17. package/lib/asf/AsfUtil.d.ts +3 -11
  18. package/lib/asf/AsfUtil.js +29 -30
  19. package/lib/asf/GUID.js +6 -9
  20. package/lib/common/BasicParser.d.ts +4 -4
  21. package/lib/common/BasicParser.js +6 -0
  22. package/lib/common/CaseInsensitiveTagMap.d.ts +1 -1
  23. package/lib/common/CombinedTagMapper.d.ts +5 -5
  24. package/lib/common/CombinedTagMapper.js +1 -1
  25. package/lib/common/FourCC.d.ts +1 -1
  26. package/lib/common/GenericTagMapper.d.ts +8 -8
  27. package/lib/common/GenericTagMapper.js +4 -4
  28. package/lib/common/GenericTagTypes.d.ts +5 -4
  29. package/lib/common/GenericTagTypes.js +2 -2
  30. package/lib/common/MetadataCollector.d.ts +9 -9
  31. package/lib/common/MetadataCollector.js +24 -17
  32. package/lib/common/RandomFileReader.d.ts +1 -1
  33. package/lib/common/RandomFileReader.js +1 -1
  34. package/lib/common/RandomUint8ArrayReader.d.ts +1 -1
  35. package/lib/common/Util.d.ts +2 -6
  36. package/lib/common/Util.js +9 -11
  37. package/lib/core.d.ts +7 -9
  38. package/lib/core.js +10 -7
  39. package/lib/dsdiff/DsdiffParser.js +26 -14
  40. package/lib/dsdiff/DsdiffToken.d.ts +2 -2
  41. package/lib/dsdiff/DsdiffToken.js +1 -0
  42. package/lib/dsf/DsfChunk.js +1 -0
  43. package/lib/dsf/DsfParser.js +4 -2
  44. package/lib/flac/FlacParser.d.ts +3 -3
  45. package/lib/flac/FlacParser.js +9 -12
  46. package/lib/id3v1/ID3v1Parser.d.ts +1 -1
  47. package/lib/id3v1/ID3v1Parser.js +7 -4
  48. package/lib/id3v2/AbstractID3Parser.d.ts +1 -1
  49. package/lib/id3v2/AbstractID3Parser.js +2 -1
  50. package/lib/id3v2/FrameParser.d.ts +28 -3
  51. package/lib/id3v2/FrameParser.js +50 -28
  52. package/lib/id3v2/ID3v22TagMapper.d.ts +1 -1
  53. package/lib/id3v2/ID3v24TagMapper.d.ts +2 -1
  54. package/lib/id3v2/ID3v24TagMapper.js +23 -16
  55. package/lib/id3v2/ID3v2Parser.d.ts +2 -2
  56. package/lib/id3v2/ID3v2Parser.js +19 -8
  57. package/lib/iff/index.js +1 -0
  58. package/lib/index.d.ts +5 -6
  59. package/lib/index.js +7 -8
  60. package/lib/lyrics3/Lyrics3.d.ts +1 -1
  61. package/lib/lyrics3/Lyrics3.js +1 -1
  62. package/lib/matroska/MatroskaDtd.d.ts +1 -1
  63. package/lib/matroska/MatroskaDtd.js +139 -138
  64. package/lib/matroska/MatroskaParser.d.ts +4 -4
  65. package/lib/matroska/MatroskaParser.js +12 -12
  66. package/lib/matroska/types.d.ts +6 -4
  67. package/lib/mp4/Atom.d.ts +3 -3
  68. package/lib/mp4/Atom.js +4 -7
  69. package/lib/mp4/AtomToken.js +2 -1
  70. package/lib/mp4/MP4Parser.js +29 -20
  71. package/lib/mp4/MP4TagMapper.d.ts +2 -2
  72. package/lib/mp4/MP4TagMapper.js +1 -1
  73. package/lib/mpeg/ExtendedLameHeader.d.ts +4 -4
  74. package/lib/mpeg/ExtendedLameHeader.js +2 -1
  75. package/lib/mpeg/MpegParser.d.ts +1 -1
  76. package/lib/mpeg/MpegParser.js +145 -96
  77. package/lib/mpeg/ReplayGainDataFormat.d.ts +1 -1
  78. package/lib/mpeg/ReplayGainDataFormat.js +1 -0
  79. package/lib/mpeg/XingTag.d.ts +4 -4
  80. package/lib/mpeg/XingTag.js +5 -4
  81. package/lib/musepack/index.js +1 -0
  82. package/lib/musepack/sv7/BitReader.js +14 -17
  83. package/lib/musepack/sv7/MpcSv7Parser.js +6 -1
  84. package/lib/musepack/sv7/StreamVersion7.js +1 -0
  85. package/lib/musepack/sv8/MpcSv8Parser.js +6 -2
  86. package/lib/musepack/sv8/StreamVersion8.d.ts +1 -1
  87. package/lib/musepack/sv8/StreamVersion8.js +1 -0
  88. package/lib/ogg/Ogg.d.ts +1 -1
  89. package/lib/ogg/Ogg.js +1 -0
  90. package/lib/ogg/OggParser.d.ts +3 -3
  91. package/lib/ogg/OggParser.js +25 -16
  92. package/lib/ogg/opus/Opus.d.ts +1 -1
  93. package/lib/ogg/opus/Opus.js +1 -0
  94. package/lib/ogg/opus/OpusParser.d.ts +4 -4
  95. package/lib/ogg/opus/OpusParser.js +2 -0
  96. package/lib/ogg/speex/Speex.js +1 -0
  97. package/lib/ogg/speex/SpeexParser.d.ts +4 -4
  98. package/lib/ogg/speex/SpeexParser.js +1 -0
  99. package/lib/ogg/theora/Theora.js +1 -0
  100. package/lib/ogg/theora/TheoraParser.d.ts +4 -4
  101. package/lib/ogg/theora/TheoraParser.js +1 -0
  102. package/lib/ogg/vorbis/Vorbis.d.ts +3 -3
  103. package/lib/ogg/vorbis/Vorbis.js +22 -11
  104. package/lib/ogg/vorbis/VorbisDecoder.d.ts +1 -1
  105. package/lib/ogg/vorbis/VorbisDecoder.js +1 -0
  106. package/lib/ogg/vorbis/VorbisParser.d.ts +4 -4
  107. package/lib/ogg/vorbis/VorbisParser.js +3 -2
  108. package/lib/ogg/vorbis/VorbisTagMapper.d.ts +2 -2
  109. package/lib/ogg/vorbis/VorbisTagMapper.js +2 -2
  110. package/lib/riff/RiffChunk.d.ts +3 -3
  111. package/lib/riff/RiffChunk.js +1 -0
  112. package/lib/riff/RiffInfoTagMap.d.ts +1 -1
  113. package/lib/type.d.ts +35 -25
  114. package/lib/wav/BwfChunk.js +1 -0
  115. package/lib/wav/WaveChunk.d.ts +1 -1
  116. package/lib/wav/WaveChunk.js +1 -0
  117. package/lib/wav/WaveParser.js +27 -17
  118. package/lib/wavpack/WavPackParser.d.ts +1 -1
  119. package/lib/wavpack/WavPackParser.js +22 -13
  120. package/lib/wavpack/WavPackToken.d.ts +13 -17
  121. package/lib/wavpack/WavPackToken.js +22 -23
  122. package/package.json +139 -150
@@ -17,7 +17,7 @@ export class DsfParser extends AbstractID3Parser {
17
17
  this.metadata.setFormat('lossless', true);
18
18
  const dsdChunk = await this.tokenizer.readToken(DsdChunk);
19
19
  if (dsdChunk.metadataPointer === BigInt(0)) {
20
- debug(`No ID3v2 tag present`);
20
+ debug("No ID3v2 tag present");
21
21
  }
22
22
  else {
23
23
  debug(`expect ID3v2 at offset=${dsdChunk.metadataPointer}`);
@@ -32,7 +32,7 @@ export class DsfParser extends AbstractID3Parser {
32
32
  const chunkHeader = await this.tokenizer.readToken(ChunkHeader);
33
33
  debug(`Parsing chunk name=${chunkHeader.id} size=${chunkHeader.size}`);
34
34
  switch (chunkHeader.id) {
35
- case 'fmt ':
35
+ case 'fmt ': {
36
36
  const formatChunk = await this.tokenizer.readToken(FormatChunk);
37
37
  this.metadata.setFormat('numberOfChannels', formatChunk.channelNum);
38
38
  this.metadata.setFormat('sampleRate', formatChunk.samplingFrequency);
@@ -42,6 +42,7 @@ export class DsfParser extends AbstractID3Parser {
42
42
  const bitrate = formatChunk.bitsPerSample * formatChunk.samplingFrequency * formatChunk.channelNum;
43
43
  this.metadata.setFormat('bitrate', bitrate);
44
44
  return; // We got what we want, stop further processing of chunks
45
+ }
45
46
  default:
46
47
  this.tokenizer.ignore(Number(chunkHeader.size) - ChunkHeader.len);
47
48
  break;
@@ -50,3 +51,4 @@ export class DsfParser extends AbstractID3Parser {
50
51
  }
51
52
  }
52
53
  }
54
+ //# sourceMappingURL=DsfParser.js.map
@@ -1,8 +1,8 @@
1
1
  import type { ITokenizer } from 'strtok3';
2
2
  import { AbstractID3Parser } from '../id3v2/AbstractID3Parser.js';
3
- import { INativeMetadataCollector } from '../common/MetadataCollector.js';
4
- import { IOptions } from '../type.js';
5
- import { ITokenParser } from '../ParserFactory.js';
3
+ import type { INativeMetadataCollector } from '../common/MetadataCollector.js';
4
+ import type { IOptions } from '../type.js';
5
+ import type { ITokenParser } from '../ParserFactory.js';
6
6
  export declare class FlacParser extends AbstractID3Parser {
7
7
  private vorbisParser;
8
8
  private padding;
@@ -45,7 +45,7 @@ export class FlacParser extends AbstractID3Parser {
45
45
  let blockHeader;
46
46
  do {
47
47
  // Read block header
48
- blockHeader = await this.tokenizer.readToken(Metadata.BlockHeader);
48
+ blockHeader = await this.tokenizer.readToken(BlockHeader);
49
49
  // Parse block data
50
50
  await this.parseDataBlock(blockHeader);
51
51
  } while (!blockHeader.lastBlock);
@@ -74,7 +74,7 @@ export class FlacParser extends AbstractID3Parser {
74
74
  await this.parsePicture(blockHeader.length);
75
75
  return;
76
76
  default:
77
- this.metadata.addWarning('Unknown block type: ' + blockHeader.type);
77
+ this.metadata.addWarning(`Unknown block type: ${blockHeader.type}`);
78
78
  }
79
79
  // Ignore data block
80
80
  return this.tokenizer.ignore(blockHeader.length).then();
@@ -83,9 +83,9 @@ export class FlacParser extends AbstractID3Parser {
83
83
  * Parse STREAMINFO
84
84
  */
85
85
  async parseBlockStreamInfo(dataLen) {
86
- if (dataLen !== Metadata.BlockStreamInfo.len)
86
+ if (dataLen !== BlockStreamInfo.len)
87
87
  throw new Error('Unexpected block-stream-info length');
88
- const streamInfo = await this.tokenizer.readToken(Metadata.BlockStreamInfo);
88
+ const streamInfo = await this.tokenizer.readToken(BlockStreamInfo);
89
89
  this.metadata.setFormat('container', 'FLAC');
90
90
  this.metadata.setFormat('codec', 'FLAC');
91
91
  this.metadata.setFormat('lossless', true);
@@ -115,15 +115,11 @@ export class FlacParser extends AbstractID3Parser {
115
115
  if (this.options.skipCovers) {
116
116
  return this.tokenizer.ignore(dataLen);
117
117
  }
118
- else {
119
- const picture = await this.tokenizer.readToken(new VorbisPictureToken(dataLen));
120
- this.vorbisParser.addTag('METADATA_BLOCK_PICTURE', picture);
121
- }
118
+ const picture = await this.tokenizer.readToken(new VorbisPictureToken(dataLen));
119
+ this.vorbisParser.addTag('METADATA_BLOCK_PICTURE', picture);
122
120
  }
123
121
  }
124
- class Metadata {
125
- }
126
- Metadata.BlockHeader = {
122
+ const BlockHeader = {
127
123
  len: 4,
128
124
  get: (buf, off) => {
129
125
  return {
@@ -137,7 +133,7 @@ Metadata.BlockHeader = {
137
133
  * METADATA_BLOCK_DATA
138
134
  * Ref: https://xiph.org/flac/format.html#metadata_block_streaminfo
139
135
  */
140
- Metadata.BlockStreamInfo = {
136
+ const BlockStreamInfo = {
141
137
  len: 34,
142
138
  get: (buf, off) => {
143
139
  return {
@@ -171,3 +167,4 @@ Metadata.BlockStreamInfo = {
171
167
  };
172
168
  }
173
169
  };
170
+ //# sourceMappingURL=FlacParser.js.map
@@ -1,5 +1,5 @@
1
1
  import { BasicParser } from '../common/BasicParser.js';
2
- import { IRandomReader } from '../type.js';
2
+ import type { IRandomReader } from '../type.js';
3
3
  /**
4
4
  * ID3v1 Genre mappings
5
5
  * Ref: https://de.wikipedia.org/wiki/Liste_der_ID3v1-Genres
@@ -66,12 +66,13 @@ const Iid3v1Token = {
66
66
  } : null;
67
67
  }
68
68
  };
69
- class Id3v1StringType extends StringType {
69
+ class Id3v1StringType {
70
70
  constructor(len) {
71
- super(len, 'latin1');
71
+ this.len = len;
72
+ this.stringType = new StringType(len, 'latin1');
72
73
  }
73
74
  get(buf, off) {
74
- let value = super.get(buf, off);
75
+ let value = this.stringType.get(buf, off);
75
76
  value = util.trimRightNull(value);
76
77
  value = value.trim();
77
78
  return value.length > 0 ? value : undefined;
@@ -103,7 +104,8 @@ export class ID3v1Parser extends BasicParser {
103
104
  const header = await this.tokenizer.readToken(Iid3v1Token, offset);
104
105
  if (header) {
105
106
  debug('ID3v1 header found at: pos=%s', this.tokenizer.fileInfo.size - Iid3v1Token.len);
106
- for (const id of ['title', 'artist', 'album', 'comment', 'track', 'year']) {
107
+ const props = ['title', 'artist', 'album', 'comment', 'track', 'year'];
108
+ for (const id of props) {
107
109
  if (header[id] && header[id] !== '')
108
110
  await this.addTag(id, header[id]);
109
111
  }
@@ -127,3 +129,4 @@ export async function hasID3v1Header(reader) {
127
129
  }
128
130
  return false;
129
131
  }
132
+ //# sourceMappingURL=ID3v1Parser.js.map
@@ -1,4 +1,4 @@
1
- import { ITokenizer } from 'strtok3';
1
+ import { type ITokenizer } from 'strtok3';
2
2
  import { BasicParser } from '../common/BasicParser.js';
3
3
  /**
4
4
  * Abstract parser which tries take ID3v2 and ID3v1 headers.
@@ -22,7 +22,7 @@ export class AbstractID3Parser extends BasicParser {
22
22
  }
23
23
  catch (err) {
24
24
  if (err instanceof EndOfStreamError) {
25
- debug(`End-of-stream`);
25
+ debug("End-of-stream");
26
26
  }
27
27
  else {
28
28
  throw err;
@@ -54,3 +54,4 @@ export class AbstractID3Parser extends BasicParser {
54
54
  }
55
55
  }
56
56
  }
57
+ //# sourceMappingURL=AbstractID3Parser.js.map
@@ -1,5 +1,29 @@
1
- import { ID3v2MajorVersion, ITextEncoding } from './ID3v2Token.js';
2
- import { IWarningCollector } from '../common/MetadataCollector.js';
1
+ import { type ID3v2MajorVersion, type ITextEncoding } from './ID3v2Token.js';
2
+ import type { IWarningCollector } from '../common/MetadataCollector.js';
3
+ interface ICustomTag {
4
+ owner_identifier: string;
5
+ }
6
+ export interface ICustomDataTag extends ICustomTag {
7
+ data: Uint8Array;
8
+ }
9
+ export interface IIdentifierTag extends ICustomTag {
10
+ identifier: Uint8Array;
11
+ }
12
+ export interface ITextTag {
13
+ description: string;
14
+ text: string[];
15
+ }
16
+ export interface IPopularimeter {
17
+ email: string;
18
+ rating: number;
19
+ counter: number;
20
+ }
21
+ export interface IGeneralEncapsulatedObject {
22
+ type: string;
23
+ filename: string;
24
+ description: string;
25
+ data: Uint8Array;
26
+ }
3
27
  export declare function parseGenre(origVal: string): string[];
4
28
  export declare class FrameParser {
5
29
  private major;
@@ -10,7 +34,7 @@ export declare class FrameParser {
10
34
  * @param warningCollector - Used to collect decode issue
11
35
  */
12
36
  constructor(major: ID3v2MajorVersion, warningCollector: IWarningCollector);
13
- readData(uint8Array: Uint8Array, type: string, includeCovers: boolean): any;
37
+ readData(uint8Array: Uint8Array, type: string, includeCovers: boolean): unknown;
14
38
  protected static readNullTerminatedString(uint8Array: Uint8Array, encoding: ITextEncoding): {
15
39
  text: string;
16
40
  len: number;
@@ -33,3 +57,4 @@ export declare class FrameParser {
33
57
  private static readIdentifierAndData;
34
58
  private static getNullTerminatorLength;
35
59
  }
60
+ export {};
@@ -1,7 +1,7 @@
1
1
  import initDebug from 'debug';
2
2
  import * as Token from 'token-types';
3
3
  import * as util from '../common/Util.js';
4
- import { AttachedPictureType, TextEncodingToken, SyncTextHeader, TextHeader } from './ID3v2Token.js';
4
+ import { AttachedPictureType, SyncTextHeader, TextEncodingToken, TextHeader } from './ID3v2Token.js';
5
5
  import { Genres } from '../id3v1/ID3v1Parser.js';
6
6
  const debug = initDebug('music-metadata:id3v2:frame-parser');
7
7
  const defaultEnc = 'latin1'; // latin1 == iso-8859-1;
@@ -39,9 +39,11 @@ export function parseGenre(origVal) {
39
39
  }
40
40
  if (word) {
41
41
  if (genres.length === 0 && word.match(/^\d*$/)) {
42
- word = Genres[word];
42
+ word = parseGenreCode(word);
43
+ }
44
+ if (word) {
45
+ genres.push(word);
43
46
  }
44
- genres.push(word);
45
47
  }
46
48
  return genres;
47
49
  }
@@ -51,7 +53,7 @@ function parseGenreCode(code) {
51
53
  if (code === 'CR')
52
54
  return 'Cover';
53
55
  if (code.match(/^\d*$/)) {
54
- return Genres[code];
56
+ return Genres[Number.parseInt(code)];
55
57
  }
56
58
  }
57
59
  export class FrameParser {
@@ -83,20 +85,23 @@ export class FrameParser {
83
85
  case 'MVIN':
84
86
  case 'MVNM':
85
87
  case 'PCS':
86
- case 'PCST':
88
+ case 'PCST': {
87
89
  let text;
88
90
  try {
89
91
  text = util.decodeString(uint8Array.slice(1), encoding).replace(/\x00+$/, '');
90
92
  }
91
93
  catch (error) {
92
- this.warningCollector.addWarning(`id3v2.${this.major} type=${type} header has invalid string value: ${error.message}`);
94
+ if (error instanceof Error) {
95
+ this.warningCollector.addWarning(`id3v2.${this.major} type=${type} header has invalid string value: ${error.message}`);
96
+ break;
97
+ }
98
+ throw error;
93
99
  }
94
100
  switch (type) {
95
101
  case 'TMCL': // Musician credits list
96
102
  case 'TIPL': // Involved people list
97
103
  case 'IPLS': // Involved people list
98
- output = this.splitValue(type, text);
99
- output = FrameParser.functionList(output);
104
+ output = FrameParser.functionList(this.splitValue(type, text));
100
105
  break;
101
106
  case 'TRK':
102
107
  case 'TRCK':
@@ -126,13 +131,16 @@ export class FrameParser {
126
131
  output = this.major >= 4 ? this.splitValue(type, text) : [text];
127
132
  }
128
133
  break;
129
- case 'TXXX':
130
- output = FrameParser.readIdentifierAndData(uint8Array, offset + 1, length, encoding);
131
- output = {
132
- description: output.id,
133
- text: this.splitValue(type, util.decodeString(output.data, encoding).replace(/\x00+$/, ''))
134
+ }
135
+ case 'TXXX': {
136
+ const idAndData = FrameParser.readIdentifierAndData(uint8Array, offset + 1, length, encoding);
137
+ const textTag = {
138
+ description: idAndData.id,
139
+ text: this.splitValue(type, util.decodeString(idAndData.data, encoding).replace(/\x00+$/, ''))
134
140
  };
141
+ output = textTag;
135
142
  break;
143
+ }
136
144
  case 'PIC':
137
145
  case 'APIC':
138
146
  if (includeCovers) {
@@ -150,7 +158,7 @@ export class FrameParser {
150
158
  offset = fzero + 1;
151
159
  break;
152
160
  default:
153
- throw new Error('Warning: unexpected major versionIndex: ' + this.major);
161
+ throw new Error(`Warning: unexpected major versionIndex: ${this.major}`);
154
162
  }
155
163
  pic.format = FrameParser.fixPictureMimeType(pic.format);
156
164
  pic.type = AttachedPictureType[uint8Array[offset]];
@@ -166,7 +174,7 @@ export class FrameParser {
166
174
  case 'PCNT':
167
175
  output = Token.UINT32_BE.get(uint8Array, 0);
168
176
  break;
169
- case 'SYLT':
177
+ case 'SYLT': {
170
178
  const syltHeader = SyncTextHeader.get(uint8Array, 0);
171
179
  offset += SyncTextHeader.len;
172
180
  const result = {
@@ -195,10 +203,11 @@ export class FrameParser {
195
203
  }
196
204
  output = result;
197
205
  break;
206
+ }
198
207
  case 'ULT':
199
208
  case 'USLT':
200
209
  case 'COM':
201
- case 'COMM':
210
+ case 'COMM': {
202
211
  const textHeader = TextHeader.get(uint8Array, offset);
203
212
  offset += TextHeader.len;
204
213
  const descriptorStr = FrameParser.readNullTerminatedString(uint8Array.subarray(offset), textHeader.encoding);
@@ -211,15 +220,18 @@ export class FrameParser {
211
220
  };
212
221
  output = comment;
213
222
  break;
214
- case 'UFID':
215
- output = FrameParser.readIdentifierAndData(uint8Array, offset, length, defaultEnc);
216
- output = { owner_identifier: output.id, identifier: output.data };
223
+ }
224
+ case 'UFID': {
225
+ const ufid = FrameParser.readIdentifierAndData(uint8Array, offset, length, defaultEnc);
226
+ output = { owner_identifier: ufid.id, identifier: ufid.data };
217
227
  break;
218
- case 'PRIV': // private frame
219
- output = FrameParser.readIdentifierAndData(uint8Array, offset, length, defaultEnc);
220
- output = { owner_identifier: output.id, data: output.data };
228
+ }
229
+ case 'PRIV': { // private frame
230
+ const priv = FrameParser.readIdentifierAndData(uint8Array, offset, length, defaultEnc);
231
+ output = { owner_identifier: priv.id, data: priv.data };
221
232
  break;
222
- case 'POPM': // Popularimeter
233
+ }
234
+ case 'POPM': { // Popularimeter
223
235
  fzero = util.findZero(uint8Array, offset, length, defaultEnc);
224
236
  const email = util.decodeString(uint8Array.slice(offset, fzero), defaultEnc);
225
237
  offset = fzero + 1;
@@ -230,6 +242,7 @@ export class FrameParser {
230
242
  counter: dataLen >= 5 ? Token.UINT32_BE.get(uint8Array, offset + 1) : undefined
231
243
  };
232
244
  break;
245
+ }
233
246
  case 'GEOB': { // General encapsulated object
234
247
  fzero = util.findZero(uint8Array, offset + 1, length, encoding);
235
248
  const mimeType = util.decodeString(uint8Array.slice(offset + 1, fzero), defaultEnc);
@@ -239,12 +252,13 @@ export class FrameParser {
239
252
  offset = fzero + 1;
240
253
  fzero = util.findZero(uint8Array, offset, length - offset, encoding);
241
254
  const description = util.decodeString(uint8Array.slice(offset, fzero), defaultEnc);
242
- output = {
255
+ const geob = {
243
256
  type: mimeType,
244
257
  filename,
245
258
  description,
246
259
  data: uint8Array.slice(offset + 1, length)
247
260
  };
261
+ output = geob;
248
262
  break;
249
263
  }
250
264
  // W-Frames:
@@ -257,6 +271,7 @@ export class FrameParser {
257
271
  case 'WPAY':
258
272
  case 'WPUB':
259
273
  // Decode URL
274
+ fzero = util.findZero(uint8Array, offset + 1, length, encoding);
260
275
  output = util.decodeString(uint8Array.slice(offset, fzero), defaultEnc);
261
276
  break;
262
277
  case 'WXXX': {
@@ -277,15 +292,21 @@ export class FrameParser {
277
292
  break;
278
293
  }
279
294
  default:
280
- debug('Warning: unsupported id3v2-tag-type: ' + type);
295
+ debug(`Warning: unsupported id3v2-tag-type: ${type}`);
281
296
  break;
282
297
  }
283
298
  return output;
284
299
  }
285
300
  static readNullTerminatedString(uint8Array, encoding) {
286
301
  let offset = encoding.bom ? 2 : 0;
287
- const txt = uint8Array.slice(offset, offset = util.findZero(uint8Array, offset, uint8Array.length, encoding.encoding));
288
- offset += encoding.encoding === 'utf-16le' ? 2 : 1;
302
+ const zeroIndex = util.findZero(uint8Array, offset, uint8Array.length, encoding.encoding);
303
+ const txt = uint8Array.slice(offset, zeroIndex);
304
+ if (encoding.encoding === 'utf-16le') {
305
+ offset = zeroIndex + 2;
306
+ }
307
+ else {
308
+ offset = zeroIndex + 1;
309
+ }
289
310
  return {
290
311
  text: util.decodeString(txt, encoding.encoding),
291
312
  len: offset
@@ -309,7 +330,7 @@ export class FrameParser {
309
330
  const res = {};
310
331
  for (let i = 0; i + 1 < entries.length; i += 2) {
311
332
  const names = entries[i + 1].split(',');
312
- res[entries[i]] = res.hasOwnProperty(entries[i]) ? res[entries[i]].concat(names) : names;
333
+ res[entries[i]] = res[entries[i]] ? res[entries[i]].concat(names) : names;
313
334
  }
314
335
  return res;
315
336
  }
@@ -349,3 +370,4 @@ export class FrameParser {
349
370
  return enc === 'utf-16le' ? 2 : 1;
350
371
  }
351
372
  }
373
+ //# sourceMappingURL=FrameParser.js.map
@@ -1,4 +1,4 @@
1
- import { INativeTagMap } from '../common/GenericTagTypes.js';
1
+ import type { INativeTagMap } from '../common/GenericTagTypes.js';
2
2
  import { CaseInsensitiveTagMap } from '../common/CaseInsensitiveTagMap.js';
3
3
  /**
4
4
  * ID3v2.2 tag mappings
@@ -1,8 +1,9 @@
1
1
  import { CaseInsensitiveTagMap } from '../common/CaseInsensitiveTagMap.js';
2
2
  import type { INativeMetadataCollector } from '../common/MetadataCollector.js';
3
3
  import type { IRating, ITag } from '../type.js';
4
+ import type { IPopularimeter } from './FrameParser.js';
4
5
  export declare class ID3v24TagMapper extends CaseInsensitiveTagMap {
5
- static toRating(popm: any): IRating;
6
+ static toRating(popm: IPopularimeter): IRating;
6
7
  constructor();
7
8
  /**
8
9
  * Handle post mapping exceptions / correction
@@ -156,25 +156,32 @@ export class ID3v24TagMapper extends CaseInsensitiveTagMap {
156
156
  */
157
157
  postMap(tag, warnings) {
158
158
  switch (tag.id) {
159
- case 'UFID': // decode MusicBrainz Recording Id
160
- if (tag.value.owner_identifier === 'http://musicbrainz.org') {
161
- tag.id += ':' + tag.value.owner_identifier;
162
- tag.value = decodeString(tag.value.identifier, 'latin1'); // latin1 == iso-8859-1
159
+ case 'UFID':
160
+ {
161
+ // decode MusicBrainz Recording Id
162
+ const idTag = tag.value;
163
+ if (idTag.owner_identifier === 'http://musicbrainz.org') {
164
+ tag.id += `:${idTag.owner_identifier}`;
165
+ tag.value = decodeString(idTag.identifier, 'latin1'); // latin1 == iso-8859-1
166
+ }
163
167
  }
164
168
  break;
165
169
  case 'PRIV':
166
- switch (tag.value.owner_identifier) {
167
- // decode Windows Media Player
168
- case 'AverageLevel':
169
- case 'PeakValue':
170
- tag.id += ':' + tag.value.owner_identifier;
171
- tag.value = tag.value.data.length === 4 ? UINT32_LE.get(tag.value.data, 0) : null;
172
- if (tag.value === null) {
173
- warnings.addWarning(`Failed to parse PRIV:PeakValue`);
174
- }
175
- break;
176
- default:
177
- warnings.addWarning(`Unknown PRIV owner-identifier: ${tag.value.owner_identifier}`);
170
+ {
171
+ const customTag = tag.value;
172
+ switch (customTag.owner_identifier) {
173
+ // decode Windows Media Player
174
+ case 'AverageLevel':
175
+ case 'PeakValue':
176
+ tag.id += `:${customTag.owner_identifier}`;
177
+ tag.value = customTag.data.length === 4 ? UINT32_LE.get(customTag.data, 0) : null;
178
+ if (tag.value === null) {
179
+ warnings.addWarning('Failed to parse PRIV:PeakValue');
180
+ }
181
+ break;
182
+ default:
183
+ warnings.addWarning(`Unknown PRIV owner-identifier: ${customTag.data}`);
184
+ }
178
185
  }
179
186
  break;
180
187
  case 'POPM':
@@ -1,6 +1,6 @@
1
1
  import type { ITokenizer } from 'strtok3';
2
- import { IOptions } from '../type.js';
3
- import { INativeMetadataCollector } from '../common/MetadataCollector.js';
2
+ import type { IOptions } from '../type.js';
3
+ import type { INativeMetadataCollector } from '../common/MetadataCollector.js';
4
4
  export declare class ID3v2Parser {
5
5
  static removeUnsyncBytes(buffer: Uint8Array): Uint8Array;
6
6
  private static getFrameHeaderLength;
@@ -4,6 +4,13 @@ import { FrameParser } from './FrameParser.js';
4
4
  import { ExtendedHeader, ID3v2Header, UINT32SYNCSAFE } from './ID3v2Token.js';
5
5
  const asciiDecoder = new TextDecoder('ascii');
6
6
  export class ID3v2Parser {
7
+ constructor() {
8
+ this.tokenizer = undefined;
9
+ this.id3Header = undefined;
10
+ this.metadata = undefined;
11
+ this.headerType = undefined;
12
+ this.options = undefined;
13
+ }
7
14
  static removeUnsyncBytes(buffer) {
8
15
  let readI = 0;
9
16
  let writeI = 0;
@@ -47,21 +54,22 @@ export class ID3v2Parser {
47
54
  };
48
55
  }
49
56
  static readFrameData(uint8Array, frameHeader, majorVer, includeCovers, warningCollector) {
57
+ var _a, _b;
50
58
  const frameParser = new FrameParser(majorVer, warningCollector);
51
59
  switch (majorVer) {
52
60
  case 2:
53
61
  return frameParser.readData(uint8Array, frameHeader.id, includeCovers);
54
62
  case 3:
55
63
  case 4:
56
- if (frameHeader.flags.format.unsynchronisation) {
64
+ if ((_a = frameHeader.flags) === null || _a === void 0 ? void 0 : _a.format.unsynchronisation) {
57
65
  uint8Array = ID3v2Parser.removeUnsyncBytes(uint8Array);
58
66
  }
59
- if (frameHeader.flags.format.data_length_indicator) {
67
+ if ((_b = frameHeader.flags) === null || _b === void 0 ? void 0 : _b.format.data_length_indicator) {
60
68
  uint8Array = uint8Array.slice(4, uint8Array.length);
61
69
  }
62
70
  return frameParser.readData(uint8Array, frameHeader.id, includeCovers);
63
71
  default:
64
- throw new Error('Unexpected majorVer: ' + majorVer);
72
+ throw new Error(`Unexpected majorVer: ${majorVer}`);
65
73
  }
66
74
  }
67
75
  /**
@@ -71,7 +79,7 @@ export class ID3v2Parser {
71
79
  * @returns string e.g. COM:iTunPGAP
72
80
  */
73
81
  static makeDescriptionTagName(tag, description) {
74
- return tag + (description ? ':' + description : '');
82
+ return tag + (description ? `:${description}` : '');
75
83
  }
76
84
  async parse(metadata, tokenizer, options) {
77
85
  this.tokenizer = tokenizer;
@@ -82,7 +90,7 @@ export class ID3v2Parser {
82
90
  throw new Error('expected ID3-header file-identifier \'ID3\' was not found');
83
91
  }
84
92
  this.id3Header = id3Header;
85
- this.headerType = ('ID3v2.' + id3Header.version.major);
93
+ this.headerType = (`ID3v2.${id3Header.version.major}`);
86
94
  return id3Header.flags.isExtendedHeader ? this.parseExtendedHeader() : this.parseId3Data(id3Header.size);
87
95
  }
88
96
  async parseExtendedHeader() {
@@ -125,9 +133,11 @@ export class ID3v2Parser {
125
133
  this.metadata.addWarning('Illegal ID3v2 tag length');
126
134
  break;
127
135
  }
128
- const frameHeaderBytes = data.slice(offset, offset += frameHeaderLength);
136
+ const frameHeaderBytes = data.slice(offset, offset + frameHeaderLength);
137
+ offset += frameHeaderLength;
129
138
  const frameHeader = this.readFrameHeader(frameHeaderBytes, this.id3Header.version.major);
130
- const frameDataBytes = data.slice(offset, offset += frameHeader.length);
139
+ const frameDataBytes = data.slice(offset, offset + frameHeader.length);
140
+ offset += frameHeader.length;
131
141
  const values = ID3v2Parser.readFrameData(frameDataBytes, frameHeader, this.id3Header.version.major, !this.options.skipCovers, this.metadata);
132
142
  if (values) {
133
143
  tags.push({ id: frameHeader.id, value: values });
@@ -159,8 +169,9 @@ export class ID3v2Parser {
159
169
  }
160
170
  break;
161
171
  default:
162
- throw new Error('Unexpected majorVer: ' + majorVer);
172
+ throw new Error(`Unexpected majorVer: ${majorVer}`);
163
173
  }
164
174
  return header;
165
175
  }
166
176
  }
177
+ //# sourceMappingURL=ID3v2Parser.js.map
package/lib/iff/index.js CHANGED
@@ -14,3 +14,4 @@ export const Header = {
14
14
  };
15
15
  }
16
16
  };
17
+ //# sourceMappingURL=index.js.map
package/lib/index.d.ts CHANGED
@@ -1,11 +1,10 @@
1
1
  /**
2
2
  * Node.js specific entry point.
3
3
  */
4
- import * as Stream from 'stream';
5
- import * as strtok3 from 'strtok3';
6
- import { IAudioMetadata, IOptions } from './type.js';
7
- export { IAudioMetadata, IOptions, ITag, INativeTagDict, ICommonTagsResult, IFormat, IPicture, IRatio, IChapter, ILyricsTag, LyricsContentType, TimestampFormat } from './type.js';
8
- export { parseFromTokenizer, parseBuffer, parseBlob, parseWebStream, selectCover, orderTags, ratingToStars, IFileInfo } from './core.js';
4
+ import type { Readable } from 'node:stream';
5
+ import { type IFileInfo } from 'strtok3';
6
+ import type { IAudioMetadata, IOptions } from './type.js';
7
+ export * from './core.js';
9
8
  /**
10
9
  * Parse audio from Node Stream.Readable
11
10
  * @param stream - Stream to read the audio track from
@@ -13,7 +12,7 @@ export { parseFromTokenizer, parseBuffer, parseBlob, parseWebStream, selectCover
13
12
  * @param options - Parsing options
14
13
  * @returns Metadata
15
14
  */
16
- export declare function parseStream(stream: Stream.Readable, fileInfo?: strtok3.IFileInfo | string, options?: IOptions): Promise<IAudioMetadata>;
15
+ export declare function parseStream(stream: Readable, fileInfo?: IFileInfo | string, options?: IOptions): Promise<IAudioMetadata>;
17
16
  /**
18
17
  * Parse audio from Node file
19
18
  * @param filePath - Media file to read meta-data from