@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,43 +1,207 @@
1
+ import { textDecode } from '@borewit/text-codec';
1
2
  import initDebug from 'debug';
2
3
  import { StringType, UINT8 } from 'token-types';
3
- import * as util from '../common/Util.js';
4
- import { BasicParser } from '../common/BasicParser.js';
5
4
  import { APEv2Parser } from '../apev2/APEv2Parser.js';
6
- import { textDecode } from '@borewit/text-codec';
5
+ import { BasicParser } from '../common/BasicParser.js';
6
+ import * as util from '../common/Util.js';
7
7
  const debug = initDebug('music-metadata:parser:ID3v1');
8
8
  /**
9
9
  * ID3v1 Genre mappings
10
10
  * Ref: https://de.wikipedia.org/wiki/Liste_der_ID3v1-Genres
11
11
  */
12
12
  export const Genres = [
13
- 'Blues', 'Classic Rock', 'Country', 'Dance', 'Disco', 'Funk', 'Grunge', 'Hip-Hop',
14
- 'Jazz', 'Metal', 'New Age', 'Oldies', 'Other', 'Pop', 'R&B', 'Rap', 'Reggae', 'Rock',
15
- 'Techno', 'Industrial', 'Alternative', 'Ska', 'Death Metal', 'Pranks', 'Soundtrack',
16
- 'Euro-Techno', 'Ambient', 'Trip-Hop', 'Vocal', 'Jazz+Funk', 'Fusion', 'Trance',
17
- 'Classical', 'Instrumental', 'Acid', 'House', 'Game', 'Sound Clip', 'Gospel', 'Noise',
18
- 'Alt. Rock', 'Bass', 'Soul', 'Punk', 'Space', 'Meditative', 'Instrumental Pop',
19
- 'Instrumental Rock', 'Ethnic', 'Gothic', 'Darkwave', 'Techno-Industrial',
20
- 'Electronic', 'Pop-Folk', 'Eurodance', 'Dream', 'Southern Rock', 'Comedy', 'Cult',
21
- 'Gangsta Rap', 'Top 40', 'Christian Rap', 'Pop/Funk', 'Jungle', 'Native American',
22
- 'Cabaret', 'New Wave', 'Psychedelic', 'Rave', 'Showtunes', 'Trailer', 'Lo-Fi', 'Tribal',
23
- 'Acid Punk', 'Acid Jazz', 'Polka', 'Retro', 'Musical', 'Rock & Roll', 'Hard Rock',
24
- 'Folk', 'Folk/Rock', 'National Folk', 'Swing', 'Fast-Fusion', 'Bebob', 'Latin', 'Revival',
25
- 'Celtic', 'Bluegrass', 'Avantgarde', 'Gothic Rock', 'Progressive Rock', 'Psychedelic Rock',
26
- 'Symphonic Rock', 'Slow Rock', 'Big Band', 'Chorus', 'Easy Listening', 'Acoustic', 'Humour',
27
- 'Speech', 'Chanson', 'Opera', 'Chamber Music', 'Sonata', 'Symphony', 'Booty Bass', 'Primus',
28
- 'Porn Groove', 'Satire', 'Slow Jam', 'Club', 'Tango', 'Samba', 'Folklore',
29
- 'Ballad', 'Power Ballad', 'Rhythmic Soul', 'Freestyle', 'Duet', 'Punk Rock', 'Drum Solo',
30
- 'A Cappella', 'Euro-House', 'Dance Hall', 'Goa', 'Drum & Bass', 'Club-House',
31
- 'Hardcore', 'Terror', 'Indie', 'BritPop', 'Negerpunk', 'Polsk Punk', 'Beat',
32
- 'Christian Gangsta Rap', 'Heavy Metal', 'Black Metal', 'Crossover', 'Contemporary Christian',
33
- 'Christian Rock', 'Merengue', 'Salsa', 'Thrash Metal', 'Anime', 'JPop', 'Synthpop',
34
- 'Abstract', 'Art Rock', 'Baroque', 'Bhangra', 'Big Beat', 'Breakbeat', 'Chillout',
35
- 'Downtempo', 'Dub', 'EBM', 'Eclectic', 'Electro', 'Electroclash', 'Emo', 'Experimental',
36
- 'Garage', 'Global', 'IDM', 'Illbient', 'Industro-Goth', 'Jam Band', 'Krautrock',
37
- 'Leftfield', 'Lounge', 'Math Rock', 'New Romantic', 'Nu-Breakz', 'Post-Punk', 'Post-Rock',
38
- 'Psytrance', 'Shoegaze', 'Space Rock', 'Trop Rock', 'World Music', 'Neoclassical', 'Audiobook',
39
- 'Audio Theatre', 'Neue Deutsche Welle', 'Podcast', 'Indie Rock', 'G-Funk', 'Dubstep',
40
- 'Garage Rock', 'Psybient'
13
+ 'Blues',
14
+ 'Classic Rock',
15
+ 'Country',
16
+ 'Dance',
17
+ 'Disco',
18
+ 'Funk',
19
+ 'Grunge',
20
+ 'Hip-Hop',
21
+ 'Jazz',
22
+ 'Metal',
23
+ 'New Age',
24
+ 'Oldies',
25
+ 'Other',
26
+ 'Pop',
27
+ 'R&B',
28
+ 'Rap',
29
+ 'Reggae',
30
+ 'Rock',
31
+ 'Techno',
32
+ 'Industrial',
33
+ 'Alternative',
34
+ 'Ska',
35
+ 'Death Metal',
36
+ 'Pranks',
37
+ 'Soundtrack',
38
+ 'Euro-Techno',
39
+ 'Ambient',
40
+ 'Trip-Hop',
41
+ 'Vocal',
42
+ 'Jazz+Funk',
43
+ 'Fusion',
44
+ 'Trance',
45
+ 'Classical',
46
+ 'Instrumental',
47
+ 'Acid',
48
+ 'House',
49
+ 'Game',
50
+ 'Sound Clip',
51
+ 'Gospel',
52
+ 'Noise',
53
+ 'Alt. Rock',
54
+ 'Bass',
55
+ 'Soul',
56
+ 'Punk',
57
+ 'Space',
58
+ 'Meditative',
59
+ 'Instrumental Pop',
60
+ 'Instrumental Rock',
61
+ 'Ethnic',
62
+ 'Gothic',
63
+ 'Darkwave',
64
+ 'Techno-Industrial',
65
+ 'Electronic',
66
+ 'Pop-Folk',
67
+ 'Eurodance',
68
+ 'Dream',
69
+ 'Southern Rock',
70
+ 'Comedy',
71
+ 'Cult',
72
+ 'Gangsta Rap',
73
+ 'Top 40',
74
+ 'Christian Rap',
75
+ 'Pop/Funk',
76
+ 'Jungle',
77
+ 'Native American',
78
+ 'Cabaret',
79
+ 'New Wave',
80
+ 'Psychedelic',
81
+ 'Rave',
82
+ 'Showtunes',
83
+ 'Trailer',
84
+ 'Lo-Fi',
85
+ 'Tribal',
86
+ 'Acid Punk',
87
+ 'Acid Jazz',
88
+ 'Polka',
89
+ 'Retro',
90
+ 'Musical',
91
+ 'Rock & Roll',
92
+ 'Hard Rock',
93
+ 'Folk',
94
+ 'Folk/Rock',
95
+ 'National Folk',
96
+ 'Swing',
97
+ 'Fast-Fusion',
98
+ 'Bebob',
99
+ 'Latin',
100
+ 'Revival',
101
+ 'Celtic',
102
+ 'Bluegrass',
103
+ 'Avantgarde',
104
+ 'Gothic Rock',
105
+ 'Progressive Rock',
106
+ 'Psychedelic Rock',
107
+ 'Symphonic Rock',
108
+ 'Slow Rock',
109
+ 'Big Band',
110
+ 'Chorus',
111
+ 'Easy Listening',
112
+ 'Acoustic',
113
+ 'Humour',
114
+ 'Speech',
115
+ 'Chanson',
116
+ 'Opera',
117
+ 'Chamber Music',
118
+ 'Sonata',
119
+ 'Symphony',
120
+ 'Booty Bass',
121
+ 'Primus',
122
+ 'Porn Groove',
123
+ 'Satire',
124
+ 'Slow Jam',
125
+ 'Club',
126
+ 'Tango',
127
+ 'Samba',
128
+ 'Folklore',
129
+ 'Ballad',
130
+ 'Power Ballad',
131
+ 'Rhythmic Soul',
132
+ 'Freestyle',
133
+ 'Duet',
134
+ 'Punk Rock',
135
+ 'Drum Solo',
136
+ 'A Cappella',
137
+ 'Euro-House',
138
+ 'Dance Hall',
139
+ 'Goa',
140
+ 'Drum & Bass',
141
+ 'Club-House',
142
+ 'Hardcore',
143
+ 'Terror',
144
+ 'Indie',
145
+ 'BritPop',
146
+ 'Negerpunk',
147
+ 'Polsk Punk',
148
+ 'Beat',
149
+ 'Christian Gangsta Rap',
150
+ 'Heavy Metal',
151
+ 'Black Metal',
152
+ 'Crossover',
153
+ 'Contemporary Christian',
154
+ 'Christian Rock',
155
+ 'Merengue',
156
+ 'Salsa',
157
+ 'Thrash Metal',
158
+ 'Anime',
159
+ 'JPop',
160
+ 'Synthpop',
161
+ 'Abstract',
162
+ 'Art Rock',
163
+ 'Baroque',
164
+ 'Bhangra',
165
+ 'Big Beat',
166
+ 'Breakbeat',
167
+ 'Chillout',
168
+ 'Downtempo',
169
+ 'Dub',
170
+ 'EBM',
171
+ 'Eclectic',
172
+ 'Electro',
173
+ 'Electroclash',
174
+ 'Emo',
175
+ 'Experimental',
176
+ 'Garage',
177
+ 'Global',
178
+ 'IDM',
179
+ 'Illbient',
180
+ 'Industro-Goth',
181
+ 'Jam Band',
182
+ 'Krautrock',
183
+ 'Leftfield',
184
+ 'Lounge',
185
+ 'Math Rock',
186
+ 'New Romantic',
187
+ 'Nu-Breakz',
188
+ 'Post-Punk',
189
+ 'Post-Rock',
190
+ 'Psytrance',
191
+ 'Shoegaze',
192
+ 'Space Rock',
193
+ 'Trop Rock',
194
+ 'World Music',
195
+ 'Neoclassical',
196
+ 'Audiobook',
197
+ 'Audio Theatre',
198
+ 'Neue Deutsche Welle',
199
+ 'Podcast',
200
+ 'Indie Rock',
201
+ 'G-Funk',
202
+ 'Dubstep',
203
+ 'Garage Rock',
204
+ 'Psybient'
41
205
  ];
42
206
  /**
43
207
  * Spec: http://id3.org/ID3v1
@@ -46,25 +210,29 @@ export const Genres = [
46
210
  const Iid3v1Token = {
47
211
  len: 128,
48
212
  /**
49
- * @param buf Buffer possibly holding the 128 bytes ID3v1.1 metadata header
213
+ * @param buf Buffer possibly holding the 128-byte ID3v1/1.1 metadata header
50
214
  * @param off Offset in buffer in bytes
51
- * @returns ID3v1.1 header if first 3 bytes equals 'TAG', otherwise null is returned
215
+ * @returns ID3v1/1.1 header if the first 3 bytes equal 'TAG', otherwise null is returned
52
216
  */
53
217
  get: (buf, off) => {
54
218
  const header = new Id3v1StringType(3).get(buf, off);
55
- return header === 'TAG' ? {
219
+ if (header !== 'TAG') {
220
+ return null;
221
+ }
222
+ const zeroByte = UINT8.get(buf, off + 125);
223
+ const track = UINT8.get(buf, off + 126);
224
+ // ID3v1.1 replaces the final two comment bytes with a zero separator and a nonzero track number.
225
+ const hasTrack = zeroByte === 0 && track !== 0;
226
+ return {
56
227
  header,
57
228
  title: new Id3v1StringType(30).get(buf, off + 3),
58
229
  artist: new Id3v1StringType(30).get(buf, off + 33),
59
230
  album: new Id3v1StringType(30).get(buf, off + 63),
60
231
  year: new Id3v1StringType(4).get(buf, off + 93),
61
- comment: new Id3v1StringType(28).get(buf, off + 97),
62
- // ID3v1.1 separator for track
63
- zeroByte: UINT8.get(buf, off + 127),
64
- // track: ID3v1.1 field added by Michael Mutschler
65
- track: UINT8.get(buf, off + 126),
232
+ comment: new Id3v1StringType(hasTrack ? 28 : 30).get(buf, off + 97),
233
+ track: hasTrack ? track : undefined,
66
234
  genre: UINT8.get(buf, off + 127)
67
- } : null;
235
+ };
68
236
  }
69
237
  };
70
238
  class Id3v1StringType {
@@ -110,12 +278,14 @@ export class ID3v1Parser extends BasicParser {
110
278
  debug('ID3v1 header found at: pos=%s', this.tokenizer.fileInfo.size - Iid3v1Token.len);
111
279
  const props = ['title', 'artist', 'album', 'comment', 'track', 'year'];
112
280
  for (const id of props) {
113
- if (header[id] && header[id] !== '')
281
+ if (header[id] && header[id] !== '') {
114
282
  await this.addTag(id, header[id]);
283
+ }
115
284
  }
116
285
  const genre = ID3v1Parser.getGenre(header.genre);
117
- if (genre)
286
+ if (genre) {
118
287
  await this.addTag('genre', genre);
288
+ }
119
289
  }
120
290
  else {
121
291
  debug('ID3v1 header not found at: pos=%s', this.tokenizer.fileInfo.size - Iid3v1Token.len);
@@ -1,9 +1,9 @@
1
- import { EndOfStreamError } from 'strtok3';
2
1
  import initDebug from 'debug';
3
- import { ID3v2Header } from './ID3v2Token.js';
4
- import { ID3v2Parser } from './ID3v2Parser.js';
5
- import { ID3v1Parser } from '../id3v1/ID3v1Parser.js';
2
+ import { EndOfStreamError } from 'strtok3';
6
3
  import { BasicParser } from '../common/BasicParser.js';
4
+ import { ID3v1Parser } from '../id3v1/ID3v1Parser.js';
5
+ import { ID3v2Parser } from './ID3v2Parser.js';
6
+ import { ID3v2Header } from './ID3v2Token.js';
7
7
  const debug = initDebug('music-metadata:parser:ID3');
8
8
  /**
9
9
  * Abstract parser which tries take ID3v2 and ID3v1 headers.
@@ -22,7 +22,7 @@ export class AbstractID3Parser extends BasicParser {
22
22
  }
23
23
  catch (err) {
24
24
  if (err instanceof EndOfStreamError) {
25
- debug("End-of-stream");
25
+ debug('End-of-stream');
26
26
  }
27
27
  else {
28
28
  throw err;
@@ -1,5 +1,5 @@
1
- import { type ID3v2MajorVersion } from './ID3v2Token.js';
2
1
  import type { IWarningCollector } from '../common/MetadataCollector.js';
2
+ import { type ID3v2MajorVersion } from './ID3v2Token.js';
3
3
  export interface IFrameFlags {
4
4
  status: {
5
5
  tag_alter_preservation: boolean;
@@ -1,18 +1,21 @@
1
1
  // lib/id3v2/FrameHeader.ts
2
+ import { textDecode } from '@borewit/text-codec';
2
3
  import * as Token from 'token-types';
3
4
  import * as util from '../common/Util.js';
4
- import { UINT32SYNCSAFE } from './ID3v2Token.js';
5
- import { textDecode } from '@borewit/text-codec';
6
5
  import { Id3v2ContentError } from './FrameParser.js';
6
+ import { UINT32SYNCSAFE } from './ID3v2Token.js';
7
7
  /**
8
8
  * Frame header length (bytes) depending on ID3v2 major version.
9
9
  */
10
10
  export function getFrameHeaderLength(majorVer) {
11
11
  switch (majorVer) {
12
- case 2: return 6;
12
+ case 2:
13
+ return 6;
13
14
  case 3:
14
- case 4: return 10;
15
- default: throw makeUnexpectedMajorVersionError(majorVer);
15
+ case 4:
16
+ return 10;
17
+ default:
18
+ throw makeUnexpectedMajorVersionError(majorVer);
16
19
  }
17
20
  }
18
21
  function readFrameFlags(b, majorVer) {
@@ -1,6 +1,6 @@
1
- import { type ID3v2MajorVersion, type ITextEncoding } from './ID3v2Token.js';
2
1
  import type { IWarningCollector } from '../common/MetadataCollector.js';
3
2
  import { type IChapterInfo } from './ID3v2ChapterToken.js';
3
+ import { type ID3v2MajorVersion, type ITextEncoding } from './ID3v2Token.js';
4
4
  interface ICustomTag {
5
5
  owner_identifier: string;
6
6
  }
@@ -65,6 +65,7 @@ export declare class FrameParser {
65
65
  /**
66
66
  * id3v2.4 defines that multiple T* values are separated by 0x00
67
67
  * id3v2.3 defines that TCOM, TEXT, TOLY, TOPE & TPE1 values are separated by /
68
+ * (TCON/TCO genre values are NOT slash-separated in ID3v2.3)
68
69
  * @param tag - Tag name
69
70
  * @param text - Concatenated tag value
70
71
  * @returns Split tag value
@@ -1,12 +1,12 @@
1
1
  import initDebug from 'debug';
2
2
  import * as Token from 'token-types';
3
3
  import * as util from '../common/Util.js';
4
- import { AttachedPictureType, SyncTextHeader, TextEncodingToken, TextHeader } from './ID3v2Token.js';
4
+ import { decodeUintBE } from '../common/Util.js';
5
5
  import { Genres } from '../id3v1/ID3v1Parser.js';
6
6
  import { makeUnexpectedFileContentError } from '../ParseError.js';
7
- import { decodeUintBE } from '../common/Util.js';
8
- import { ChapterInfo } from './ID3v2ChapterToken.js';
9
7
  import { getFrameHeaderLength, readFrameHeader } from './FrameHeader.js';
8
+ import { ChapterInfo } from './ID3v2ChapterToken.js';
9
+ import { AttachedPictureType, SyncTextHeader, TextEncodingToken, TextHeader } from './ID3v2Token.js';
10
10
  const debug = initDebug('music-metadata:id3v2:frame-parser');
11
11
  const defaultEnc = 'latin1'; // latin1 == iso-8859-1;
12
12
  const urlEnc = { encoding: defaultEnc, bom: false };
@@ -32,8 +32,9 @@ export function parseGenre(origVal) {
32
32
  }
33
33
  code = undefined;
34
34
  }
35
- else
35
+ else {
36
36
  code += c;
37
+ }
37
38
  }
38
39
  else if (c === '(') {
39
40
  code = '';
@@ -53,10 +54,12 @@ export function parseGenre(origVal) {
53
54
  return genres;
54
55
  }
55
56
  function parseGenreCode(code) {
56
- if (code === 'RX')
57
+ if (code === 'RX') {
57
58
  return 'Remix';
58
- if (code === 'CR')
59
+ }
60
+ if (code === 'CR') {
59
61
  return 'Cover';
62
+ }
60
63
  if (code.match(/^\d*$/)) {
61
64
  return Genres[Number.parseInt(code, 10)];
62
65
  }
@@ -128,13 +131,15 @@ export class FrameParser {
128
131
  break;
129
132
  case 'TCO':
130
133
  case 'TCON':
131
- output = this.splitValue(type, text).map(v => parseGenre(v)).reduce((acc, val) => acc.concat(val), []);
134
+ output = this.splitValue(type, text)
135
+ .map(v => parseGenre(v))
136
+ .reduce((acc, val) => acc.concat(val), []);
132
137
  break;
133
138
  case 'PCS':
134
139
  case 'PCST':
135
140
  // TODO: Why `default` not results `1` but `''`?
136
141
  output = this.major >= 4 ? this.splitValue(type, text) : [text];
137
- output = (Array.isArray(output) && output[0] === '') ? 1 : 0;
142
+ output = Array.isArray(output) && output[0] === '' ? 1 : 0;
138
143
  break;
139
144
  default:
140
145
  output = this.major >= 4 ? this.splitValue(type, text) : [text];
@@ -234,12 +239,14 @@ export class FrameParser {
234
239
  output = { owner_identifier: ufid.id, identifier: ufid.data };
235
240
  break;
236
241
  }
237
- case 'PRIV': { // private frame
242
+ case 'PRIV': {
243
+ // private frame
238
244
  const priv = FrameParser.readIdentifierAndData(uint8Array, defaultEnc);
239
245
  output = { owner_identifier: priv.id, data: priv.data };
240
246
  break;
241
247
  }
242
- case 'POPM': { // Popularimeter
248
+ case 'POPM': {
249
+ // Popularimeter
243
250
  uint8Array = uint8Array.subarray(offset);
244
251
  const emailStr = FrameParser.readNullTerminatedString(uint8Array, urlEnc);
245
252
  const email = emailStr.text;
@@ -258,7 +265,8 @@ export class FrameParser {
258
265
  };
259
266
  break;
260
267
  }
261
- case 'GEOB': { // General encapsulated object
268
+ case 'GEOB': {
269
+ // General encapsulated object
262
270
  // [encoding] <MIME> 0x00 <filename> 0x00/0x00 0x00 <description> 0x00/0x00 0x00 <data>
263
271
  const encoding = TextEncodingToken.get(uint8Array, 0);
264
272
  uint8Array = uint8Array.subarray(1);
@@ -317,8 +325,9 @@ export class FrameParser {
317
325
  }
318
326
  // ID3v2 Chapters 1.0
319
327
  // https://mutagen-specs.readthedocs.io/en/latest/id3/id3v2-chapters-1.0.html#chapter-frame
320
- case 'CHAP': { // // Chapter frame
321
- debug("Reading CHAP");
328
+ case 'CHAP': {
329
+ // // Chapter frame
330
+ debug('Reading CHAP');
322
331
  fzero = util.findZero(uint8Array, defaultEnc);
323
332
  const chapter = {
324
333
  label: util.decodeString(uint8Array.subarray(0, fzero), defaultEnc),
@@ -339,7 +348,8 @@ export class FrameParser {
339
348
  }
340
349
  // ID3v2 Chapters 1.0
341
350
  // https://mutagen-specs.readthedocs.io/en/latest/id3/id3v2-chapters-1.0.html#table-of-contents-frame
342
- case 'CTOC': { // Table of contents frame
351
+ case 'CTOC': {
352
+ // Table of contents frame
343
353
  debug('Reading CTOC');
344
354
  // Element ID (null-terminated latin1)
345
355
  const idEnd = util.findZero(uint8Array, defaultEnc);
@@ -383,21 +393,19 @@ export class FrameParser {
383
393
  return output;
384
394
  }
385
395
  static readNullTerminatedString(uint8Array, encoding) {
386
- const bomSize = encoding.bom ? 2 : 0;
387
396
  const originalLen = uint8Array.length;
388
- const valueArray = uint8Array.subarray(bomSize);
389
- const zeroIndex = util.findZero(valueArray, encoding.encoding);
390
- if (zeroIndex >= valueArray.length) {
391
- // No terminator found, decode full buffer remainder
397
+ const zeroIndex = util.findZero(uint8Array, encoding.encoding);
398
+ if (zeroIndex >= originalLen) {
399
+ // No terminator found, decode the whole buffer
392
400
  return {
393
401
  text: util.decodeString(uint8Array, encoding.encoding),
394
402
  len: originalLen
395
403
  };
396
404
  }
397
- const txt = uint8Array.subarray(0, bomSize + zeroIndex);
405
+ const txt = uint8Array.subarray(0, zeroIndex);
398
406
  return {
399
407
  text: util.decodeString(txt, encoding.encoding),
400
- len: bomSize + zeroIndex + FrameParser.getNullTerminatorLength(encoding.encoding)
408
+ len: zeroIndex + FrameParser.getNullTerminatorLength(encoding.encoding)
401
409
  };
402
410
  }
403
411
  static fixPictureMimeType(pictureType) {
@@ -425,6 +433,7 @@ export class FrameParser {
425
433
  /**
426
434
  * id3v2.4 defines that multiple T* values are separated by 0x00
427
435
  * id3v2.3 defines that TCOM, TEXT, TOLY, TOPE & TPE1 values are separated by /
436
+ * (TCON/TCO genre values are NOT slash-separated in ID3v2.3)
428
437
  * @param tag - Tag name
429
438
  * @param text - Concatenated tag value
430
439
  * @returns Split tag value
@@ -436,7 +445,29 @@ export class FrameParser {
436
445
  if (values.length > 1) {
437
446
  this.warningCollector.addWarning(`ID3v2.${this.major} ${tag} uses non standard null-separator.`);
438
447
  }
439
- else {
448
+ else if ([
449
+ /* v2.3: */ 'TPE1',
450
+ 'TPE2',
451
+ 'TPE3',
452
+ 'TPE4',
453
+ 'TCOM',
454
+ 'TEXT',
455
+ 'TOLY',
456
+ 'TOPE',
457
+ /* v2.2: */ 'TP1',
458
+ 'TCM',
459
+ 'TXT',
460
+ 'TOA',
461
+ 'TOL',
462
+ // Picard can flatten multiple values with '/' in these frames.
463
+ // https://picard-docs.musicbrainz.org/en/v2.13/config/options_tags_compatibility_id3.html
464
+ 'TXXX',
465
+ 'TSRC',
466
+ // Retain legacy support for nonstandard slash-separated credits.
467
+ 'IPLS'
468
+ ].includes(tag)) {
469
+ // note that field Genre (TCON/TCO) is NOT in this list:
470
+ // a genre like "Duo Cello/Piano" must stay intact
440
471
  values = text.split(/\//g);
441
472
  }
442
473
  }
@@ -1,5 +1,5 @@
1
- import type { INativeTagMap } from '../common/GenericTagTypes.js';
2
1
  import { CaseInsensitiveTagMap } from '../common/CaseInsensitiveTagMap.js';
2
+ import type { INativeTagMap } from '../common/GenericTagTypes.js';
3
3
  /**
4
4
  * ID3v2.2 tag mappings
5
5
  */
@@ -28,7 +28,7 @@ export const id3v22TagMap = {
28
28
  TSS: 'encodersettings',
29
29
  WAR: 'website',
30
30
  PCS: 'podcast',
31
- TCP: "compilation",
31
+ TCP: 'compilation',
32
32
  TDR: 'date',
33
33
  TS2: 'albumartistsort',
34
34
  TSA: 'albumsort',
@@ -1,6 +1,6 @@
1
1
  import { UINT32_LE } from 'token-types';
2
- import { CommonTagMapper } from '../common/GenericTagMapper.js';
3
2
  import { CaseInsensitiveTagMap } from '../common/CaseInsensitiveTagMap.js';
3
+ import { CommonTagMapper } from '../common/GenericTagMapper.js';
4
4
  import { decodeString } from '../common/Util.js';
5
5
  /**
6
6
  * ID3v2.3/ID3v2.4 tag mappings
@@ -138,13 +138,13 @@ const id3v24TagMap = {
138
138
  TKWD: 'keywords',
139
139
  WFED: 'podcasturl',
140
140
  GRP1: 'grouping',
141
- PCNT: 'playCounter',
141
+ PCNT: 'playCounter'
142
142
  };
143
143
  export class ID3v24TagMapper extends CaseInsensitiveTagMap {
144
144
  static toRating(popm) {
145
145
  return {
146
146
  source: popm.email,
147
- rating: popm.rating > 0 ? (popm.rating - 1) / 254 * CommonTagMapper.maxRatingScore : undefined
147
+ rating: popm.rating > 0 ? ((popm.rating - 1) / 254) * CommonTagMapper.maxRatingScore : undefined
148
148
  };
149
149
  }
150
150
  constructor() {
@@ -10,8 +10,8 @@ export const ChapterInfo = {
10
10
  return {
11
11
  startTime: Token.UINT32_BE.get(buf, off),
12
12
  endTime: Token.UINT32_BE.get(buf, off + 4),
13
- startOffset: startOffset === 0xFFFFFFFF ? undefined : startOffset,
14
- endOffset: endOffset === 0xFFFFFFFF ? undefined : endOffset,
13
+ startOffset: startOffset === 0xffffffff ? undefined : startOffset,
14
+ endOffset: endOffset === 0xffffffff ? undefined : endOffset
15
15
  };
16
16
  }
17
17
  };
@@ -1,6 +1,6 @@
1
1
  import type { ITokenizer } from 'strtok3';
2
- import type { IOptions } from '../type.js';
3
2
  import type { INativeMetadataCollector } from '../common/MetadataCollector.js';
3
+ import type { IOptions } from '../type.js';
4
4
  export declare class ID3v2Parser {
5
5
  static removeUnsyncBytes(buffer: Uint8Array): Uint8Array;
6
6
  private static readFrameData;