music-metadata 9.0.0 → 9.0.1

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.
@@ -9,13 +9,13 @@ export declare class RandomFileReader implements IRandomReader {
9
9
  private constructor();
10
10
  /**
11
11
  * Read from a given position of an abstracted file or buffer.
12
- * @param buffer {Buffer} is the buffer that the data will be written to.
12
+ * @param buffer {Uint8Array} is the buffer that the data will be written to.
13
13
  * @param offset {number} is the offset in the buffer to start writing at.
14
14
  * @param length {number}is an integer specifying the number of bytes to read.
15
15
  * @param position {number} is an argument specifying where to begin reading from in the file.
16
16
  * @return {Promise<number>} bytes read
17
17
  */
18
- randomRead(buffer: Buffer, offset: number, length: number, position: number): Promise<number>;
18
+ randomRead(buffer: Uint8Array, offset: number, length: number, position: number): Promise<number>;
19
19
  close(): Promise<void>;
20
20
  static init(filePath: string, fileSize: number): Promise<RandomFileReader>;
21
21
  }
@@ -10,7 +10,7 @@ export class RandomFileReader {
10
10
  }
11
11
  /**
12
12
  * Read from a given position of an abstracted file or buffer.
13
- * @param buffer {Buffer} is the buffer that the data will be written to.
13
+ * @param buffer {Uint8Array} is the buffer that the data will be written to.
14
14
  * @param offset {number} is the offset in the buffer to start writing at.
15
15
  * @param length {number}is an integer specifying the number of bytes to read.
16
16
  * @param position {number} is an argument specifying where to begin reading from in the file.
@@ -121,9 +121,9 @@ export class ID3v1Parser extends BasicParser {
121
121
  }
122
122
  export async function hasID3v1Header(reader) {
123
123
  if (reader.fileSize >= 128) {
124
- const tag = Buffer.alloc(3);
124
+ const tag = new Uint8Array(3);
125
125
  await reader.randomRead(tag, 0, tag.length, reader.fileSize - 128);
126
- return tag.toString('latin1') === 'TAG';
126
+ return new TextDecoder('latin1').decode(tag) === 'TAG';
127
127
  }
128
128
  return false;
129
129
  }
@@ -1,12 +1,12 @@
1
1
  export const endTag2 = 'LYRICS200';
2
2
  export async function getLyricsHeaderLength(reader) {
3
3
  if (reader.fileSize >= 143) {
4
- const buf = Buffer.alloc(15);
4
+ const buf = new Uint8Array(15);
5
5
  await reader.randomRead(buf, 0, buf.length, reader.fileSize - 143);
6
- const txt = buf.toString('latin1');
7
- const tag = txt.substr(6);
6
+ const txt = new TextDecoder('latin1').decode(buf);
7
+ const tag = txt.slice(6);
8
8
  if (tag === endTag2) {
9
- return parseInt(txt.substr(0, 6), 10) + 15;
9
+ return parseInt(txt.slice(0, 6), 10) + 15;
10
10
  }
11
11
  }
12
12
  return 0;
@@ -27,11 +27,18 @@ export declare class MatroskaParser extends BasicParser {
27
27
  private parseContainer;
28
28
  private readVintData;
29
29
  private readElement;
30
- private isMaxValue;
31
30
  private readFloat;
32
31
  private readFlag;
33
32
  private readUint;
34
33
  private readString;
35
34
  private readBuffer;
36
35
  private addTag;
36
+ private static readUIntBE;
37
+ /**
38
+ * Reeds an unsigned integer from a big endian buffer of length `len`
39
+ * @param buf Buffer to decode from
40
+ * @param len Number of bytes
41
+ * @private
42
+ */
43
+ private static readUIntBeAsBigInt;
37
44
  }
@@ -3,6 +3,7 @@ import initDebug from 'debug';
3
3
  import { BasicParser } from '../common/BasicParser.js';
4
4
  import * as matroskaDtd from './MatroskaDtd.js';
5
5
  import { DataType, TargetType, TrackType } from './types.js';
6
+ import * as Token from 'token-types';
6
7
  const debug = initDebug('music-metadata:parser:matroska');
7
8
  /**
8
9
  * Extensible Binary Meta Language (EBML) parser
@@ -21,7 +22,7 @@ export class MatroskaParser extends BasicParser {
21
22
  this.parserMap.set(DataType.uint, e => this.readUint(e));
22
23
  this.parserMap.set(DataType.string, e => this.readString(e));
23
24
  this.parserMap.set(DataType.binary, e => this.readBuffer(e));
24
- this.parserMap.set(DataType.uid, async (e) => await this.readUint(e) === 1);
25
+ this.parserMap.set(DataType.uid, async (e) => this.readBuffer(e));
25
26
  this.parserMap.set(DataType.bool, e => this.readFlag(e));
26
27
  this.parserMap.set(DataType.float, e => this.readFloat(e));
27
28
  }
@@ -45,7 +46,7 @@ export class MatroskaParser extends BasicParser {
45
46
  if (typeof info.duration === 'number') {
46
47
  const duration = info.duration * timecodeScale / 1000000000;
47
48
  await this.addTag('segment:title', info.title);
48
- this.metadata.setFormat('duration', duration);
49
+ this.metadata.setFormat('duration', Number(duration));
49
50
  }
50
51
  }
51
52
  const audioTracks = matroska.segment.tracks;
@@ -168,7 +169,7 @@ export class MatroskaParser extends BasicParser {
168
169
  ++oc;
169
170
  mask >>= 1;
170
171
  }
171
- const id = Buffer.alloc(oc);
172
+ const id = new Uint8Array(oc);
172
173
  await this.tokenizer.readBuffer(id);
173
174
  return id;
174
175
  }
@@ -176,22 +177,11 @@ export class MatroskaParser extends BasicParser {
176
177
  const id = await this.readVintData(this.ebmlMaxIDLength);
177
178
  const lenField = await this.readVintData(this.ebmlMaxSizeLength);
178
179
  lenField[0] ^= 0x80 >> (lenField.length - 1);
179
- const nrLen = Math.min(6, lenField.length); // JavaScript can max read 6 bytes integer
180
180
  return {
181
- id: id.readUIntBE(0, id.length),
182
- len: lenField.readUIntBE(lenField.length - nrLen, nrLen)
181
+ id: MatroskaParser.readUIntBE(id, id.length),
182
+ len: MatroskaParser.readUIntBE(lenField, lenField.length)
183
183
  };
184
184
  }
185
- isMaxValue(vintData) {
186
- if (vintData.length === this.ebmlMaxSizeLength) {
187
- for (let n = 1; n < this.ebmlMaxSizeLength; ++n) {
188
- if (vintData[n] !== 0xff)
189
- return false;
190
- }
191
- return true;
192
- }
193
- return false;
194
- }
195
185
  async readFloat(e) {
196
186
  switch (e.len) {
197
187
  case 0:
@@ -211,19 +201,38 @@ export class MatroskaParser extends BasicParser {
211
201
  }
212
202
  async readUint(e) {
213
203
  const buf = await this.readBuffer(e);
214
- const nrLen = Math.min(6, e.len); // JavaScript can max read 6 bytes integer
215
- return buf.readUIntBE(e.len - nrLen, nrLen);
204
+ return MatroskaParser.readUIntBE(buf, e.len);
216
205
  }
217
206
  async readString(e) {
218
207
  const rawString = await this.tokenizer.readToken(new StringType(e.len, 'utf-8'));
219
208
  return rawString.replace(/\x00.*$/g, '');
220
209
  }
221
210
  async readBuffer(e) {
222
- const buf = Buffer.alloc(e.len);
211
+ const buf = new Uint8Array(e.len);
223
212
  await this.tokenizer.readBuffer(buf);
224
213
  return buf;
225
214
  }
226
215
  async addTag(tagId, value) {
227
216
  await this.metadata.addTag('matroska', tagId, value);
228
217
  }
218
+ static readUIntBE(buf, len) {
219
+ return Number(MatroskaParser.readUIntBeAsBigInt(buf, len));
220
+ }
221
+ /**
222
+ * Reeds an unsigned integer from a big endian buffer of length `len`
223
+ * @param buf Buffer to decode from
224
+ * @param len Number of bytes
225
+ * @private
226
+ */
227
+ static readUIntBeAsBigInt(buf, len) {
228
+ const normalizedNumber = new Uint8Array(8);
229
+ const cleanNumber = buf.subarray(0, len);
230
+ try {
231
+ normalizedNumber.set(cleanNumber, 8 - len);
232
+ return Token.UINT64_BE.get(normalizedNumber, 0);
233
+ }
234
+ catch (error) {
235
+ return BigInt(-1);
236
+ }
237
+ }
229
238
  }
@@ -17,20 +17,20 @@ export interface IElementType<T> {
17
17
  readonly multiple?: boolean;
18
18
  }
19
19
  export interface IContainerType {
20
- [id: number]: IElementType<string | number | boolean | Buffer>;
20
+ [id: number]: IElementType<string | number | boolean | Uint8Array>;
21
21
  }
22
22
  export interface ITree {
23
- [name: string]: string | number | boolean | Buffer | ITree | ITree[];
23
+ [name: string]: string | number | boolean | Uint8Array | ITree | ITree[];
24
24
  }
25
25
  export interface ISeekHead {
26
- id?: Buffer;
26
+ id?: Uint8Array;
27
27
  position?: number;
28
28
  }
29
29
  export interface IMetaSeekInformation {
30
30
  seekHeads: ISeekHead[];
31
31
  }
32
32
  export interface ISegmentInformation {
33
- uid?: Buffer;
33
+ uid?: Uint8Array;
34
34
  timecodeScale?: number;
35
35
  duration?: number;
36
36
  dateUTC?: number;
@@ -39,7 +39,7 @@ export interface ISegmentInformation {
39
39
  writingApp?: string;
40
40
  }
41
41
  export interface ITrackEntry {
42
- uid?: Buffer;
42
+ uid?: Uint8Array;
43
43
  trackNumber?: number;
44
44
  trackType?: TrackType;
45
45
  audio?: ITrackAudio;
@@ -52,7 +52,7 @@ export interface ITrackEntry {
52
52
  name?: string;
53
53
  language?: string;
54
54
  codecID?: string;
55
- codecPrivate?: Buffer;
55
+ codecPrivate?: Uint8Array;
56
56
  codecName?: string;
57
57
  codecSettings?: string;
58
58
  codecInfoUrl?: string;
@@ -69,14 +69,14 @@ export interface ITrackVideo {
69
69
  displayHeight?: number;
70
70
  displayUnit?: number;
71
71
  aspectRatioType?: number;
72
- colourSpace?: Buffer;
72
+ colourSpace?: Uint8Array;
73
73
  gammaValue?: number;
74
74
  }
75
75
  export interface ITrackAudio {
76
76
  samplingFrequency?: number;
77
77
  outputSamplingFrequency?: number;
78
78
  channels?: number;
79
- channelPositions?: Buffer;
79
+ channelPositions?: Uint8Array;
80
80
  bitDepth?: number;
81
81
  }
82
82
  export interface ICuePoint {
@@ -99,7 +99,7 @@ export interface ICueReference {
99
99
  export interface ISimpleTag {
100
100
  name?: string;
101
101
  'string'?: string;
102
- binary?: Buffer;
102
+ binary?: Uint8Array;
103
103
  language?: string;
104
104
  default?: boolean;
105
105
  }
@@ -122,9 +122,9 @@ export declare enum TrackType {
122
122
  control = 32
123
123
  }
124
124
  export interface ITarget {
125
- trackUID?: Buffer;
126
- chapterUID?: Buffer;
127
- attachmentUID?: Buffer;
125
+ trackUID?: Uint8Array;
126
+ chapterUID?: Uint8Array;
127
+ attachmentUID?: Uint8Array;
128
128
  targetTypeValue?: TargetType;
129
129
  targetType?: string;
130
130
  }
@@ -142,7 +142,7 @@ export interface IAttachmedFile {
142
142
  description?: string;
143
143
  name: string;
144
144
  mimeType: string;
145
- data: Buffer;
145
+ data: Uint8Array;
146
146
  uid: string;
147
147
  }
148
148
  export interface IAttachments {
@@ -123,6 +123,7 @@ export declare abstract class FixedLengthAtom {
123
123
  *
124
124
  * @param {number} len Length as specified in the size field
125
125
  * @param {number} expLen Total length of sum of specified fields in the standard
126
+ * @param atomId Atom ID
126
127
  */
127
128
  protected constructor(len: number, expLen: number, atomId: string);
128
129
  }
@@ -148,7 +149,7 @@ export interface IAtomMdhd extends IAtomMxhd {
148
149
  export declare class MdhdAtom extends FixedLengthAtom implements IGetToken<IAtomMdhd> {
149
150
  len: number;
150
151
  constructor(len: number);
151
- get(buf: Buffer, off: number): IAtomMdhd;
152
+ get(buf: Uint8Array, off: number): IAtomMdhd;
152
153
  }
153
154
  /**
154
155
  * Token: Movie Header Atom
@@ -156,7 +157,7 @@ export declare class MdhdAtom extends FixedLengthAtom implements IGetToken<IAtom
156
157
  export declare class MvhdAtom extends FixedLengthAtom implements IGetToken<IAtomMvhd> {
157
158
  len: number;
158
159
  constructor(len: number);
159
- get(buf: Buffer, off: number): IAtomMvhd;
160
+ get(buf: Uint8Array, off: number): IAtomMvhd;
160
161
  }
161
162
  /**
162
163
  * Data Atom Structure ('data')
@@ -209,7 +210,7 @@ export interface INameAtom extends IVersionAndFlags {
209
210
  export declare class NameAtom implements IGetToken<INameAtom> {
210
211
  len: number;
211
212
  constructor(len: number);
212
- get(buf: Buffer, off: number): INameAtom;
213
+ get(buf: Uint8Array, off: number): INameAtom;
213
214
  }
214
215
  /**
215
216
  * Track Header Atoms interface
@@ -262,7 +263,7 @@ export interface ITrackHeaderAtom extends IVersionAndFlags {
262
263
  export declare class TrackHeaderAtom implements IGetToken<ITrackHeaderAtom> {
263
264
  len: number;
264
265
  constructor(len: number);
265
- get(buf: Buffer, off: number): ITrackHeaderAtom;
266
+ get(buf: Uint8Array, off: number): ITrackHeaderAtom;
266
267
  }
267
268
  /**
268
269
  * Atom: Sample Description Atom ('stsd')
@@ -289,7 +290,7 @@ export interface IAtomStsd {
289
290
  export declare class StsdAtom implements IGetToken<IAtomStsd> {
290
291
  len: number;
291
292
  constructor(len: number);
292
- get(buf: Buffer, off: number): IAtomStsd;
293
+ get(buf: Uint8Array, off: number): IAtomStsd;
293
294
  }
294
295
  export interface ISoundSampleDescriptionVersion {
295
296
  version: number;
@@ -327,7 +328,7 @@ declare class SimpleTableAtom<T> implements IGetToken<ITableAtom<T>> {
327
328
  len: number;
328
329
  private token;
329
330
  constructor(len: number, token: IGetToken<T>);
330
- get(buf: Buffer, off: number): ITableAtom<T>;
331
+ get(buf: Uint8Array, off: number): ITableAtom<T>;
331
332
  }
332
333
  export interface ITimeToSampleToken {
333
334
  count: number;
@@ -373,7 +374,7 @@ export interface IStszAtom extends ITableAtom<number> {
373
374
  export declare class StszAtom implements IGetToken<IStszAtom> {
374
375
  len: number;
375
376
  constructor(len: number);
376
- get(buf: Buffer, off: number): IStszAtom;
377
+ get(buf: Uint8Array, off: number): IStszAtom;
377
378
  }
378
379
  /**
379
380
  * Chunk offset atom, 'stco'
@@ -389,6 +390,6 @@ export declare class StcoAtom extends SimpleTableAtom<number> {
389
390
  export declare class ChapterText implements IGetToken<string> {
390
391
  len: number;
391
392
  constructor(len: number);
392
- get(buf: Buffer, off: number): string;
393
+ get(buf: Uint8Array, off: number): string;
393
394
  }
394
395
  export {};
@@ -61,6 +61,7 @@ export class FixedLengthAtom {
61
61
  *
62
62
  * @param {number} len Length as specified in the size field
63
63
  * @param {number} expLen Total length of sum of specified fields in the standard
64
+ * @param atomId Atom ID
64
65
  */
65
66
  constructor(len, expLen, atomId) {
66
67
  this.len = len;
@@ -212,9 +212,9 @@ export class MpegParser extends AbstractID3Parser {
212
212
  this.totalDataLength = 0;
213
213
  this.bitrates = [];
214
214
  this.calculateEofDuration = false;
215
- this.buf_frame_header = Buffer.alloc(4);
215
+ this.buf_frame_header = new Uint8Array(4);
216
216
  this.syncPeek = {
217
- buf: Buffer.alloc(maxPeekLen),
217
+ buf: new Uint8Array(maxPeekLen),
218
218
  len: 0
219
219
  };
220
220
  }
@@ -394,7 +394,7 @@ export class MpegParser extends AbstractID3Parser {
394
394
  }
395
395
  }
396
396
  async parseAdts(header) {
397
- const buf = Buffer.alloc(3);
397
+ const buf = new Uint8Array(3);
398
398
  await this.tokenizer.readBuffer(buf);
399
399
  header.frameLength += common.getBitAllignedNumber(buf, 0, 0, 11);
400
400
  this.totalDataLength += header.frameLength;
@@ -26,7 +26,7 @@ export interface IXingInfoTag {
26
26
  * Actual stream size = file size - header(s) size [bytes]
27
27
  */
28
28
  streamSize?: number;
29
- toc?: Buffer;
29
+ toc?: Uint8Array;
30
30
  /**
31
31
  * the number of header data bytes (from original file)
32
32
  */
@@ -40,7 +40,7 @@ export async function readXingHeader(tokenizer) {
40
40
  xingInfoTag.streamSize = await tokenizer.readToken(Token.UINT32_BE);
41
41
  }
42
42
  if (flags.toc) {
43
- xingInfoTag.toc = Buffer.alloc(100);
43
+ xingInfoTag.toc = new Uint8Array(100);
44
44
  await tokenizer.readBuffer(xingInfoTag.toc);
45
45
  }
46
46
  if (flags.vbrScale) {
@@ -16,9 +16,9 @@ export declare class OpusParser extends VorbisParser {
16
16
  /**
17
17
  * Parse first Opus Ogg page
18
18
  * @param {IPageHeader} header
19
- * @param {Buffer} pageData
19
+ * @param {Uint8Array} pageData
20
20
  */
21
- protected parseFirstPage(header: IPageHeader, pageData: Buffer): void;
22
- protected parseFullPage(pageData: Buffer): Promise<void>;
21
+ protected parseFirstPage(header: IPageHeader, pageData: Uint8Array): void;
22
+ protected parseFullPage(pageData: Uint8Array): Promise<void>;
23
23
  calculateDuration(header: IPageHeader): void;
24
24
  }
@@ -15,7 +15,7 @@ export class OpusParser extends VorbisParser {
15
15
  /**
16
16
  * Parse first Opus Ogg page
17
17
  * @param {IPageHeader} header
18
- * @param {Buffer} pageData
18
+ * @param {Uint8Array} pageData
19
19
  */
20
20
  parseFirstPage(header, pageData) {
21
21
  this.metadata.setFormat('codec', 'Opus');
@@ -15,7 +15,7 @@ export declare class SpeexParser extends VorbisParser {
15
15
  /**
16
16
  * Parse first Speex Ogg page
17
17
  * @param {IPageHeader} header
18
- * @param {Buffer} pageData
18
+ * @param {Uint8Array} pageData
19
19
  */
20
- protected parseFirstPage(header: IPageHeader, pageData: Buffer): void;
20
+ protected parseFirstPage(header: IPageHeader, pageData: Uint8Array): void;
21
21
  }
@@ -16,7 +16,7 @@ export class SpeexParser extends VorbisParser {
16
16
  /**
17
17
  * Parse first Speex Ogg page
18
18
  * @param {IPageHeader} header
19
- * @param {Buffer} pageData
19
+ * @param {Uint8Array} pageData
20
20
  */
21
21
  parseFirstPage(header, pageData) {
22
22
  debug('First Ogg/Speex page');
@@ -15,7 +15,7 @@ export declare class TheoraParser implements Ogg.IPageConsumer {
15
15
  * @param header Ogg Page Header
16
16
  * @param pageData Page data
17
17
  */
18
- parsePage(header: Ogg.IPageHeader, pageData: Buffer): Promise<void>;
18
+ parsePage(header: Ogg.IPageHeader, pageData: Uint8Array): Promise<void>;
19
19
  flush(): Promise<void>;
20
20
  calculateDuration(header: Ogg.IPageHeader): void;
21
21
  /**
@@ -23,5 +23,5 @@ export declare class TheoraParser implements Ogg.IPageConsumer {
23
23
  * @param {IPageHeader} header
24
24
  * @param {Buffer} pageData
25
25
  */
26
- protected parseFirstPage(header: Ogg.IPageHeader, pageData: Buffer): Promise<void>;
26
+ protected parseFirstPage(header: Ogg.IPageHeader, pageData: Uint8Array): Promise<void>;
27
27
  }
@@ -16,9 +16,10 @@ export declare class VorbisParser implements IPageConsumer {
16
16
  * @param header Ogg Page Header
17
17
  * @param pageData Page data
18
18
  */
19
- parsePage(header: IPageHeader, pageData: Buffer): Promise<void>;
19
+ parsePage(header: IPageHeader, pageData: Uint8Array): Promise<void>;
20
+ private static mergeUint8Arrays;
20
21
  flush(): Promise<void>;
21
- parseUserComment(pageData: Buffer, offset: number): Promise<number>;
22
+ parseUserComment(pageData: Uint8Array, offset: number): Promise<number>;
22
23
  addTag(id: string, value: string | IVorbisPicture): Promise<void>;
23
24
  calculateDuration(header: IPageHeader): void;
24
25
  /**
@@ -26,10 +27,10 @@ export declare class VorbisParser implements IPageConsumer {
26
27
  * @param header
27
28
  * @param pageData
28
29
  */
29
- protected parseFirstPage(header: IPageHeader, pageData: Buffer): void;
30
- protected parseFullPage(pageData: Buffer): Promise<void>;
30
+ protected parseFirstPage(header: IPageHeader, pageData: Uint8Array): void;
31
+ protected parseFullPage(pageData: Uint8Array): Promise<void>;
31
32
  /**
32
33
  * Ref: https://xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-840005.2
33
34
  */
34
- protected parseUserCommentList(pageData: Buffer, offset: number): Promise<void>;
35
+ protected parseUserCommentList(pageData: Uint8Array, offset: number): Promise<void>;
35
36
  }
@@ -32,7 +32,7 @@ export class VorbisParser {
32
32
  if (header.headerType.lastPage || !header.headerType.continued) {
33
33
  // Flush page segments
34
34
  if (this.pageSegments.length > 0) {
35
- const fullPage = Buffer.concat(this.pageSegments);
35
+ const fullPage = VorbisParser.mergeUint8Arrays(this.pageSegments);
36
36
  await this.parseFullPage(fullPage);
37
37
  }
38
38
  // Reset page segments
@@ -43,8 +43,17 @@ export class VorbisParser {
43
43
  this.calculateDuration(header);
44
44
  }
45
45
  }
46
+ static mergeUint8Arrays(arrays) {
47
+ const totalSize = arrays.reduce((acc, e) => acc + e.length, 0);
48
+ const merged = new Uint8Array(totalSize);
49
+ arrays.forEach((array, i, _arrays) => {
50
+ const offset = _arrays.slice(0, i).reduce((acc, e) => acc + e.length, 0);
51
+ merged.set(array, offset);
52
+ });
53
+ return merged;
54
+ }
46
55
  async flush() {
47
- await this.parseFullPage(Buffer.concat(this.pageSegments));
56
+ await this.parseFullPage(VorbisParser.mergeUint8Arrays(this.pageSegments));
48
57
  }
49
58
  async parseUserComment(pageData, offset) {
50
59
  const decoder = new VorbisDecoder(pageData, offset);
@@ -59,5 +59,5 @@ export interface IFactChunk {
59
59
  export declare class FactChunk implements IGetToken<IFactChunk> {
60
60
  len: number;
61
61
  constructor(header: IChunkHeader);
62
- get(buf: Buffer, off: number): IFactChunk;
62
+ get(buf: Uint8Array, off: number): IFactChunk;
63
63
  }
@@ -8,6 +8,7 @@ export declare class WavPackParser extends BasicParser {
8
8
  parseWavPackBlocks(): Promise<void>;
9
9
  /**
10
10
  * Ref: http://www.wavpack.com/WavPack5FileFormat.pdf, 3.0 Metadata Sub-blocks
11
+ * @param header Header
11
12
  * @param remainingLength
12
13
  */
13
14
  private parseMetadataSubBlock;
@@ -4,6 +4,7 @@ import { FourCcToken } from '../common/FourCC.js';
4
4
  import { BasicParser } from '../common/BasicParser.js';
5
5
  import { WavPack } from './WavPackToken.js';
6
6
  import initDebug from 'debug';
7
+ import { uint8ArrayToHex } from 'uint8array-extras';
7
8
  const debug = initDebug('music-metadata:parser:WavPack');
8
9
  /**
9
10
  * WavPack Parser
@@ -49,13 +50,14 @@ export class WavPackParser extends BasicParser {
49
50
  }
50
51
  /**
51
52
  * Ref: http://www.wavpack.com/WavPack5FileFormat.pdf, 3.0 Metadata Sub-blocks
53
+ * @param header Header
52
54
  * @param remainingLength
53
55
  */
54
56
  async parseMetadataSubBlock(header, remainingLength) {
55
57
  while (remainingLength > WavPack.MetadataIdToken.len) {
56
58
  const id = await this.tokenizer.readToken(WavPack.MetadataIdToken);
57
59
  const dataSizeInWords = await this.tokenizer.readNumber(id.largeBlock ? Token.UINT24_LE : Token.UINT8);
58
- const data = Buffer.alloc(dataSizeInWords * 2 - (id.isOddSize ? 1 : 0));
60
+ const data = new Uint8Array(dataSizeInWords * 2 - (id.isOddSize ? 1 : 0));
59
61
  await this.tokenizer.readBuffer(data);
60
62
  debug(`Metadata Sub-Blocks functionId=0x${id.functionId.toString(16)}, id.largeBlock=${id.largeBlock},data-size=${data.length}`);
61
63
  switch (id.functionId) {
@@ -78,7 +80,7 @@ export class WavPackParser extends BasicParser {
78
80
  this.metadata.setFormat('audioMD5', data);
79
81
  break;
80
82
  case 0x2f: // ID_BLOCK_CHECKSUM
81
- debug(`ID_BLOCK_CHECKSUM: checksum=${data.toString('hex')}`);
83
+ debug(`ID_BLOCK_CHECKSUM: checksum=${uint8ArrayToHex(data)}`);
82
84
  break;
83
85
  default:
84
86
  debug(`Ignore unsupported meta-sub-block-id functionId=0x${id.functionId.toString(16)}`);