@openclaw/whatsapp 2026.9.34 → 2026.9.36

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 (105) hide show
  1. package/dist/.source-module-urls/c3803b0fa58e9b1fe1f7418a46193ebc53b9c744f6359f04d40d05af48c1dce2.json +1 -0
  2. package/node_modules/baileys/node_modules/music-metadata/README.md +35 -32
  3. package/node_modules/baileys/node_modules/music-metadata/lib/ParserFactory.d.ts +1 -1
  4. package/node_modules/baileys/node_modules/music-metadata/lib/ParserFactory.js +17 -13
  5. package/node_modules/baileys/node_modules/music-metadata/lib/aiff/AiffParser.js +19 -12
  6. package/node_modules/baileys/node_modules/music-metadata/lib/aiff/AiffToken.d.ts +1 -1
  7. package/node_modules/baileys/node_modules/music-metadata/lib/aiff/AiffToken.js +2 -1
  8. package/node_modules/baileys/node_modules/music-metadata/lib/apev2/APEv2Parser.d.ts +4 -3
  9. package/node_modules/baileys/node_modules/music-metadata/lib/apev2/APEv2Parser.js +59 -16
  10. package/node_modules/baileys/node_modules/music-metadata/lib/apev2/APEv2TagMapper.js +1 -0
  11. package/node_modules/baileys/node_modules/music-metadata/lib/apev2/APEv2Token.d.ts +1 -1
  12. package/node_modules/baileys/node_modules/music-metadata/lib/apev2/APEv2Token.js +1 -1
  13. package/node_modules/baileys/node_modules/music-metadata/lib/asf/AsfGuid.js +56 -50
  14. package/node_modules/baileys/node_modules/music-metadata/lib/asf/AsfObject.d.ts +1 -1
  15. package/node_modules/baileys/node_modules/music-metadata/lib/asf/AsfObject.js +3 -2
  16. package/node_modules/baileys/node_modules/music-metadata/lib/asf/AsfParser.js +15 -7
  17. package/node_modules/baileys/node_modules/music-metadata/lib/asf/AsfTagMapper.d.ts +3 -2
  18. package/node_modules/baileys/node_modules/music-metadata/lib/asf/AsfTagMapper.js +21 -4
  19. package/node_modules/baileys/node_modules/music-metadata/lib/common/CaseInsensitiveTagMap.d.ts +1 -1
  20. package/node_modules/baileys/node_modules/music-metadata/lib/common/CombinedTagMapper.d.ts +2 -2
  21. package/node_modules/baileys/node_modules/music-metadata/lib/common/CombinedTagMapper.js +6 -6
  22. package/node_modules/baileys/node_modules/music-metadata/lib/common/FourCC.js +3 -2
  23. package/node_modules/baileys/node_modules/music-metadata/lib/common/GenericTagMapper.d.ts +1 -1
  24. package/node_modules/baileys/node_modules/music-metadata/lib/common/GenericTagTypes.js +1 -1
  25. package/node_modules/baileys/node_modules/music-metadata/lib/common/MetadataCollector.d.ts +3 -1
  26. package/node_modules/baileys/node_modules/music-metadata/lib/common/MetadataCollector.js +28 -9
  27. package/node_modules/baileys/node_modules/music-metadata/lib/common/Util.js +25 -17
  28. package/node_modules/baileys/node_modules/music-metadata/lib/core.d.ts +4 -4
  29. package/node_modules/baileys/node_modules/music-metadata/lib/core.js +18 -11
  30. package/node_modules/baileys/node_modules/music-metadata/lib/dsdiff/DsdiffParser.js +29 -16
  31. package/node_modules/baileys/node_modules/music-metadata/lib/dsf/DsfChunk.d.ts +1 -1
  32. package/node_modules/baileys/node_modules/music-metadata/lib/dsf/DsfParser.js +3 -5
  33. package/node_modules/baileys/node_modules/music-metadata/lib/ebml/EbmlIterator.d.ts +1 -1
  34. package/node_modules/baileys/node_modules/music-metadata/lib/ebml/EbmlIterator.js +35 -6
  35. package/node_modules/baileys/node_modules/music-metadata/lib/ebml/types.d.ts +1 -1
  36. package/node_modules/baileys/node_modules/music-metadata/lib/ebml/types.js +1 -1
  37. package/node_modules/baileys/node_modules/music-metadata/lib/flac/FlacParser.d.ts +1 -1
  38. package/node_modules/baileys/node_modules/music-metadata/lib/flac/FlacParser.js +6 -5
  39. package/node_modules/baileys/node_modules/music-metadata/lib/flac/FlacToken.d.ts +1 -1
  40. package/node_modules/baileys/node_modules/music-metadata/lib/flac/FlacToken.js +1 -1
  41. package/node_modules/baileys/node_modules/music-metadata/lib/id3v1/ID3v1Parser.d.ts +1 -1
  42. package/node_modules/baileys/node_modules/music-metadata/lib/id3v1/ID3v1Parser.js +212 -42
  43. package/node_modules/baileys/node_modules/music-metadata/lib/id3v2/AbstractID3Parser.js +5 -5
  44. package/node_modules/baileys/node_modules/music-metadata/lib/id3v2/FrameHeader.d.ts +1 -1
  45. package/node_modules/baileys/node_modules/music-metadata/lib/id3v2/FrameHeader.js +8 -5
  46. package/node_modules/baileys/node_modules/music-metadata/lib/id3v2/FrameParser.d.ts +2 -1
  47. package/node_modules/baileys/node_modules/music-metadata/lib/id3v2/FrameParser.js +53 -22
  48. package/node_modules/baileys/node_modules/music-metadata/lib/id3v2/ID3v22TagMapper.d.ts +1 -1
  49. package/node_modules/baileys/node_modules/music-metadata/lib/id3v2/ID3v22TagMapper.js +1 -1
  50. package/node_modules/baileys/node_modules/music-metadata/lib/id3v2/ID3v24TagMapper.js +3 -3
  51. package/node_modules/baileys/node_modules/music-metadata/lib/id3v2/ID3v2ChapterToken.js +2 -2
  52. package/node_modules/baileys/node_modules/music-metadata/lib/id3v2/ID3v2Parser.d.ts +1 -1
  53. package/node_modules/baileys/node_modules/music-metadata/lib/id3v2/ID3v2Parser.js +32 -16
  54. package/node_modules/baileys/node_modules/music-metadata/lib/id3v2/ID3v2Token.d.ts +2 -2
  55. package/node_modules/baileys/node_modules/music-metadata/lib/id3v2/ID3v2Token.js +2 -3
  56. package/node_modules/baileys/node_modules/music-metadata/lib/index.js +6 -3
  57. package/node_modules/baileys/node_modules/music-metadata/lib/lrc/LyricsParser.js +3 -5
  58. package/node_modules/baileys/node_modules/music-metadata/lib/matroska/MatroskaDtd.js +7 -3
  59. package/node_modules/baileys/node_modules/music-metadata/lib/matroska/MatroskaParser.js +22 -11
  60. package/node_modules/baileys/node_modules/music-metadata/lib/matroska/types.d.ts +2 -2
  61. package/node_modules/baileys/node_modules/music-metadata/lib/mp4/Atom.d.ts +4 -3
  62. package/node_modules/baileys/node_modules/music-metadata/lib/mp4/Atom.js +44 -11
  63. package/node_modules/baileys/node_modules/music-metadata/lib/mp4/AtomToken.d.ts +1 -1
  64. package/node_modules/baileys/node_modules/music-metadata/lib/mp4/AtomToken.js +30 -8
  65. package/node_modules/baileys/node_modules/music-metadata/lib/mp4/MP4Parser.d.ts +2 -0
  66. package/node_modules/baileys/node_modules/music-metadata/lib/mp4/MP4Parser.js +79 -54
  67. package/node_modules/baileys/node_modules/music-metadata/lib/mp4/MP4TagMapper.d.ts +2 -2
  68. package/node_modules/baileys/node_modules/music-metadata/lib/mpeg/MpegLoader.js +1 -1
  69. package/node_modules/baileys/node_modules/music-metadata/lib/mpeg/MpegParser.js +41 -19
  70. package/node_modules/baileys/node_modules/music-metadata/lib/mpeg/ReplayGainDataFormat.d.ts +2 -2
  71. package/node_modules/baileys/node_modules/music-metadata/lib/mpeg/ReplayGainDataFormat.js +1 -1
  72. package/node_modules/baileys/node_modules/music-metadata/lib/mpeg/XingTag.d.ts +1 -1
  73. package/node_modules/baileys/node_modules/music-metadata/lib/musepack/MusepackParser.js +2 -2
  74. package/node_modules/baileys/node_modules/music-metadata/lib/musepack/sv7/BitReader.js +1 -1
  75. package/node_modules/baileys/node_modules/music-metadata/lib/musepack/sv7/MpcSv7Parser.js +4 -3
  76. package/node_modules/baileys/node_modules/music-metadata/lib/musepack/sv7/StreamVersion7.js +3 -3
  77. package/node_modules/baileys/node_modules/music-metadata/lib/musepack/sv8/MpcSv8Parser.js +7 -5
  78. package/node_modules/baileys/node_modules/music-metadata/lib/musepack/sv8/StreamVersion8.js +2 -2
  79. package/node_modules/baileys/node_modules/music-metadata/lib/ogg/OggParser.js +16 -12
  80. package/node_modules/baileys/node_modules/music-metadata/lib/ogg/OggToken.js +1 -1
  81. package/node_modules/baileys/node_modules/music-metadata/lib/ogg/flac/FlacStream.d.ts +2 -2
  82. package/node_modules/baileys/node_modules/music-metadata/lib/ogg/flac/FlacStream.js +2 -2
  83. package/node_modules/baileys/node_modules/music-metadata/lib/ogg/opus/OpusStream.d.ts +2 -2
  84. package/node_modules/baileys/node_modules/music-metadata/lib/ogg/opus/OpusStream.js +8 -4
  85. package/node_modules/baileys/node_modules/music-metadata/lib/ogg/speex/SpeexStream.d.ts +2 -2
  86. package/node_modules/baileys/node_modules/music-metadata/lib/ogg/speex/SpeexStream.js +2 -1
  87. package/node_modules/baileys/node_modules/music-metadata/lib/ogg/theora/TheoraStream.d.ts +2 -2
  88. package/node_modules/baileys/node_modules/music-metadata/lib/ogg/vorbis/Vorbis.d.ts +1 -1
  89. package/node_modules/baileys/node_modules/music-metadata/lib/ogg/vorbis/VorbisDecoder.js +1 -1
  90. package/node_modules/baileys/node_modules/music-metadata/lib/ogg/vorbis/VorbisStream.d.ts +3 -3
  91. package/node_modules/baileys/node_modules/music-metadata/lib/ogg/vorbis/VorbisStream.js +14 -9
  92. package/node_modules/baileys/node_modules/music-metadata/lib/ogg/vorbis/VorbisTagMapper.js +4 -0
  93. package/node_modules/baileys/node_modules/music-metadata/lib/riff/RiffChunk.d.ts +3 -1
  94. package/node_modules/baileys/node_modules/music-metadata/lib/riff/RiffChunk.js +3 -2
  95. package/node_modules/baileys/node_modules/music-metadata/lib/riff/RiffInfoTagMap.d.ts +1 -1
  96. package/node_modules/baileys/node_modules/music-metadata/lib/type.d.ts +3 -3
  97. package/node_modules/baileys/node_modules/music-metadata/lib/type.js +1 -1
  98. package/node_modules/baileys/node_modules/music-metadata/lib/wav/WaveChunk.d.ts +1 -1
  99. package/node_modules/baileys/node_modules/music-metadata/lib/wav/WaveChunk.js +3 -2
  100. package/node_modules/baileys/node_modules/music-metadata/lib/wav/WaveParser.d.ts +6 -2
  101. package/node_modules/baileys/node_modules/music-metadata/lib/wav/WaveParser.js +75 -22
  102. package/node_modules/baileys/node_modules/music-metadata/lib/wavpack/WavPackParser.js +22 -13
  103. package/node_modules/baileys/node_modules/music-metadata/lib/wavpack/WavPackToken.js +3 -2
  104. package/node_modules/baileys/node_modules/music-metadata/package.json +3 -2
  105. package/package.json +4 -4
@@ -1,13 +1,13 @@
1
+ import { textDecode } from '@borewit/text-codec';
1
2
  import initDebug from 'debug';
2
3
  import * as Token from 'token-types';
4
+ import { uint8ArrayToHex } from 'uint8array-extras';
3
5
  import { BasicParser } from '../common/BasicParser.js';
4
6
  import { Genres } from '../id3v1/ID3v1Parser.js';
7
+ import { TrackType } from '../type.js';
5
8
  import { Atom } from './Atom.js';
6
9
  import * as AtomToken from './AtomToken.js';
7
10
  import { ChapterTrackReferenceBox, Mp4ContentError } from './AtomToken.js';
8
- import { TrackType } from '../type.js';
9
- import { uint8ArrayToHex } from 'uint8array-extras';
10
- import { textDecode } from '@borewit/text-codec';
11
11
  const debug = initDebug('music-metadata:parser:MP4');
12
12
  const tagFormat = 'iTunes';
13
13
  const encoderDict = {
@@ -122,7 +122,7 @@ export class MP4Parser extends BasicParser {
122
122
  * Ref: https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html#//apple_ref/doc/uid/TP40000939-CH204-56313
123
123
  */
124
124
  mvhd: async (len) => {
125
- const mvhd = await this.tokenizer.readToken(new AtomToken.MvhdAtom(len));
125
+ const mvhd = await this.readToken(new AtomToken.MvhdAtom(len));
126
126
  this.metadata.setFormat('creationTime', mvhd.creationTime);
127
127
  this.metadata.setFormat('modificationTime', mvhd.modificationTime);
128
128
  },
@@ -153,9 +153,12 @@ export class MP4Parser extends BasicParser {
153
153
  await this.tokenizer.ignore(len);
154
154
  },
155
155
  ftyp: async (len) => {
156
+ if (len < 8 || len % AtomToken.ftyp.len !== 0) {
157
+ throw new Mp4ContentError(`Invalid ftyp payload length: ${len}`);
158
+ }
156
159
  const types = [];
157
160
  while (len > 0) {
158
- const ftype = await this.tokenizer.readToken(AtomToken.ftyp);
161
+ const ftype = await this.readToken(AtomToken.ftyp);
159
162
  len -= AtomToken.ftyp.len;
160
163
  const value = ftype.type.replace(/\W/g, '');
161
164
  if (value.length > 0) {
@@ -170,7 +173,7 @@ export class MP4Parser extends BasicParser {
170
173
  * Parse sample description atom
171
174
  */
172
175
  stsd: async (len) => {
173
- const stsd = await this.tokenizer.readToken(new AtomToken.StsdAtom(len));
176
+ const stsd = await this.readToken(new AtomToken.StsdAtom(len));
174
177
  const trackDescription = this.getTrackDescription();
175
178
  trackDescription.soundSampleDescription = stsd.table.map(dfEntry => this.parseSoundSampleDescription(dfEntry));
176
179
  },
@@ -178,13 +181,13 @@ export class MP4Parser extends BasicParser {
178
181
  * Parse sample-sizes atom ('stsz')
179
182
  */
180
183
  stsz: async (len) => {
181
- const stsz = await this.tokenizer.readToken(new AtomToken.StszAtom(len));
184
+ const stsz = await this.readToken(new AtomToken.StszAtom(len));
182
185
  const td = this.getTrackDescription();
183
186
  td.sampleSize = stsz.sampleSize;
184
187
  td.sampleSizeTable = stsz.entries;
185
188
  },
186
189
  date: async (len) => {
187
- const date = await this.tokenizer.readToken(new Token.StringType(len, 'utf-8'));
190
+ const date = await this.readToken(new Token.StringType(len, 'utf-8'));
188
191
  await this.addTag('date', date);
189
192
  }
190
193
  };
@@ -197,12 +200,23 @@ export class MP4Parser extends BasicParser {
197
200
  }
198
201
  return Number(token.get(array, 0));
199
202
  }
203
+ // Metadata and sample tables are buffered; media data is skipped separately.
204
+ // A bound is also necessary for streams whose total size is unknown.
205
+ validatePayloadLength(length) {
206
+ if (!Number.isSafeInteger(length) || length < 0 || length > 64 * 1024 * 1024) {
207
+ throw new Mp4ContentError(`Atom payload exceeds the 64 MiB buffering limit: ${length}`);
208
+ }
209
+ }
210
+ async readToken(token) {
211
+ this.validatePayloadLength(token.len);
212
+ return this.tokenizer.readToken(token);
213
+ }
200
214
  async parse() {
201
215
  this.hasVideoTrack = false;
202
216
  this.hasAudioTrack = true;
203
217
  this.tracks.clear();
204
- let remainingFileSize = this.tokenizer.fileInfo.size || 0;
205
- while (!this.tokenizer.fileInfo.size || remainingFileSize > 0) {
218
+ let remainingFileSize = this.tokenizer.fileInfo.size ?? Number.POSITIVE_INFINITY;
219
+ while (remainingFileSize > 0) {
206
220
  try {
207
221
  const token = await this.tokenizer.peekToken(AtomToken.Header);
208
222
  if (token.name === '\0\0\0\0') {
@@ -218,12 +232,13 @@ export class MP4Parser extends BasicParser {
218
232
  debug(errMsg);
219
233
  this.addWarning(errMsg);
220
234
  }
221
- else
235
+ else {
222
236
  throw error;
237
+ }
223
238
  break;
224
239
  }
225
240
  const rootAtom = await Atom.readAtom(this.tokenizer, (atom, remaining) => this.handleAtom(atom, remaining), null, remainingFileSize);
226
- remainingFileSize -= rootAtom.header.length === BigInt(0) ? remainingFileSize : Number(rootAtom.header.length);
241
+ remainingFileSize = rootAtom.header.length === 0n ? 0 : remainingFileSize - Number(rootAtom.header.length);
227
242
  }
228
243
  // Post process metadata
229
244
  const formatList = [];
@@ -279,10 +294,10 @@ export class MP4Parser extends BasicParser {
279
294
  const dur = sample.sampleDuration ?? fragment.header.defaultSampleDuration ?? 0;
280
295
  const size = sample.sampleSize ?? fragment.header.defaultSampleSize ?? 0;
281
296
  if (dur === 0) {
282
- throw new Error("Missing sampleDuration and no defaultSampleDuration in track fragment header");
297
+ throw new Error('Missing sampleDuration and no defaultSampleDuration in track fragment header');
283
298
  }
284
299
  if (size === 0) {
285
- throw new Error("Missing sampleSize and no defaultSampleSize in track fragment header");
300
+ throw new Error('Missing sampleSize and no defaultSampleSize in track fragment header');
286
301
  }
287
302
  totalTimeUnits += dur;
288
303
  audioTrack.sizeInBytes += size;
@@ -321,7 +336,7 @@ export class MP4Parser extends BasicParser {
321
336
  if (firstAudioTrack.duration) {
322
337
  this.metadata.setFormat('duration', firstAudioTrack.duration);
323
338
  if (firstAudioTrack.sizeInBytes) {
324
- this.metadata.setFormat('bitrate', 8 * firstAudioTrack.sizeInBytes / firstAudioTrack.duration);
339
+ this.metadata.setFormat('bitrate', (8 * firstAudioTrack.sizeInBytes) / firstAudioTrack.duration);
325
340
  }
326
341
  }
327
342
  }
@@ -349,8 +364,10 @@ export class MP4Parser extends BasicParser {
349
364
  }
350
365
  }
351
366
  }
352
- // const payloadLength = atom.getPayloadLength(remaining);
353
367
  if (this.atomParsers[atom.header.name]) {
368
+ if (atom.header.name !== 'mdat') {
369
+ this.validatePayloadLength(remaining);
370
+ }
354
371
  return this.atomParsers[atom.header.name](remaining);
355
372
  }
356
373
  debug(`No parser for atom path=${atom.atomPath}, payload-len=${remaining}, ignoring atom`);
@@ -375,27 +392,27 @@ export class MP4Parser extends BasicParser {
375
392
  */
376
393
  parseMetadataItemData(metaAtom) {
377
394
  let tagKey = metaAtom.header.name;
378
- return metaAtom.readAtoms(this.tokenizer, async (child, remaining) => {
379
- const payLoadLength = child.getPayloadLength(remaining);
395
+ return metaAtom.readAtoms(this.tokenizer, async (child) => {
396
+ const payLoadLength = child.getPayloadLength();
380
397
  switch (child.header.name) {
381
398
  case 'data': // value atom
382
399
  return this.parseValueAtom(tagKey, child);
383
400
  case 'name': // name atom (optional)
384
401
  case 'mean':
385
402
  case 'rate': {
386
- const name = await this.tokenizer.readToken(new AtomToken.NameAtom(payLoadLength));
403
+ const name = await this.readToken(new AtomToken.NameAtom(payLoadLength));
387
404
  tagKey += `:${name.name}`;
388
405
  break;
389
406
  }
390
407
  default: {
391
- const uint8Array = await this.tokenizer.readToken(new Token.Uint8ArrayType(payLoadLength));
408
+ const uint8Array = await this.readToken(new Token.Uint8ArrayType(payLoadLength));
392
409
  this.addWarning(`Unsupported meta-item: ${tagKey}[${child.header.name}] => value=${uint8ArrayToHex(uint8Array)} ascii=${textDecode(uint8Array, 'ascii')}`);
393
410
  }
394
411
  }
395
- }, metaAtom.getPayloadLength(0));
412
+ }, metaAtom.getPayloadLength());
396
413
  }
397
414
  async parseValueAtom(tagKey, metaAtom) {
398
- const dataAtom = await this.tokenizer.readToken(new AtomToken.DataAtom(Number(metaAtom.header.length) - AtomToken.Header.len));
415
+ const dataAtom = await this.readToken(new AtomToken.DataAtom(metaAtom.getPayloadLength()));
399
416
  if (dataAtom.type.set !== 0) {
400
417
  throw new Mp4ContentError(`Unsupported type-set != 0: ${dataAtom.type.set}`);
401
418
  }
@@ -433,16 +450,18 @@ export class MP4Parser extends BasicParser {
433
450
  await this.addTag(tagKey, textDecode(dataAtom.value));
434
451
  break;
435
452
  case 13: // JPEG
436
- if (this.options.skipCovers)
453
+ if (this.options.skipCovers) {
437
454
  break;
455
+ }
438
456
  await this.addTag(tagKey, {
439
457
  format: 'image/jpeg',
440
458
  data: Uint8Array.from(dataAtom.value)
441
459
  });
442
460
  break;
443
461
  case 14: // PNG
444
- if (this.options.skipCovers)
462
+ if (this.options.skipCovers) {
445
463
  break;
464
+ }
446
465
  await this.addTag(tagKey, {
447
466
  format: 'image/png',
448
467
  data: Uint8Array.from(dataAtom.value)
@@ -473,19 +492,19 @@ export class MP4Parser extends BasicParser {
473
492
  media: {},
474
493
  fragments: []
475
494
  };
476
- await trakBox.readAtoms(this.tokenizer, async (child, remaining) => {
477
- const payLoadLength = child.getPayloadLength(remaining);
495
+ await trakBox.readAtoms(this.tokenizer, async (child) => {
496
+ const payLoadLength = child.getPayloadLength();
478
497
  switch (child.header.name) {
479
498
  case 'chap': {
480
- const chap = await this.tokenizer.readToken(new ChapterTrackReferenceBox(remaining));
499
+ const chap = await this.readToken(new ChapterTrackReferenceBox(payLoadLength));
481
500
  track.chapterList = chap;
482
501
  break;
483
502
  }
484
503
  case 'tkhd': // TrackHeaderBox
485
- track.header = await this.tokenizer.readToken(new AtomToken.TrackHeaderAtom(payLoadLength));
504
+ track.header = await this.readToken(new AtomToken.TrackHeaderAtom(payLoadLength));
486
505
  break;
487
506
  case 'hdlr': // TrackHeaderBox
488
- track.handler = await this.tokenizer.readToken(new AtomToken.HandlerBox(payLoadLength));
507
+ track.handler = await this.readToken(new AtomToken.HandlerBox(payLoadLength));
489
508
  track.isAudio = () => track.handler.handlerType === 'audi' || track.handler.handlerType === 'soun';
490
509
  track.isVideo = () => track.handler.handlerType === 'vide';
491
510
  if (track.isAudio()) {
@@ -495,33 +514,37 @@ export class MP4Parser extends BasicParser {
495
514
  this.hasVideoTrack = true;
496
515
  }
497
516
  break;
498
- case 'mdhd': { // Parse media header (mdhd) box
499
- const mdhd_data = await this.tokenizer.readToken(new AtomToken.MdhdAtom(payLoadLength));
517
+ case 'mdhd': {
518
+ // Parse media header (mdhd) box
519
+ const mdhd_data = await this.readToken(new AtomToken.MdhdAtom(payLoadLength));
500
520
  track.media.header = mdhd_data;
501
521
  break;
502
522
  }
503
523
  case 'stco': {
504
- const stco = await this.tokenizer.readToken(new AtomToken.StcoAtom(payLoadLength));
524
+ const stco = await this.readToken(new AtomToken.StcoAtom(payLoadLength));
505
525
  track.chunkOffsetTable = stco.entries; // remember chunk offsets
506
526
  break;
507
527
  }
508
- case 'stsc': { // sample-to-Chunk box
509
- const stsc = await this.tokenizer.readToken(new AtomToken.StscAtom(payLoadLength));
528
+ case 'stsc': {
529
+ // sample-to-Chunk box
530
+ const stsc = await this.readToken(new AtomToken.StscAtom(payLoadLength));
510
531
  track.sampleToChunkTable = stsc.entries;
511
532
  break;
512
533
  }
513
- case 'stsd': { // sample description box
514
- const stsd = await this.tokenizer.readToken(new AtomToken.StsdAtom(payLoadLength));
534
+ case 'stsd': {
535
+ // sample description box
536
+ const stsd = await this.readToken(new AtomToken.StsdAtom(payLoadLength));
515
537
  track.soundSampleDescription = stsd.table.map(dfEntry => this.parseSoundSampleDescription(dfEntry));
516
538
  break;
517
539
  }
518
- case 'stts': { // time-to-sample table
519
- const stts = await this.tokenizer.readToken(new AtomToken.SttsAtom(payLoadLength));
540
+ case 'stts': {
541
+ // time-to-sample table
542
+ const stts = await this.readToken(new AtomToken.SttsAtom(payLoadLength));
520
543
  track.timeToSampleTable = stts.entries;
521
544
  break;
522
545
  }
523
546
  case 'stsz': {
524
- const stsz = await this.tokenizer.readToken(new AtomToken.StszAtom(payLoadLength));
547
+ const stsz = await this.readToken(new AtomToken.StszAtom(payLoadLength));
525
548
  track.sampleSize = stsz.sampleSize;
526
549
  track.sampleSizeTable = stsz.entries;
527
550
  break;
@@ -537,26 +560,28 @@ export class MP4Parser extends BasicParser {
537
560
  await this.tokenizer.ignore(payLoadLength);
538
561
  }
539
562
  }
540
- }, trakBox.getPayloadLength(0));
563
+ }, trakBox.getPayloadLength());
541
564
  // Register track
542
565
  this.tracks.set(track.header.trackId, track);
543
566
  }
544
567
  parseTrackFragmentBox(trafBox) {
545
568
  let tfhd;
546
- return trafBox.readAtoms(this.tokenizer, async (child, remaining) => {
547
- const payLoadLength = child.getPayloadLength(remaining);
569
+ return trafBox.readAtoms(this.tokenizer, async (child) => {
570
+ const payLoadLength = child.getPayloadLength();
548
571
  switch (child.header.name) {
549
- case 'tfhd': { // TrackFragmentHeaderBox
550
- const fragmentHeaderBox = new AtomToken.TrackFragmentHeaderBox(child.getPayloadLength(remaining));
551
- tfhd = await this.tokenizer.readToken(fragmentHeaderBox);
572
+ case 'tfhd': {
573
+ // TrackFragmentHeaderBox
574
+ const fragmentHeaderBox = new AtomToken.TrackFragmentHeaderBox(child.getPayloadLength());
575
+ tfhd = await this.readToken(fragmentHeaderBox);
552
576
  break;
553
577
  }
554
578
  case 'tfdt': // TrackFragmentBaseMediaDecodeTimeBo
555
579
  await this.tokenizer.ignore(payLoadLength);
556
580
  break;
557
- case 'trun': { // TrackRunBox
581
+ case 'trun': {
582
+ // TrackRunBox
558
583
  const trackRunBox = new AtomToken.TrackRunBox(payLoadLength);
559
- const trun = await this.tokenizer.readToken(trackRunBox);
584
+ const trun = await this.readToken(trackRunBox);
560
585
  if (tfhd) {
561
586
  const track = this.tracks.get(tfhd.trackId);
562
587
  track?.fragments.push({ header: tfhd, trackRun: trun });
@@ -568,7 +593,7 @@ export class MP4Parser extends BasicParser {
568
593
  await this.tokenizer.ignore(payLoadLength);
569
594
  }
570
595
  }
571
- }, trafBox.getPayloadLength(0));
596
+ }, trafBox.getPayloadLength());
572
597
  }
573
598
  /**
574
599
  * @param sampleDescription
@@ -603,22 +628,22 @@ export class MP4Parser extends BasicParser {
603
628
  }
604
629
  async parseChapterTrack(chapterTrack, track, len) {
605
630
  if (!chapterTrack.sampleSize) {
606
- if (chapterTrack.chunkOffsetTable.length !== chapterTrack.sampleSizeTable.length)
631
+ if (chapterTrack.chunkOffsetTable.length !== chapterTrack.sampleSizeTable.length) {
607
632
  throw new Error('Expected equal chunk-offset-table & sample-size-table length.');
633
+ }
608
634
  }
609
635
  const chapters = [];
610
636
  for (let i = 0; i < chapterTrack.chunkOffsetTable.length && len > 0; ++i) {
611
- const start = chapterTrack.timeToSampleTable
612
- .slice(0, i)
613
- .reduce((acc, cur) => acc + cur.duration, 0);
637
+ const start = chapterTrack.timeToSampleTable.slice(0, i).reduce((acc, cur) => acc + cur.duration, 0);
614
638
  const chunkOffset = chapterTrack.chunkOffsetTable[i];
615
639
  const nextChunkLen = chunkOffset - this.tokenizer.position;
616
640
  const sampleSize = chapterTrack.sampleSize > 0 ? chapterTrack.sampleSize : chapterTrack.sampleSizeTable[i];
617
641
  len -= nextChunkLen + sampleSize;
618
- if (len < 0)
642
+ if (len < 0) {
619
643
  throw new Mp4ContentError('Chapter chunk exceeding token length');
644
+ }
620
645
  await this.tokenizer.ignore(nextChunkLen);
621
- const title = await this.tokenizer.readToken(new AtomToken.ChapterText(sampleSize));
646
+ const title = await this.readToken(new AtomToken.ChapterText(sampleSize));
622
647
  debug(`Chapter ${i + 1}: ${title}`);
623
648
  const chapter = {
624
649
  title,
@@ -1,6 +1,6 @@
1
1
  import { CaseInsensitiveTagMap } from '../common/CaseInsensitiveTagMap.js';
2
- import type { ITag } from "../type.js";
3
- import type { INativeMetadataCollector } from "../common/MetadataCollector.js";
2
+ import type { INativeMetadataCollector } from '../common/MetadataCollector.js';
3
+ import type { ITag } from '../type.js';
4
4
  export declare const tagType = "iTunes";
5
5
  export declare class MP4TagMapper extends CaseInsensitiveTagMap {
6
6
  constructor();
@@ -1,6 +1,6 @@
1
1
  export const mpegParserLoader = {
2
2
  parserType: 'mpeg',
3
- extensions: ['.mp2', '.mp3', '.m2a', '.aac', 'aacp'],
3
+ extensions: ['.mp1', '.mp2', '.mp3', '.m2a', '.aac', 'aacp'],
4
4
  mimeTypes: ['audio/mpeg', 'audio/mp3', 'audio/aacs', 'audio/aacp'],
5
5
  async load() {
6
6
  return (await import('./MpegParser.js')).MpegParser;
@@ -1,10 +1,10 @@
1
- import * as Token from 'token-types';
2
- import { EndOfStreamError } from 'strtok3';
3
1
  import initDebug from 'debug';
2
+ import { EndOfStreamError } from 'strtok3';
3
+ import * as Token from 'token-types';
4
4
  import * as common from '../common/Util.js';
5
5
  import { AbstractID3Parser } from '../id3v2/AbstractID3Parser.js';
6
- import { InfoTagHeaderTag, LameEncoderVersion, readXingHeader } from './XingTag.js';
7
6
  import { makeUnexpectedFileContentError } from '../ParseError.js';
7
+ import { InfoTagHeaderTag, LameEncoderVersion, readXingHeader } from './XingTag.js';
8
8
  const debug = initDebug('music-metadata:parser:mpeg');
9
9
  export class MpegContentError extends makeUnexpectedFileContentError('MPEG') {
10
10
  }
@@ -31,7 +31,22 @@ const MPEG4 = {
31
31
  * https://wiki.multimedia.cx/index.php/MPEG-4_Audio#Sampling_Frequencies
32
32
  */
33
33
  SamplingFrequencies: [
34
- 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350, null, null, null
34
+ 96000,
35
+ 88200,
36
+ 64000,
37
+ 48000,
38
+ 44100,
39
+ 32000,
40
+ 24000,
41
+ 22050,
42
+ 16000,
43
+ 12000,
44
+ 11025,
45
+ 8000,
46
+ 7350,
47
+ null,
48
+ null,
49
+ null
35
50
  ]
36
51
  /**
37
52
  * Channel Configurations
@@ -87,14 +102,15 @@ class MpegFrameHeader {
87
102
  this.isProtectedByCRC = !common.isBitSet(buf, off + 1, 7);
88
103
  }
89
104
  calcDuration(numFrames) {
90
- return this.samplingRate == null ? null : (numFrames * this.calcSamplesPerFrame() / this.samplingRate);
105
+ return this.samplingRate == null ? null : (numFrames * this.calcSamplesPerFrame()) / this.samplingRate;
91
106
  }
92
107
  calcSamplesPerFrame() {
93
108
  return MpegFrameHeader.samplesInFrameTable[this.version === 1 ? 0 : 1][this.layer];
94
109
  }
95
110
  calculateSideInfoLength() {
96
- if (this.layer !== 3)
111
+ if (this.layer !== 3) {
97
112
  return 2;
113
+ }
98
114
  if (this.channelModeIndex === 3) {
99
115
  // mono
100
116
  if (this.version === 1) {
@@ -153,7 +169,7 @@ class MpegFrameHeader {
153
169
  }
154
170
  }
155
171
  parseAdtsHeader(buf, off) {
156
- debug("layer=0 => ADTS");
172
+ debug('layer=0 => ADTS');
157
173
  this.version = this.versionIndex === 2 ? 4 : 2;
158
174
  this.container = `ADTS/MPEG-${this.version}`;
159
175
  const profileIndex = common.getBitAllignedNumber(buf, off + 2, 0, 2);
@@ -170,7 +186,8 @@ class MpegFrameHeader {
170
186
  }
171
187
  calcBitrate() {
172
188
  if (this.bitrateIndex === 0x00 || // free
173
- this.bitrateIndex === 0x0F) { // reserved
189
+ this.bitrateIndex === 0x0f) {
190
+ // reserved
174
191
  return null;
175
192
  }
176
193
  if (this.version && this.bitrateIndex) {
@@ -180,13 +197,14 @@ class MpegFrameHeader {
180
197
  return null;
181
198
  }
182
199
  calcSamplingRate() {
183
- if (this.sampRateFreqIndex === 0x03 || this.version === null || this.sampRateFreqIndex == null)
200
+ if (this.sampRateFreqIndex === 0x03 || this.version === null || this.sampRateFreqIndex == null) {
184
201
  return null; // 'reserved'
202
+ }
185
203
  return MpegFrameHeader.sampling_rate_freq_index[this.version][this.sampRateFreqIndex];
186
204
  }
187
205
  }
188
- MpegFrameHeader.SyncByte1 = 0xFF;
189
- MpegFrameHeader.SyncByte2 = 0xE0;
206
+ MpegFrameHeader.SyncByte1 = 0xff;
207
+ MpegFrameHeader.SyncByte2 = 0xe0;
190
208
  MpegFrameHeader.VersionID = [2.5, null, 2, 1];
191
209
  MpegFrameHeader.LayerDescription = [0, 3, 2, 1];
192
210
  MpegFrameHeader.ChannelMode = ['stereo', 'joint_stereo', 'dual_channel', 'mono'];
@@ -264,7 +282,7 @@ export class MpegParser extends AbstractID3Parser {
264
282
  }
265
283
  catch (err) {
266
284
  if (err instanceof EndOfStreamError) {
267
- debug("End-of-stream");
285
+ debug('End-of-stream');
268
286
  if (this.calculateEofDuration) {
269
287
  if (this.samplesPerFrame !== null) {
270
288
  const numberOfSamples = this.frameCount * this.samplesPerFrame;
@@ -292,7 +310,7 @@ export class MpegParser extends AbstractID3Parser {
292
310
  if (format.duration && this.tokenizer.fileInfo.size) {
293
311
  const mpegSize = this.tokenizer.fileInfo.size - this.mpegOffset - (hasID3v1 ? 128 : 0);
294
312
  if (format.codecProfile && format.codecProfile[0] === 'V') {
295
- this.metadata.setFormat('bitrate', mpegSize * 8 / format.duration);
313
+ this.metadata.setFormat('bitrate', (mpegSize * 8) / format.duration);
296
314
  }
297
315
  }
298
316
  if (this.tokenizer.fileInfo.size && format.codecProfile === 'CBR') {
@@ -302,7 +320,7 @@ export class MpegParser extends AbstractID3Parser {
302
320
  this.metadata.setFormat('numberOfSamples', numberOfSamples);
303
321
  if (format.sampleRate && !format.duration) {
304
322
  const duration = numberOfSamples / format.sampleRate;
305
- debug("Calculate CBR duration based on file size: %s", duration);
323
+ debug('Calculate CBR duration based on file size: %s', duration);
306
324
  this.metadata.setFormat('duration', duration);
307
325
  }
308
326
  }
@@ -318,7 +336,7 @@ export class MpegParser extends AbstractID3Parser {
318
336
  throw new EndOfStreamError();
319
337
  }
320
338
  while (true) {
321
- if (gotFirstSync && (this.syncPeek.buf[bo] & 0xE0) === 0xE0) {
339
+ if (gotFirstSync && (this.syncPeek.buf[bo] & 0xe0) === 0xe0) {
322
340
  this.buf_frame_header[0] = MpegFrameHeader.SyncByte1;
323
341
  this.buf_frame_header[1] = this.syncPeek.buf[bo];
324
342
  await this.tokenizer.ignore(bo);
@@ -372,7 +390,9 @@ export class MpegParser extends AbstractID3Parser {
372
390
  this.metadata.setFormat('lossless', false);
373
391
  this.metadata.setFormat('sampleRate', header.samplingRate);
374
392
  this.frameCount++;
375
- return header.version !== null && header.version >= 2 && header.layer === 0 ? this.parseAdts(header) : this.parseAudioFrameHeader(header);
393
+ return header.version !== null && header.version >= 2 && header.layer === 0
394
+ ? this.parseAdts(header)
395
+ : this.parseAudioFrameHeader(header);
376
396
  }
377
397
  /**
378
398
  * @return {Promise<boolean>} true if parser should quit
@@ -391,7 +411,7 @@ export class MpegParser extends AbstractID3Parser {
391
411
  debug(`samples_per_frame=${samples_per_frame}`);
392
412
  const bps = samples_per_frame / 8.0;
393
413
  if (header.bitrate !== null && header.samplingRate != null) {
394
- const fsize = (bps * header.bitrate / header.samplingRate) + ((header.padding) ? slot_size : 0);
414
+ const fsize = (bps * header.bitrate) / header.samplingRate + (header.padding ? slot_size : 0);
395
415
  this.frame_size = Math.floor(fsize);
396
416
  }
397
417
  this.audioFrameHeader = header;
@@ -410,8 +430,9 @@ export class MpegParser extends AbstractID3Parser {
410
430
  // Actual calculation will be done in finalize
411
431
  this.samplesPerFrame = samples_per_frame;
412
432
  this.metadata.setFormat('codecProfile', 'CBR');
413
- if (this.tokenizer.fileInfo.size)
433
+ if (this.tokenizer.fileInfo.size) {
414
434
  return true; // Will calculate duration based on the file size
435
+ }
415
436
  }
416
437
  else if (this.metadata.format.duration) {
417
438
  return true; // We already got the duration, stop processing MPEG stream any further
@@ -556,8 +577,9 @@ export class MpegParser extends AbstractID3Parser {
556
577
  return infoTag;
557
578
  }
558
579
  async skipFrameData(frameDataLeft) {
559
- if (frameDataLeft < 0)
580
+ if (frameDataLeft < 0) {
560
581
  throw new MpegContentError('frame-data-left cannot be negative');
582
+ }
561
583
  await this.tokenizer.ignore(frameDataLeft);
562
584
  }
563
585
  areAllSame(array) {
@@ -21,7 +21,7 @@ declare const NameCode: {
21
21
  */
22
22
  audiophile: number;
23
23
  };
24
- type NameCode = typeof NameCode[keyof typeof NameCode];
24
+ type NameCode = (typeof NameCode)[keyof typeof NameCode];
25
25
  /**
26
26
  * https://github.com/Borewit/music-metadata/wiki/Replay-Gain-Data-Format#originator-code
27
27
  */
@@ -47,7 +47,7 @@ declare const ReplayGainOriginator: {
47
47
  */
48
48
  rms_average: number;
49
49
  };
50
- type ReplayGainOriginator = typeof ReplayGainOriginator[keyof typeof ReplayGainOriginator];
50
+ type ReplayGainOriginator = (typeof ReplayGainOriginator)[keyof typeof ReplayGainOriginator];
51
51
  /**
52
52
  * Replay Gain Data Format
53
53
  *
@@ -56,7 +56,7 @@ export const ReplayGain = {
56
56
  return {
57
57
  type: common.getBitAllignedNumber(buf, off, 0, 3),
58
58
  origin: common.getBitAllignedNumber(buf, off, 3, 3),
59
- adjustment: (sign ? -gain_adj : gain_adj)
59
+ adjustment: sign ? -gain_adj : gain_adj
60
60
  };
61
61
  }
62
62
  return undefined;
@@ -1,5 +1,5 @@
1
- import * as Token from 'token-types';
2
1
  import type { IGetToken, ITokenizer } from 'strtok3';
2
+ import * as Token from 'token-types';
3
3
  import { type IExtendedLameHeader } from './ExtendedLameHeader.js';
4
4
  export interface IXingHeaderFlags {
5
5
  frames: boolean;
@@ -1,9 +1,9 @@
1
1
  import initDebug from 'debug';
2
2
  import * as Token from 'token-types';
3
3
  import { AbstractID3Parser } from '../id3v2/AbstractID3Parser.js';
4
- import { MpcSv8Parser } from './sv8/MpcSv8Parser.js';
5
- import { MpcSv7Parser } from './sv7/MpcSv7Parser.js';
6
4
  import { MusepackContentError } from './MusepackConentError.js';
5
+ import { MpcSv7Parser } from './sv7/MpcSv7Parser.js';
6
+ import { MpcSv8Parser } from './sv8/MpcSv8Parser.js';
7
7
  const debug = initDebug('music-metadata:parser:musepack');
8
8
  export class MusepackParser extends AbstractID3Parser {
9
9
  async postId3v2Parse() {
@@ -16,7 +16,7 @@ export class BitReader {
16
16
  let out = this.dword;
17
17
  this.pos += bits;
18
18
  if (this.pos < 32) {
19
- out >>>= (32 - this.pos);
19
+ out >>>= 32 - this.pos;
20
20
  return out & ((1 << bits) - 1);
21
21
  }
22
22
  this.pos -= 32;
@@ -1,9 +1,9 @@
1
1
  import initDebug from 'debug';
2
- import { BasicParser } from '../../common/BasicParser.js';
3
2
  import { tryParseApeHeader } from '../../apev2/APEv2Parser.js';
3
+ import { BasicParser } from '../../common/BasicParser.js';
4
+ import { MusepackContentError } from '../MusepackConentError.js';
4
5
  import { BitReader } from './BitReader.js';
5
6
  import * as SV7 from './StreamVersion7.js';
6
- import { MusepackContentError } from '../MusepackConentError.js';
7
7
  const debug = initDebug('music-metadata:parser:musepack');
8
8
  export class MpcSv7Parser extends BasicParser {
9
9
  constructor() {
@@ -14,8 +14,9 @@ export class MpcSv7Parser extends BasicParser {
14
14
  }
15
15
  async parse() {
16
16
  const header = await this.tokenizer.readToken(SV7.Header);
17
- if (header.signature !== 'MP+')
17
+ if (header.signature !== 'MP+') {
18
18
  throw new MusepackContentError('Unexpected magic number');
19
+ }
19
20
  debug(`stream-version=${header.streamMajorVersion}.${header.streamMinorVersion}`);
20
21
  this.metadata.setFormat('container', 'Musepack, SV7');
21
22
  this.metadata.setFormat('sampleRate', header.sampleFrequency);
@@ -1,6 +1,6 @@
1
+ import { textDecode } from '@borewit/text-codec';
1
2
  import * as Token from 'token-types';
2
3
  import * as util from '../../common/Util.js';
3
- import { textDecode } from '@borewit/text-codec';
4
4
  /**
5
5
  * BASIC STRUCTURE
6
6
  */
@@ -30,10 +30,10 @@ export const Header = {
30
30
  albumPeak: Token.UINT16_LE.get(buf, off + 16),
31
31
  albumGain: Token.UINT16_LE.get(buf, off + 18),
32
32
  // word
33
- lastFrameLength: (Token.UINT32_LE.get(buf, off + 20) >>> 20) & 0x7FF,
33
+ lastFrameLength: (Token.UINT32_LE.get(buf, off + 20) >>> 20) & 0x7ff,
34
34
  trueGapless: util.isBitSet(buf, off + 23, 0)
35
35
  };
36
- header.lastFrameLength = header.trueGapless ? (Token.UINT32_LE.get(buf, 20) >>> 20) & 0x7FF : 0;
36
+ header.lastFrameLength = header.trueGapless ? (Token.UINT32_LE.get(buf, 20) >>> 20) & 0x7ff : 0;
37
37
  return header;
38
38
  }
39
39
  };