music-metadata 7.12.6 → 8.0.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 (154) hide show
  1. package/README.md +47 -31
  2. package/lib/ParserFactory.js +37 -41
  3. package/lib/aiff/AiffParser.js +12 -16
  4. package/lib/aiff/AiffToken.js +4 -8
  5. package/lib/apev2/APEv2Parser.js +29 -32
  6. package/lib/apev2/APEv2TagMapper.js +2 -6
  7. package/lib/apev2/APEv2Token.js +13 -19
  8. package/lib/asf/AsfObject.js +42 -56
  9. package/lib/asf/AsfParser.js +15 -19
  10. package/lib/asf/AsfTagMapper.js +2 -6
  11. package/lib/asf/AsfUtil.js +4 -7
  12. package/lib/asf/GUID.js +1 -4
  13. package/lib/common/BasicParser.js +1 -5
  14. package/lib/common/CaseInsensitiveTagMap.js +2 -6
  15. package/lib/common/CombinedTagMapper.js +20 -24
  16. package/lib/common/FourCC.js +3 -6
  17. package/lib/common/GenericTagMapper.js +2 -6
  18. package/lib/common/GenericTagTypes.js +5 -10
  19. package/lib/common/MetadataCollector.js +20 -25
  20. package/lib/common/RandomFileReader.js +2 -6
  21. package/lib/common/RandomUint8ArrayReader.js +1 -5
  22. package/lib/common/Util.js +11 -25
  23. package/lib/core.js +18 -28
  24. package/lib/dsdiff/DsdiffParser.js +24 -28
  25. package/lib/dsdiff/DsdiffToken.js +4 -7
  26. package/lib/dsf/DsfChunk.js +8 -11
  27. package/lib/dsf/DsfParser.js +13 -17
  28. package/lib/flac/FlacParser.js +22 -26
  29. package/lib/id3v1/ID3v1Parser.js +16 -21
  30. package/lib/id3v1/ID3v1TagMap.js +2 -6
  31. package/lib/id3v2/AbstractID3Parser.js +13 -17
  32. package/lib/id3v2/FrameParser.js +12 -17
  33. package/lib/id3v2/ID3v22TagMapper.js +4 -8
  34. package/lib/id3v2/ID3v24TagMapper.js +5 -9
  35. package/lib/id3v2/ID3v2Parser.js +10 -14
  36. package/lib/id3v2/ID3v2Token.js +9 -12
  37. package/lib/iff/index.js +4 -7
  38. package/lib/index.js +14 -44
  39. package/lib/lyrics3/Lyrics3.js +3 -7
  40. package/lib/matroska/MatroskaDtd.js +111 -114
  41. package/lib/matroska/MatroskaParser.js +20 -24
  42. package/lib/matroska/MatroskaTagMapper.js +2 -6
  43. package/lib/matroska/types.js +6 -9
  44. package/lib/mp4/Atom.js +4 -8
  45. package/lib/mp4/AtomToken.js +29 -44
  46. package/lib/mp4/MP4Parser.js +12 -16
  47. package/lib/mp4/MP4TagMapper.js +4 -8
  48. package/lib/mpeg/ExtendedLameHeader.js +6 -9
  49. package/lib/mpeg/MpegParser.js +17 -21
  50. package/lib/mpeg/ReplayGainDataFormat.js +2 -5
  51. package/lib/mpeg/XingTag.js +9 -13
  52. package/lib/musepack/index.js +10 -12
  53. package/lib/musepack/sv7/BitReader.js +2 -6
  54. package/lib/musepack/sv7/MpcSv7Parser.js +9 -13
  55. package/lib/musepack/sv7/StreamVersion7.js +3 -6
  56. package/lib/musepack/sv8/MpcSv8Parser.js +9 -13
  57. package/lib/musepack/sv8/StreamVersion8.js +5 -9
  58. package/lib/ogg/Ogg.js +1 -2
  59. package/lib/ogg/OggParser.js +19 -24
  60. package/lib/ogg/opus/Opus.js +2 -6
  61. package/lib/ogg/opus/OpusParser.js +4 -8
  62. package/lib/ogg/speex/Speex.js +3 -6
  63. package/lib/ogg/speex/SpeexParser.js +5 -9
  64. package/lib/ogg/theora/Theora.js +2 -5
  65. package/lib/ogg/theora/TheoraParser.js +5 -9
  66. package/lib/ogg/vorbis/Vorbis.js +6 -10
  67. package/lib/ogg/vorbis/VorbisDecoder.js +2 -6
  68. package/lib/ogg/vorbis/VorbisParser.js +18 -22
  69. package/lib/ogg/vorbis/VorbisTagMapper.js +3 -7
  70. package/lib/riff/RiffChunk.js +3 -7
  71. package/lib/riff/RiffInfoTagMap.js +4 -8
  72. package/lib/type.js +1 -5
  73. package/lib/wav/BwfChunk.js +8 -11
  74. package/lib/wav/WaveChunk.js +4 -9
  75. package/lib/wav/WaveParser.js +17 -21
  76. package/lib/wavpack/WavPackParser.js +17 -21
  77. package/lib/wavpack/WavPackToken.js +4 -8
  78. package/package.json +23 -33
  79. package/lib/ParserFactory.d.ts +0 -48
  80. package/lib/aiff/AiffParser.d.ts +0 -14
  81. package/lib/aiff/AiffToken.d.ts +0 -22
  82. package/lib/apev2/APEv2Parser.d.ts +0 -30
  83. package/lib/apev2/APEv2TagMapper.d.ts +0 -4
  84. package/lib/apev2/APEv2Token.d.ts +0 -100
  85. package/lib/asf/AsfObject.d.ts +0 -319
  86. package/lib/asf/AsfParser.d.ts +0 -17
  87. package/lib/asf/AsfTagMapper.d.ts +0 -7
  88. package/lib/asf/AsfUtil.d.ts +0 -13
  89. package/lib/asf/GUID.d.ts +0 -84
  90. package/lib/common/BasicParser.d.ts +0 -17
  91. package/lib/common/CaseInsensitiveTagMap.d.ts +0 -10
  92. package/lib/common/CombinedTagMapper.d.ts +0 -19
  93. package/lib/common/FourCC.d.ts +0 -6
  94. package/lib/common/GenericTagMapper.d.ts +0 -51
  95. package/lib/common/GenericTagTypes.d.ts +0 -33
  96. package/lib/common/MetadataCollector.d.ts +0 -76
  97. package/lib/common/RandomFileReader.d.ts +0 -22
  98. package/lib/common/RandomUint8ArrayReader.d.ts +0 -18
  99. package/lib/common/Util.d.ts +0 -57
  100. package/lib/core.d.ts +0 -48
  101. package/lib/dsdiff/DsdiffParser.d.ts +0 -14
  102. package/lib/dsdiff/DsdiffToken.d.ts +0 -9
  103. package/lib/dsf/DsfChunk.d.ts +0 -86
  104. package/lib/dsf/DsfParser.d.ts +0 -9
  105. package/lib/flac/FlacParser.d.ts +0 -28
  106. package/lib/id3v1/ID3v1Parser.d.ts +0 -13
  107. package/lib/id3v1/ID3v1TagMap.d.ts +0 -4
  108. package/lib/id3v2/AbstractID3Parser.d.ts +0 -17
  109. package/lib/id3v2/FrameParser.d.ts +0 -31
  110. package/lib/id3v2/ID3v22TagMapper.d.ts +0 -9
  111. package/lib/id3v2/ID3v24TagMapper.d.ts +0 -14
  112. package/lib/id3v2/ID3v2Parser.d.ts +0 -28
  113. package/lib/id3v2/ID3v2Token.d.ts +0 -73
  114. package/lib/iff/index.d.ts +0 -33
  115. package/lib/index.d.ts +0 -45
  116. package/lib/lyrics3/Lyrics3.d.ts +0 -3
  117. package/lib/matroska/MatroskaDtd.d.ts +0 -8
  118. package/lib/matroska/MatroskaParser.d.ts +0 -37
  119. package/lib/matroska/MatroskaTagMapper.d.ts +0 -4
  120. package/lib/matroska/types.d.ts +0 -175
  121. package/lib/mp4/Atom.d.ts +0 -16
  122. package/lib/mp4/AtomToken.d.ts +0 -395
  123. package/lib/mp4/MP4Parser.d.ts +0 -30
  124. package/lib/mp4/MP4TagMapper.d.ts +0 -5
  125. package/lib/mpeg/ExtendedLameHeader.d.ts +0 -27
  126. package/lib/mpeg/MpegParser.d.ts +0 -49
  127. package/lib/mpeg/ReplayGainDataFormat.d.ts +0 -55
  128. package/lib/mpeg/XingTag.d.ts +0 -45
  129. package/lib/musepack/index.d.ts +0 -5
  130. package/lib/musepack/sv7/BitReader.d.ts +0 -13
  131. package/lib/musepack/sv7/MpcSv7Parser.d.ts +0 -8
  132. package/lib/musepack/sv7/StreamVersion7.d.ts +0 -28
  133. package/lib/musepack/sv8/MpcSv8Parser.d.ts +0 -6
  134. package/lib/musepack/sv8/StreamVersion8.d.ts +0 -40
  135. package/lib/ogg/Ogg.d.ts +0 -72
  136. package/lib/ogg/OggParser.d.ts +0 -23
  137. package/lib/ogg/opus/Opus.d.ts +0 -48
  138. package/lib/ogg/opus/OpusParser.d.ts +0 -25
  139. package/lib/ogg/speex/Speex.d.ts +0 -36
  140. package/lib/ogg/speex/SpeexParser.d.ts +0 -22
  141. package/lib/ogg/theora/Theora.d.ts +0 -20
  142. package/lib/ogg/theora/TheoraParser.d.ts +0 -28
  143. package/lib/ogg/vorbis/Vorbis.d.ts +0 -69
  144. package/lib/ogg/vorbis/VorbisDecoder.d.ts +0 -12
  145. package/lib/ogg/vorbis/VorbisParser.d.ts +0 -36
  146. package/lib/ogg/vorbis/VorbisTagMapper.d.ts +0 -7
  147. package/lib/riff/RiffChunk.d.ts +0 -16
  148. package/lib/riff/RiffInfoTagMap.d.ts +0 -10
  149. package/lib/type.d.ts +0 -592
  150. package/lib/wav/BwfChunk.d.ts +0 -17
  151. package/lib/wav/WaveChunk.d.ts +0 -64
  152. package/lib/wav/WaveParser.d.ts +0 -24
  153. package/lib/wavpack/WavPackParser.d.ts +0 -14
  154. package/lib/wavpack/WavPackToken.d.ts +0 -64
@@ -1,20 +1,17 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.joinArtists = exports.MetadataCollector = void 0;
4
- const type_1 = require("../type");
5
- const debug_1 = require("debug");
6
- const GenericTagTypes_1 = require("./GenericTagTypes");
7
- const CombinedTagMapper_1 = require("./CombinedTagMapper");
8
- const GenericTagMapper_1 = require("./GenericTagMapper");
9
- const Util_1 = require("./Util");
10
- const FileType = require("file-type/core");
11
- const debug = (0, debug_1.default)('music-metadata:collector');
1
+ import { TrackType } from '../type.js';
2
+ import initDebug from 'debug';
3
+ import { isSingleton, isUnique } from './GenericTagTypes.js';
4
+ import { CombinedTagMapper } from './CombinedTagMapper.js';
5
+ import { CommonTagMapper } from './GenericTagMapper.js';
6
+ import { toRatio } from './Util.js';
7
+ import { fileTypeFromBuffer } from 'file-type';
8
+ const debug = initDebug('music-metadata:collector');
12
9
  const TagPriority = ['matroska', 'APEv2', 'vorbis', 'ID3v2.4', 'ID3v2.3', 'ID3v2.2', 'exif', 'asf', 'iTunes', 'ID3v1'];
13
10
  /**
14
11
  * Provided to the parser to uodate the metadata result.
15
12
  * Responsible for triggering async updates
16
13
  */
17
- class MetadataCollector {
14
+ export class MetadataCollector {
18
15
  constructor(opts) {
19
16
  this.opts = opts;
20
17
  this.format = {
@@ -38,7 +35,7 @@ class MetadataCollector {
38
35
  * Maps a tag type to a priority
39
36
  */
40
37
  this.originPriority = {};
41
- this.tagMapper = new CombinedTagMapper_1.CombinedTagMapper();
38
+ this.tagMapper = new CombinedTagMapper();
42
39
  let priority = 1;
43
40
  for (const tagType of TagPriority) {
44
41
  this.originPriority[tagType] = priority++;
@@ -53,7 +50,7 @@ class MetadataCollector {
53
50
  return Object.keys(this.native).length > 0;
54
51
  }
55
52
  addStreamInfo(streamInfo) {
56
- debug(`streamInfo: type=${type_1.TrackType[streamInfo.type]}, codec=${streamInfo.codecName}`);
53
+ debug(`streamInfo: type=${TrackType[streamInfo.type]}, codec=${streamInfo.codecName}`);
57
54
  this.format.trackInfo.push(streamInfo);
58
55
  }
59
56
  setFormat(key, value) {
@@ -111,19 +108,19 @@ class MetadataCollector {
111
108
  });
112
109
  return;
113
110
  case 'totaltracks':
114
- this.common.track.of = GenericTagMapper_1.CommonTagMapper.toIntOrNull(tag.value);
111
+ this.common.track.of = CommonTagMapper.toIntOrNull(tag.value);
115
112
  return;
116
113
  case 'totaldiscs':
117
- this.common.disk.of = GenericTagMapper_1.CommonTagMapper.toIntOrNull(tag.value);
114
+ this.common.disk.of = CommonTagMapper.toIntOrNull(tag.value);
118
115
  return;
119
116
  case 'movementTotal':
120
- this.common.movementIndex.of = GenericTagMapper_1.CommonTagMapper.toIntOrNull(tag.value);
117
+ this.common.movementIndex.of = CommonTagMapper.toIntOrNull(tag.value);
121
118
  return;
122
119
  case 'track':
123
120
  case 'disk':
124
121
  case 'movementIndex':
125
122
  const of = this.common[tag.id].of; // store of value, maybe maybe overwritten
126
- this.common[tag.id] = GenericTagMapper_1.CommonTagMapper.normalizeTrack(tag.value);
123
+ this.common[tag.id] = CommonTagMapper.normalizeTrack(tag.value);
127
124
  this.common[tag.id].of = of != null ? of : this.common[tag.id].of;
128
125
  return;
129
126
  case 'bpm':
@@ -149,7 +146,7 @@ class MetadataCollector {
149
146
  case 'replaygain_track_peak':
150
147
  case 'replaygain_album_gain':
151
148
  case 'replaygain_album_peak':
152
- tag.value = (0, Util_1.toRatio)(tag.value);
149
+ tag.value = toRatio(tag.value);
153
150
  break;
154
151
  case 'replaygain_track_minmax':
155
152
  tag.value = tag.value.split(',').map(v => parseInt(v, 10));
@@ -197,7 +194,7 @@ class MetadataCollector {
197
194
  async postFixPicture(picture) {
198
195
  if (picture.data && picture.data.length > 0) {
199
196
  if (!picture.format) {
200
- const fileType = await FileType.fromBuffer(picture.data);
197
+ const fileType = await fileTypeFromBuffer(picture.data);
201
198
  if (fileType) {
202
199
  picture.format = fileType.mime;
203
200
  }
@@ -232,7 +229,7 @@ class MetadataCollector {
232
229
  debug(`common.${tag.id} = ${tag.value}`);
233
230
  const prio0 = this.commonOrigin[tag.id] || 1000;
234
231
  const prio1 = this.originPriority[tagType];
235
- if ((0, GenericTagTypes_1.isSingleton)(tag.id)) {
232
+ if (isSingleton(tag.id)) {
236
233
  if (prio1 <= prio0) {
237
234
  this.common[tag.id] = tag.value;
238
235
  this.commonOrigin[tag.id] = prio1;
@@ -243,7 +240,7 @@ class MetadataCollector {
243
240
  }
244
241
  else {
245
242
  if (prio1 === prio0) {
246
- if (!(0, GenericTagTypes_1.isUnique)(tag.id) || this.common[tag.id].indexOf(tag.value) === -1) {
243
+ if (!isUnique(tag.id) || this.common[tag.id].indexOf(tag.value) === -1) {
247
244
  this.common[tag.id].push(tag.value);
248
245
  }
249
246
  else {
@@ -265,12 +262,10 @@ class MetadataCollector {
265
262
  // ToDo: trigger metadata event
266
263
  }
267
264
  }
268
- exports.MetadataCollector = MetadataCollector;
269
- function joinArtists(artists) {
265
+ export function joinArtists(artists) {
270
266
  if (artists.length > 2) {
271
267
  return artists.slice(0, artists.length - 1).join(', ') + ' & ' + artists[artists.length - 1];
272
268
  }
273
269
  return artists.join(' & ');
274
270
  }
275
- exports.joinArtists = joinArtists;
276
271
  //# sourceMappingURL=MetadataCollector.js.map
@@ -1,11 +1,8 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.RandomFileReader = void 0;
4
- const fs = require("fs");
1
+ import * as fs from 'fs';
5
2
  /**
6
3
  * Provides abstract file access via the IRandomRead interface
7
4
  */
8
- class RandomFileReader {
5
+ export class RandomFileReader {
9
6
  constructor(fileHandle, filePath, fileSize) {
10
7
  this.fileHandle = fileHandle;
11
8
  this.filePath = filePath;
@@ -31,4 +28,3 @@ class RandomFileReader {
31
28
  return new RandomFileReader(fileHandle, filePath, fileSize);
32
29
  }
33
30
  }
34
- exports.RandomFileReader = RandomFileReader;
@@ -1,10 +1,7 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.RandomUint8ArrayReader = void 0;
4
1
  /**
5
2
  * Provides abstract Uint8Array access via the IRandomRead interface
6
3
  */
7
- class RandomUint8ArrayReader {
4
+ export class RandomUint8ArrayReader {
8
5
  constructor(uint8Array) {
9
6
  this.uint8Array = uint8Array;
10
7
  this.fileSize = uint8Array.length;
@@ -22,4 +19,3 @@ class RandomUint8ArrayReader {
22
19
  return length;
23
20
  }
24
21
  }
25
- exports.RandomUint8ArrayReader = RandomUint8ArrayReader;
@@ -1,10 +1,6 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.toRatio = exports.dbToRatio = exports.ratioToDb = exports.a2hex = exports.isBitSet = exports.getBitAllignedNumber = exports.stripNulls = exports.decodeString = exports.trimRightNull = exports.findZero = exports.getBit = void 0;
4
- function getBit(buf, off, bit) {
1
+ export function getBit(buf, off, bit) {
5
2
  return (buf[off] & (1 << bit)) !== 0;
6
3
  }
7
- exports.getBit = getBit;
8
4
  /**
9
5
  * Found delimiting zero in uint8Array
10
6
  * @param uint8Array Uint8Array to find the zero delimiter in
@@ -13,7 +9,7 @@ exports.getBit = getBit;
13
9
  * @param encoding The string encoding used
14
10
  * @return Absolute position on uint8Array where zero found
15
11
  */
16
- function findZero(uint8Array, start, end, encoding) {
12
+ export function findZero(uint8Array, start, end, encoding) {
17
13
  let i = start;
18
14
  if (encoding === 'utf16le') {
19
15
  while (uint8Array[i] !== 0 || uint8Array[i + 1] !== 0) {
@@ -32,12 +28,10 @@ function findZero(uint8Array, start, end, encoding) {
32
28
  return i;
33
29
  }
34
30
  }
35
- exports.findZero = findZero;
36
- function trimRightNull(x) {
31
+ export function trimRightNull(x) {
37
32
  const pos0 = x.indexOf('\0');
38
33
  return pos0 === -1 ? x : x.substr(0, pos0);
39
34
  }
40
- exports.trimRightNull = trimRightNull;
41
35
  function swapBytes(uint8Array) {
42
36
  const l = uint8Array.length;
43
37
  if ((l & 1) !== 0)
@@ -52,7 +46,7 @@ function swapBytes(uint8Array) {
52
46
  /**
53
47
  * Decode string
54
48
  */
55
- function decodeString(uint8Array, encoding) {
49
+ export function decodeString(uint8Array, encoding) {
56
50
  // annoying workaround for a double BOM issue
57
51
  // https://github.com/leetreveil/musicmetadata/issues/84
58
52
  if (uint8Array[0] === 0xFF && uint8Array[1] === 0xFE) { // little endian
@@ -66,13 +60,11 @@ function decodeString(uint8Array, encoding) {
66
60
  }
67
61
  return Buffer.from(uint8Array).toString(encoding);
68
62
  }
69
- exports.decodeString = decodeString;
70
- function stripNulls(str) {
63
+ export function stripNulls(str) {
71
64
  str = str.replace(/^\x00+/g, '');
72
65
  str = str.replace(/\x00+$/g, '');
73
66
  return str;
74
67
  }
75
- exports.stripNulls = stripNulls;
76
68
  /**
77
69
  * Read bit-aligned number start from buffer
78
70
  * Total offset in bits = byteOffset * 8 + bitOffset
@@ -82,7 +74,7 @@ exports.stripNulls = stripNulls;
82
74
  * @param len Length of number in bits
83
75
  * @return Decoded bit aligned number
84
76
  */
85
- function getBitAllignedNumber(source, byteOffset, bitOffset, len) {
77
+ export function getBitAllignedNumber(source, byteOffset, bitOffset, len) {
86
78
  const byteOff = byteOffset + ~~(bitOffset / 8);
87
79
  const bitOff = bitOffset % 8;
88
80
  let value = source[byteOff];
@@ -98,7 +90,6 @@ function getBitAllignedNumber(source, byteOffset, bitOffset, len) {
98
90
  }
99
91
  return value;
100
92
  }
101
- exports.getBitAllignedNumber = getBitAllignedNumber;
102
93
  /**
103
94
  * Read bit-aligned number start from buffer
104
95
  * Total offset in bits = byteOffset * 8 + bitOffset
@@ -107,11 +98,10 @@ exports.getBitAllignedNumber = getBitAllignedNumber;
107
98
  * @param bitOffset Starting offset in bits: 0 = most significant bit, 7 is the least significant bit
108
99
  * @return True if bit is set
109
100
  */
110
- function isBitSet(source, byteOffset, bitOffset) {
101
+ export function isBitSet(source, byteOffset, bitOffset) {
111
102
  return getBitAllignedNumber(source, byteOffset, bitOffset, 1) === 1;
112
103
  }
113
- exports.isBitSet = isBitSet;
114
- function a2hex(str) {
104
+ export function a2hex(str) {
115
105
  const arr = [];
116
106
  for (let i = 0, l = str.length; i < l; i++) {
117
107
  const hex = Number(str.charCodeAt(i)).toString(16);
@@ -119,28 +109,25 @@ function a2hex(str) {
119
109
  }
120
110
  return arr.join(' ');
121
111
  }
122
- exports.a2hex = a2hex;
123
112
  /**
124
113
  * Convert power ratio to DB
125
114
  * ratio: [0..1]
126
115
  */
127
- function ratioToDb(ratio) {
116
+ export function ratioToDb(ratio) {
128
117
  return 10 * Math.log10(ratio);
129
118
  }
130
- exports.ratioToDb = ratioToDb;
131
119
  /**
132
120
  * Convert dB to ratio
133
121
  * db Decibels
134
122
  */
135
- function dbToRatio(dB) {
123
+ export function dbToRatio(dB) {
136
124
  return Math.pow(10, dB / 10);
137
125
  }
138
- exports.dbToRatio = dbToRatio;
139
126
  /**
140
127
  * Convert replay gain to ratio and Decibel
141
128
  * @param value string holding a ratio like '0.034' or '-7.54 dB'
142
129
  */
143
- function toRatio(value) {
130
+ export function toRatio(value) {
144
131
  const ps = value.split(' ').map(p => p.trim().toLowerCase());
145
132
  // @ts-ignore
146
133
  if (ps.length >= 1) {
@@ -154,5 +141,4 @@ function toRatio(value) {
154
141
  };
155
142
  }
156
143
  }
157
- exports.toRatio = toRatio;
158
144
  //# sourceMappingURL=Util.js.map
package/lib/core.js CHANGED
@@ -1,12 +1,9 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.scanAppendingHeaders = exports.selectCover = exports.ratingToStars = exports.orderTags = exports.parseFromTokenizer = exports.parseBuffer = exports.parseStream = void 0;
4
- const strtok3 = require("strtok3/lib/core");
5
- const ParserFactory_1 = require("./ParserFactory");
6
- const RandomUint8ArrayReader_1 = require("./common/RandomUint8ArrayReader");
7
- const APEv2Parser_1 = require("./apev2/APEv2Parser");
8
- const ID3v1Parser_1 = require("./id3v1/ID3v1Parser");
9
- const Lyrics3_1 = require("./lyrics3/Lyrics3");
1
+ import * as strtok3 from 'strtok3/core';
2
+ import { ParserFactory } from './ParserFactory.js';
3
+ import { RandomUint8ArrayReader } from './common/RandomUint8ArrayReader.js';
4
+ import { APEv2Parser } from './apev2/APEv2Parser.js';
5
+ import { hasID3v1Header } from './id3v1/ID3v1Parser.js';
6
+ import { getLyricsHeaderLength } from './lyrics3/Lyrics3.js';
10
7
  /**
11
8
  * Parse audio from Node Stream.Readable
12
9
  * @param stream - Stream to read the audio track from
@@ -14,10 +11,9 @@ const Lyrics3_1 = require("./lyrics3/Lyrics3");
14
11
  * @param fileInfo - File information object or MIME-type string
15
12
  * @returns Metadata
16
13
  */
17
- function parseStream(stream, fileInfo, options = {}) {
14
+ export function parseStream(stream, fileInfo, options = {}) {
18
15
  return parseFromTokenizer(strtok3.fromStream(stream, typeof fileInfo === 'string' ? { mimeType: fileInfo } : fileInfo), options);
19
16
  }
20
- exports.parseStream = parseStream;
21
17
  /**
22
18
  * Parse audio from Node Buffer
23
19
  * @param uint8Array - Uint8Array holding audio data
@@ -26,65 +22,59 @@ exports.parseStream = parseStream;
26
22
  * @returns Metadata
27
23
  * Ref: https://github.com/Borewit/strtok3/blob/e6938c81ff685074d5eb3064a11c0b03ca934c1d/src/index.ts#L15
28
24
  */
29
- async function parseBuffer(uint8Array, fileInfo, options = {}) {
30
- const bufferReader = new RandomUint8ArrayReader_1.RandomUint8ArrayReader(uint8Array);
25
+ export async function parseBuffer(uint8Array, fileInfo, options = {}) {
26
+ const bufferReader = new RandomUint8ArrayReader(uint8Array);
31
27
  await scanAppendingHeaders(bufferReader, options);
32
28
  const tokenizer = strtok3.fromBuffer(uint8Array, typeof fileInfo === 'string' ? { mimeType: fileInfo } : fileInfo);
33
29
  return parseFromTokenizer(tokenizer, options);
34
30
  }
35
- exports.parseBuffer = parseBuffer;
36
31
  /**
37
32
  * Parse audio from ITokenizer source
38
33
  * @param tokenizer - Audio source implementing the tokenizer interface
39
34
  * @param options - Parsing options
40
35
  * @returns Metadata
41
36
  */
42
- function parseFromTokenizer(tokenizer, options) {
43
- return ParserFactory_1.ParserFactory.parseOnContentType(tokenizer, options);
37
+ export function parseFromTokenizer(tokenizer, options) {
38
+ return ParserFactory.parseOnContentType(tokenizer, options);
44
39
  }
45
- exports.parseFromTokenizer = parseFromTokenizer;
46
40
  /**
47
41
  * Create a dictionary ordered by their tag id (key)
48
42
  * @param nativeTags list of tags
49
43
  * @returns tags indexed by id
50
44
  */
51
- function orderTags(nativeTags) {
45
+ export function orderTags(nativeTags) {
52
46
  const tags = {};
53
47
  for (const tag of nativeTags) {
54
48
  (tags[tag.id] = (tags[tag.id] || [])).push(tag.value);
55
49
  }
56
50
  return tags;
57
51
  }
58
- exports.orderTags = orderTags;
59
52
  /**
60
53
  * Convert rating to 1-5 star rating
61
54
  * @param rating: Normalized rating [0..1] (common.rating[n].rating)
62
55
  * @returns Number of stars: 1, 2, 3, 4 or 5 stars
63
56
  */
64
- function ratingToStars(rating) {
57
+ export function ratingToStars(rating) {
65
58
  return rating === undefined ? 0 : 1 + Math.round(rating * 4);
66
59
  }
67
- exports.ratingToStars = ratingToStars;
68
60
  /**
69
61
  * Select most likely cover image.
70
62
  * @param pictures Usually metadata.common.picture
71
63
  * @return Cover image, if any, otherwise null
72
64
  */
73
- function selectCover(pictures) {
65
+ export function selectCover(pictures) {
74
66
  return pictures ? pictures.reduce((acc, cur) => {
75
67
  if (cur.name && cur.name.toLowerCase() in ['front', 'cover', 'cover (front)'])
76
68
  return cur;
77
69
  return acc;
78
70
  }) : null;
79
71
  }
80
- exports.selectCover = selectCover;
81
- async function scanAppendingHeaders(randomReader, options = {}) {
72
+ export async function scanAppendingHeaders(randomReader, options = {}) {
82
73
  let apeOffset = randomReader.fileSize;
83
- if (await (0, ID3v1Parser_1.hasID3v1Header)(randomReader)) {
74
+ if (await hasID3v1Header(randomReader)) {
84
75
  apeOffset -= 128;
85
- const lyricsLen = await (0, Lyrics3_1.getLyricsHeaderLength)(randomReader);
76
+ const lyricsLen = await getLyricsHeaderLength(randomReader);
86
77
  apeOffset -= lyricsLen;
87
78
  }
88
- options.apeHeader = await APEv2Parser_1.APEv2Parser.findApeFooterOffset(randomReader, apeOffset);
79
+ options.apeHeader = await APEv2Parser.findApeFooterOffset(randomReader, apeOffset);
89
80
  }
90
- exports.scanAppendingHeaders = scanAppendingHeaders;
@@ -1,42 +1,39 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DsdiffParser = void 0;
4
- const Token = require("token-types");
5
- const debug_1 = require("debug");
6
- const strtok3 = require("strtok3/lib/core");
7
- const FourCC_1 = require("../common/FourCC");
8
- const BasicParser_1 = require("../common/BasicParser");
9
- const ID3v2Parser_1 = require("../id3v2/ID3v2Parser");
10
- const DsdiffToken_1 = require("./DsdiffToken");
11
- const debug = (0, debug_1.default)('music-metadata:parser:aiff');
1
+ import * as Token from 'token-types';
2
+ import initDebug from 'debug';
3
+ import * as strtok3 from 'strtok3/core';
4
+ import { FourCcToken } from '../common/FourCC.js';
5
+ import { BasicParser } from '../common/BasicParser.js';
6
+ import { ID3v2Parser } from '../id3v2/ID3v2Parser.js';
7
+ import { ChunkHeader64 } from './DsdiffToken.js';
8
+ const debug = initDebug('music-metadata:parser:aiff');
12
9
  /**
13
10
  * DSDIFF - Direct Stream Digital Interchange File Format (Phillips)
14
11
  *
15
12
  * Ref:
16
13
  * - http://www.sonicstudio.com/pdf/dsd/DSDIFF_1.5_Spec.pdf
17
14
  */
18
- class DsdiffParser extends BasicParser_1.BasicParser {
15
+ export class DsdiffParser extends BasicParser {
19
16
  async parse() {
20
- const header = await this.tokenizer.readToken(DsdiffToken_1.ChunkHeader64);
17
+ const header = await this.tokenizer.readToken(ChunkHeader64);
21
18
  if (header.chunkID !== 'FRM8')
22
19
  throw new Error('Unexpected chunk-ID');
23
- const type = (await this.tokenizer.readToken(FourCC_1.FourCcToken)).trim();
20
+ const type = (await this.tokenizer.readToken(FourCcToken)).trim();
24
21
  switch (type) {
25
22
  case 'DSD':
26
23
  this.metadata.setFormat('container', `DSDIFF/${type}`);
27
24
  this.metadata.setFormat('lossless', true);
28
- return this.readFmt8Chunks(header.chunkSize - BigInt(FourCC_1.FourCcToken.len));
25
+ return this.readFmt8Chunks(header.chunkSize - BigInt(FourCcToken.len));
29
26
  default:
30
27
  throw Error(`Unsupported DSDIFF type: ${type}`);
31
28
  }
32
29
  }
33
30
  async readFmt8Chunks(remainingSize) {
34
- while (remainingSize >= DsdiffToken_1.ChunkHeader64.len) {
35
- const chunkHeader = await this.tokenizer.readToken(DsdiffToken_1.ChunkHeader64);
31
+ while (remainingSize >= ChunkHeader64.len) {
32
+ const chunkHeader = await this.tokenizer.readToken(ChunkHeader64);
36
33
  // If the data is an odd number of bytes in length, a pad byte must be added at the end
37
34
  debug(`Chunk id=${chunkHeader.chunkID}`);
38
35
  await this.readData(chunkHeader);
39
- remainingSize -= (BigInt(DsdiffToken_1.ChunkHeader64.len) + chunkHeader.chunkSize);
36
+ remainingSize -= (BigInt(ChunkHeader64.len) + chunkHeader.chunkSize);
40
37
  }
41
38
  }
42
39
  async readData(header) {
@@ -48,15 +45,15 @@ class DsdiffParser extends BasicParser_1.BasicParser {
48
45
  debug(`DSDIFF version=${version}`);
49
46
  break;
50
47
  case 'PROP': // 3.2 PROPERTY CHUNK
51
- const propType = await this.tokenizer.readToken(FourCC_1.FourCcToken);
48
+ const propType = await this.tokenizer.readToken(FourCcToken);
52
49
  if (propType !== 'SND ')
53
50
  throw new Error('Unexpected PROP-chunk ID');
54
- await this.handleSoundPropertyChunks(header.chunkSize - BigInt(FourCC_1.FourCcToken.len));
51
+ await this.handleSoundPropertyChunks(header.chunkSize - BigInt(FourCcToken.len));
55
52
  break;
56
53
  case 'ID3': // Unofficial ID3 tag support
57
54
  const id3_data = await this.tokenizer.readToken(new Token.Uint8ArrayType(Number(header.chunkSize)));
58
55
  const rst = strtok3.fromBuffer(id3_data);
59
- await new ID3v2Parser_1.ID3v2Parser().parse(this.metadata, rst, this.options);
56
+ await new ID3v2Parser().parse(this.metadata, rst, this.options);
60
57
  break;
61
58
  default:
62
59
  debug(`Ignore chunk[ID=${header.chunkID}, size=${header.chunkSize}]`);
@@ -75,7 +72,7 @@ class DsdiffParser extends BasicParser_1.BasicParser {
75
72
  async handleSoundPropertyChunks(remainingSize) {
76
73
  debug(`Parsing sound-property-chunks, remainingSize=${remainingSize}`);
77
74
  while (remainingSize > 0) {
78
- const sndPropHeader = await this.tokenizer.readToken(DsdiffToken_1.ChunkHeader64);
75
+ const sndPropHeader = await this.tokenizer.readToken(ChunkHeader64);
79
76
  debug(`Sound-property-chunk[ID=${sndPropHeader.chunkID}, size=${sndPropHeader.chunkSize}]`);
80
77
  const p0 = this.tokenizer.position;
81
78
  switch (sndPropHeader.chunkID.trim()) {
@@ -89,7 +86,7 @@ class DsdiffParser extends BasicParser_1.BasicParser {
89
86
  await this.handleChannelChunks(sndPropHeader.chunkSize - BigInt(Token.UINT16_BE.len));
90
87
  break;
91
88
  case 'CMPR': // 3.2.3 Compression Type Chunk
92
- const compressionIdCode = (await this.tokenizer.readToken(FourCC_1.FourCcToken)).trim();
89
+ const compressionIdCode = (await this.tokenizer.readToken(FourCcToken)).trim();
93
90
  const count = await this.tokenizer.readToken(Token.UINT8);
94
91
  const compressionName = await this.tokenizer.readToken(new Token.StringType(count, 'ascii'));
95
92
  if (compressionIdCode === 'DSD') {
@@ -119,7 +116,7 @@ class DsdiffParser extends BasicParser_1.BasicParser {
119
116
  debug(`After Parsing sound-property-chunk ${sndPropHeader.chunkSize}, remaining ${remaining} bytes`);
120
117
  await this.tokenizer.ignore(Number(remaining));
121
118
  }
122
- remainingSize -= BigInt(DsdiffToken_1.ChunkHeader64.len) + sndPropHeader.chunkSize;
119
+ remainingSize -= BigInt(ChunkHeader64.len) + sndPropHeader.chunkSize;
123
120
  debug(`Parsing sound-property-chunks, remainingSize=${remainingSize}`);
124
121
  }
125
122
  if (this.metadata.format.lossless && this.metadata.format.sampleRate && this.metadata.format.numberOfChannels && this.metadata.format.bitsPerSample) {
@@ -130,14 +127,13 @@ class DsdiffParser extends BasicParser_1.BasicParser {
130
127
  async handleChannelChunks(remainingSize) {
131
128
  debug(`Parsing channel-chunks, remainingSize=${remainingSize}`);
132
129
  const channels = [];
133
- while (remainingSize >= FourCC_1.FourCcToken.len) {
134
- const channelId = await this.tokenizer.readToken(FourCC_1.FourCcToken);
130
+ while (remainingSize >= FourCcToken.len) {
131
+ const channelId = await this.tokenizer.readToken(FourCcToken);
135
132
  debug(`Channel[ID=${channelId}]`);
136
133
  channels.push(channelId);
137
- remainingSize -= BigInt(FourCC_1.FourCcToken.len);
134
+ remainingSize -= BigInt(FourCcToken.len);
138
135
  }
139
136
  debug(`Channels: ${channels.join(', ')}`);
140
137
  return channels;
141
138
  }
142
139
  }
143
- exports.DsdiffParser = DsdiffParser;
@@ -1,19 +1,16 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ChunkHeader64 = void 0;
4
- const Token = require("token-types");
5
- const FourCC_1 = require("../common/FourCC");
1
+ import * as Token from 'token-types';
2
+ import { FourCcToken } from '../common/FourCC.js';
6
3
  /**
7
4
  * DSDIFF chunk header
8
5
  * The data-size encoding is deviating from EA-IFF 85
9
6
  * Ref: http://www.sonicstudio.com/pdf/dsd/DSDIFF_1.5_Spec.pdf
10
7
  */
11
- exports.ChunkHeader64 = {
8
+ export const ChunkHeader64 = {
12
9
  len: 12,
13
10
  get: (buf, off) => {
14
11
  return {
15
12
  // Group-ID
16
- chunkID: FourCC_1.FourCcToken.get(buf, off),
13
+ chunkID: FourCcToken.get(buf, off),
17
14
  // Size
18
15
  chunkSize: Token.INT64_BE.get(buf, off + 4)
19
16
  };
@@ -1,21 +1,18 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.FormatChunk = exports.ChannelType = exports.DsdChunk = exports.ChunkHeader = void 0;
4
- const Token = require("token-types");
5
- const FourCC_1 = require("../common/FourCC");
1
+ import * as Token from 'token-types';
2
+ import { FourCcToken } from '../common/FourCC.js';
6
3
  /**
7
4
  * Common chunk DSD header: the 'chunk name (Four-CC)' & chunk size
8
5
  */
9
- exports.ChunkHeader = {
6
+ export const ChunkHeader = {
10
7
  len: 12,
11
8
  get: (buf, off) => {
12
- return { id: FourCC_1.FourCcToken.get(buf, off), size: Token.UINT64_LE.get(buf, off + 4) };
9
+ return { id: FourCcToken.get(buf, off), size: Token.UINT64_LE.get(buf, off + 4) };
13
10
  }
14
11
  };
15
12
  /**
16
13
  * Common chunk DSD header: the 'chunk name (Four-CC)' & chunk size
17
14
  */
18
- exports.DsdChunk = {
15
+ export const DsdChunk = {
19
16
  len: 16,
20
17
  get: (buf, off) => {
21
18
  return {
@@ -24,7 +21,7 @@ exports.DsdChunk = {
24
21
  };
25
22
  }
26
23
  };
27
- var ChannelType;
24
+ export var ChannelType;
28
25
  (function (ChannelType) {
29
26
  ChannelType[ChannelType["mono"] = 1] = "mono";
30
27
  ChannelType[ChannelType["stereo"] = 2] = "stereo";
@@ -33,11 +30,11 @@ var ChannelType;
33
30
  ChannelType[ChannelType["4 channels"] = 5] = "4 channels";
34
31
  ChannelType[ChannelType["5 channels"] = 6] = "5 channels";
35
32
  ChannelType[ChannelType["5.1 channels"] = 7] = "5.1 channels";
36
- })(ChannelType = exports.ChannelType || (exports.ChannelType = {}));
33
+ })(ChannelType = ChannelType || (ChannelType = {}));
37
34
  /**
38
35
  * Common chunk DSD header: the 'chunk name (Four-CC)' & chunk size
39
36
  */
40
- exports.FormatChunk = {
37
+ export const FormatChunk = {
41
38
  len: 40,
42
39
  get: (buf, off) => {
43
40
  return {
@@ -1,24 +1,21 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DsfParser = void 0;
4
- const debug_1 = require("debug");
5
- const AbstractID3Parser_1 = require("../id3v2/AbstractID3Parser");
6
- const DsfChunk_1 = require("./DsfChunk");
7
- const ID3v2Parser_1 = require("../id3v2/ID3v2Parser");
8
- const debug = (0, debug_1.default)('music-metadata:parser:DSF');
1
+ import initDebug from 'debug';
2
+ import { AbstractID3Parser } from '../id3v2/AbstractID3Parser.js';
3
+ import { ChunkHeader, DsdChunk, FormatChunk } from './DsfChunk.js';
4
+ import { ID3v2Parser } from "../id3v2/ID3v2Parser.js";
5
+ const debug = initDebug('music-metadata:parser:DSF');
9
6
  /**
10
7
  * DSF (dsd stream file) File Parser
11
8
  * Ref: https://dsd-guide.com/sites/default/files/white-papers/DSFFileFormatSpec_E.pdf
12
9
  */
13
- class DsfParser extends AbstractID3Parser_1.AbstractID3Parser {
10
+ export class DsfParser extends AbstractID3Parser {
14
11
  async postId3v2Parse() {
15
12
  const p0 = this.tokenizer.position; // mark start position, normally 0
16
- const chunkHeader = await this.tokenizer.readToken(DsfChunk_1.ChunkHeader);
13
+ const chunkHeader = await this.tokenizer.readToken(ChunkHeader);
17
14
  if (chunkHeader.id !== 'DSD ')
18
15
  throw new Error('Invalid chunk signature');
19
16
  this.metadata.setFormat('container', 'DSF');
20
17
  this.metadata.setFormat('lossless', true);
21
- const dsdChunk = await this.tokenizer.readToken(DsfChunk_1.DsdChunk);
18
+ const dsdChunk = await this.tokenizer.readToken(DsdChunk);
22
19
  if (dsdChunk.metadataPointer === BigInt(0)) {
23
20
  debug(`No ID3v2 tag present`);
24
21
  }
@@ -27,16 +24,16 @@ class DsfParser extends AbstractID3Parser_1.AbstractID3Parser {
27
24
  await this.parseChunks(dsdChunk.fileSize - chunkHeader.size);
28
25
  // Jump to ID3 header
29
26
  await this.tokenizer.ignore(Number(dsdChunk.metadataPointer) - this.tokenizer.position - p0);
30
- return new ID3v2Parser_1.ID3v2Parser().parse(this.metadata, this.tokenizer, this.options);
27
+ return new ID3v2Parser().parse(this.metadata, this.tokenizer, this.options);
31
28
  }
32
29
  }
33
30
  async parseChunks(bytesRemaining) {
34
- while (bytesRemaining >= DsfChunk_1.ChunkHeader.len) {
35
- const chunkHeader = await this.tokenizer.readToken(DsfChunk_1.ChunkHeader);
31
+ while (bytesRemaining >= ChunkHeader.len) {
32
+ const chunkHeader = await this.tokenizer.readToken(ChunkHeader);
36
33
  debug(`Parsing chunk name=${chunkHeader.id} size=${chunkHeader.size}`);
37
34
  switch (chunkHeader.id) {
38
35
  case 'fmt ':
39
- const formatChunk = await this.tokenizer.readToken(DsfChunk_1.FormatChunk);
36
+ const formatChunk = await this.tokenizer.readToken(FormatChunk);
40
37
  this.metadata.setFormat('numberOfChannels', formatChunk.channelNum);
41
38
  this.metadata.setFormat('sampleRate', formatChunk.samplingFrequency);
42
39
  this.metadata.setFormat('bitsPerSample', formatChunk.bitsPerSample);
@@ -46,11 +43,10 @@ class DsfParser extends AbstractID3Parser_1.AbstractID3Parser {
46
43
  this.metadata.setFormat('bitrate', bitrate);
47
44
  return; // We got what we want, stop further processing of chunks
48
45
  default:
49
- this.tokenizer.ignore(Number(chunkHeader.size) - DsfChunk_1.ChunkHeader.len);
46
+ this.tokenizer.ignore(Number(chunkHeader.size) - ChunkHeader.len);
50
47
  break;
51
48
  }
52
49
  bytesRemaining -= chunkHeader.size;
53
50
  }
54
51
  }
55
52
  }
56
- exports.DsfParser = DsfParser;