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
@@ -1,11 +1,11 @@
1
- import { IGetToken } from 'strtok3';
1
+ import { type IGetToken } from 'strtok3';
2
2
  import { BasicParser } from '../common/BasicParser.js';
3
- import * as Ogg from './Ogg.js';
3
+ import type * as Ogg from './Ogg.js';
4
4
  export declare class SegmentTable implements IGetToken<Ogg.ISegmentTable> {
5
5
  private static sum;
6
6
  len: number;
7
7
  constructor(header: Ogg.IPageHeader);
8
- get(buf: any, off: any): Ogg.ISegmentTable;
8
+ get(buf: Uint8Array, off: number): Ogg.ISegmentTable;
9
9
  }
10
10
  /**
11
11
  * Parser for Ogg logical bitstream framing
@@ -11,9 +11,10 @@ import { TheoraParser } from './theora/TheoraParser.js';
11
11
  const debug = initDebug('music-metadata:parser:ogg');
12
12
  export class SegmentTable {
13
13
  static sum(buf, off, len) {
14
+ const dv = new DataView(buf.buffer, 0);
14
15
  let s = 0;
15
16
  for (let i = off; i < off + len; ++i) {
16
- s += buf[i];
17
+ s += dv.getUint8(i);
17
18
  }
18
19
  return s;
19
20
  }
@@ -30,6 +31,12 @@ export class SegmentTable {
30
31
  * Parser for Ogg logical bitstream framing
31
32
  */
32
33
  export class OggParser extends BasicParser {
34
+ constructor() {
35
+ super(...arguments);
36
+ this.header = null;
37
+ this.pageNumber = 0;
38
+ this.pageConsumer = null;
39
+ }
33
40
  /**
34
41
  * Parse page
35
42
  * @returns {Promise<void>}
@@ -71,31 +78,32 @@ export class OggParser extends BasicParser {
71
78
  this.pageConsumer = new TheoraParser(this.metadata, this.options, this.tokenizer);
72
79
  break;
73
80
  default:
74
- throw new Error('gg audio-codec not recognized (id=' + id + ')');
81
+ throw new Error(`gg audio-codec not recognized (id=${id})`);
75
82
  }
76
83
  }
77
84
  await this.pageConsumer.parsePage(header, pageData);
78
85
  } while (!header.headerType.lastPage);
79
86
  }
80
87
  catch (err) {
81
- if (err instanceof EndOfStreamError) {
82
- this.metadata.addWarning('Last OGG-page is not marked with last-page flag');
83
- debug(`End-of-stream`);
84
- this.metadata.addWarning('Last OGG-page is not marked with last-page flag');
85
- if (this.header) {
86
- this.pageConsumer.calculateDuration(this.header);
88
+ if (err instanceof Error) {
89
+ if (err instanceof EndOfStreamError) {
90
+ this.metadata.addWarning('Last OGG-page is not marked with last-page flag');
91
+ debug("End-of-stream");
92
+ this.metadata.addWarning('Last OGG-page is not marked with last-page flag');
93
+ if (this.header) {
94
+ this.pageConsumer.calculateDuration(this.header);
95
+ }
87
96
  }
88
- }
89
- else if (err.message.startsWith('FourCC')) {
90
- if (this.pageNumber > 0) {
91
- // ignore this error: work-around if last OGG-page is not marked with last-page flag
92
- this.metadata.addWarning('Invalid FourCC ID, maybe last OGG-page is not marked with last-page flag');
93
- await this.pageConsumer.flush();
97
+ else if (err.message.startsWith('FourCC')) {
98
+ if (this.pageNumber > 0) {
99
+ // ignore this error: work-around if last OGG-page is not marked with last-page flag
100
+ this.metadata.addWarning('Invalid FourCC ID, maybe last OGG-page is not marked with last-page flag');
101
+ await this.pageConsumer.flush();
102
+ }
94
103
  }
95
104
  }
96
- else {
105
+ else
97
106
  throw err;
98
- }
99
107
  }
100
108
  }
101
109
  }
@@ -119,3 +127,4 @@ OggParser.Header = {
119
127
  };
120
128
  }
121
129
  };
130
+ //# sourceMappingURL=OggParser.js.map
@@ -44,5 +44,5 @@ export interface IIdHeader {
44
44
  export declare class IdHeader implements IGetToken<IIdHeader> {
45
45
  len: number;
46
46
  constructor(len: number);
47
- get(buf: any, off: any): IIdHeader;
47
+ get(buf: Uint8Array, off: number): IIdHeader;
48
48
  }
@@ -22,3 +22,4 @@ export class IdHeader {
22
22
  };
23
23
  }
24
24
  }
25
+ //# sourceMappingURL=Opus.js.map
@@ -1,8 +1,8 @@
1
- import { ITokenizer } from 'strtok3';
2
- import { IPageHeader } from '../Ogg.js';
1
+ import type { ITokenizer } from 'strtok3';
2
+ import type { IPageHeader } from '../Ogg.js';
3
3
  import { VorbisParser } from '../vorbis/VorbisParser.js';
4
- import { IOptions } from '../../type.js';
5
- import { INativeMetadataCollector } from '../../common/MetadataCollector.js';
4
+ import type { IOptions } from '../../type.js';
5
+ import type { INativeMetadataCollector } from '../../common/MetadataCollector.js';
6
6
  /**
7
7
  * Opus parser
8
8
  * Internet Engineering Task Force (IETF) - RFC 6716
@@ -10,6 +10,7 @@ export class OpusParser extends VorbisParser {
10
10
  constructor(metadata, options, tokenizer) {
11
11
  super(metadata, options);
12
12
  this.tokenizer = tokenizer;
13
+ this.idHeader = null;
13
14
  this.lastPos = -1;
14
15
  }
15
16
  /**
@@ -50,3 +51,4 @@ export class OpusParser extends VorbisParser {
50
51
  }
51
52
  }
52
53
  }
54
+ //# sourceMappingURL=OpusParser.js.map
@@ -26,3 +26,4 @@ export const Header = {
26
26
  };
27
27
  }
28
28
  };
29
+ //# sourceMappingURL=Speex.js.map
@@ -1,8 +1,8 @@
1
- import { ITokenizer } from 'strtok3';
2
- import { IPageHeader } from '../Ogg.js';
1
+ import type { ITokenizer } from 'strtok3';
2
+ import type { IPageHeader } from '../Ogg.js';
3
3
  import { VorbisParser } from '../vorbis/VorbisParser.js';
4
- import { IOptions } from '../../type.js';
5
- import { INativeMetadataCollector } from '../../common/MetadataCollector.js';
4
+ import type { IOptions } from '../../type.js';
5
+ import type { INativeMetadataCollector } from '../../common/MetadataCollector.js';
6
6
  /**
7
7
  * Speex, RFC 5574
8
8
  * Ref:
@@ -29,3 +29,4 @@ export class SpeexParser extends VorbisParser {
29
29
  }
30
30
  }
31
31
  }
32
+ //# sourceMappingURL=SpeexParser.js.map
@@ -18,3 +18,4 @@ export const IdentificationHeader = {
18
18
  };
19
19
  }
20
20
  };
21
+ //# sourceMappingURL=Theora.js.map
@@ -1,7 +1,7 @@
1
- import { ITokenizer } from 'strtok3';
2
- import * as Ogg from '../Ogg.js';
3
- import { IOptions } from '../../type.js';
4
- import { INativeMetadataCollector } from '../../common/MetadataCollector.js';
1
+ import type { ITokenizer } from 'strtok3';
2
+ import type * as Ogg from '../Ogg.js';
3
+ import type { IOptions } from '../../type.js';
4
+ import type { INativeMetadataCollector } from '../../common/MetadataCollector.js';
5
5
  /**
6
6
  * Ref:
7
7
  * - https://theora.org/doc/Theora.pdf
@@ -38,3 +38,4 @@ export class TheoraParser {
38
38
  this.metadata.setFormat('bitrate', idHeader.nombr);
39
39
  }
40
40
  }
41
+ //# sourceMappingURL=TheoraParser.js.map
@@ -1,4 +1,4 @@
1
- import { IPicture } from '../../type.js';
1
+ import type { IPicture } from '../../type.js';
2
2
  import type { IGetToken } from 'strtok3';
3
3
  /**
4
4
  * Interface to parsed result of METADATA_BLOCK_PICTURE
@@ -20,10 +20,10 @@ export interface IVorbisPicture extends IPicture {
20
20
  * // ToDo: move to ID3 / APIC?
21
21
  */
22
22
  export declare class VorbisPictureToken implements IGetToken<IVorbisPicture> {
23
- len: any;
23
+ len: number;
24
24
  static fromBase64(base64str: string): IVorbisPicture;
25
25
  static fromBuffer(buffer: Uint8Array): IVorbisPicture;
26
- constructor(len: any);
26
+ constructor(len: number);
27
27
  get(buffer: Uint8Array, offset: number): IVorbisPicture;
28
28
  }
29
29
  /**
@@ -8,7 +8,7 @@ import { AttachedPictureType } from '../../id3v2/ID3v2Token.js';
8
8
  */
9
9
  export class VorbisPictureToken {
10
10
  static fromBase64(base64str) {
11
- return this.fromBuffer(Uint8Array.from(atob(base64str), c => c.charCodeAt(0)));
11
+ return VorbisPictureToken.fromBuffer(Uint8Array.from(atob(base64str), c => c.charCodeAt(0)));
12
12
  }
13
13
  static fromBuffer(buffer) {
14
14
  const pic = new VorbisPictureToken(buffer.length);
@@ -19,16 +19,26 @@ export class VorbisPictureToken {
19
19
  }
20
20
  get(buffer, offset) {
21
21
  const type = AttachedPictureType[Token.UINT32_BE.get(buffer, offset)];
22
- const mimeLen = Token.UINT32_BE.get(buffer, offset += 4);
23
- const format = new Token.StringType(mimeLen, 'utf-8').get(buffer, offset += 4);
24
- const descLen = Token.UINT32_BE.get(buffer, offset += mimeLen);
25
- const description = new Token.StringType(descLen, 'utf-8').get(buffer, offset += 4);
26
- const width = Token.UINT32_BE.get(buffer, offset += descLen);
27
- const height = Token.UINT32_BE.get(buffer, offset += 4);
28
- const colour_depth = Token.UINT32_BE.get(buffer, offset += 4);
29
- const indexed_color = Token.UINT32_BE.get(buffer, offset += 4);
30
- const picDataLen = Token.UINT32_BE.get(buffer, offset += 4);
31
- const data = Uint8Array.from(buffer.slice(offset += 4, offset + picDataLen));
22
+ offset += 4;
23
+ const mimeLen = Token.UINT32_BE.get(buffer, offset);
24
+ offset += 4;
25
+ const format = new Token.StringType(mimeLen, 'utf-8').get(buffer, offset);
26
+ offset += mimeLen;
27
+ const descLen = Token.UINT32_BE.get(buffer, offset);
28
+ offset += 4;
29
+ const description = new Token.StringType(descLen, 'utf-8').get(buffer, offset);
30
+ offset += descLen;
31
+ const width = Token.UINT32_BE.get(buffer, offset);
32
+ offset += 4;
33
+ const height = Token.UINT32_BE.get(buffer, offset);
34
+ offset += 4;
35
+ const colour_depth = Token.UINT32_BE.get(buffer, offset);
36
+ offset += 4;
37
+ const indexed_color = Token.UINT32_BE.get(buffer, offset);
38
+ offset += 4;
39
+ const picDataLen = Token.UINT32_BE.get(buffer, offset);
40
+ offset += 4;
41
+ const data = Uint8Array.from(buffer.slice(offset, offset + picDataLen));
32
42
  return {
33
43
  type,
34
44
  format,
@@ -71,3 +81,4 @@ export const IdentificationHeader = {
71
81
  };
72
82
  }
73
83
  };
84
+ //# sourceMappingURL=Vorbis.js.map
@@ -1,7 +1,7 @@
1
1
  export declare class VorbisDecoder {
2
2
  private readonly data;
3
3
  private offset;
4
- constructor(data: Uint8Array, offset: any);
4
+ constructor(data: Uint8Array, offset: number);
5
5
  readInt32(): number;
6
6
  readStringUtf8(): string;
7
7
  parseUserComment(): {
@@ -26,3 +26,4 @@ export class VorbisDecoder {
26
26
  };
27
27
  }
28
28
  }
29
+ //# sourceMappingURL=VorbisDecoder.js.map
@@ -1,7 +1,7 @@
1
- import { IVorbisPicture } from './Vorbis.js';
2
- import { IPageConsumer, IPageHeader } from '../Ogg.js';
3
- import { IOptions } from '../../type.js';
4
- import { INativeMetadataCollector } from '../../common/MetadataCollector.js';
1
+ import { type IVorbisPicture } from './Vorbis.js';
2
+ import type { IPageConsumer, IPageHeader } from '../Ogg.js';
3
+ import type { IOptions } from '../../type.js';
4
+ import type { INativeMetadataCollector } from '../../common/MetadataCollector.js';
5
5
  /**
6
6
  * Vorbis 1 Parser.
7
7
  * Used by OggParser
@@ -64,7 +64,7 @@ export class VorbisParser {
64
64
  async addTag(id, value) {
65
65
  if (id === 'METADATA_BLOCK_PICTURE' && (typeof value === 'string')) {
66
66
  if (this.options.skipCovers) {
67
- debug(`Ignore picture`);
67
+ debug("Ignore picture");
68
68
  return;
69
69
  }
70
70
  value = VorbisPictureToken.fromBase64(value);
@@ -79,7 +79,7 @@ export class VorbisParser {
79
79
  if (this.metadata.format.sampleRate && header.absoluteGranulePosition >= 0) {
80
80
  // Calculate duration
81
81
  this.metadata.setFormat('numberOfSamples', header.absoluteGranulePosition);
82
- this.metadata.setFormat('duration', this.metadata.format.numberOfSamples / this.metadata.format.sampleRate);
82
+ this.metadata.setFormat('duration', header.absoluteGranulePosition / this.metadata.format.sampleRate);
83
83
  }
84
84
  }
85
85
  /**
@@ -131,3 +131,4 @@ export class VorbisParser {
131
131
  }
132
132
  }
133
133
  }
134
+ //# sourceMappingURL=VorbisParser.js.map
@@ -1,7 +1,7 @@
1
1
  import { CommonTagMapper } from '../../common/GenericTagMapper.js';
2
- import { IRating, ITag } from '../../type.js';
2
+ import type { IRating, ITag } from '../../type.js';
3
3
  export declare class VorbisTagMapper extends CommonTagMapper {
4
- static toRating(email: string, rating: string, maxScore: number): IRating;
4
+ static toRating(email: string | undefined | null, rating: string, maxScore: number): IRating;
5
5
  constructor();
6
6
  protected postMap(tag: ITag): void;
7
7
  }
@@ -112,8 +112,8 @@ const vorbisTagMap = {
112
112
  export class VorbisTagMapper extends CommonTagMapper {
113
113
  static toRating(email, rating, maxScore) {
114
114
  return {
115
- source: email ? email.toLowerCase() : email,
116
- rating: (parseFloat(rating) / maxScore) * CommonTagMapper.maxRatingScore
115
+ source: email ? email.toLowerCase() : undefined,
116
+ rating: (Number.parseFloat(rating) / maxScore) * CommonTagMapper.maxRatingScore
117
117
  };
118
118
  }
119
119
  constructor() {
@@ -1,6 +1,6 @@
1
1
  import type { IGetToken } from 'strtok3';
2
- import { IChunkHeader } from '../iff/index.js';
3
- export { IChunkHeader } from '../iff/index.js';
2
+ import type { IChunkHeader } from '../iff/index.js';
3
+ export { type IChunkHeader } from '../iff/index.js';
4
4
  /**
5
5
  * Common RIFF chunk header
6
6
  */
@@ -12,5 +12,5 @@ export declare class ListInfoTagValue implements IGetToken<string> {
12
12
  private tagHeader;
13
13
  len: number;
14
14
  constructor(tagHeader: IChunkHeader);
15
- get(buf: any, off: any): string;
15
+ get(buf: Uint8Array, off: number): string;
16
16
  }
@@ -26,3 +26,4 @@ export class ListInfoTagValue {
26
26
  return new Token.StringType(this.tagHeader.chunkSize, 'ascii').get(buf, off);
27
27
  }
28
28
  }
29
+ //# sourceMappingURL=RiffChunk.js.map
@@ -1,4 +1,4 @@
1
- import { INativeTagMap } from '../common/GenericTagTypes.js';
1
+ import type { INativeTagMap } from '../common/GenericTagTypes.js';
2
2
  import { CommonTagMapper } from '../common/GenericTagMapper.js';
3
3
  /**
4
4
  * RIFF Info Tags; part of the EXIF 2.3
package/lib/type.d.ts CHANGED
@@ -1,9 +1,10 @@
1
- import { GenericTagId, TagType } from './common/GenericTagTypes.js';
2
- import { IFooter } from './apev2/APEv2Token.js';
3
- import { TrackType } from './matroska/types.js';
4
- import { LyricsContentType, TimestampFormat } from './id3v2/ID3v2Token.js';
1
+ import type { TagType } from './common/GenericTagTypes.js';
2
+ import type { IFooter } from './apev2/APEv2Token.js';
3
+ import type { TrackType } from './matroska/types.js';
4
+ import type { LyricsContentType, TimestampFormat } from './id3v2/ID3v2Token.js';
5
5
  export { TrackType } from './matroska/types.js';
6
6
  export { LyricsContentType, TimestampFormat } from './id3v2/ID3v2Token.js';
7
+ export type AnyTagValue = unknown;
7
8
  /**
8
9
  * Attached picture, typically used for cover art
9
10
  */
@@ -40,7 +41,7 @@ export interface IRating {
40
41
  /**
41
42
  * Rating [0..1]
42
43
  */
43
- rating: number;
44
+ rating?: number;
44
45
  }
45
46
  export interface ICommonTagsResult {
46
47
  track: {
@@ -159,6 +160,10 @@ export interface ICommonTagsResult {
159
160
  * Engineer(s)
160
161
  */
161
162
  engineer?: string[];
163
+ /**
164
+ * Publisher(s)
165
+ */
166
+ publisher?: string[];
162
167
  /**
163
168
  * Producer(s)
164
169
  */
@@ -293,9 +298,13 @@ export interface ICommonTagsResult {
293
298
  rightChannel: number;
294
299
  };
295
300
  /**
296
- * minimum & maximum global gain values across a set of files scanned as an album
301
+ * minimum & maximum global gain values across a set of file
297
302
  */
298
303
  replaygain_track_minmax?: number[];
304
+ /**
305
+ * minimum & maximum global gain values across a set of files scanned as an album
306
+ */
307
+ replaygain_album_minmax?: number[];
299
308
  /**
300
309
  * The initial key of the music in the file, e.g. "A Minor".
301
310
  * Ref: https://docs.microsoft.com/en-us/windows/win32/wmformat/wm-initialkey
@@ -325,8 +334,8 @@ export interface ICommonTagsResult {
325
334
  * Movement Index/Total
326
335
  */
327
336
  movementIndex: {
328
- no?: number;
329
- of?: number;
337
+ no: number | null;
338
+ of: number | null;
330
339
  };
331
340
  /**
332
341
  * Podcast Identifier
@@ -402,7 +411,7 @@ export interface IFormat {
402
411
  /**
403
412
  * List of tags found in parsed audio file
404
413
  */
405
- readonly tagTypes?: TagType[];
414
+ readonly tagTypes: TagType[];
406
415
  /**
407
416
  * Duration in seconds
408
417
  */
@@ -464,7 +473,7 @@ export interface IFormat {
464
473
  }
465
474
  export interface ITag {
466
475
  id: string;
467
- value: any;
476
+ value: AnyTagValue;
468
477
  }
469
478
  export interface IChapter {
470
479
  /**
@@ -487,7 +496,7 @@ export interface INativeTags {
487
496
  * Tags ordered by tag-ID
488
497
  */
489
498
  export interface INativeTagDict {
490
- [tagId: string]: any[];
499
+ [tagId: string]: AnyTagValue[];
491
500
  }
492
501
  export interface INativeAudioMetadata {
493
502
  format: IFormat;
@@ -549,6 +558,20 @@ export interface IApeHeader extends IOptions {
549
558
  export interface IPrivateOptions extends IOptions {
550
559
  apeHeader?: IApeHeader;
551
560
  }
561
+ export interface IMetadataEventTag {
562
+ /**
563
+ * Either `common` if it is a generic tag event, or `format` for format related updates
564
+ */
565
+ type: 'common' | 'format';
566
+ /**
567
+ * Tag id
568
+ */
569
+ id: keyof ICommonTagsResult | FormatId;
570
+ /**
571
+ * Tag value
572
+ */
573
+ value: AnyTagValue;
574
+ }
552
575
  /**
553
576
  * Event definition send after each change to common/format metadata change to observer.
554
577
  */
@@ -556,20 +579,7 @@ export interface IMetadataEvent {
556
579
  /**
557
580
  * Tag which has been updated.
558
581
  */
559
- tag: {
560
- /**
561
- * Either 'common' if it a generic tag event, or 'format' for format related updates
562
- */
563
- type: 'common' | 'format';
564
- /**
565
- * Tag id
566
- */
567
- id: GenericTagId | FormatId;
568
- /**
569
- * Tag value
570
- */
571
- value: any;
572
- };
582
+ tag: IMetadataEventTag;
573
583
  /**
574
584
  * Metadata model including the attached tag
575
585
  */
@@ -24,3 +24,4 @@ export const BroadcastAudioExtensionChunk = {
24
24
  };
25
25
  }
26
26
  };
27
+ //# sourceMappingURL=BwfChunk.js.map
@@ -1,5 +1,5 @@
1
1
  import type { IGetToken } from 'strtok3';
2
- import { IChunkHeader } from '../iff/index.js';
2
+ import type { IChunkHeader } from '../iff/index.js';
3
3
  /**
4
4
  * Ref: https://msdn.microsoft.com/en-us/library/windows/desktop/dd317599(v=vs.85).aspx
5
5
  */
@@ -59,3 +59,4 @@ export class FactChunk {
59
59
  };
60
60
  }
61
61
  }
62
+ //# sourceMappingURL=WaveChunk.js.map
@@ -2,12 +2,12 @@ import * as strtok3 from 'strtok3';
2
2
  import * as Token from 'token-types';
3
3
  import initDebug from 'debug';
4
4
  import * as riff from '../riff/RiffChunk.js';
5
- import * as WaveChunk from './../wav/WaveChunk.js';
5
+ import * as WaveChunk from './WaveChunk.js';
6
6
  import { ID3v2Parser } from '../id3v2/ID3v2Parser.js';
7
7
  import * as util from '../common/Util.js';
8
8
  import { FourCcToken } from '../common/FourCC.js';
9
9
  import { BasicParser } from '../common/BasicParser.js';
10
- import { BroadcastAudioExtensionChunk } from '../wav/BwfChunk.js';
10
+ import { BroadcastAudioExtensionChunk } from './BwfChunk.js';
11
11
  const debug = initDebug('music-metadata:parser:RIFF');
12
12
  /**
13
13
  * Resource Interchange File Format (RIFF) Parser
@@ -21,6 +21,10 @@ const debug = initDebug('music-metadata:parser:RIFF');
21
21
  * ToDo: Split WAVE part from RIFF parser
22
22
  */
23
23
  export class WaveParser extends BasicParser {
24
+ constructor() {
25
+ super(...arguments);
26
+ this.blockAlign = 0;
27
+ }
24
28
  async parse() {
25
29
  const riffHeader = await this.tokenizer.readToken(riff.Header);
26
30
  debug(`pos=${this.tokenizer.position}, parse: chunkID=${riffHeader.chunkID}`);
@@ -59,12 +63,12 @@ export class WaveParser extends BasicParser {
59
63
  this.metadata.setFormat('lossless', false);
60
64
  this.fact = await this.tokenizer.readToken(new WaveChunk.FactChunk(header));
61
65
  break;
62
- case 'fmt ': // The Util Chunk, non-PCM Formats
66
+ case 'fmt ': { // The Util Chunk, non-PCM Formats
63
67
  const fmt = await this.tokenizer.readToken(new WaveChunk.Format(header));
64
68
  let subFormat = WaveChunk.WaveFormat[fmt.wFormatTag];
65
69
  if (!subFormat) {
66
- debug('WAVE/non-PCM format=' + fmt.wFormatTag);
67
- subFormat = 'non-PCM (' + fmt.wFormatTag + ')';
70
+ debug(`WAVE/non-PCM format=${fmt.wFormatTag}`);
71
+ subFormat = `non-PCM (${fmt.wFormatTag})`;
68
72
  }
69
73
  this.metadata.setFormat('codec', subFormat);
70
74
  this.metadata.setFormat('bitsPerSample', fmt.wBitsPerSample);
@@ -73,13 +77,15 @@ export class WaveParser extends BasicParser {
73
77
  this.metadata.setFormat('bitrate', fmt.nBlockAlign * fmt.nSamplesPerSec * 8);
74
78
  this.blockAlign = fmt.nBlockAlign;
75
79
  break;
80
+ }
76
81
  case 'id3 ': // The way Picard, FooBar currently stores, ID3 meta-data
77
- case 'ID3 ': // The way Mp3Tags stores ID3 meta-data
82
+ case 'ID3 ': { // The way Mp3Tags stores ID3 meta-data
78
83
  const id3_data = await this.tokenizer.readToken(new Token.Uint8ArrayType(header.chunkSize));
79
84
  const rst = strtok3.fromBuffer(id3_data);
80
85
  await new ID3v2Parser().parse(this.metadata, rst, this.options);
81
86
  break;
82
- case 'data': // PCM-data
87
+ }
88
+ case 'data': { // PCM-data
83
89
  if (this.metadata.format.lossless !== false) {
84
90
  this.metadata.setFormat('lossless', true);
85
91
  }
@@ -94,32 +100,36 @@ export class WaveParser extends BasicParser {
94
100
  const numberOfSamples = this.fact ? this.fact.dwSampleLength : (chunkSize === 0xffffffff ? undefined : chunkSize / this.blockAlign);
95
101
  if (numberOfSamples) {
96
102
  this.metadata.setFormat('numberOfSamples', numberOfSamples);
97
- this.metadata.setFormat('duration', numberOfSamples / this.metadata.format.sampleRate);
103
+ if (this.metadata.format.sampleRate) {
104
+ this.metadata.setFormat('duration', numberOfSamples / this.metadata.format.sampleRate);
105
+ }
98
106
  }
99
107
  if (this.metadata.format.codec === 'ADPCM') { // ADPCM is 4 bits lossy encoding resulting in 352kbps
100
108
  this.metadata.setFormat('bitrate', 352000);
101
109
  }
102
- else {
110
+ else if (this.metadata.format.sampleRate) {
103
111
  this.metadata.setFormat('bitrate', this.blockAlign * this.metadata.format.sampleRate * 8);
104
112
  }
105
113
  await this.tokenizer.ignore(header.chunkSize);
106
114
  break;
107
- case 'bext': // Broadcast Audio Extension chunk https://tech.ebu.ch/docs/tech/tech3285.pdf
115
+ }
116
+ case 'bext': { // Broadcast Audio Extension chunk https://tech.ebu.ch/docs/tech/tech3285.pdf
108
117
  const bext = await this.tokenizer.readToken(BroadcastAudioExtensionChunk);
109
118
  Object.keys(bext).forEach(key => {
110
- this.metadata.addTag('exif', 'bext.' + key, bext[key]);
119
+ this.metadata.addTag('exif', `bext.${key}`, bext[key]);
111
120
  });
112
121
  const bextRemaining = header.chunkSize - BroadcastAudioExtensionChunk.len;
113
122
  await this.tokenizer.ignore(bextRemaining);
114
123
  break;
124
+ }
115
125
  case '\x00\x00\x00\x00': // padding ??
116
126
  debug(`Ignore padding chunk: RIFF/${header.chunkID} of ${header.chunkSize} bytes`);
117
- this.metadata.addWarning('Ignore chunk: RIFF/' + header.chunkID);
127
+ this.metadata.addWarning(`Ignore chunk: RIFF/${header.chunkID}`);
118
128
  await this.tokenizer.ignore(header.chunkSize);
119
129
  break;
120
130
  default:
121
131
  debug(`Ignore chunk: RIFF/${header.chunkID} of ${header.chunkSize} bytes`);
122
- this.metadata.addWarning('Ignore chunk: RIFF/' + header.chunkID);
132
+ this.metadata.addWarning(`Ignore chunk: RIFF/${header.chunkID}`);
123
133
  await this.tokenizer.ignore(header.chunkSize);
124
134
  }
125
135
  if (this.header.chunkSize % 2 === 1) {
@@ -134,10 +144,9 @@ export class WaveParser extends BasicParser {
134
144
  switch (listType) {
135
145
  case 'INFO':
136
146
  return this.parseRiffInfoTags(listHeader.chunkSize - 4);
137
- case 'adtl':
138
147
  default:
139
- this.metadata.addWarning('Ignore chunk: RIFF/WAVE/LIST/' + listType);
140
- debug('Ignoring chunkID=RIFF/WAVE/LIST/' + listType);
148
+ this.metadata.addWarning(`Ignore chunk: RIFF/WAVE/LIST/${listType}`);
149
+ debug(`Ignoring chunkID=RIFF/WAVE/LIST/${listType}`);
141
150
  return this.tokenizer.ignore(listHeader.chunkSize - 4).then();
142
151
  }
143
152
  }
@@ -150,10 +159,11 @@ export class WaveParser extends BasicParser {
150
159
  chunkSize -= (8 + valueToken.len);
151
160
  }
152
161
  if (chunkSize !== 0) {
153
- throw Error('Illegal remaining size: ' + chunkSize);
162
+ throw new Error(`Illegal remaining size: ${chunkSize}`);
154
163
  }
155
164
  }
156
165
  addTag(id, value) {
157
166
  this.metadata.addTag('exif', id, value);
158
167
  }
159
168
  }
169
+ //# sourceMappingURL=WaveParser.js.map
@@ -9,7 +9,7 @@ export declare class WavPackParser extends BasicParser {
9
9
  /**
10
10
  * Ref: http://www.wavpack.com/WavPack5FileFormat.pdf, 3.0 Metadata Sub-blocks
11
11
  * @param header Header
12
- * @param remainingLength
12
+ * @param remainingLength Remaining length
13
13
  */
14
14
  private parseMetadataSubBlock;
15
15
  }