music-metadata 8.3.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.
- package/LICENSE.txt +9 -9
- package/README.md +519 -488
- package/lib/ParserFactory.d.ts +1 -1
- package/lib/ParserFactory.js +1 -2
- package/lib/aiff/AiffParser.js +3 -4
- package/lib/aiff/AiffToken.d.ts +2 -4
- package/lib/aiff/AiffToken.js +7 -7
- package/lib/apev2/APEv2Parser.d.ts +1 -1
- package/lib/apev2/APEv2Parser.js +10 -12
- package/lib/apev2/APEv2Token.d.ts +1 -1
- package/lib/asf/AsfObject.d.ts +15 -17
- package/lib/asf/AsfObject.js +51 -45
- package/lib/asf/AsfParser.js +6 -8
- package/lib/asf/AsfUtil.d.ts +1 -3
- package/lib/asf/AsfUtil.js +4 -5
- package/lib/asf/GUID.d.ts +4 -5
- package/lib/asf/GUID.js +14 -11
- package/lib/common/BasicParser.d.ts +1 -1
- package/lib/common/FourCC.d.ts +1 -1
- package/lib/common/FourCC.js +5 -3
- package/lib/common/MetadataCollector.d.ts +3 -3
- package/lib/common/MetadataCollector.js +7 -8
- package/lib/common/RandomFileReader.d.ts +2 -3
- package/lib/common/RandomFileReader.js +1 -1
- package/lib/common/Util.d.ts +1 -1
- package/lib/common/Util.js +4 -3
- package/lib/core.d.ts +16 -8
- package/lib/core.js +19 -5
- package/lib/dsdiff/DsdiffParser.js +1 -1
- package/lib/dsdiff/DsdiffToken.d.ts +1 -1
- package/lib/dsf/DsfChunk.d.ts +1 -1
- package/lib/flac/FlacParser.d.ts +1 -1
- package/lib/flac/FlacParser.js +6 -4
- package/lib/id3v1/ID3v1Parser.js +7 -7
- package/lib/id3v2/AbstractID3Parser.d.ts +1 -1
- package/lib/id3v2/AbstractID3Parser.js +1 -1
- package/lib/id3v2/FrameParser.js +3 -3
- package/lib/id3v2/ID3v24TagMapper.d.ts +2 -3
- package/lib/id3v2/ID3v24TagMapper.js +4 -4
- package/lib/id3v2/ID3v2Parser.d.ts +1 -1
- package/lib/id3v2/ID3v2Parser.js +10 -17
- package/lib/id3v2/ID3v2Token.d.ts +1 -1
- package/lib/id3v2/ID3v2Token.js +2 -2
- package/lib/iff/index.d.ts +1 -1
- package/lib/index.d.ts +1 -2
- package/lib/index.js +1 -1
- package/lib/lyrics3/Lyrics3.js +4 -4
- package/lib/matroska/MatroskaParser.d.ts +9 -2
- package/lib/matroska/MatroskaParser.js +44 -39
- package/lib/matroska/types.d.ts +13 -14
- package/lib/mp4/Atom.d.ts +1 -1
- package/lib/mp4/AtomToken.d.ts +11 -11
- package/lib/mp4/AtomToken.js +3 -2
- package/lib/mp4/MP4Parser.js +20 -19
- package/lib/mpeg/ExtendedLameHeader.d.ts +1 -1
- package/lib/mpeg/MpegParser.js +4 -4
- package/lib/mpeg/ReplayGainDataFormat.d.ts +1 -1
- package/lib/mpeg/XingTag.d.ts +2 -3
- package/lib/mpeg/XingTag.js +1 -1
- package/lib/musepack/index.js +1 -1
- package/lib/musepack/sv7/BitReader.d.ts +1 -1
- package/lib/musepack/sv7/StreamVersion7.d.ts +1 -1
- package/lib/musepack/sv7/StreamVersion7.js +1 -1
- package/lib/musepack/sv8/StreamVersion8.d.ts +1 -1
- package/lib/musepack/sv8/StreamVersion8.js +1 -1
- package/lib/ogg/Ogg.d.ts +2 -2
- package/lib/ogg/OggParser.d.ts +1 -1
- package/lib/ogg/OggParser.js +5 -5
- package/lib/ogg/opus/Opus.d.ts +1 -1
- package/lib/ogg/opus/Opus.js +6 -6
- package/lib/ogg/opus/OpusParser.d.ts +4 -5
- package/lib/ogg/opus/OpusParser.js +3 -3
- package/lib/ogg/speex/Speex.d.ts +1 -1
- package/lib/ogg/speex/Speex.js +13 -13
- package/lib/ogg/speex/SpeexParser.d.ts +3 -4
- package/lib/ogg/speex/SpeexParser.js +1 -1
- package/lib/ogg/theora/Theora.d.ts +1 -1
- package/lib/ogg/theora/Theora.js +6 -6
- package/lib/ogg/theora/TheoraParser.d.ts +4 -5
- package/lib/ogg/theora/TheoraParser.js +4 -4
- package/lib/ogg/vorbis/Vorbis.d.ts +3 -4
- package/lib/ogg/vorbis/Vorbis.js +11 -12
- package/lib/ogg/vorbis/VorbisDecoder.js +1 -1
- package/lib/ogg/vorbis/VorbisParser.d.ts +8 -8
- package/lib/ogg/vorbis/VorbisParser.js +21 -12
- package/lib/riff/RiffChunk.d.ts +1 -1
- package/lib/riff/RiffChunk.js +2 -2
- package/lib/type.d.ts +9 -11
- package/lib/wav/BwfChunk.d.ts +1 -1
- package/lib/wav/WaveChunk.d.ts +3 -4
- package/lib/wav/WaveChunk.js +8 -7
- package/lib/wav/WaveParser.js +2 -2
- package/lib/wavpack/WavPackParser.d.ts +1 -0
- package/lib/wavpack/WavPackParser.js +5 -3
- package/lib/wavpack/WavPackToken.d.ts +1 -1
- package/package.json +141 -140
package/lib/lyrics3/Lyrics3.js
CHANGED
|
@@ -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 =
|
|
4
|
+
const buf = new Uint8Array(15);
|
|
5
5
|
await reader.randomRead(buf, 0, buf.length, reader.fileSize - 143);
|
|
6
|
-
const txt =
|
|
7
|
-
const tag = txt.
|
|
6
|
+
const txt = new TextDecoder('latin1').decode(buf);
|
|
7
|
+
const tag = txt.slice(6);
|
|
8
8
|
if (tag === endTag2) {
|
|
9
|
-
return parseInt(txt.
|
|
9
|
+
return parseInt(txt.slice(0, 6), 10) + 15;
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
12
|
return 0;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ITokenizer } from 'strtok3
|
|
1
|
+
import type { ITokenizer } from 'strtok3';
|
|
2
2
|
import { INativeMetadataCollector } from '../common/MetadataCollector.js';
|
|
3
3
|
import { BasicParser } from '../common/BasicParser.js';
|
|
4
4
|
import { IOptions } from '../type.js';
|
|
@@ -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) =>
|
|
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
|
}
|
|
@@ -44,8 +45,8 @@ export class MatroskaParser extends BasicParser {
|
|
|
44
45
|
const timecodeScale = info.timecodeScale ? info.timecodeScale : 1000000;
|
|
45
46
|
if (typeof info.duration === 'number') {
|
|
46
47
|
const duration = info.duration * timecodeScale / 1000000000;
|
|
47
|
-
this.addTag('segment:title', info.title);
|
|
48
|
-
this.metadata.setFormat('duration', duration);
|
|
48
|
+
await this.addTag('segment:title', info.title);
|
|
49
|
+
this.metadata.setFormat('duration', Number(duration));
|
|
49
50
|
}
|
|
50
51
|
}
|
|
51
52
|
const audioTracks = matroska.segment.tracks;
|
|
@@ -87,28 +88,24 @@ export class MatroskaParser extends BasicParser {
|
|
|
87
88
|
this.metadata.setFormat('numberOfChannels', audioTrack.audio.channels);
|
|
88
89
|
}
|
|
89
90
|
if (matroska.segment.tags) {
|
|
90
|
-
matroska.segment.tags.tag.
|
|
91
|
+
await Promise.all(matroska.segment.tags.tag.map(async (tag) => {
|
|
91
92
|
const target = tag.target;
|
|
92
93
|
const targetType = (target === null || target === void 0 ? void 0 : target.targetTypeValue) ? TargetType[target.targetTypeValue] : ((target === null || target === void 0 ? void 0 : target.targetType) ? target.targetType : 'track');
|
|
93
|
-
tag.simpleTags.
|
|
94
|
+
await Promise.all(tag.simpleTags.map(async (simpleTag) => {
|
|
94
95
|
const value = simpleTag.string ? simpleTag.string : simpleTag.binary;
|
|
95
|
-
this.addTag(`${targetType}:${simpleTag.name}`, value);
|
|
96
|
-
});
|
|
97
|
-
});
|
|
96
|
+
await this.addTag(`${targetType}:${simpleTag.name}`, value);
|
|
97
|
+
}));
|
|
98
|
+
}));
|
|
98
99
|
}
|
|
99
100
|
if (matroska.segment.attachments) {
|
|
100
|
-
matroska.segment.attachments.attachedFiles
|
|
101
|
+
await Promise.all(matroska.segment.attachments.attachedFiles
|
|
101
102
|
.filter(file => file.mimeType.startsWith('image/'))
|
|
102
|
-
.map(file => {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
};
|
|
109
|
-
}).forEach(picture => {
|
|
110
|
-
this.addTag('picture', picture);
|
|
111
|
-
});
|
|
103
|
+
.map(file => this.addTag('picture', {
|
|
104
|
+
data: file.data,
|
|
105
|
+
format: file.mimeType,
|
|
106
|
+
description: file.description,
|
|
107
|
+
name: file.name
|
|
108
|
+
})));
|
|
112
109
|
}
|
|
113
110
|
}
|
|
114
111
|
}
|
|
@@ -172,7 +169,7 @@ export class MatroskaParser extends BasicParser {
|
|
|
172
169
|
++oc;
|
|
173
170
|
mask >>= 1;
|
|
174
171
|
}
|
|
175
|
-
const id =
|
|
172
|
+
const id = new Uint8Array(oc);
|
|
176
173
|
await this.tokenizer.readBuffer(id);
|
|
177
174
|
return id;
|
|
178
175
|
}
|
|
@@ -180,22 +177,11 @@ export class MatroskaParser extends BasicParser {
|
|
|
180
177
|
const id = await this.readVintData(this.ebmlMaxIDLength);
|
|
181
178
|
const lenField = await this.readVintData(this.ebmlMaxSizeLength);
|
|
182
179
|
lenField[0] ^= 0x80 >> (lenField.length - 1);
|
|
183
|
-
const nrLen = Math.min(6, lenField.length); // JavaScript can max read 6 bytes integer
|
|
184
180
|
return {
|
|
185
|
-
id:
|
|
186
|
-
len:
|
|
181
|
+
id: MatroskaParser.readUIntBE(id, id.length),
|
|
182
|
+
len: MatroskaParser.readUIntBE(lenField, lenField.length)
|
|
187
183
|
};
|
|
188
184
|
}
|
|
189
|
-
isMaxValue(vintData) {
|
|
190
|
-
if (vintData.length === this.ebmlMaxSizeLength) {
|
|
191
|
-
for (let n = 1; n < this.ebmlMaxSizeLength; ++n) {
|
|
192
|
-
if (vintData[n] !== 0xff)
|
|
193
|
-
return false;
|
|
194
|
-
}
|
|
195
|
-
return true;
|
|
196
|
-
}
|
|
197
|
-
return false;
|
|
198
|
-
}
|
|
199
185
|
async readFloat(e) {
|
|
200
186
|
switch (e.len) {
|
|
201
187
|
case 0:
|
|
@@ -215,19 +201,38 @@ export class MatroskaParser extends BasicParser {
|
|
|
215
201
|
}
|
|
216
202
|
async readUint(e) {
|
|
217
203
|
const buf = await this.readBuffer(e);
|
|
218
|
-
|
|
219
|
-
return buf.readUIntBE(e.len - nrLen, nrLen);
|
|
204
|
+
return MatroskaParser.readUIntBE(buf, e.len);
|
|
220
205
|
}
|
|
221
206
|
async readString(e) {
|
|
222
207
|
const rawString = await this.tokenizer.readToken(new StringType(e.len, 'utf-8'));
|
|
223
|
-
return rawString.replace(/\
|
|
208
|
+
return rawString.replace(/\x00.*$/g, '');
|
|
224
209
|
}
|
|
225
210
|
async readBuffer(e) {
|
|
226
|
-
const buf =
|
|
211
|
+
const buf = new Uint8Array(e.len);
|
|
227
212
|
await this.tokenizer.readBuffer(buf);
|
|
228
213
|
return buf;
|
|
229
214
|
}
|
|
230
|
-
addTag(tagId, value) {
|
|
231
|
-
this.metadata.addTag('matroska', tagId, value);
|
|
215
|
+
async addTag(tagId, value) {
|
|
216
|
+
await this.metadata.addTag('matroska', tagId, value);
|
|
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
|
+
}
|
|
232
237
|
}
|
|
233
238
|
}
|
package/lib/matroska/types.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/// <reference types="node" resolution-mode="require"/>
|
|
2
1
|
export interface IHeader {
|
|
3
2
|
id: number;
|
|
4
3
|
len: number;
|
|
@@ -18,20 +17,20 @@ export interface IElementType<T> {
|
|
|
18
17
|
readonly multiple?: boolean;
|
|
19
18
|
}
|
|
20
19
|
export interface IContainerType {
|
|
21
|
-
[id: number]: IElementType<string | number | boolean |
|
|
20
|
+
[id: number]: IElementType<string | number | boolean | Uint8Array>;
|
|
22
21
|
}
|
|
23
22
|
export interface ITree {
|
|
24
|
-
[name: string]: string | number | boolean |
|
|
23
|
+
[name: string]: string | number | boolean | Uint8Array | ITree | ITree[];
|
|
25
24
|
}
|
|
26
25
|
export interface ISeekHead {
|
|
27
|
-
id?:
|
|
26
|
+
id?: Uint8Array;
|
|
28
27
|
position?: number;
|
|
29
28
|
}
|
|
30
29
|
export interface IMetaSeekInformation {
|
|
31
30
|
seekHeads: ISeekHead[];
|
|
32
31
|
}
|
|
33
32
|
export interface ISegmentInformation {
|
|
34
|
-
uid?:
|
|
33
|
+
uid?: Uint8Array;
|
|
35
34
|
timecodeScale?: number;
|
|
36
35
|
duration?: number;
|
|
37
36
|
dateUTC?: number;
|
|
@@ -40,7 +39,7 @@ export interface ISegmentInformation {
|
|
|
40
39
|
writingApp?: string;
|
|
41
40
|
}
|
|
42
41
|
export interface ITrackEntry {
|
|
43
|
-
uid?:
|
|
42
|
+
uid?: Uint8Array;
|
|
44
43
|
trackNumber?: number;
|
|
45
44
|
trackType?: TrackType;
|
|
46
45
|
audio?: ITrackAudio;
|
|
@@ -53,7 +52,7 @@ export interface ITrackEntry {
|
|
|
53
52
|
name?: string;
|
|
54
53
|
language?: string;
|
|
55
54
|
codecID?: string;
|
|
56
|
-
codecPrivate?:
|
|
55
|
+
codecPrivate?: Uint8Array;
|
|
57
56
|
codecName?: string;
|
|
58
57
|
codecSettings?: string;
|
|
59
58
|
codecInfoUrl?: string;
|
|
@@ -70,14 +69,14 @@ export interface ITrackVideo {
|
|
|
70
69
|
displayHeight?: number;
|
|
71
70
|
displayUnit?: number;
|
|
72
71
|
aspectRatioType?: number;
|
|
73
|
-
colourSpace?:
|
|
72
|
+
colourSpace?: Uint8Array;
|
|
74
73
|
gammaValue?: number;
|
|
75
74
|
}
|
|
76
75
|
export interface ITrackAudio {
|
|
77
76
|
samplingFrequency?: number;
|
|
78
77
|
outputSamplingFrequency?: number;
|
|
79
78
|
channels?: number;
|
|
80
|
-
channelPositions?:
|
|
79
|
+
channelPositions?: Uint8Array;
|
|
81
80
|
bitDepth?: number;
|
|
82
81
|
}
|
|
83
82
|
export interface ICuePoint {
|
|
@@ -100,7 +99,7 @@ export interface ICueReference {
|
|
|
100
99
|
export interface ISimpleTag {
|
|
101
100
|
name?: string;
|
|
102
101
|
'string'?: string;
|
|
103
|
-
binary?:
|
|
102
|
+
binary?: Uint8Array;
|
|
104
103
|
language?: string;
|
|
105
104
|
default?: boolean;
|
|
106
105
|
}
|
|
@@ -123,9 +122,9 @@ export declare enum TrackType {
|
|
|
123
122
|
control = 32
|
|
124
123
|
}
|
|
125
124
|
export interface ITarget {
|
|
126
|
-
trackUID?:
|
|
127
|
-
chapterUID?:
|
|
128
|
-
attachmentUID?:
|
|
125
|
+
trackUID?: Uint8Array;
|
|
126
|
+
chapterUID?: Uint8Array;
|
|
127
|
+
attachmentUID?: Uint8Array;
|
|
129
128
|
targetTypeValue?: TargetType;
|
|
130
129
|
targetType?: string;
|
|
131
130
|
}
|
|
@@ -143,7 +142,7 @@ export interface IAttachmedFile {
|
|
|
143
142
|
description?: string;
|
|
144
143
|
name: string;
|
|
145
144
|
mimeType: string;
|
|
146
|
-
data:
|
|
145
|
+
data: Uint8Array;
|
|
147
146
|
uid: string;
|
|
148
147
|
}
|
|
149
148
|
export interface IAttachments {
|
package/lib/mp4/Atom.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as AtomToken from './AtomToken.js';
|
|
2
|
-
import { ITokenizer } from 'strtok3
|
|
2
|
+
import type { ITokenizer } from 'strtok3';
|
|
3
3
|
export type AtomDataHandler = (atom: Atom, remaining: number) => Promise<void>;
|
|
4
4
|
export declare class Atom {
|
|
5
5
|
readonly header: AtomToken.IAtomHeader;
|
package/lib/mp4/AtomToken.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
import { IToken, IGetToken } from 'strtok3/core';
|
|
1
|
+
import type { IToken, IGetToken } from 'strtok3';
|
|
3
2
|
interface IVersionAndFlags {
|
|
4
3
|
/**
|
|
5
4
|
* A 1-byte specification of the version
|
|
@@ -124,6 +123,7 @@ export declare abstract class FixedLengthAtom {
|
|
|
124
123
|
*
|
|
125
124
|
* @param {number} len Length as specified in the size field
|
|
126
125
|
* @param {number} expLen Total length of sum of specified fields in the standard
|
|
126
|
+
* @param atomId Atom ID
|
|
127
127
|
*/
|
|
128
128
|
protected constructor(len: number, expLen: number, atomId: string);
|
|
129
129
|
}
|
|
@@ -149,7 +149,7 @@ export interface IAtomMdhd extends IAtomMxhd {
|
|
|
149
149
|
export declare class MdhdAtom extends FixedLengthAtom implements IGetToken<IAtomMdhd> {
|
|
150
150
|
len: number;
|
|
151
151
|
constructor(len: number);
|
|
152
|
-
get(buf:
|
|
152
|
+
get(buf: Uint8Array, off: number): IAtomMdhd;
|
|
153
153
|
}
|
|
154
154
|
/**
|
|
155
155
|
* Token: Movie Header Atom
|
|
@@ -157,7 +157,7 @@ export declare class MdhdAtom extends FixedLengthAtom implements IGetToken<IAtom
|
|
|
157
157
|
export declare class MvhdAtom extends FixedLengthAtom implements IGetToken<IAtomMvhd> {
|
|
158
158
|
len: number;
|
|
159
159
|
constructor(len: number);
|
|
160
|
-
get(buf:
|
|
160
|
+
get(buf: Uint8Array, off: number): IAtomMvhd;
|
|
161
161
|
}
|
|
162
162
|
/**
|
|
163
163
|
* Data Atom Structure ('data')
|
|
@@ -183,7 +183,7 @@ export interface IDataAtom {
|
|
|
183
183
|
/**
|
|
184
184
|
* An array of bytes containing the value of the metadata.
|
|
185
185
|
*/
|
|
186
|
-
value:
|
|
186
|
+
value: Uint8Array;
|
|
187
187
|
}
|
|
188
188
|
/**
|
|
189
189
|
* Data Atom Structure
|
|
@@ -210,7 +210,7 @@ export interface INameAtom extends IVersionAndFlags {
|
|
|
210
210
|
export declare class NameAtom implements IGetToken<INameAtom> {
|
|
211
211
|
len: number;
|
|
212
212
|
constructor(len: number);
|
|
213
|
-
get(buf:
|
|
213
|
+
get(buf: Uint8Array, off: number): INameAtom;
|
|
214
214
|
}
|
|
215
215
|
/**
|
|
216
216
|
* Track Header Atoms interface
|
|
@@ -263,7 +263,7 @@ export interface ITrackHeaderAtom extends IVersionAndFlags {
|
|
|
263
263
|
export declare class TrackHeaderAtom implements IGetToken<ITrackHeaderAtom> {
|
|
264
264
|
len: number;
|
|
265
265
|
constructor(len: number);
|
|
266
|
-
get(buf:
|
|
266
|
+
get(buf: Uint8Array, off: number): ITrackHeaderAtom;
|
|
267
267
|
}
|
|
268
268
|
/**
|
|
269
269
|
* Atom: Sample Description Atom ('stsd')
|
|
@@ -290,7 +290,7 @@ export interface IAtomStsd {
|
|
|
290
290
|
export declare class StsdAtom implements IGetToken<IAtomStsd> {
|
|
291
291
|
len: number;
|
|
292
292
|
constructor(len: number);
|
|
293
|
-
get(buf:
|
|
293
|
+
get(buf: Uint8Array, off: number): IAtomStsd;
|
|
294
294
|
}
|
|
295
295
|
export interface ISoundSampleDescriptionVersion {
|
|
296
296
|
version: number;
|
|
@@ -328,7 +328,7 @@ declare class SimpleTableAtom<T> implements IGetToken<ITableAtom<T>> {
|
|
|
328
328
|
len: number;
|
|
329
329
|
private token;
|
|
330
330
|
constructor(len: number, token: IGetToken<T>);
|
|
331
|
-
get(buf:
|
|
331
|
+
get(buf: Uint8Array, off: number): ITableAtom<T>;
|
|
332
332
|
}
|
|
333
333
|
export interface ITimeToSampleToken {
|
|
334
334
|
count: number;
|
|
@@ -374,7 +374,7 @@ export interface IStszAtom extends ITableAtom<number> {
|
|
|
374
374
|
export declare class StszAtom implements IGetToken<IStszAtom> {
|
|
375
375
|
len: number;
|
|
376
376
|
constructor(len: number);
|
|
377
|
-
get(buf:
|
|
377
|
+
get(buf: Uint8Array, off: number): IStszAtom;
|
|
378
378
|
}
|
|
379
379
|
/**
|
|
380
380
|
* Chunk offset atom, 'stco'
|
|
@@ -390,6 +390,6 @@ export declare class StcoAtom extends SimpleTableAtom<number> {
|
|
|
390
390
|
export declare class ChapterText implements IGetToken<string> {
|
|
391
391
|
len: number;
|
|
392
392
|
constructor(len: number);
|
|
393
|
-
get(buf:
|
|
393
|
+
get(buf: Uint8Array, off: number): string;
|
|
394
394
|
}
|
|
395
395
|
export {};
|
package/lib/mp4/AtomToken.js
CHANGED
|
@@ -10,7 +10,7 @@ export const Header = {
|
|
|
10
10
|
throw new Error('Invalid atom header length');
|
|
11
11
|
return {
|
|
12
12
|
length: BigInt(length),
|
|
13
|
-
name: new Token.StringType(4, '
|
|
13
|
+
name: new Token.StringType(4, 'latin1').get(buf, off + 4)
|
|
14
14
|
};
|
|
15
15
|
},
|
|
16
16
|
put: (buf, off, hdr) => {
|
|
@@ -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;
|
|
@@ -150,7 +151,7 @@ export class DataAtom {
|
|
|
150
151
|
type: Token.UINT24_BE.get(buf, off + 1)
|
|
151
152
|
},
|
|
152
153
|
locale: Token.UINT24_BE.get(buf, off + 4),
|
|
153
|
-
value:
|
|
154
|
+
value: new Token.Uint8ArrayType(this.len - 8).get(buf, off + 8)
|
|
154
155
|
};
|
|
155
156
|
}
|
|
156
157
|
}
|
package/lib/mp4/MP4Parser.js
CHANGED
|
@@ -5,6 +5,7 @@ import { Genres } from '../id3v1/ID3v1Parser.js';
|
|
|
5
5
|
import { Atom } from './Atom.js';
|
|
6
6
|
import * as AtomToken from './AtomToken.js';
|
|
7
7
|
import { TrackType } from '../type.js';
|
|
8
|
+
import { uint8ArrayToHex, uint8ArrayToString } from 'uint8array-extras';
|
|
8
9
|
const debug = initDebug('music-metadata:parser:MP4');
|
|
9
10
|
const tagFormat = 'iTunes';
|
|
10
11
|
const encoderDict = {
|
|
@@ -199,7 +200,7 @@ export class MP4Parser extends BasicParser {
|
|
|
199
200
|
},
|
|
200
201
|
date: async (len) => {
|
|
201
202
|
const date = await this.tokenizer.readToken(new Token.StringType(len, 'utf-8'));
|
|
202
|
-
this.addTag('date', date);
|
|
203
|
+
await this.addTag('date', date);
|
|
203
204
|
}
|
|
204
205
|
};
|
|
205
206
|
}
|
|
@@ -321,8 +322,8 @@ export class MP4Parser extends BasicParser {
|
|
|
321
322
|
this.metadata.setFormat('bitrate', 8 * this.audioLengthInBytes / this.metadata.format.duration);
|
|
322
323
|
}
|
|
323
324
|
}
|
|
324
|
-
addTag(id, value) {
|
|
325
|
-
this.metadata.addTag(tagFormat, id, value);
|
|
325
|
+
async addTag(id, value) {
|
|
326
|
+
await this.metadata.addTag(tagFormat, id, value);
|
|
326
327
|
}
|
|
327
328
|
addWarning(message) {
|
|
328
329
|
debug('Warning: ' + message);
|
|
@@ -347,8 +348,8 @@ export class MP4Parser extends BasicParser {
|
|
|
347
348
|
tagKey += ':' + name.name;
|
|
348
349
|
break;
|
|
349
350
|
default:
|
|
350
|
-
const
|
|
351
|
-
this.addWarning('Unsupported meta-item: ' + tagKey + '[' + child.header.name + '] => value=' +
|
|
351
|
+
const uint8Array = await this.tokenizer.readToken(new Token.Uint8ArrayType(payLoadLength));
|
|
352
|
+
this.addWarning('Unsupported meta-item: ' + tagKey + '[' + child.header.name + '] => value=' + uint8ArrayToHex(uint8Array) + ' ascii=' + uint8ArrayToString(uint8Array, 'ascii'));
|
|
352
353
|
}
|
|
353
354
|
}, metaAtom.getPayloadLength(0));
|
|
354
355
|
}
|
|
@@ -367,17 +368,17 @@ export class MP4Parser extends BasicParser {
|
|
|
367
368
|
const num = Token.UINT8.get(dataAtom.value, 3);
|
|
368
369
|
const of = Token.UINT8.get(dataAtom.value, 5);
|
|
369
370
|
// console.log(" %s[data] = %s/%s", tagKey, num, of);
|
|
370
|
-
this.addTag(tagKey, num + '/' + of);
|
|
371
|
+
await this.addTag(tagKey, num + '/' + of);
|
|
371
372
|
break;
|
|
372
373
|
case 'gnre':
|
|
373
374
|
const genreInt = Token.UINT8.get(dataAtom.value, 1);
|
|
374
375
|
const genreStr = Genres[genreInt - 1];
|
|
375
376
|
// console.log(" %s[data] = %s", tagKey, genreStr);
|
|
376
|
-
this.addTag(tagKey, genreStr);
|
|
377
|
+
await this.addTag(tagKey, genreStr);
|
|
377
378
|
break;
|
|
378
379
|
case 'rate':
|
|
379
|
-
const rate =
|
|
380
|
-
this.addTag(tagKey, rate);
|
|
380
|
+
const rate = new TextDecoder('ascii').decode(dataAtom.value);
|
|
381
|
+
await this.addTag(tagKey, rate);
|
|
381
382
|
break;
|
|
382
383
|
default:
|
|
383
384
|
debug('unknown proprietary value type for: ' + metaAtom.atomPath);
|
|
@@ -385,38 +386,38 @@ export class MP4Parser extends BasicParser {
|
|
|
385
386
|
break;
|
|
386
387
|
case 1: // UTF-8: Without any count or NULL terminator
|
|
387
388
|
case 18: // Unknown: Found in m4b in combination with a '©gen' tag
|
|
388
|
-
this.addTag(tagKey,
|
|
389
|
+
await this.addTag(tagKey, new TextDecoder('utf-8').decode(dataAtom.value));
|
|
389
390
|
break;
|
|
390
391
|
case 13: // JPEG
|
|
391
392
|
if (this.options.skipCovers)
|
|
392
393
|
break;
|
|
393
|
-
this.addTag(tagKey, {
|
|
394
|
+
await this.addTag(tagKey, {
|
|
394
395
|
format: 'image/jpeg',
|
|
395
|
-
data:
|
|
396
|
+
data: Uint8Array.from(dataAtom.value)
|
|
396
397
|
});
|
|
397
398
|
break;
|
|
398
399
|
case 14: // PNG
|
|
399
400
|
if (this.options.skipCovers)
|
|
400
401
|
break;
|
|
401
|
-
this.addTag(tagKey, {
|
|
402
|
+
await this.addTag(tagKey, {
|
|
402
403
|
format: 'image/png',
|
|
403
|
-
data:
|
|
404
|
+
data: Uint8Array.from(dataAtom.value)
|
|
404
405
|
});
|
|
405
406
|
break;
|
|
406
407
|
case 21: // BE Signed Integer
|
|
407
|
-
this.addTag(tagKey, MP4Parser.read_BE_Integer(dataAtom.value, true));
|
|
408
|
+
await this.addTag(tagKey, MP4Parser.read_BE_Integer(dataAtom.value, true));
|
|
408
409
|
break;
|
|
409
410
|
case 22: // BE Unsigned Integer
|
|
410
|
-
this.addTag(tagKey, MP4Parser.read_BE_Integer(dataAtom.value, false));
|
|
411
|
+
await this.addTag(tagKey, MP4Parser.read_BE_Integer(dataAtom.value, false));
|
|
411
412
|
break;
|
|
412
413
|
case 65: // An 8-bit signed integer
|
|
413
|
-
this.addTag(tagKey, dataAtom.value
|
|
414
|
+
await this.addTag(tagKey, Token.UINT8.get(dataAtom.value, 0));
|
|
414
415
|
break;
|
|
415
416
|
case 66: // A big-endian 16-bit signed integer
|
|
416
|
-
this.addTag(tagKey, dataAtom.value
|
|
417
|
+
await this.addTag(tagKey, Token.UINT16_BE.get(dataAtom.value, 0));
|
|
417
418
|
break;
|
|
418
419
|
case 67: // A big-endian 32-bit signed integer
|
|
419
|
-
this.addTag(tagKey, dataAtom.value
|
|
420
|
+
await this.addTag(tagKey, Token.UINT32_BE.get(dataAtom.value, 0));
|
|
420
421
|
break;
|
|
421
422
|
default:
|
|
422
423
|
this.addWarning(`atom key=${tagKey}, has unknown well-known-type (data-type): ${dataAtom.type.type}`);
|
package/lib/mpeg/MpegParser.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as Token from 'token-types';
|
|
2
|
-
import { EndOfStreamError } from 'strtok3
|
|
2
|
+
import { EndOfStreamError } from 'strtok3';
|
|
3
3
|
import initDebug from 'debug';
|
|
4
4
|
import * as common from '../common/Util.js';
|
|
5
5
|
import { AbstractID3Parser } from '../id3v2/AbstractID3Parser.js';
|
|
@@ -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 =
|
|
215
|
+
this.buf_frame_header = new Uint8Array(4);
|
|
216
216
|
this.syncPeek = {
|
|
217
|
-
buf:
|
|
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 =
|
|
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;
|
package/lib/mpeg/XingTag.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
/// <reference types="node" resolution-mode="require"/>
|
|
2
1
|
import * as Token from 'token-types';
|
|
3
|
-
import { IGetToken, ITokenizer } from 'strtok3
|
|
2
|
+
import type { IGetToken, ITokenizer } from 'strtok3';
|
|
4
3
|
import { IExtendedLameHeader } from './ExtendedLameHeader.js';
|
|
5
4
|
export interface IXingHeaderFlags {
|
|
6
5
|
frames: boolean;
|
|
@@ -27,7 +26,7 @@ export interface IXingInfoTag {
|
|
|
27
26
|
* Actual stream size = file size - header(s) size [bytes]
|
|
28
27
|
*/
|
|
29
28
|
streamSize?: number;
|
|
30
|
-
toc?:
|
|
29
|
+
toc?: Uint8Array;
|
|
31
30
|
/**
|
|
32
31
|
* the number of header data bytes (from original file)
|
|
33
32
|
*/
|
package/lib/mpeg/XingTag.js
CHANGED
|
@@ -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 =
|
|
43
|
+
xingInfoTag.toc = new Uint8Array(100);
|
|
44
44
|
await tokenizer.readBuffer(xingInfoTag.toc);
|
|
45
45
|
}
|
|
46
46
|
if (flags.vbrScale) {
|
package/lib/musepack/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import { MpcSv7Parser } from './sv7/MpcSv7Parser.js';
|
|
|
6
6
|
const debug = initDebug('music-metadata:parser:musepack');
|
|
7
7
|
class MusepackParser extends AbstractID3Parser {
|
|
8
8
|
async postId3v2Parse() {
|
|
9
|
-
const signature = await this.tokenizer.peekToken(new Token.StringType(3, '
|
|
9
|
+
const signature = await this.tokenizer.peekToken(new Token.StringType(3, 'latin1'));
|
|
10
10
|
let mpcParser;
|
|
11
11
|
switch (signature) {
|
|
12
12
|
case 'MP+': {
|
|
@@ -8,7 +8,7 @@ export const Header = {
|
|
|
8
8
|
get: (buf, off) => {
|
|
9
9
|
const header = {
|
|
10
10
|
// word 0
|
|
11
|
-
signature:
|
|
11
|
+
signature: new TextDecoder('latin1').decode(buf.subarray(off, off + 3)),
|
|
12
12
|
// versionIndex number * 1000 (3.81 = 3810) (remember that 4-byte alignment causes this to take 4-bytes)
|
|
13
13
|
streamMinorVersion: util.getBitAllignedNumber(buf, off + 3, 0, 4),
|
|
14
14
|
streamMajorVersion: util.getBitAllignedNumber(buf, off + 3, 4, 4),
|
|
@@ -2,7 +2,7 @@ import * as Token from 'token-types';
|
|
|
2
2
|
import initDebug from 'debug';
|
|
3
3
|
import * as util from '../../common/Util.js';
|
|
4
4
|
const debug = initDebug('music-metadata:parser:musepack:sv8');
|
|
5
|
-
const PacketKey = new Token.StringType(2, '
|
|
5
|
+
const PacketKey = new Token.StringType(2, 'latin1');
|
|
6
6
|
/**
|
|
7
7
|
* Stream Header Packet part 1
|
|
8
8
|
* Ref: http://trac.musepack.net/musepack/wiki/SV8Specification#StreamHeaderPacket
|
package/lib/ogg/Ogg.d.ts
CHANGED
|
@@ -59,7 +59,7 @@ export interface IPageConsumer {
|
|
|
59
59
|
* @param {IPageHeader} header Ogg page header
|
|
60
60
|
* @param {Buffer} pageData Ogg page data
|
|
61
61
|
*/
|
|
62
|
-
parsePage(header: IPageHeader, pageData: Uint8Array):
|
|
62
|
+
parsePage(header: IPageHeader, pageData: Uint8Array): Promise<void>;
|
|
63
63
|
/**
|
|
64
64
|
* Calculate duration of provided header
|
|
65
65
|
* @param header Ogg header
|
|
@@ -68,5 +68,5 @@ export interface IPageConsumer {
|
|
|
68
68
|
/**
|
|
69
69
|
* Force to parse pending segments
|
|
70
70
|
*/
|
|
71
|
-
flush():
|
|
71
|
+
flush(): Promise<void>;
|
|
72
72
|
}
|