music-metadata 10.1.0 → 10.2.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.
package/README.md CHANGED
@@ -11,15 +11,31 @@
11
11
 
12
12
  # music-metadata
13
13
 
14
- Stream and file based music metadata parser for [node.js](https://nodejs.org/) and browser projects.
15
- Supports any common audio and tagging format.
14
+ Key features:
15
+ * **Comprehensive Format Support**: Supports popular audio formats like MP3, MP4, FLAC, Ogg, WAV, AIFF, and more.
16
+ * **Extensive Metadata Extraction**: Extracts detailed metadata, including ID3v1, ID3v2, APE, Vorbis, and iTunes/MP4 tags.
17
+ * **Streaming Support**: Efficiently handles large audio files by reading metadata from streams, making it suitable for server-side and browser-based applications.
18
+ * **Promise-Based API**: Provides a modern, promise-based API for easy integration into asynchronous workflows.
19
+ * **Cross-Platform**: Works in both [Node.js](https://nodejs.org/) and browser environments with the help of bundlers like [Webpack](https://webpack.js.org/) or [Rollup](https://rollupjs.org/introduction/).
20
+
21
+ The [`music-metadata`](https://github.com/Borewit/music-metadata) module is ideal for developers working on media applications, music players, or any project that requires access to detailed audio file metadata.
16
22
 
17
23
  ## Compatibility
18
24
 
19
25
  Module: version 8 migrated from [CommonJS](https://en.wikipedia.org/wiki/CommonJS) to [pure ECMAScript Module (ESM)](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c).
20
- JavaScript is compliant with [ECMAScript 2019 (ES10)](https://en.wikipedia.org/wiki/ECMAScript#10th_Edition_%E2%80%93_ECMAScript_2019).
21
- Requires Node.js ≥ 16 engine.
22
- Primarily designed for [Node.js](https://nodejs.org/), but has also been designed for browser compatibility.
26
+ The distributed JavaScript codebase is compliant with the [ECMAScript 2020 (11th Edition)](https://en.wikipedia.org/wiki/ECMAScript_version_history#11th_Edition_%E2%80%93_ECMAScript_2020) standard.
27
+
28
+ This module requires a [Node.js ≥ 16](https://nodejs.org/en/about/previous-releases) engine.
29
+ It can also be used in a browser environment when bundled with a module bundler.
30
+
31
+ ## Sponsor
32
+ If you appreciate my work and want to support the development of open-source projects like [music-metadata](https://github.com/Borewit/music-metadata), [file-type](https://github.com/sindresorhus/file-type), and [listFix()](https://github.com/Borewit/listFix), consider becoming a sponsor or making a small contribution.
33
+ Your support helps sustain ongoing development and improvements.
34
+ [Become a sponsor to Borewit](https://github.com/sponsors/Borewit)
35
+
36
+ or
37
+
38
+ <a href="https://www.buymeacoffee.com/borewit" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/default-orange.png" alt="Buy me A coffee" height="41" width="174"></a>
23
39
 
24
40
  ## Features
25
41
 
@@ -81,11 +97,6 @@ Support for encoding / format details:
81
97
  - [<img src="https://cdn.sanity.io/images/3do82whm/next/ba8c847f13a5fa39d88f8bc9b7846b7886531b18-2500x2500.svg" width="40"> Webamp](https://webamp.org/)
82
98
 
83
99
 
84
- ### Sponsor
85
- [Become a sponsor to Borewit](https://github.com/sponsors/Borewit)
86
-
87
- <a href="https://www.buymeacoffee.com/borewit" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/default-orange.png" alt="Buy me A coffee" height="41" width="174"></a>
88
-
89
100
  ## Dependencies
90
101
 
91
102
  Dependency diagram:
@@ -192,7 +203,7 @@ An extension (e.g.: `.mp3`), filename or path will also work.
192
203
  If the MIME-type or filename (via `fileInfo.path`) is not provided, or not understood, music-metadata will try to derive the type from the content.
193
204
 
194
205
  ```ts
195
- parseStream(stream: Stream.Readable, fileInfo?: IFileInfo | string, opts?: IOptions = {}): Promise<IAudioMetadata>`
206
+ parseStream(stream: Stream.Readable, fileInfo?: IFileInfo | string, opts?: IOptions = {}): Promise<IAudioMetadata>
196
207
  ```
197
208
 
198
209
  Example:
@@ -327,7 +338,11 @@ import { parseFile, selectCover } from 'music-metadata';
327
338
  - `observer: (update: MetadataEvent) => void;`: Will be called after each change to `common` (generic) tag, or `format` properties.
328
339
  - `skipCovers`: default: `false`, if set to `true`, it will not return embedded cover-art (images).
329
340
  - `skipPostHeaders? boolean` default: `false`, if set to `true`, it will not search all the entire track for additional headers. Only recommenced to use in combination with streams.
330
- - `includeChapters` default: `false`, if set to `true`, it will parse chapters (currently only MP4 files). _experimental functionality_
341
+ - `mkvUseIndex` default: `false`, if set to `true`, in Matroska based files, use the _SeekHead_ element index to skip _segment/cluster_ elements..
342
+ _experimental functionality_
343
+ Can have a significant performance impact if enabled.
344
+ Possible side effect can be that certain metadata maybe skipped, depending on the index.
345
+ If there is no _SeekHead_ element present in the Matroska file, this flag has no effect.
331
346
 
332
347
  Although in most cases duration is included, in some cases it requires `music-metadata` parsing the entire file.
333
348
  To enforce parsing the entire file if needed you should set `duration` to `true`.
@@ -362,7 +377,7 @@ Audio format information. Defined in the TypeScript `IFormat` interface:
362
377
 
363
378
  #### `metadata.trackInfo`
364
379
 
365
- To support advanced containers like [Matroska](https://wikipedia.org/wiki/Matroska) or [MPEG-4](https://en.wikipedia.org/wiki/MPEG-4), which may contain multiple audio and video tracks, the **experimental*- `metadata.trackInfo` has been added,
380
+ To support advanced containers like [Matroska](https://wikipedia.org/wiki/Matroska) or [MPEG-4](https://en.wikipedia.org/wiki/MPEG-4), which may contain multiple audio and video tracks, the **experimental**- `metadata.trackInfo` has been added,
366
381
 
367
382
  `metadata.trackInfo` is either `undefined` or has an **array** of [trackInfo](#trackinfo)
368
383
 
@@ -483,29 +498,29 @@ img.src = `data:${picture.format};base64,${uint8ArrayToBase64(picture.data)}`;
483
498
 
484
499
  ```
485
500
 
486
- 2. Use async/await
501
+ 1. Use async/await
487
502
 
488
- Use [async/await](https://javascript.info/async-await)
503
+ Use [async/await](https://javascript.info/async-await)
489
504
 
490
- ```js
491
- import { parseFile } from 'music-metadata';
505
+ ```js
506
+ import { parseFile } from 'music-metadata';
492
507
 
493
- // it is required to declare the function 'async' to allow the use of await
494
- async function parseFiles(audioFiles) {
508
+ // it is required to declare the function 'async' to allow the use of await
509
+ async function parseFiles(audioFiles) {
495
510
 
496
- for (const audioFile of audioFiles) {
511
+ for (const audioFile of audioFiles) {
497
512
 
498
- // await will ensure the metadata parsing is completed before we move on to the next file
499
- const metadata = await parseFile(audioFile);
500
- // Do great things with the metadata
501
- }
502
- }
503
- ```
513
+ // await will ensure the metadata parsing is completed before we move on to the next file
514
+ const metadata = await parseFile(audioFile);
515
+ // Do great things with the metadata
516
+ }
517
+ }
518
+ ```
504
519
 
505
- 3. Use a specialized module to traverse files
520
+ 1. Use a specialized module to traverse files
506
521
 
507
- There are specialized modules to traversing (walking) files and directory,
508
- like [walk](https://www.npmjs.com/package/walk).
522
+ There are specialized modules to traversing (walking) files and directory,
523
+ like [walk](https://www.npmjs.com/package/walk).
509
524
 
510
525
  ## Licence
511
526
 
@@ -66,7 +66,7 @@ export async function parse(tokenizer, parserId, opts) {
66
66
  // Parser found, execute parser
67
67
  const parser = await loadParser(parserId);
68
68
  const metadata = new MetadataCollector(opts);
69
- await parser.init(metadata, tokenizer, opts !== null && opts !== void 0 ? opts : {}).parse();
69
+ await parser.init(metadata, tokenizer, opts ?? {}).parse();
70
70
  return metadata.toCommonMetadata();
71
71
  }
72
72
  /**
@@ -57,7 +57,6 @@ export class AIFFParser extends BasicParser {
57
57
  }
58
58
  }
59
59
  async readData(header) {
60
- var _a;
61
60
  switch (header.chunkID) {
62
61
  case 'COMM': { // The Common Chunk
63
62
  if (this.isCompressed === null) {
@@ -70,7 +69,7 @@ export class AIFFParser extends BasicParser {
70
69
  this.metadata.setFormat('numberOfSamples', common.numSampleFrames);
71
70
  this.metadata.setFormat('duration', common.numSampleFrames / common.sampleRate);
72
71
  if (common.compressionName || common.compressionType) {
73
- this.metadata.setFormat('codec', (_a = common.compressionName) !== null && _a !== void 0 ? _a : compressionTypes[common.compressionType]);
72
+ this.metadata.setFormat('codec', common.compressionName ?? compressionTypes[common.compressionType]);
74
73
  }
75
74
  return header.chunkSize;
76
75
  }
@@ -97,7 +96,7 @@ export class AIFFParser extends BasicParser {
97
96
  }
98
97
  async readTextChunk(header) {
99
98
  const value = await this.tokenizer.readToken(new Token.StringType(header.chunkSize, 'ascii'));
100
- const values = value.split('\0').map(v => v.trim()).filter(v => v === null || v === void 0 ? void 0 : v.length);
99
+ const values = value.split('\0').map(v => v.trim()).filter(v => v?.length);
101
100
  await Promise.all(values.map(v => this.metadata.addTag('AIFF', header.chunkID, v)));
102
101
  return header.chunkSize;
103
102
  }
@@ -54,10 +54,9 @@ export class MetadataCollector {
54
54
  this.format.trackInfo.push(streamInfo);
55
55
  }
56
56
  setFormat(key, value) {
57
- var _a;
58
57
  debug(`format: ${key} = ${value}`);
59
58
  this.format[key] = value; // as any to override readonly
60
- if ((_a = this.opts) === null || _a === void 0 ? void 0 : _a.observer) {
59
+ if (this.opts?.observer) {
61
60
  this.opts.observer({ metadata: this, tag: { type: 'format', id: key, value } });
62
61
  }
63
62
  }
@@ -239,7 +238,6 @@ export class MetadataCollector {
239
238
  * Set generic tag
240
239
  */
241
240
  setGenericTag(tagType, tag) {
242
- var _a;
243
241
  debug(`common.${tag.id} = ${tag.value}`);
244
242
  const prio0 = this.commonOrigin[tag.id] || 1000;
245
243
  const prio1 = this.originPriority[tagType];
@@ -270,7 +268,7 @@ export class MetadataCollector {
270
268
  return debug(`Ignore native tag (list): ${tagType}.${tag.id} = ${tag.value}`);
271
269
  }
272
270
  }
273
- if ((_a = this.opts) === null || _a === void 0 ? void 0 : _a.observer) {
271
+ if (this.opts?.observer) {
274
272
  this.opts.observer({ metadata: this, tag: { type: 'common', id: tag.id, value: tag.value } });
275
273
  }
276
274
  // ToDo: trigger metadata event
@@ -0,0 +1,52 @@
1
+ import { type ITokenizer } from 'strtok3';
2
+ import { type IElementType, type ITree, type ValueType } from './types.js';
3
+ export interface ILinkedElementType extends IElementType {
4
+ id: number;
5
+ parent: ILinkedElementType | undefined;
6
+ readonly container?: {
7
+ [id: number]: ILinkedElementType;
8
+ };
9
+ }
10
+ export declare enum ParseAction {
11
+ ReadNext = 0,// Continue reading the next elements
12
+ IgnoreElement = 2,// Ignore (do not read) this element
13
+ SkipSiblings = 3,// Skip all remaining elements at the same level
14
+ TerminateParsing = 4,// Terminate the parsing process
15
+ SkipElement = 5
16
+ }
17
+ /**
18
+ * @return true, to quit the parser
19
+ */
20
+ export type IElementListener = {
21
+ startNext: (dtdElement: ILinkedElementType) => ParseAction;
22
+ elementValue: (dtdElement: ILinkedElementType, value: ValueType, offset: number) => Promise<void>;
23
+ };
24
+ /**
25
+ * Extensible Binary Meta Language (EBML) iterator
26
+ * https://en.wikipedia.org/wiki/Extensible_Binary_Meta_Language
27
+ * http://matroska.sourceforge.net/technical/specs/rfc/index.html
28
+ *
29
+ * WEBM VP8 AUDIO FILE
30
+ */
31
+ export declare class EbmlIterator {
32
+ private tokenizer;
33
+ private padding;
34
+ private parserMap;
35
+ private ebmlMaxIDLength;
36
+ private ebmlMaxSizeLength;
37
+ /**
38
+ * @param {ITokenizer} tokenizer Input
39
+ * @param tokenizer
40
+ */
41
+ constructor(tokenizer: ITokenizer);
42
+ iterate(dtdElement: IElementType, posDone: number, listener: IElementListener): Promise<ITree>;
43
+ private parseContainer;
44
+ private readVintData;
45
+ private readElement;
46
+ private readFloat;
47
+ private readFlag;
48
+ private readUint;
49
+ private readString;
50
+ private readBuffer;
51
+ }
52
+ export declare function getElementPath(element: ILinkedElementType): string;
@@ -0,0 +1,220 @@
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
+ const debug = initDebug('music-metadata:parser:ebml');
7
+ export var ParseAction;
8
+ (function (ParseAction) {
9
+ ParseAction[ParseAction["ReadNext"] = 0] = "ReadNext";
10
+ ParseAction[ParseAction["IgnoreElement"] = 2] = "IgnoreElement";
11
+ ParseAction[ParseAction["SkipSiblings"] = 3] = "SkipSiblings";
12
+ ParseAction[ParseAction["TerminateParsing"] = 4] = "TerminateParsing";
13
+ ParseAction[ParseAction["SkipElement"] = 5] = "SkipElement"; // Consider the element has read, assume position is at the next element
14
+ })(ParseAction || (ParseAction = {}));
15
+ /**
16
+ * Extensible Binary Meta Language (EBML) iterator
17
+ * https://en.wikipedia.org/wiki/Extensible_Binary_Meta_Language
18
+ * http://matroska.sourceforge.net/technical/specs/rfc/index.html
19
+ *
20
+ * WEBM VP8 AUDIO FILE
21
+ */
22
+ export class EbmlIterator {
23
+ /**
24
+ * @param {ITokenizer} tokenizer Input
25
+ * @param tokenizer
26
+ */
27
+ constructor(tokenizer) {
28
+ this.tokenizer = tokenizer;
29
+ this.padding = 0;
30
+ this.parserMap = new Map();
31
+ this.ebmlMaxIDLength = 4;
32
+ this.ebmlMaxSizeLength = 8;
33
+ this.parserMap.set(DataType.uint, e => this.readUint(e));
34
+ this.parserMap.set(DataType.string, e => this.readString(e));
35
+ this.parserMap.set(DataType.binary, e => this.readBuffer(e));
36
+ this.parserMap.set(DataType.uid, async (e) => this.readBuffer(e));
37
+ this.parserMap.set(DataType.bool, e => this.readFlag(e));
38
+ this.parserMap.set(DataType.float, e => this.readFloat(e));
39
+ }
40
+ async iterate(dtdElement, posDone, listener) {
41
+ return this.parseContainer(linkParents(dtdElement), posDone, listener);
42
+ }
43
+ async parseContainer(dtdElement, posDone, listener) {
44
+ const tree = {};
45
+ while (this.tokenizer.position < posDone) {
46
+ let element;
47
+ const elementPosition = this.tokenizer.position;
48
+ try {
49
+ element = await this.readElement();
50
+ }
51
+ catch (error) {
52
+ if (error instanceof EndOfStreamError) {
53
+ break;
54
+ }
55
+ throw error;
56
+ }
57
+ const child = dtdElement.container[element.id];
58
+ if (child) {
59
+ const action = listener.startNext(child);
60
+ switch (action) {
61
+ case ParseAction.ReadNext:
62
+ {
63
+ if (element.id === 0x1F43B675) {
64
+ // Hack to ignore remaining segment, when cluster element received
65
+ // await this.tokenizer.ignore(posDone - this.tokenizer.position);
66
+ // break;
67
+ }
68
+ debug(`Read element: name=${getElementPath(child)}{id=0x${element.id.toString(16)}, container=${!!child.container}} at position=${elementPosition}`);
69
+ if (child.container) {
70
+ const res = await this.parseContainer(child, element.len >= 0 ? this.tokenizer.position + element.len : -1, listener);
71
+ if (child.multiple) {
72
+ if (!tree[child.name]) {
73
+ tree[child.name] = [];
74
+ }
75
+ tree[child.name].push(res);
76
+ }
77
+ else {
78
+ tree[child.name] = res;
79
+ }
80
+ await listener.elementValue(child, res, elementPosition);
81
+ }
82
+ else {
83
+ const parser = this.parserMap.get(child.value);
84
+ if (typeof parser === 'function') {
85
+ const value = await parser(element);
86
+ tree[child.name] = value;
87
+ await listener.elementValue(child, value, elementPosition);
88
+ }
89
+ }
90
+ }
91
+ break;
92
+ case ParseAction.SkipElement:
93
+ debug(`Go to next element: name=${getElementPath(child)}, element.id=0x${element.id}, container=${!!child.container} at position=${elementPosition}`);
94
+ break;
95
+ case ParseAction.IgnoreElement:
96
+ debug(`Ignore element: name=${getElementPath(child)}, element.id=0x${element.id}, container=${!!child.container} at position=${elementPosition}`);
97
+ await this.tokenizer.ignore(element.len);
98
+ break;
99
+ case ParseAction.SkipSiblings:
100
+ debug(`Ignore remaining container, at: name=${getElementPath(child)}, element.id=0x${element.id}, container=${!!child.container} at position=${elementPosition}`);
101
+ await this.tokenizer.ignore(posDone - this.tokenizer.position);
102
+ break;
103
+ case ParseAction.TerminateParsing:
104
+ debug(`Terminate parsing at element: name=${getElementPath(child)}, element.id=0x${element.id}, container=${!!child.container} at position=${elementPosition}`);
105
+ return tree;
106
+ }
107
+ }
108
+ else {
109
+ switch (element.id) {
110
+ case 0xec: // void
111
+ this.padding += element.len;
112
+ await this.tokenizer.ignore(element.len);
113
+ break;
114
+ default:
115
+ debug(`parseEbml: parent=${getElementPath(dtdElement)}, unknown child: id=${element.id.toString(16)} at position=${elementPosition}`);
116
+ this.padding += element.len;
117
+ await this.tokenizer.ignore(element.len);
118
+ }
119
+ }
120
+ }
121
+ return tree;
122
+ }
123
+ async readVintData(maxLength) {
124
+ const msb = await this.tokenizer.peekNumber(UINT8);
125
+ let mask = 0x80;
126
+ let oc = 1;
127
+ // Calculate VINT_WIDTH
128
+ while ((msb & mask) === 0) {
129
+ if (oc > maxLength) {
130
+ throw new Error('VINT value exceeding maximum size');
131
+ }
132
+ ++oc;
133
+ mask >>= 1;
134
+ }
135
+ const id = new Uint8Array(oc);
136
+ await this.tokenizer.readBuffer(id);
137
+ return id;
138
+ }
139
+ async readElement() {
140
+ const id = await this.readVintData(this.ebmlMaxIDLength);
141
+ const lenField = await this.readVintData(this.ebmlMaxSizeLength);
142
+ lenField[0] ^= 0x80 >> (lenField.length - 1);
143
+ return {
144
+ id: readUIntBE(id, id.length),
145
+ len: readUIntBE(lenField, lenField.length)
146
+ };
147
+ }
148
+ async readFloat(e) {
149
+ switch (e.len) {
150
+ case 0:
151
+ return 0.0;
152
+ case 4:
153
+ return this.tokenizer.readNumber(Float32_BE);
154
+ case 8:
155
+ return this.tokenizer.readNumber(Float64_BE);
156
+ case 10:
157
+ return this.tokenizer.readNumber(Float64_BE);
158
+ default:
159
+ throw new Error(`Invalid IEEE-754 float length: ${e.len}`);
160
+ }
161
+ }
162
+ async readFlag(e) {
163
+ return (await this.readUint(e)) === 1;
164
+ }
165
+ async readUint(e) {
166
+ const buf = await this.readBuffer(e);
167
+ return readUIntBE(buf, e.len);
168
+ }
169
+ async readString(e) {
170
+ const rawString = await this.tokenizer.readToken(new StringType(e.len, 'utf-8'));
171
+ return rawString.replace(/\x00.*$/g, '');
172
+ }
173
+ async readBuffer(e) {
174
+ const buf = new Uint8Array(e.len);
175
+ await this.tokenizer.readBuffer(buf);
176
+ return buf;
177
+ }
178
+ }
179
+ function readUIntBE(buf, len) {
180
+ return Number(readUIntBeAsBigInt(buf, len));
181
+ }
182
+ /**
183
+ * Reeds an unsigned integer from a big endian buffer of length `len`
184
+ * @param buf Buffer to decode from
185
+ * @param len Number of bytes
186
+ * @private
187
+ */
188
+ function readUIntBeAsBigInt(buf, len) {
189
+ const normalizedNumber = new Uint8Array(8);
190
+ const cleanNumber = buf.subarray(0, len);
191
+ try {
192
+ normalizedNumber.set(cleanNumber, 8 - len);
193
+ return Token.UINT64_BE.get(normalizedNumber, 0);
194
+ }
195
+ catch (error) {
196
+ return BigInt(-1);
197
+ }
198
+ }
199
+ function linkParents(element) {
200
+ if (element.container) {
201
+ Object.keys(element.container)
202
+ .map(id => {
203
+ const child = element.container[id];
204
+ child.id = Number.parseInt(id);
205
+ return child;
206
+ }).forEach(child => {
207
+ child.parent = element;
208
+ linkParents(child);
209
+ });
210
+ }
211
+ return element;
212
+ }
213
+ export function getElementPath(element) {
214
+ let path = '';
215
+ if (element.parent && element.parent.name !== 'dtd') {
216
+ path += `${getElementPath(element.parent)}/`;
217
+ }
218
+ return path + element.name;
219
+ }
220
+ //# 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
@@ -54,17 +54,16 @@ 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);
@@ -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;