music-metadata 10.2.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 (53) hide show
  1. package/README.md +435 -126
  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 +8 -7
  6. package/lib/aiff/AiffParser.js +4 -4
  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/Util.js +3 -2
  17. package/lib/core.d.ts +2 -1
  18. package/lib/core.js +1 -1
  19. package/lib/default.cjs +5 -0
  20. package/lib/dsdiff/DsdiffParser.d.ts +15 -0
  21. package/lib/dsdiff/DsdiffParser.js +6 -3
  22. package/lib/dsf/DsfParser.d.ts +15 -0
  23. package/lib/dsf/DsfParser.js +4 -1
  24. package/lib/ebml/EbmlIterator.d.ts +15 -0
  25. package/lib/ebml/EbmlIterator.js +5 -2
  26. package/lib/flac/FlacParser.js +5 -2
  27. package/lib/id3v2/FrameParser.d.ts +14 -0
  28. package/lib/id3v2/FrameParser.js +7 -1
  29. package/lib/id3v2/ID3v2Parser.js +8 -5
  30. package/lib/mp4/AtomToken.d.ts +14 -0
  31. package/lib/mp4/AtomToken.js +6 -3
  32. package/lib/mp4/MP4Parser.js +4 -3
  33. package/lib/mpeg/MpegParser.d.ts +15 -0
  34. package/lib/mpeg/MpegParser.js +7 -4
  35. package/lib/musepack/MusepackConentError.d.ts +15 -0
  36. package/lib/musepack/MusepackConentError.js +4 -0
  37. package/lib/musepack/index.js +4 -3
  38. package/lib/musepack/sv7/MpcSv7Parser.js +2 -1
  39. package/lib/musepack/sv8/MpcSv8Parser.js +3 -2
  40. package/lib/node.cjs +5 -0
  41. package/lib/ogg/OggParser.d.ts +15 -0
  42. package/lib/ogg/OggParser.js +5 -2
  43. package/lib/ogg/opus/Opus.d.ts +15 -0
  44. package/lib/ogg/opus/Opus.js +4 -1
  45. package/lib/ogg/opus/OpusParser.js +2 -1
  46. package/lib/ogg/vorbis/VorbisParser.d.ts +15 -0
  47. package/lib/ogg/vorbis/VorbisParser.js +6 -3
  48. package/lib/wav/WaveChunk.d.ts +15 -0
  49. package/lib/wav/WaveChunk.js +5 -2
  50. package/lib/wav/WaveParser.js +3 -2
  51. package/lib/wavpack/WavPackParser.d.ts +15 -0
  52. package/lib/wavpack/WavPackParser.js +6 -3
  53. package/package.json +16 -7
@@ -3,7 +3,10 @@ import initDebug from 'debug';
3
3
  import { EndOfStreamError } from 'strtok3';
4
4
  import { DataType } from './types.js';
5
5
  import * as Token from 'token-types';
6
+ import { makeUnexpectedFileContentError } from '../ParseError.js';
6
7
  const debug = initDebug('music-metadata:parser:ebml');
8
+ export class EbmlContentError extends makeUnexpectedFileContentError('EBML') {
9
+ }
7
10
  export var ParseAction;
8
11
  (function (ParseAction) {
9
12
  ParseAction[ParseAction["ReadNext"] = 0] = "ReadNext";
@@ -127,7 +130,7 @@ export class EbmlIterator {
127
130
  // Calculate VINT_WIDTH
128
131
  while ((msb & mask) === 0) {
129
132
  if (oc > maxLength) {
130
- throw new Error('VINT value exceeding maximum size');
133
+ throw new EbmlContentError('VINT value exceeding maximum size');
131
134
  }
132
135
  ++oc;
133
136
  mask >>= 1;
@@ -156,7 +159,7 @@ export class EbmlIterator {
156
159
  case 10:
157
160
  return this.tokenizer.readNumber(Float64_BE);
158
161
  default:
159
- throw new Error(`Invalid IEEE-754 float length: ${e.len}`);
162
+ throw new EbmlContentError(`Invalid IEEE-754 float length: ${e.len}`);
160
163
  }
161
164
  }
162
165
  async readFlag(e) {
@@ -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) {
@@ -68,7 +68,7 @@ export class ID3v2Parser {
68
68
  }
69
69
  return frameParser.readData(uint8Array, frameHeader.id, includeCovers);
70
70
  default:
71
- throw new Error(`Unexpected majorVer: ${majorVer}`);
71
+ throw makeUnexpectedMajorVersionError(majorVer);
72
72
  }
73
73
  }
74
74
  /**
@@ -86,7 +86,7 @@ export class ID3v2Parser {
86
86
  this.options = options;
87
87
  const id3Header = await this.tokenizer.readToken(ID3v2Header);
88
88
  if (id3Header.fileIdentifier !== 'ID3') {
89
- 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');
90
90
  }
91
91
  this.id3Header = id3Header;
92
92
  this.headerType = (`ID3v2.${id3Header.version.major}`);
@@ -168,9 +168,12 @@ export class ID3v2Parser {
168
168
  }
169
169
  break;
170
170
  default:
171
- throw new Error(`Unexpected majorVer: ${majorVer}`);
171
+ throw makeUnexpectedMajorVersionError(majorVer);
172
172
  }
173
173
  return header;
174
174
  }
175
175
  }
176
+ function makeUnexpectedMajorVersionError(majorVer) {
177
+ throw new Id3v2ContentError(`Unexpected majorVer: ${majorVer}`);
178
+ }
176
179
  //# sourceMappingURL=ID3v2Parser.js.map
@@ -1,4 +1,18 @@
1
1
  import type { IToken, IGetToken } from 'strtok3';
2
+ declare const Mp4ContentError_base: {
3
+ new (message: string): {
4
+ readonly fileType: string;
5
+ toString(): string;
6
+ name: "UnexpectedFileContentError";
7
+ message: string;
8
+ stack?: string;
9
+ };
10
+ captureStackTrace(targetObject: object, constructorOpt?: Function): void;
11
+ prepareStackTrace?: ((err: Error, stackTraces: NodeJS.CallSite[]) => any) | undefined;
12
+ stackTraceLimit: number;
13
+ };
14
+ export declare class Mp4ContentError extends Mp4ContentError_base {
15
+ }
2
16
  interface IVersionAndFlags {
3
17
  /**
4
18
  * A 1-byte specification of the version
@@ -1,13 +1,16 @@
1
1
  import * as Token from 'token-types';
2
2
  import initDebug from 'debug';
3
3
  import { FourCcToken } from '../common/FourCC.js';
4
+ import { makeUnexpectedFileContentError } from '../ParseError.js';
4
5
  const debug = initDebug('music-metadata:parser:MP4:atom');
6
+ export class Mp4ContentError extends makeUnexpectedFileContentError('MP4') {
7
+ }
5
8
  export const Header = {
6
9
  len: 8,
7
10
  get: (buf, off) => {
8
11
  const length = Token.UINT32_BE.get(buf, off);
9
12
  if (length < 0)
10
- throw new Error('Invalid atom header length');
13
+ throw new Mp4ContentError('Invalid atom header length');
11
14
  return {
12
15
  length: BigInt(length),
13
16
  name: new Token.StringType(4, 'latin1').get(buf, off + 4)
@@ -66,7 +69,7 @@ export class FixedLengthAtom {
66
69
  constructor(len, expLen, atomId) {
67
70
  this.len = len;
68
71
  if (len < expLen) {
69
- throw new Error(`Atom ${atomId} expected to be ${expLen}, but specifies ${len} bytes long.`);
72
+ throw new Mp4ContentError(`Atom ${atomId} expected to be ${expLen}, but specifies ${len} bytes long.`);
70
73
  }
71
74
  if (len > expLen) {
72
75
  debug(`Warning: atom ${atomId} expected to be ${expLen}, but was actually ${len} bytes long.`);
@@ -381,7 +384,7 @@ function readTokenTable(buf, token, off, remainingLen, numberOfEntries) {
381
384
  if (remainingLen === 0)
382
385
  return [];
383
386
  if (remainingLen !== numberOfEntries * token.len)
384
- throw new Error('mismatch number-of-entries with remaining atom-length');
387
+ throw new Mp4ContentError('mismatch number-of-entries with remaining atom-length');
385
388
  const entries = [];
386
389
  // parse offset-table
387
390
  for (let n = 0; n < numberOfEntries; ++n) {
@@ -6,6 +6,7 @@ import { Atom } from './Atom.js';
6
6
  import * as AtomToken from './AtomToken.js';
7
7
  import { TrackType } from '../type.js';
8
8
  import { uint8ArrayToHex, uint8ArrayToString } from 'uint8array-extras';
9
+ import { Mp4ContentError } from './AtomToken.js';
9
10
  const debug = initDebug('music-metadata:parser:MP4');
10
11
  const tagFormat = 'iTunes';
11
12
  const encoderDict = {
@@ -209,7 +210,7 @@ export class MP4Parser extends BasicParser {
209
210
  const integerType = (signed ? 'INT' : 'UINT') + array.length * 8 + (array.length > 1 ? '_BE' : '');
210
211
  const token = Token[integerType];
211
212
  if (!token) {
212
- throw new Error(`Token for integer type not found: "${integerType}"`);
213
+ throw new Mp4ContentError(`Token for integer type not found: "${integerType}"`);
213
214
  }
214
215
  return Number(token.get(array, 0));
215
216
  }
@@ -361,7 +362,7 @@ export class MP4Parser extends BasicParser {
361
362
  async parseValueAtom(tagKey, metaAtom) {
362
363
  const dataAtom = await this.tokenizer.readToken(new AtomToken.DataAtom(Number(metaAtom.header.length) - AtomToken.Header.len));
363
364
  if (dataAtom.type.set !== 0) {
364
- throw new Error(`Unsupported type-set != 0: ${dataAtom.type.set}`);
365
+ throw new Mp4ContentError(`Unsupported type-set != 0: ${dataAtom.type.set}`);
365
366
  }
366
367
  // Use well-known-type table
367
368
  // Ref: https://developer.apple.com/library/content/documentation/QuickTime/QTFF/Metadata/Metadata.html#//apple_ref/doc/uid/TP40000939-CH1-SW35
@@ -464,7 +465,7 @@ export class MP4Parser extends BasicParser {
464
465
  const sampleSize = chapterTrack.sampleSize > 0 ? chapterTrack.sampleSize : chapterTrack.sampleSizeTable[i];
465
466
  len -= nextChunkLen + sampleSize;
466
467
  if (len < 0)
467
- throw new Error('Chapter chunk exceeding token length');
468
+ throw new Mp4ContentError('Chapter chunk exceeding token length');
468
469
  await this.tokenizer.ignore(nextChunkLen);
469
470
  const title = await this.tokenizer.readToken(new AtomToken.ChapterText(sampleSize));
470
471
  debug(`Chapter ${i + 1}: ${title}`);
@@ -1,4 +1,18 @@
1
1
  import { AbstractID3Parser } from '../id3v2/AbstractID3Parser.js';
2
+ declare const MpegContentError_base: {
3
+ new (message: string): {
4
+ readonly fileType: string;
5
+ toString(): string;
6
+ name: "UnexpectedFileContentError";
7
+ message: string;
8
+ stack?: string;
9
+ };
10
+ captureStackTrace(targetObject: object, constructorOpt?: Function): void;
11
+ prepareStackTrace?: ((err: Error, stackTraces: NodeJS.CallSite[]) => any) | undefined;
12
+ stackTraceLimit: number;
13
+ };
14
+ export declare class MpegContentError extends MpegContentError_base {
15
+ }
2
16
  export declare class MpegParser extends AbstractID3Parser {
3
17
  private frameCount;
4
18
  private syncFrameCount;
@@ -47,3 +61,4 @@ export declare class MpegParser extends AbstractID3Parser {
47
61
  private skipFrameData;
48
62
  private areAllSame;
49
63
  }
64
+ export {};
@@ -4,7 +4,10 @@ import initDebug from 'debug';
4
4
  import * as common from '../common/Util.js';
5
5
  import { AbstractID3Parser } from '../id3v2/AbstractID3Parser.js';
6
6
  import { InfoTagHeaderTag, LameEncoderVersion, readXingHeader } from './XingTag.js';
7
+ import { makeUnexpectedFileContentError } from '../ParseError.js';
7
8
  const debug = initDebug('music-metadata:parser:mpeg');
9
+ export class MpegContentError extends makeUnexpectedFileContentError('MPEG') {
10
+ }
8
11
  /**
9
12
  * Cache buffer size used for searching synchronization preabmle
10
13
  */
@@ -140,13 +143,13 @@ class MpegFrameHeader {
140
143
  // Calculate bitrate
141
144
  const bitrateInKbps = this.calcBitrate();
142
145
  if (!bitrateInKbps) {
143
- throw new Error('Cannot determine bit-rate');
146
+ throw new MpegContentError('Cannot determine bit-rate');
144
147
  }
145
148
  this.bitrate = bitrateInKbps * 1000;
146
149
  // Calculate sampling rate
147
150
  this.samplingRate = this.calcSamplingRate();
148
151
  if (this.samplingRate == null) {
149
- throw new Error('Cannot determine sampling-rate');
152
+ throw new MpegContentError('Cannot determine sampling-rate');
150
153
  }
151
154
  }
152
155
  parseAdtsHeader(buf, off) {
@@ -383,7 +386,7 @@ export class MpegParser extends AbstractID3Parser {
383
386
  }
384
387
  const slot_size = header.calcSlotSize();
385
388
  if (slot_size === null) {
386
- throw new Error('invalid slot_size');
389
+ throw new MpegContentError('invalid slot_size');
387
390
  }
388
391
  const samples_per_frame = header.calcSamplesPerFrame();
389
392
  debug(`samples_per_frame=${samples_per_frame}`);
@@ -555,7 +558,7 @@ export class MpegParser extends AbstractID3Parser {
555
558
  }
556
559
  async skipFrameData(frameDataLeft) {
557
560
  if (frameDataLeft < 0)
558
- throw new Error('frame-data-left cannot be negative');
561
+ throw new MpegContentError('frame-data-left cannot be negative');
559
562
  await this.tokenizer.ignore(frameDataLeft);
560
563
  this.countSkipFrameData += frameDataLeft;
561
564
  }
@@ -0,0 +1,15 @@
1
+ declare const MusepackContentError_base: {
2
+ new (message: string): {
3
+ readonly fileType: string;
4
+ toString(): string;
5
+ name: "UnexpectedFileContentError";
6
+ message: string;
7
+ stack?: string;
8
+ };
9
+ captureStackTrace(targetObject: object, constructorOpt?: Function): void;
10
+ prepareStackTrace?: ((err: Error, stackTraces: NodeJS.CallSite[]) => any) | undefined;
11
+ stackTraceLimit: number;
12
+ };
13
+ export declare class MusepackContentError extends MusepackContentError_base {
14
+ }
15
+ export {};
@@ -0,0 +1,4 @@
1
+ import { makeUnexpectedFileContentError } from '../ParseError.js';
2
+ export class MusepackContentError extends makeUnexpectedFileContentError('Musepack') {
3
+ }
4
+ //# sourceMappingURL=MusepackConentError.js.map
@@ -3,6 +3,7 @@ import * as Token from 'token-types';
3
3
  import { AbstractID3Parser } from '../id3v2/AbstractID3Parser.js';
4
4
  import { MpcSv8Parser } from './sv8/MpcSv8Parser.js';
5
5
  import { MpcSv7Parser } from './sv7/MpcSv7Parser.js';
6
+ import { MusepackContentError } from './MusepackConentError.js';
6
7
  const debug = initDebug('music-metadata:parser:musepack');
7
8
  class MusepackParser extends AbstractID3Parser {
8
9
  async postId3v2Parse() {
@@ -10,17 +11,17 @@ class MusepackParser extends AbstractID3Parser {
10
11
  let mpcParser;
11
12
  switch (signature) {
12
13
  case 'MP+': {
13
- debug('Musepack stream-version 7');
14
+ debug('Stream-version 7');
14
15
  mpcParser = new MpcSv7Parser();
15
16
  break;
16
17
  }
17
18
  case 'MPC': {
18
- debug('Musepack stream-version 8');
19
+ debug('Stream-version 8');
19
20
  mpcParser = new MpcSv8Parser();
20
21
  break;
21
22
  }
22
23
  default: {
23
- throw new Error('Invalid Musepack signature prefix');
24
+ throw new MusepackContentError('Invalid signature prefix');
24
25
  }
25
26
  }
26
27
  mpcParser.init(this.metadata, this.tokenizer, this.options);
@@ -3,6 +3,7 @@ import { BasicParser } from '../../common/BasicParser.js';
3
3
  import { APEv2Parser } from '../../apev2/APEv2Parser.js';
4
4
  import { BitReader } from './BitReader.js';
5
5
  import * as SV7 from './StreamVersion7.js';
6
+ import { MusepackContentError } from '../MusepackConentError.js';
6
7
  const debug = initDebug('music-metadata:parser:musepack');
7
8
  export class MpcSv7Parser extends BasicParser {
8
9
  constructor() {
@@ -14,7 +15,7 @@ export class MpcSv7Parser extends BasicParser {
14
15
  async parse() {
15
16
  const header = await this.tokenizer.readToken(SV7.Header);
16
17
  if (header.signature !== 'MP+')
17
- throw new Error('Unexpected magic number');
18
+ throw new MusepackContentError('Unexpected magic number');
18
19
  debug(`stream-version=${header.streamMajorVersion}.${header.streamMinorVersion}`);
19
20
  this.metadata.setFormat('container', 'Musepack, SV7');
20
21
  this.metadata.setFormat('sampleRate', header.sampleFrequency);
@@ -3,6 +3,7 @@ import { BasicParser } from '../../common/BasicParser.js';
3
3
  import { APEv2Parser } from '../../apev2/APEv2Parser.js';
4
4
  import { FourCcToken } from '../../common/FourCC.js';
5
5
  import * as SV8 from './StreamVersion8.js';
6
+ import { MusepackContentError } from '../MusepackConentError.js';
6
7
  const debug = initDebug('music-metadata:parser:musepack');
7
8
  export class MpcSv8Parser extends BasicParser {
8
9
  constructor() {
@@ -12,7 +13,7 @@ export class MpcSv8Parser extends BasicParser {
12
13
  async parse() {
13
14
  const signature = await this.tokenizer.readToken(FourCcToken);
14
15
  if (signature !== 'MPCK')
15
- throw new Error('Invalid Magic number');
16
+ throw new MusepackContentError('Invalid Magic number');
16
17
  this.metadata.setFormat('container', 'Musepack, SV8');
17
18
  return this.parsePacket();
18
19
  }
@@ -47,7 +48,7 @@ export class MpcSv8Parser extends BasicParser {
47
48
  }
48
49
  return APEv2Parser.tryParseApeHeader(this.metadata, this.tokenizer, this.options);
49
50
  default:
50
- throw new Error(`Unexpected header: ${header.key}`);
51
+ throw new MusepackContentError(`Unexpected header: ${header.key}`);
51
52
  }
52
53
  } while (true);
53
54
  }
package/lib/node.cjs ADDED
@@ -0,0 +1,5 @@
1
+ // CommonJS Node entry point
2
+ "use strict";
3
+ module.exports = {
4
+ loadMusicMetadata: () => import('./index.js'),
5
+ };
@@ -1,6 +1,20 @@
1
1
  import { type IGetToken } from 'strtok3';
2
2
  import { BasicParser } from '../common/BasicParser.js';
3
3
  import type * as Ogg from './Ogg.js';
4
+ declare const OggContentError_base: {
5
+ new (message: string): {
6
+ readonly fileType: string;
7
+ toString(): string;
8
+ name: "UnexpectedFileContentError";
9
+ message: string;
10
+ stack?: string;
11
+ };
12
+ captureStackTrace(targetObject: object, constructorOpt?: Function): void;
13
+ prepareStackTrace?: ((err: Error, stackTraces: NodeJS.CallSite[]) => any) | undefined;
14
+ stackTraceLimit: number;
15
+ };
16
+ export declare class OggContentError extends OggContentError_base {
17
+ }
4
18
  export declare class SegmentTable implements IGetToken<Ogg.ISegmentTable> {
5
19
  private static sum;
6
20
  len: number;
@@ -21,3 +35,4 @@ export declare class OggParser extends BasicParser {
21
35
  */
22
36
  parse(): Promise<void>;
23
37
  }
38
+ export {};
@@ -8,6 +8,9 @@ import { VorbisParser } from './vorbis/VorbisParser.js';
8
8
  import { OpusParser } from './opus/OpusParser.js';
9
9
  import { SpeexParser } from './speex/SpeexParser.js';
10
10
  import { TheoraParser } from './theora/TheoraParser.js';
11
+ import { makeUnexpectedFileContentError } from '../ParseError.js';
12
+ export class OggContentError extends makeUnexpectedFileContentError('Ogg') {
13
+ }
11
14
  const debug = initDebug('music-metadata:parser:ogg');
12
15
  export class SegmentTable {
13
16
  static sum(buf, off, len) {
@@ -48,7 +51,7 @@ export class OggParser extends BasicParser {
48
51
  do {
49
52
  header = await this.tokenizer.readToken(OggParser.Header);
50
53
  if (header.capturePattern !== 'OggS')
51
- throw new Error('Invalid Ogg capture pattern');
54
+ throw new OggContentError('Invalid Ogg capture pattern');
52
55
  this.metadata.setFormat('container', 'Ogg');
53
56
  this.header = header;
54
57
  this.pageNumber = header.pageSequenceNo;
@@ -78,7 +81,7 @@ export class OggParser extends BasicParser {
78
81
  this.pageConsumer = new TheoraParser(this.metadata, this.options, this.tokenizer);
79
82
  break;
80
83
  default:
81
- throw new Error(`gg audio-codec not recognized (id=${id})`);
84
+ throw new OggContentError(`gg audio-codec not recognized (id=${id})`);
82
85
  }
83
86
  }
84
87
  await this.pageConsumer.parsePage(header, pageData);
@@ -37,6 +37,20 @@ export interface IIdHeader {
37
37
  */
38
38
  channelMapping: number;
39
39
  }
40
+ declare const OpusContentError_base: {
41
+ new (message: string): {
42
+ readonly fileType: string;
43
+ toString(): string;
44
+ name: "UnexpectedFileContentError";
45
+ message: string;
46
+ stack?: string;
47
+ };
48
+ captureStackTrace(targetObject: object, constructorOpt?: Function): void;
49
+ prepareStackTrace?: ((err: Error, stackTraces: NodeJS.CallSite[]) => any) | undefined;
50
+ stackTraceLimit: number;
51
+ };
52
+ export declare class OpusContentError extends OpusContentError_base {
53
+ }
40
54
  /**
41
55
  * Opus ID Header parser
42
56
  * Ref: https://wiki.xiph.org/OggOpus#ID_Header
@@ -46,3 +60,4 @@ export declare class IdHeader implements IGetToken<IIdHeader> {
46
60
  constructor(len: number);
47
61
  get(buf: Uint8Array, off: number): IIdHeader;
48
62
  }
63
+ export {};
@@ -1,4 +1,7 @@
1
1
  import * as Token from 'token-types';
2
+ import { makeUnexpectedFileContentError } from '../../ParseError.js';
3
+ export class OpusContentError extends makeUnexpectedFileContentError('Opus') {
4
+ }
2
5
  /**
3
6
  * Opus ID Header parser
4
7
  * Ref: https://wiki.xiph.org/OggOpus#ID_Header
@@ -7,7 +10,7 @@ export class IdHeader {
7
10
  constructor(len) {
8
11
  this.len = len;
9
12
  if (len < 19) {
10
- throw new Error("ID-header-page 0 should be at least 19 bytes long");
13
+ throw new OpusContentError('ID-header-page 0 should be at least 19 bytes long');
11
14
  }
12
15
  }
13
16
  get(buf, off) {
@@ -1,6 +1,7 @@
1
1
  import * as Token from 'token-types';
2
2
  import { VorbisParser } from '../vorbis/VorbisParser.js';
3
3
  import * as Opus from './Opus.js';
4
+ import { OpusContentError } from './Opus.js';
4
5
  /**
5
6
  * Opus parser
6
7
  * Internet Engineering Task Force (IETF) - RFC 6716
@@ -23,7 +24,7 @@ export class OpusParser extends VorbisParser {
23
24
  // Parse Opus ID Header
24
25
  this.idHeader = new Opus.IdHeader(pageData.length).get(pageData, 0);
25
26
  if (this.idHeader.magicSignature !== "OpusHead")
26
- throw new Error("Illegal ogg/Opus magic-signature");
27
+ throw new OpusContentError("Illegal ogg/Opus magic-signature");
27
28
  this.metadata.setFormat('sampleRate', this.idHeader.inputSampleRate);
28
29
  this.metadata.setFormat('numberOfChannels', this.idHeader.channelCount);
29
30
  }
@@ -2,6 +2,20 @@ import { type IVorbisPicture } from './Vorbis.js';
2
2
  import type { IPageConsumer, IPageHeader } from '../Ogg.js';
3
3
  import type { IOptions } from '../../type.js';
4
4
  import type { INativeMetadataCollector } from '../../common/MetadataCollector.js';
5
+ declare const VorbisContentError_base: {
6
+ new (message: string): {
7
+ readonly fileType: string;
8
+ toString(): string;
9
+ name: "UnexpectedFileContentError";
10
+ message: string;
11
+ stack?: string;
12
+ };
13
+ captureStackTrace(targetObject: object, constructorOpt?: Function): void;
14
+ prepareStackTrace?: ((err: Error, stackTraces: NodeJS.CallSite[]) => any) | undefined;
15
+ stackTraceLimit: number;
16
+ };
17
+ export declare class VorbisContentError extends VorbisContentError_base {
18
+ }
5
19
  /**
6
20
  * Vorbis 1 Parser.
7
21
  * Used by OggParser
@@ -34,3 +48,4 @@ export declare class VorbisParser implements IPageConsumer {
34
48
  */
35
49
  protected parseUserCommentList(pageData: Uint8Array, offset: number): Promise<void>;
36
50
  }
51
+ export {};
@@ -2,7 +2,10 @@ import * as Token from 'token-types';
2
2
  import debugInit from 'debug';
3
3
  import { VorbisDecoder } from './VorbisDecoder.js';
4
4
  import { CommonHeader, IdentificationHeader, VorbisPictureToken } from './Vorbis.js';
5
+ import { makeUnexpectedFileContentError } from '../../ParseError.js';
5
6
  const debug = debugInit('music-metadata:parser:ogg:vorbis1');
7
+ export class VorbisContentError extends makeUnexpectedFileContentError('Vorbis') {
8
+ }
6
9
  /**
7
10
  * Vorbis 1 Parser.
8
11
  * Used by OggParser
@@ -25,7 +28,7 @@ export class VorbisParser {
25
28
  else {
26
29
  if (header.headerType.continued) {
27
30
  if (this.pageSegments.length === 0) {
28
- throw new Error('Cannot continue on previous page');
31
+ throw new VorbisContentError('Cannot continue on previous page');
29
32
  }
30
33
  this.pageSegments.push(pageData);
31
34
  }
@@ -93,7 +96,7 @@ export class VorbisParser {
93
96
  // Parse Vorbis common header
94
97
  const commonHeader = CommonHeader.get(pageData, 0);
95
98
  if (commonHeader.vorbis !== 'vorbis')
96
- throw new Error('Metadata does not look like Vorbis');
99
+ throw new VorbisContentError('Metadata does not look like Vorbis');
97
100
  if (commonHeader.packetType === 1) {
98
101
  const idHeader = IdentificationHeader.get(pageData, CommonHeader.len);
99
102
  this.metadata.setFormat('sampleRate', idHeader.sampleRate);
@@ -102,7 +105,7 @@ export class VorbisParser {
102
105
  debug('sample-rate=%s[hz], bitrate=%s[b/s], channel-mode=%s', idHeader.sampleRate, idHeader.bitrateNominal, idHeader.channelMode);
103
106
  }
104
107
  else
105
- throw new Error('First Ogg page should be type 1: the identification header');
108
+ throw new VorbisContentError('First Ogg page should be type 1: the identification header');
106
109
  }
107
110
  async parseFullPage(pageData) {
108
111
  // New page
@@ -1,5 +1,19 @@
1
1
  import type { IGetToken } from 'strtok3';
2
2
  import type { IChunkHeader } from '../iff/index.js';
3
+ declare const WaveContentError_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 WaveContentError extends WaveContentError_base {
16
+ }
3
17
  /**
4
18
  * Ref: https://msdn.microsoft.com/en-us/library/windows/desktop/dd317599(v=vs.85).aspx
5
19
  */
@@ -61,3 +75,4 @@ export declare class FactChunk implements IGetToken<IFactChunk> {
61
75
  constructor(header: IChunkHeader);
62
76
  get(buf: Uint8Array, off: number): IFactChunk;
63
77
  }
78
+ export {};
@@ -1,4 +1,7 @@
1
1
  import * as Token from 'token-types';
2
+ import { makeUnexpectedFileContentError } from '../ParseError.js';
3
+ export class WaveContentError extends makeUnexpectedFileContentError('Wave') {
4
+ }
2
5
  /**
3
6
  * Ref: https://msdn.microsoft.com/en-us/library/windows/desktop/dd317599(v=vs.85).aspx
4
7
  */
@@ -27,7 +30,7 @@ export var WaveFormat;
27
30
  export class Format {
28
31
  constructor(header) {
29
32
  if (header.chunkSize < 16)
30
- throw new Error('Invalid chunk size');
33
+ throw new WaveContentError('Invalid chunk size');
31
34
  this.len = header.chunkSize;
32
35
  }
33
36
  get(buf, off) {
@@ -49,7 +52,7 @@ export class Format {
49
52
  export class FactChunk {
50
53
  constructor(header) {
51
54
  if (header.chunkSize < 4) {
52
- throw new Error('Invalid fact chunk size.');
55
+ throw new WaveContentError('Invalid fact chunk size.');
53
56
  }
54
57
  this.len = header.chunkSize;
55
58
  }