music-metadata 10.1.0 → 10.3.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 (63) hide show
  1. package/README.md +465 -141
  2. package/lib/ParseError.d.ts +87 -0
  3. package/lib/ParseError.js +39 -0
  4. package/lib/ParserFactory.d.ts +1 -1
  5. package/lib/ParserFactory.js +9 -8
  6. package/lib/aiff/AiffParser.js +6 -7
  7. package/lib/aiff/AiffToken.d.ts +15 -0
  8. package/lib/aiff/AiffToken.js +5 -2
  9. package/lib/apev2/APEv2Parser.d.ts +15 -0
  10. package/lib/apev2/APEv2Parser.js +6 -3
  11. package/lib/asf/AsfObject.d.ts +15 -0
  12. package/lib/asf/AsfObject.js +4 -1
  13. package/lib/asf/AsfParser.js +2 -1
  14. package/lib/common/CombinedTagMapper.js +2 -1
  15. package/lib/common/FourCC.js +3 -2
  16. package/lib/common/MetadataCollector.js +2 -4
  17. package/lib/common/Util.js +3 -2
  18. package/lib/core.d.ts +2 -1
  19. package/lib/core.js +1 -1
  20. package/lib/default.cjs +5 -0
  21. package/lib/dsdiff/DsdiffParser.d.ts +15 -0
  22. package/lib/dsdiff/DsdiffParser.js +6 -3
  23. package/lib/dsf/DsfParser.d.ts +15 -0
  24. package/lib/dsf/DsfParser.js +4 -1
  25. package/lib/ebml/EbmlIterator.d.ts +67 -0
  26. package/lib/ebml/EbmlIterator.js +223 -0
  27. package/lib/ebml/types.d.ts +36 -0
  28. package/lib/ebml/types.js +10 -0
  29. package/lib/flac/FlacParser.js +5 -2
  30. package/lib/id3v2/FrameParser.d.ts +14 -0
  31. package/lib/id3v2/FrameParser.js +7 -1
  32. package/lib/id3v2/ID3v2Parser.js +10 -8
  33. package/lib/matroska/MatroskaDtd.d.ts +2 -2
  34. package/lib/matroska/MatroskaDtd.js +246 -239
  35. package/lib/matroska/MatroskaParser.d.ts +8 -22
  36. package/lib/matroska/MatroskaParser.js +119 -204
  37. package/lib/matroska/types.d.ts +8 -44
  38. package/lib/matroska/types.js +0 -9
  39. package/lib/mp4/AtomToken.d.ts +14 -0
  40. package/lib/mp4/AtomToken.js +6 -3
  41. package/lib/mp4/MP4Parser.js +4 -3
  42. package/lib/mpeg/MpegParser.d.ts +15 -0
  43. package/lib/mpeg/MpegParser.js +7 -4
  44. package/lib/musepack/MusepackConentError.d.ts +15 -0
  45. package/lib/musepack/MusepackConentError.js +4 -0
  46. package/lib/musepack/index.js +4 -3
  47. package/lib/musepack/sv7/MpcSv7Parser.js +2 -1
  48. package/lib/musepack/sv8/MpcSv8Parser.js +3 -2
  49. package/lib/node.cjs +5 -0
  50. package/lib/ogg/OggParser.d.ts +15 -0
  51. package/lib/ogg/OggParser.js +5 -2
  52. package/lib/ogg/opus/Opus.d.ts +15 -0
  53. package/lib/ogg/opus/Opus.js +4 -1
  54. package/lib/ogg/opus/OpusParser.js +2 -1
  55. package/lib/ogg/vorbis/VorbisParser.d.ts +15 -0
  56. package/lib/ogg/vorbis/VorbisParser.js +6 -3
  57. package/lib/type.d.ts +9 -0
  58. package/lib/wav/WaveChunk.d.ts +15 -0
  59. package/lib/wav/WaveChunk.js +5 -2
  60. package/lib/wav/WaveParser.js +3 -2
  61. package/lib/wavpack/WavPackParser.d.ts +15 -0
  62. package/lib/wavpack/WavPackParser.js +6 -3
  63. package/package.json +20 -11
@@ -2,7 +2,10 @@ import initDebug from 'debug';
2
2
  import { AbstractID3Parser } from '../id3v2/AbstractID3Parser.js';
3
3
  import { ChunkHeader, DsdChunk, FormatChunk } from './DsfChunk.js';
4
4
  import { ID3v2Parser } from "../id3v2/ID3v2Parser.js";
5
+ import { makeUnexpectedFileContentError } from '../ParseError.js';
5
6
  const debug = initDebug('music-metadata:parser:DSF');
7
+ export class DsdContentParseError extends makeUnexpectedFileContentError('DSD') {
8
+ }
6
9
  /**
7
10
  * DSF (dsd stream file) File Parser
8
11
  * Ref: https://dsd-guide.com/sites/default/files/white-papers/DSFFileFormatSpec_E.pdf
@@ -12,7 +15,7 @@ export class DsfParser extends AbstractID3Parser {
12
15
  const p0 = this.tokenizer.position; // mark start position, normally 0
13
16
  const chunkHeader = await this.tokenizer.readToken(ChunkHeader);
14
17
  if (chunkHeader.id !== 'DSD ')
15
- throw new Error('Invalid chunk signature');
18
+ throw new DsdContentParseError('Invalid chunk signature');
16
19
  this.metadata.setFormat('container', 'DSF');
17
20
  this.metadata.setFormat('lossless', true);
18
21
  const dsdChunk = await this.tokenizer.readToken(DsdChunk);
@@ -0,0 +1,67 @@
1
+ import { type ITokenizer } from 'strtok3';
2
+ import { type IElementType, type ITree, type ValueType } from './types.js';
3
+ declare const EbmlContentError_base: {
4
+ new (message: string): {
5
+ readonly fileType: string;
6
+ toString(): string;
7
+ name: "UnexpectedFileContentError";
8
+ message: string;
9
+ stack?: string;
10
+ };
11
+ captureStackTrace(targetObject: object, constructorOpt?: Function): void;
12
+ prepareStackTrace?: ((err: Error, stackTraces: NodeJS.CallSite[]) => any) | undefined;
13
+ stackTraceLimit: number;
14
+ };
15
+ export declare class EbmlContentError extends EbmlContentError_base {
16
+ }
17
+ export interface ILinkedElementType extends IElementType {
18
+ id: number;
19
+ parent: ILinkedElementType | undefined;
20
+ readonly container?: {
21
+ [id: number]: ILinkedElementType;
22
+ };
23
+ }
24
+ export declare enum ParseAction {
25
+ ReadNext = 0,// Continue reading the next elements
26
+ IgnoreElement = 2,// Ignore (do not read) this element
27
+ SkipSiblings = 3,// Skip all remaining elements at the same level
28
+ TerminateParsing = 4,// Terminate the parsing process
29
+ SkipElement = 5
30
+ }
31
+ /**
32
+ * @return true, to quit the parser
33
+ */
34
+ export type IElementListener = {
35
+ startNext: (dtdElement: ILinkedElementType) => ParseAction;
36
+ elementValue: (dtdElement: ILinkedElementType, value: ValueType, offset: number) => Promise<void>;
37
+ };
38
+ /**
39
+ * Extensible Binary Meta Language (EBML) iterator
40
+ * https://en.wikipedia.org/wiki/Extensible_Binary_Meta_Language
41
+ * http://matroska.sourceforge.net/technical/specs/rfc/index.html
42
+ *
43
+ * WEBM VP8 AUDIO FILE
44
+ */
45
+ export declare class EbmlIterator {
46
+ private tokenizer;
47
+ private padding;
48
+ private parserMap;
49
+ private ebmlMaxIDLength;
50
+ private ebmlMaxSizeLength;
51
+ /**
52
+ * @param {ITokenizer} tokenizer Input
53
+ * @param tokenizer
54
+ */
55
+ constructor(tokenizer: ITokenizer);
56
+ iterate(dtdElement: IElementType, posDone: number, listener: IElementListener): Promise<ITree>;
57
+ private parseContainer;
58
+ private readVintData;
59
+ private readElement;
60
+ private readFloat;
61
+ private readFlag;
62
+ private readUint;
63
+ private readString;
64
+ private readBuffer;
65
+ }
66
+ export declare function getElementPath(element: ILinkedElementType): string;
67
+ export {};
@@ -0,0 +1,223 @@
1
+ import { Float32_BE, Float64_BE, StringType, UINT8 } from 'token-types';
2
+ import initDebug from 'debug';
3
+ import { EndOfStreamError } from 'strtok3';
4
+ import { DataType } from './types.js';
5
+ import * as Token from 'token-types';
6
+ import { makeUnexpectedFileContentError } from '../ParseError.js';
7
+ const debug = initDebug('music-metadata:parser:ebml');
8
+ export class EbmlContentError extends makeUnexpectedFileContentError('EBML') {
9
+ }
10
+ export var ParseAction;
11
+ (function (ParseAction) {
12
+ ParseAction[ParseAction["ReadNext"] = 0] = "ReadNext";
13
+ ParseAction[ParseAction["IgnoreElement"] = 2] = "IgnoreElement";
14
+ ParseAction[ParseAction["SkipSiblings"] = 3] = "SkipSiblings";
15
+ ParseAction[ParseAction["TerminateParsing"] = 4] = "TerminateParsing";
16
+ ParseAction[ParseAction["SkipElement"] = 5] = "SkipElement"; // Consider the element has read, assume position is at the next element
17
+ })(ParseAction || (ParseAction = {}));
18
+ /**
19
+ * Extensible Binary Meta Language (EBML) iterator
20
+ * https://en.wikipedia.org/wiki/Extensible_Binary_Meta_Language
21
+ * http://matroska.sourceforge.net/technical/specs/rfc/index.html
22
+ *
23
+ * WEBM VP8 AUDIO FILE
24
+ */
25
+ export class EbmlIterator {
26
+ /**
27
+ * @param {ITokenizer} tokenizer Input
28
+ * @param tokenizer
29
+ */
30
+ constructor(tokenizer) {
31
+ this.tokenizer = tokenizer;
32
+ this.padding = 0;
33
+ this.parserMap = new Map();
34
+ this.ebmlMaxIDLength = 4;
35
+ this.ebmlMaxSizeLength = 8;
36
+ this.parserMap.set(DataType.uint, e => this.readUint(e));
37
+ this.parserMap.set(DataType.string, e => this.readString(e));
38
+ this.parserMap.set(DataType.binary, e => this.readBuffer(e));
39
+ this.parserMap.set(DataType.uid, async (e) => this.readBuffer(e));
40
+ this.parserMap.set(DataType.bool, e => this.readFlag(e));
41
+ this.parserMap.set(DataType.float, e => this.readFloat(e));
42
+ }
43
+ async iterate(dtdElement, posDone, listener) {
44
+ return this.parseContainer(linkParents(dtdElement), posDone, listener);
45
+ }
46
+ async parseContainer(dtdElement, posDone, listener) {
47
+ const tree = {};
48
+ while (this.tokenizer.position < posDone) {
49
+ let element;
50
+ const elementPosition = this.tokenizer.position;
51
+ try {
52
+ element = await this.readElement();
53
+ }
54
+ catch (error) {
55
+ if (error instanceof EndOfStreamError) {
56
+ break;
57
+ }
58
+ throw error;
59
+ }
60
+ const child = dtdElement.container[element.id];
61
+ if (child) {
62
+ const action = listener.startNext(child);
63
+ switch (action) {
64
+ case ParseAction.ReadNext:
65
+ {
66
+ if (element.id === 0x1F43B675) {
67
+ // Hack to ignore remaining segment, when cluster element received
68
+ // await this.tokenizer.ignore(posDone - this.tokenizer.position);
69
+ // break;
70
+ }
71
+ debug(`Read element: name=${getElementPath(child)}{id=0x${element.id.toString(16)}, container=${!!child.container}} at position=${elementPosition}`);
72
+ if (child.container) {
73
+ const res = await this.parseContainer(child, element.len >= 0 ? this.tokenizer.position + element.len : -1, listener);
74
+ if (child.multiple) {
75
+ if (!tree[child.name]) {
76
+ tree[child.name] = [];
77
+ }
78
+ tree[child.name].push(res);
79
+ }
80
+ else {
81
+ tree[child.name] = res;
82
+ }
83
+ await listener.elementValue(child, res, elementPosition);
84
+ }
85
+ else {
86
+ const parser = this.parserMap.get(child.value);
87
+ if (typeof parser === 'function') {
88
+ const value = await parser(element);
89
+ tree[child.name] = value;
90
+ await listener.elementValue(child, value, elementPosition);
91
+ }
92
+ }
93
+ }
94
+ break;
95
+ case ParseAction.SkipElement:
96
+ debug(`Go to next element: name=${getElementPath(child)}, element.id=0x${element.id}, container=${!!child.container} at position=${elementPosition}`);
97
+ break;
98
+ case ParseAction.IgnoreElement:
99
+ debug(`Ignore element: name=${getElementPath(child)}, element.id=0x${element.id}, container=${!!child.container} at position=${elementPosition}`);
100
+ await this.tokenizer.ignore(element.len);
101
+ break;
102
+ case ParseAction.SkipSiblings:
103
+ debug(`Ignore remaining container, at: name=${getElementPath(child)}, element.id=0x${element.id}, container=${!!child.container} at position=${elementPosition}`);
104
+ await this.tokenizer.ignore(posDone - this.tokenizer.position);
105
+ break;
106
+ case ParseAction.TerminateParsing:
107
+ debug(`Terminate parsing at element: name=${getElementPath(child)}, element.id=0x${element.id}, container=${!!child.container} at position=${elementPosition}`);
108
+ return tree;
109
+ }
110
+ }
111
+ else {
112
+ switch (element.id) {
113
+ case 0xec: // void
114
+ this.padding += element.len;
115
+ await this.tokenizer.ignore(element.len);
116
+ break;
117
+ default:
118
+ debug(`parseEbml: parent=${getElementPath(dtdElement)}, unknown child: id=${element.id.toString(16)} at position=${elementPosition}`);
119
+ this.padding += element.len;
120
+ await this.tokenizer.ignore(element.len);
121
+ }
122
+ }
123
+ }
124
+ return tree;
125
+ }
126
+ async readVintData(maxLength) {
127
+ const msb = await this.tokenizer.peekNumber(UINT8);
128
+ let mask = 0x80;
129
+ let oc = 1;
130
+ // Calculate VINT_WIDTH
131
+ while ((msb & mask) === 0) {
132
+ if (oc > maxLength) {
133
+ throw new EbmlContentError('VINT value exceeding maximum size');
134
+ }
135
+ ++oc;
136
+ mask >>= 1;
137
+ }
138
+ const id = new Uint8Array(oc);
139
+ await this.tokenizer.readBuffer(id);
140
+ return id;
141
+ }
142
+ async readElement() {
143
+ const id = await this.readVintData(this.ebmlMaxIDLength);
144
+ const lenField = await this.readVintData(this.ebmlMaxSizeLength);
145
+ lenField[0] ^= 0x80 >> (lenField.length - 1);
146
+ return {
147
+ id: readUIntBE(id, id.length),
148
+ len: readUIntBE(lenField, lenField.length)
149
+ };
150
+ }
151
+ async readFloat(e) {
152
+ switch (e.len) {
153
+ case 0:
154
+ return 0.0;
155
+ case 4:
156
+ return this.tokenizer.readNumber(Float32_BE);
157
+ case 8:
158
+ return this.tokenizer.readNumber(Float64_BE);
159
+ case 10:
160
+ return this.tokenizer.readNumber(Float64_BE);
161
+ default:
162
+ throw new EbmlContentError(`Invalid IEEE-754 float length: ${e.len}`);
163
+ }
164
+ }
165
+ async readFlag(e) {
166
+ return (await this.readUint(e)) === 1;
167
+ }
168
+ async readUint(e) {
169
+ const buf = await this.readBuffer(e);
170
+ return readUIntBE(buf, e.len);
171
+ }
172
+ async readString(e) {
173
+ const rawString = await this.tokenizer.readToken(new StringType(e.len, 'utf-8'));
174
+ return rawString.replace(/\x00.*$/g, '');
175
+ }
176
+ async readBuffer(e) {
177
+ const buf = new Uint8Array(e.len);
178
+ await this.tokenizer.readBuffer(buf);
179
+ return buf;
180
+ }
181
+ }
182
+ function readUIntBE(buf, len) {
183
+ return Number(readUIntBeAsBigInt(buf, len));
184
+ }
185
+ /**
186
+ * Reeds an unsigned integer from a big endian buffer of length `len`
187
+ * @param buf Buffer to decode from
188
+ * @param len Number of bytes
189
+ * @private
190
+ */
191
+ function readUIntBeAsBigInt(buf, len) {
192
+ const normalizedNumber = new Uint8Array(8);
193
+ const cleanNumber = buf.subarray(0, len);
194
+ try {
195
+ normalizedNumber.set(cleanNumber, 8 - len);
196
+ return Token.UINT64_BE.get(normalizedNumber, 0);
197
+ }
198
+ catch (error) {
199
+ return BigInt(-1);
200
+ }
201
+ }
202
+ function linkParents(element) {
203
+ if (element.container) {
204
+ Object.keys(element.container)
205
+ .map(id => {
206
+ const child = element.container[id];
207
+ child.id = Number.parseInt(id);
208
+ return child;
209
+ }).forEach(child => {
210
+ child.parent = element;
211
+ linkParents(child);
212
+ });
213
+ }
214
+ return element;
215
+ }
216
+ export function getElementPath(element) {
217
+ let path = '';
218
+ if (element.parent && element.parent.name !== 'dtd') {
219
+ path += `${getElementPath(element.parent)}/`;
220
+ }
221
+ return path + element.name;
222
+ }
223
+ //# sourceMappingURL=EbmlIterator.js.map
@@ -0,0 +1,36 @@
1
+ export interface ITree {
2
+ [name: string]: string | number | boolean | Uint8Array | ITree | ITree[];
3
+ }
4
+ export declare enum DataType {
5
+ 'string' = 0,
6
+ uint = 1,
7
+ uid = 2,
8
+ bool = 3,
9
+ binary = 4,
10
+ float = 5
11
+ }
12
+ export type ValueType = string | number | Uint8Array | boolean | ITree | ITree[];
13
+ export interface IHeader {
14
+ id: number;
15
+ len: number;
16
+ }
17
+ export interface IEbmlElements {
18
+ version?: number;
19
+ readVersion?: number;
20
+ maxIDWidth?: number;
21
+ maxSizeWidth?: number;
22
+ docType?: string;
23
+ docTypeVersion?: number;
24
+ docTypeReadVersion?: number;
25
+ }
26
+ export interface IElementType {
27
+ readonly name: string;
28
+ readonly value?: DataType;
29
+ readonly container?: {
30
+ [id: number]: IElementType;
31
+ };
32
+ readonly multiple?: boolean;
33
+ }
34
+ export interface IEbmlDoc {
35
+ ebml: IEbmlElements;
36
+ }
@@ -0,0 +1,10 @@
1
+ export var DataType;
2
+ (function (DataType) {
3
+ DataType[DataType["string"] = 0] = "string";
4
+ DataType[DataType["uint"] = 1] = "uint";
5
+ DataType[DataType["uid"] = 2] = "uid";
6
+ DataType[DataType["bool"] = 3] = "bool";
7
+ DataType[DataType["binary"] = 4] = "binary";
8
+ DataType[DataType["float"] = 5] = "float";
9
+ })(DataType || (DataType = {}));
10
+ //# sourceMappingURL=types.js.map
@@ -6,7 +6,10 @@ import { AbstractID3Parser } from '../id3v2/AbstractID3Parser.js';
6
6
  import { FourCcToken } from '../common/FourCC.js';
7
7
  import { VorbisParser } from '../ogg/vorbis/VorbisParser.js';
8
8
  import { VorbisDecoder } from '../ogg/vorbis/VorbisDecoder.js';
9
+ import { makeUnexpectedFileContentError } from '../ParseError.js';
9
10
  const debug = initDebug('music-metadata:parser:FLAC');
11
+ class FlacContentError extends makeUnexpectedFileContentError('FLAC') {
12
+ }
10
13
  /**
11
14
  * FLAC supports up to 128 kinds of metadata blocks; currently the following are defined:
12
15
  * ref: https://xiph.org/flac/format.html#metadata_block
@@ -40,7 +43,7 @@ export class FlacParser extends AbstractID3Parser {
40
43
  async postId3v2Parse() {
41
44
  const fourCC = await this.tokenizer.readToken(FourCcToken);
42
45
  if (fourCC.toString() !== 'fLaC') {
43
- throw new Error('Invalid FLAC preamble');
46
+ throw new FlacContentError('Invalid FLAC preamble');
44
47
  }
45
48
  let blockHeader;
46
49
  do {
@@ -84,7 +87,7 @@ export class FlacParser extends AbstractID3Parser {
84
87
  */
85
88
  async parseBlockStreamInfo(dataLen) {
86
89
  if (dataLen !== BlockStreamInfo.len)
87
- throw new Error('Unexpected block-stream-info length');
90
+ throw new FlacContentError('Unexpected block-stream-info length');
88
91
  const streamInfo = await this.tokenizer.readToken(BlockStreamInfo);
89
92
  this.metadata.setFormat('container', 'FLAC');
90
93
  this.metadata.setFormat('codec', 'FLAC');
@@ -57,4 +57,18 @@ export declare class FrameParser {
57
57
  private static readIdentifierAndData;
58
58
  private static getNullTerminatorLength;
59
59
  }
60
+ declare const Id3v2ContentError_base: {
61
+ new (message: string): {
62
+ readonly fileType: string;
63
+ toString(): string;
64
+ name: "UnexpectedFileContentError";
65
+ message: string;
66
+ stack?: string;
67
+ };
68
+ captureStackTrace(targetObject: object, constructorOpt?: Function): void;
69
+ prepareStackTrace?: ((err: Error, stackTraces: NodeJS.CallSite[]) => any) | undefined;
70
+ stackTraceLimit: number;
71
+ };
72
+ export declare class Id3v2ContentError extends Id3v2ContentError_base {
73
+ }
60
74
  export {};
@@ -3,6 +3,7 @@ import * as Token from 'token-types';
3
3
  import * as util from '../common/Util.js';
4
4
  import { AttachedPictureType, SyncTextHeader, TextEncodingToken, TextHeader } from './ID3v2Token.js';
5
5
  import { Genres } from '../id3v1/ID3v1Parser.js';
6
+ import { makeUnexpectedFileContentError } from '../ParseError.js';
6
7
  const debug = initDebug('music-metadata:id3v2:frame-parser');
7
8
  const defaultEnc = 'latin1'; // latin1 == iso-8859-1;
8
9
  export function parseGenre(origVal) {
@@ -158,7 +159,7 @@ export class FrameParser {
158
159
  offset = fzero + 1;
159
160
  break;
160
161
  default:
161
- throw new Error(`Warning: unexpected major versionIndex: ${this.major}`);
162
+ throw makeUnexpectedMajorVersionError(this.major);
162
163
  }
163
164
  pic.format = FrameParser.fixPictureMimeType(pic.format);
164
165
  pic.type = AttachedPictureType[uint8Array[offset]];
@@ -370,4 +371,9 @@ export class FrameParser {
370
371
  return enc === 'utf-16le' ? 2 : 1;
371
372
  }
372
373
  }
374
+ export class Id3v2ContentError extends makeUnexpectedFileContentError('id3v2') {
375
+ }
376
+ function makeUnexpectedMajorVersionError(majorVer) {
377
+ throw new Id3v2ContentError(`Unexpected majorVer: ${majorVer}`);
378
+ }
373
379
  //# sourceMappingURL=FrameParser.js.map
@@ -1,6 +1,6 @@
1
1
  import * as Token from 'token-types';
2
2
  import * as util from '../common/Util.js';
3
- import { FrameParser } from './FrameParser.js';
3
+ import { FrameParser, Id3v2ContentError } from './FrameParser.js';
4
4
  import { ExtendedHeader, ID3v2Header, UINT32SYNCSAFE } from './ID3v2Token.js';
5
5
  const asciiDecoder = new TextDecoder('ascii');
6
6
  export class ID3v2Parser {
@@ -34,7 +34,7 @@ export class ID3v2Parser {
34
34
  case 4:
35
35
  return 10;
36
36
  default:
37
- throw new Error('header versionIndex is incorrect');
37
+ throw makeUnexpectedMajorVersionError(majorVer);
38
38
  }
39
39
  }
40
40
  static readFrameFlags(b) {
@@ -54,22 +54,21 @@ export class ID3v2Parser {
54
54
  };
55
55
  }
56
56
  static readFrameData(uint8Array, frameHeader, majorVer, includeCovers, warningCollector) {
57
- var _a, _b;
58
57
  const frameParser = new FrameParser(majorVer, warningCollector);
59
58
  switch (majorVer) {
60
59
  case 2:
61
60
  return frameParser.readData(uint8Array, frameHeader.id, includeCovers);
62
61
  case 3:
63
62
  case 4:
64
- if ((_a = frameHeader.flags) === null || _a === void 0 ? void 0 : _a.format.unsynchronisation) {
63
+ if (frameHeader.flags?.format.unsynchronisation) {
65
64
  uint8Array = ID3v2Parser.removeUnsyncBytes(uint8Array);
66
65
  }
67
- if ((_b = frameHeader.flags) === null || _b === void 0 ? void 0 : _b.format.data_length_indicator) {
66
+ if (frameHeader.flags?.format.data_length_indicator) {
68
67
  uint8Array = uint8Array.slice(4, uint8Array.length);
69
68
  }
70
69
  return frameParser.readData(uint8Array, frameHeader.id, includeCovers);
71
70
  default:
72
- throw new Error(`Unexpected majorVer: ${majorVer}`);
71
+ throw makeUnexpectedMajorVersionError(majorVer);
73
72
  }
74
73
  }
75
74
  /**
@@ -87,7 +86,7 @@ export class ID3v2Parser {
87
86
  this.options = options;
88
87
  const id3Header = await this.tokenizer.readToken(ID3v2Header);
89
88
  if (id3Header.fileIdentifier !== 'ID3') {
90
- throw new Error('expected ID3-header file-identifier \'ID3\' was not found');
89
+ throw new Id3v2ContentError('expected ID3-header file-identifier \'ID3\' was not found');
91
90
  }
92
91
  this.id3Header = id3Header;
93
92
  this.headerType = (`ID3v2.${id3Header.version.major}`);
@@ -169,9 +168,12 @@ export class ID3v2Parser {
169
168
  }
170
169
  break;
171
170
  default:
172
- throw new Error(`Unexpected majorVer: ${majorVer}`);
171
+ throw makeUnexpectedMajorVersionError(majorVer);
173
172
  }
174
173
  return header;
175
174
  }
176
175
  }
176
+ function makeUnexpectedMajorVersionError(majorVer) {
177
+ throw new Id3v2ContentError(`Unexpected majorVer: ${majorVer}`);
178
+ }
177
179
  //# sourceMappingURL=ID3v2Parser.js.map
@@ -1,8 +1,8 @@
1
- import { type IContainerType } from './types.js';
1
+ import { type IElementType } from '../ebml/types.js';
2
2
  /**
3
3
  * Elements of document type description
4
4
  * Derived from https://github.com/tungol/EBML/blob/master/doctypes/matroska.dtd
5
5
  * Extended with:
6
6
  * - https://www.matroska.org/technical/specs/index.html
7
7
  */
8
- export declare const elements: IContainerType;
8
+ export declare const matroskaDtd: IElementType;