@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.
- package/dist/.source-module-urls/c3803b0fa58e9b1fe1f7418a46193ebc53b9c744f6359f04d40d05af48c1dce2.json +1 -0
- package/node_modules/baileys/node_modules/music-metadata/README.md +35 -32
- package/node_modules/baileys/node_modules/music-metadata/lib/ParserFactory.d.ts +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/ParserFactory.js +17 -13
- package/node_modules/baileys/node_modules/music-metadata/lib/aiff/AiffParser.js +19 -12
- package/node_modules/baileys/node_modules/music-metadata/lib/aiff/AiffToken.d.ts +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/aiff/AiffToken.js +2 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/apev2/APEv2Parser.d.ts +4 -3
- package/node_modules/baileys/node_modules/music-metadata/lib/apev2/APEv2Parser.js +59 -16
- package/node_modules/baileys/node_modules/music-metadata/lib/apev2/APEv2TagMapper.js +1 -0
- package/node_modules/baileys/node_modules/music-metadata/lib/apev2/APEv2Token.d.ts +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/apev2/APEv2Token.js +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/asf/AsfGuid.js +56 -50
- package/node_modules/baileys/node_modules/music-metadata/lib/asf/AsfObject.d.ts +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/asf/AsfObject.js +3 -2
- package/node_modules/baileys/node_modules/music-metadata/lib/asf/AsfParser.js +15 -7
- package/node_modules/baileys/node_modules/music-metadata/lib/asf/AsfTagMapper.d.ts +3 -2
- package/node_modules/baileys/node_modules/music-metadata/lib/asf/AsfTagMapper.js +21 -4
- package/node_modules/baileys/node_modules/music-metadata/lib/common/CaseInsensitiveTagMap.d.ts +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/common/CombinedTagMapper.d.ts +2 -2
- package/node_modules/baileys/node_modules/music-metadata/lib/common/CombinedTagMapper.js +6 -6
- package/node_modules/baileys/node_modules/music-metadata/lib/common/FourCC.js +3 -2
- package/node_modules/baileys/node_modules/music-metadata/lib/common/GenericTagMapper.d.ts +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/common/GenericTagTypes.js +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/common/MetadataCollector.d.ts +3 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/common/MetadataCollector.js +28 -9
- package/node_modules/baileys/node_modules/music-metadata/lib/common/Util.js +25 -17
- package/node_modules/baileys/node_modules/music-metadata/lib/core.d.ts +4 -4
- package/node_modules/baileys/node_modules/music-metadata/lib/core.js +18 -11
- package/node_modules/baileys/node_modules/music-metadata/lib/dsdiff/DsdiffParser.js +29 -16
- package/node_modules/baileys/node_modules/music-metadata/lib/dsf/DsfChunk.d.ts +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/dsf/DsfParser.js +3 -5
- package/node_modules/baileys/node_modules/music-metadata/lib/ebml/EbmlIterator.d.ts +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/ebml/EbmlIterator.js +35 -6
- package/node_modules/baileys/node_modules/music-metadata/lib/ebml/types.d.ts +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/ebml/types.js +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/flac/FlacParser.d.ts +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/flac/FlacParser.js +6 -5
- package/node_modules/baileys/node_modules/music-metadata/lib/flac/FlacToken.d.ts +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/flac/FlacToken.js +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/id3v1/ID3v1Parser.d.ts +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/id3v1/ID3v1Parser.js +212 -42
- package/node_modules/baileys/node_modules/music-metadata/lib/id3v2/AbstractID3Parser.js +5 -5
- package/node_modules/baileys/node_modules/music-metadata/lib/id3v2/FrameHeader.d.ts +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/id3v2/FrameHeader.js +8 -5
- package/node_modules/baileys/node_modules/music-metadata/lib/id3v2/FrameParser.d.ts +2 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/id3v2/FrameParser.js +53 -22
- package/node_modules/baileys/node_modules/music-metadata/lib/id3v2/ID3v22TagMapper.d.ts +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/id3v2/ID3v22TagMapper.js +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/id3v2/ID3v24TagMapper.js +3 -3
- package/node_modules/baileys/node_modules/music-metadata/lib/id3v2/ID3v2ChapterToken.js +2 -2
- package/node_modules/baileys/node_modules/music-metadata/lib/id3v2/ID3v2Parser.d.ts +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/id3v2/ID3v2Parser.js +32 -16
- package/node_modules/baileys/node_modules/music-metadata/lib/id3v2/ID3v2Token.d.ts +2 -2
- package/node_modules/baileys/node_modules/music-metadata/lib/id3v2/ID3v2Token.js +2 -3
- package/node_modules/baileys/node_modules/music-metadata/lib/index.js +6 -3
- package/node_modules/baileys/node_modules/music-metadata/lib/lrc/LyricsParser.js +3 -5
- package/node_modules/baileys/node_modules/music-metadata/lib/matroska/MatroskaDtd.js +7 -3
- package/node_modules/baileys/node_modules/music-metadata/lib/matroska/MatroskaParser.js +22 -11
- package/node_modules/baileys/node_modules/music-metadata/lib/matroska/types.d.ts +2 -2
- package/node_modules/baileys/node_modules/music-metadata/lib/mp4/Atom.d.ts +4 -3
- package/node_modules/baileys/node_modules/music-metadata/lib/mp4/Atom.js +44 -11
- package/node_modules/baileys/node_modules/music-metadata/lib/mp4/AtomToken.d.ts +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/mp4/AtomToken.js +30 -8
- package/node_modules/baileys/node_modules/music-metadata/lib/mp4/MP4Parser.d.ts +2 -0
- package/node_modules/baileys/node_modules/music-metadata/lib/mp4/MP4Parser.js +79 -54
- package/node_modules/baileys/node_modules/music-metadata/lib/mp4/MP4TagMapper.d.ts +2 -2
- package/node_modules/baileys/node_modules/music-metadata/lib/mpeg/MpegLoader.js +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/mpeg/MpegParser.js +41 -19
- package/node_modules/baileys/node_modules/music-metadata/lib/mpeg/ReplayGainDataFormat.d.ts +2 -2
- package/node_modules/baileys/node_modules/music-metadata/lib/mpeg/ReplayGainDataFormat.js +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/mpeg/XingTag.d.ts +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/musepack/MusepackParser.js +2 -2
- package/node_modules/baileys/node_modules/music-metadata/lib/musepack/sv7/BitReader.js +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/musepack/sv7/MpcSv7Parser.js +4 -3
- package/node_modules/baileys/node_modules/music-metadata/lib/musepack/sv7/StreamVersion7.js +3 -3
- package/node_modules/baileys/node_modules/music-metadata/lib/musepack/sv8/MpcSv8Parser.js +7 -5
- package/node_modules/baileys/node_modules/music-metadata/lib/musepack/sv8/StreamVersion8.js +2 -2
- package/node_modules/baileys/node_modules/music-metadata/lib/ogg/OggParser.js +16 -12
- package/node_modules/baileys/node_modules/music-metadata/lib/ogg/OggToken.js +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/ogg/flac/FlacStream.d.ts +2 -2
- package/node_modules/baileys/node_modules/music-metadata/lib/ogg/flac/FlacStream.js +2 -2
- package/node_modules/baileys/node_modules/music-metadata/lib/ogg/opus/OpusStream.d.ts +2 -2
- package/node_modules/baileys/node_modules/music-metadata/lib/ogg/opus/OpusStream.js +8 -4
- package/node_modules/baileys/node_modules/music-metadata/lib/ogg/speex/SpeexStream.d.ts +2 -2
- package/node_modules/baileys/node_modules/music-metadata/lib/ogg/speex/SpeexStream.js +2 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/ogg/theora/TheoraStream.d.ts +2 -2
- package/node_modules/baileys/node_modules/music-metadata/lib/ogg/vorbis/Vorbis.d.ts +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/ogg/vorbis/VorbisDecoder.js +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/ogg/vorbis/VorbisStream.d.ts +3 -3
- package/node_modules/baileys/node_modules/music-metadata/lib/ogg/vorbis/VorbisStream.js +14 -9
- package/node_modules/baileys/node_modules/music-metadata/lib/ogg/vorbis/VorbisTagMapper.js +4 -0
- package/node_modules/baileys/node_modules/music-metadata/lib/riff/RiffChunk.d.ts +3 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/riff/RiffChunk.js +3 -2
- package/node_modules/baileys/node_modules/music-metadata/lib/riff/RiffInfoTagMap.d.ts +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/type.d.ts +3 -3
- package/node_modules/baileys/node_modules/music-metadata/lib/type.js +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/wav/WaveChunk.d.ts +1 -1
- package/node_modules/baileys/node_modules/music-metadata/lib/wav/WaveChunk.js +3 -2
- package/node_modules/baileys/node_modules/music-metadata/lib/wav/WaveParser.d.ts +6 -2
- package/node_modules/baileys/node_modules/music-metadata/lib/wav/WaveParser.js +75 -22
- package/node_modules/baileys/node_modules/music-metadata/lib/wavpack/WavPackParser.js +22 -13
- package/node_modules/baileys/node_modules/music-metadata/lib/wavpack/WavPackToken.js +3 -2
- package/node_modules/baileys/node_modules/music-metadata/package.json +3 -2
- package/package.json +4 -4
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Primary entry point, Node.js specific entry point is MusepackParser.ts
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
5
|
-
import { ParserFactory } from './ParserFactory.js';
|
|
4
|
+
import { fromBlob, fromBuffer, fromWebStream } from 'strtok3';
|
|
6
5
|
import { APEv2Parser } from './apev2/APEv2Parser.js';
|
|
7
6
|
import { hasID3v1Header } from './id3v1/ID3v1Parser.js';
|
|
8
7
|
import { getLyricsHeaderLength } from './lyrics3/Lyrics3.js';
|
|
9
|
-
|
|
10
|
-
export { CouldNotDetermineFileTypeError, UnsupportedFileTypeError } from './ParseError.js';
|
|
8
|
+
import { ParserFactory } from './ParserFactory.js';
|
|
11
9
|
export * from './ParseError.js';
|
|
10
|
+
export { CouldNotDetermineFileTypeError, UnsupportedFileTypeError } from './ParseError.js';
|
|
11
|
+
export { LyricsContentType, TimestampFormat } from './type.js';
|
|
12
12
|
/**
|
|
13
13
|
* Parse Web API File
|
|
14
14
|
* Requires Blob to be able to stream using a ReadableStreamBYOBReader, only available since Node.js ≥ 20
|
|
@@ -33,7 +33,9 @@ export async function parseBlob(blob, options = {}) {
|
|
|
33
33
|
* @returns Metadata
|
|
34
34
|
*/
|
|
35
35
|
export async function parseWebStream(webStream, fileInfo, options = {}) {
|
|
36
|
-
const tokenizer = fromWebStream(webStream, {
|
|
36
|
+
const tokenizer = fromWebStream(webStream, {
|
|
37
|
+
fileInfo: typeof fileInfo === 'string' ? { mimeType: fileInfo } : fileInfo
|
|
38
|
+
});
|
|
37
39
|
try {
|
|
38
40
|
return await parseFromTokenizer(tokenizer, options);
|
|
39
41
|
}
|
|
@@ -50,7 +52,9 @@ export async function parseWebStream(webStream, fileInfo, options = {}) {
|
|
|
50
52
|
* Ref: https://github.com/Borewit/strtok3/blob/e6938c81ff685074d5eb3064a11c0b03ca934c1d/src/index.ts#L15
|
|
51
53
|
*/
|
|
52
54
|
export async function parseBuffer(uint8Array, fileInfo, options = {}) {
|
|
53
|
-
const tokenizer = fromBuffer(uint8Array, {
|
|
55
|
+
const tokenizer = fromBuffer(uint8Array, {
|
|
56
|
+
fileInfo: typeof fileInfo === 'string' ? { mimeType: fileInfo } : fileInfo
|
|
57
|
+
});
|
|
54
58
|
return parseFromTokenizer(tokenizer, options);
|
|
55
59
|
}
|
|
56
60
|
/**
|
|
@@ -89,11 +93,14 @@ export function ratingToStars(rating) {
|
|
|
89
93
|
* @return Cover image, if any, otherwise null
|
|
90
94
|
*/
|
|
91
95
|
export function selectCover(pictures) {
|
|
92
|
-
return pictures
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
96
|
+
return pictures
|
|
97
|
+
? pictures.reduce((acc, cur) => {
|
|
98
|
+
if (cur.name && cur.name.toLowerCase() in ['front', 'cover', 'cover (front)']) {
|
|
99
|
+
return cur;
|
|
100
|
+
}
|
|
101
|
+
return acc;
|
|
102
|
+
})
|
|
103
|
+
: null;
|
|
97
104
|
}
|
|
98
105
|
export async function scanAppendingHeaders(tokenizer, options = {}) {
|
|
99
106
|
let apeOffset = tokenizer.fileInfo.size;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import * as Token from 'token-types';
|
|
2
1
|
import initDebug from 'debug';
|
|
3
2
|
import * as strtok3 from 'strtok3';
|
|
4
|
-
import
|
|
3
|
+
import * as Token from 'token-types';
|
|
5
4
|
import { BasicParser } from '../common/BasicParser.js';
|
|
5
|
+
import { FourCcToken } from '../common/FourCC.js';
|
|
6
6
|
import { ID3v2Parser } from '../id3v2/ID3v2Parser.js';
|
|
7
|
-
import { ChunkHeader64 } from './DsdiffToken.js';
|
|
8
7
|
import { makeUnexpectedFileContentError } from '../ParseError.js';
|
|
8
|
+
import { ChunkHeader64 } from './DsdiffToken.js';
|
|
9
9
|
const debug = initDebug('music-metadata:parser:aiff');
|
|
10
10
|
export class DsdiffContentParseError extends makeUnexpectedFileContentError('DSDIFF') {
|
|
11
11
|
}
|
|
@@ -18,8 +18,9 @@ export class DsdiffContentParseError extends makeUnexpectedFileContentError('DSD
|
|
|
18
18
|
export class DsdiffParser extends BasicParser {
|
|
19
19
|
async parse() {
|
|
20
20
|
const header = await this.tokenizer.readToken(ChunkHeader64);
|
|
21
|
-
if (header.chunkID !== 'FRM8')
|
|
21
|
+
if (header.chunkID !== 'FRM8') {
|
|
22
22
|
throw new DsdiffContentParseError('Unexpected chunk-ID');
|
|
23
|
+
}
|
|
23
24
|
this.metadata.setAudioOnly();
|
|
24
25
|
const type = (await this.tokenizer.readToken(FourCcToken)).trim();
|
|
25
26
|
switch (type) {
|
|
@@ -37,26 +38,30 @@ export class DsdiffParser extends BasicParser {
|
|
|
37
38
|
// If the data is an odd number of bytes in length, a pad byte must be added at the end
|
|
38
39
|
debug(`Chunk id=${chunkHeader.chunkID}`);
|
|
39
40
|
await this.readData(chunkHeader);
|
|
40
|
-
remainingSize -=
|
|
41
|
+
remainingSize -= BigInt(ChunkHeader64.len) + chunkHeader.chunkSize;
|
|
41
42
|
}
|
|
42
43
|
}
|
|
43
44
|
async readData(header) {
|
|
44
45
|
debug(`Reading data of chunk[ID=${header.chunkID}, size=${header.chunkSize}]`);
|
|
45
46
|
const p0 = this.tokenizer.position;
|
|
46
47
|
switch (header.chunkID.trim()) {
|
|
47
|
-
case 'FVER': {
|
|
48
|
+
case 'FVER': {
|
|
49
|
+
// 3.1 FORMAT VERSION CHUNK
|
|
48
50
|
const version = await this.tokenizer.readToken(Token.UINT32_LE);
|
|
49
51
|
debug(`DSDIFF version=${version}`);
|
|
50
52
|
break;
|
|
51
53
|
}
|
|
52
|
-
case 'PROP': {
|
|
54
|
+
case 'PROP': {
|
|
55
|
+
// 3.2 PROPERTY CHUNK
|
|
53
56
|
const propType = await this.tokenizer.readToken(FourCcToken);
|
|
54
|
-
if (propType !== 'SND ')
|
|
57
|
+
if (propType !== 'SND ') {
|
|
55
58
|
throw new DsdiffContentParseError('Unexpected PROP-chunk ID');
|
|
59
|
+
}
|
|
56
60
|
await this.handleSoundPropertyChunks(header.chunkSize - BigInt(FourCcToken.len));
|
|
57
61
|
break;
|
|
58
62
|
}
|
|
59
|
-
case 'ID3': {
|
|
63
|
+
case 'ID3': {
|
|
64
|
+
// Unofficial ID3 tag support
|
|
60
65
|
const id3_data = await this.tokenizer.readToken(new Token.Uint8ArrayType(Number(header.chunkSize)));
|
|
61
66
|
const rst = strtok3.fromBuffer(id3_data);
|
|
62
67
|
await new ID3v2Parser().parse(this.metadata, rst, this.options);
|
|
@@ -64,7 +69,7 @@ export class DsdiffParser extends BasicParser {
|
|
|
64
69
|
}
|
|
65
70
|
case 'DSD':
|
|
66
71
|
if (this.metadata.format.numberOfChannels) {
|
|
67
|
-
this.metadata.setFormat('numberOfSamples', Number(header.chunkSize * BigInt(8) / BigInt(this.metadata.format.numberOfChannels)));
|
|
72
|
+
this.metadata.setFormat('numberOfSamples', Number((header.chunkSize * BigInt(8)) / BigInt(this.metadata.format.numberOfChannels)));
|
|
68
73
|
}
|
|
69
74
|
if (this.metadata.format.numberOfSamples && this.metadata.format.sampleRate) {
|
|
70
75
|
this.metadata.setFormat('duration', this.metadata.format.numberOfSamples / this.metadata.format.sampleRate);
|
|
@@ -87,18 +92,21 @@ export class DsdiffParser extends BasicParser {
|
|
|
87
92
|
debug(`Sound-property-chunk[ID=${sndPropHeader.chunkID}, size=${sndPropHeader.chunkSize}]`);
|
|
88
93
|
const p0 = this.tokenizer.position;
|
|
89
94
|
switch (sndPropHeader.chunkID.trim()) {
|
|
90
|
-
case 'FS': {
|
|
95
|
+
case 'FS': {
|
|
96
|
+
// 3.2.1 Sample Rate Chunk
|
|
91
97
|
const sampleRate = await this.tokenizer.readToken(Token.UINT32_BE);
|
|
92
98
|
this.metadata.setFormat('sampleRate', sampleRate);
|
|
93
99
|
break;
|
|
94
100
|
}
|
|
95
|
-
case 'CHNL': {
|
|
101
|
+
case 'CHNL': {
|
|
102
|
+
// 3.2.2 Channels Chunk
|
|
96
103
|
const numChannels = await this.tokenizer.readToken(Token.UINT16_BE);
|
|
97
104
|
this.metadata.setFormat('numberOfChannels', numChannels);
|
|
98
105
|
await this.handleChannelChunks(sndPropHeader.chunkSize - BigInt(Token.UINT16_BE.len));
|
|
99
106
|
break;
|
|
100
107
|
}
|
|
101
|
-
case 'CMPR': {
|
|
108
|
+
case 'CMPR': {
|
|
109
|
+
// 3.2.3 Compression Type Chunk
|
|
102
110
|
const compressionIdCode = (await this.tokenizer.readToken(FourCcToken)).trim();
|
|
103
111
|
const count = await this.tokenizer.readToken(Token.UINT8);
|
|
104
112
|
const compressionName = await this.tokenizer.readToken(new Token.StringType(count, 'ascii'));
|
|
@@ -109,7 +117,8 @@ export class DsdiffParser extends BasicParser {
|
|
|
109
117
|
this.metadata.setFormat('codec', `${compressionIdCode} (${compressionName})`);
|
|
110
118
|
break;
|
|
111
119
|
}
|
|
112
|
-
case 'ABSS': {
|
|
120
|
+
case 'ABSS': {
|
|
121
|
+
// 3.2.4 Absolute Start Time Chunk
|
|
113
122
|
const hours = await this.tokenizer.readToken(Token.UINT16_BE);
|
|
114
123
|
const minutes = await this.tokenizer.readToken(Token.UINT8);
|
|
115
124
|
const seconds = await this.tokenizer.readToken(Token.UINT8);
|
|
@@ -117,7 +126,8 @@ export class DsdiffParser extends BasicParser {
|
|
|
117
126
|
debug(`ABSS ${hours}:${minutes}:${seconds}.${samples}`);
|
|
118
127
|
break;
|
|
119
128
|
}
|
|
120
|
-
case 'LSCO': {
|
|
129
|
+
case 'LSCO': {
|
|
130
|
+
// 3.2.5 Loudspeaker Configuration Chunk
|
|
121
131
|
const lsConfig = await this.tokenizer.readToken(Token.UINT16_BE);
|
|
122
132
|
debug(`LSCO lsConfig=${lsConfig}`);
|
|
123
133
|
break;
|
|
@@ -134,7 +144,10 @@ export class DsdiffParser extends BasicParser {
|
|
|
134
144
|
remainingSize -= BigInt(ChunkHeader64.len) + sndPropHeader.chunkSize;
|
|
135
145
|
debug(`Parsing sound-property-chunks, remainingSize=${remainingSize}`);
|
|
136
146
|
}
|
|
137
|
-
if (this.metadata.format.lossless &&
|
|
147
|
+
if (this.metadata.format.lossless &&
|
|
148
|
+
this.metadata.format.sampleRate &&
|
|
149
|
+
this.metadata.format.numberOfChannels &&
|
|
150
|
+
this.metadata.format.bitsPerSample) {
|
|
138
151
|
const bitrate = this.metadata.format.sampleRate * this.metadata.format.numberOfChannels * this.metadata.format.bitsPerSample;
|
|
139
152
|
this.metadata.setFormat('bitrate', bitrate);
|
|
140
153
|
}
|
|
@@ -43,7 +43,7 @@ export declare const ChannelType: {
|
|
|
43
43
|
'5 channels': number;
|
|
44
44
|
'5.1 channels': number;
|
|
45
45
|
};
|
|
46
|
-
export type ChannelType = typeof ChannelType[keyof typeof ChannelType];
|
|
46
|
+
export type ChannelType = (typeof ChannelType)[keyof typeof ChannelType];
|
|
47
47
|
/**
|
|
48
48
|
* Interface to format chunk payload chunk
|
|
49
49
|
*/
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import initDebug from 'debug';
|
|
2
2
|
import { AbstractID3Parser } from '../id3v2/AbstractID3Parser.js';
|
|
3
|
-
import { ChunkHeader, DsdChunk, FormatChunk } from './DsfChunk.js';
|
|
4
3
|
import { ID3v2Parser } from '../id3v2/ID3v2Parser.js';
|
|
5
|
-
import { makeUnexpectedFileContentError } from '../ParseError.js';
|
|
6
4
|
import { ID3v2Header } from '../id3v2/ID3v2Token.js';
|
|
5
|
+
import { makeUnexpectedFileContentError } from '../ParseError.js';
|
|
6
|
+
import { ChunkHeader, DsdChunk, FormatChunk } from './DsfChunk.js';
|
|
7
7
|
const debug = initDebug('music-metadata:parser:DSF');
|
|
8
8
|
export class DsdContentParseError extends makeUnexpectedFileContentError('DSD') {
|
|
9
9
|
}
|
|
@@ -66,9 +66,7 @@ export class DsfParser extends AbstractID3Parser {
|
|
|
66
66
|
this.metadata.setFormat('bitsPerSample', formatChunk.bitsPerSample);
|
|
67
67
|
this.metadata.setFormat('numberOfSamples', formatChunk.sampleCount);
|
|
68
68
|
this.metadata.setFormat('duration', Number(formatChunk.sampleCount) / formatChunk.samplingFrequency);
|
|
69
|
-
const bitrate = formatChunk.bitsPerSample *
|
|
70
|
-
formatChunk.samplingFrequency *
|
|
71
|
-
formatChunk.channelNum;
|
|
69
|
+
const bitrate = formatChunk.bitsPerSample * formatChunk.samplingFrequency * formatChunk.channelNum;
|
|
72
70
|
this.metadata.setFormat('bitrate', bitrate);
|
|
73
71
|
return; // We got what we want, stop further processing of chunks
|
|
74
72
|
}
|
|
@@ -28,7 +28,7 @@ export declare const ParseAction: {
|
|
|
28
28
|
readonly TerminateParsing: 4;
|
|
29
29
|
readonly SkipElement: 5;
|
|
30
30
|
};
|
|
31
|
-
export type ParseAction = typeof ParseAction[keyof typeof ParseAction];
|
|
31
|
+
export type ParseAction = (typeof ParseAction)[keyof typeof ParseAction];
|
|
32
32
|
/**
|
|
33
33
|
* @return true, to quit the parser
|
|
34
34
|
*/
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { Float32_BE, Float64_BE, StringType, UINT8 } from 'token-types';
|
|
2
1
|
import initDebug from 'debug';
|
|
3
2
|
import { EndOfStreamError } from 'strtok3';
|
|
4
|
-
import { DataType } from './types.js';
|
|
5
3
|
import * as Token from 'token-types';
|
|
4
|
+
import { Float32_BE, Float64_BE, StringType, UINT8 } from 'token-types';
|
|
6
5
|
import { makeUnexpectedFileContentError } from '../ParseError.js';
|
|
6
|
+
import { DataType } from './types.js';
|
|
7
7
|
const debug = initDebug('music-metadata:parser:ebml');
|
|
8
8
|
export class EbmlContentError extends makeUnexpectedFileContentError('EBML') {
|
|
9
9
|
}
|
|
@@ -61,14 +61,15 @@ export class EbmlIterator {
|
|
|
61
61
|
switch (action) {
|
|
62
62
|
case ParseAction.ReadNext:
|
|
63
63
|
{
|
|
64
|
-
if (element.id ===
|
|
64
|
+
if (element.id === 0x1f43b675) {
|
|
65
65
|
// Hack to ignore remaining segment, when cluster element received
|
|
66
66
|
// await this.tokenizer.ignore(posDone - this.tokenizer.position);
|
|
67
67
|
// break;
|
|
68
68
|
}
|
|
69
69
|
debug(`Read element: name=${getElementPath(child)}{id=0x${element.id.toString(16)}, container=${!!child.container}} at position=${elementPosition}`);
|
|
70
70
|
if (child.container) {
|
|
71
|
-
const
|
|
71
|
+
const childEnd = Math.min(posDone, this.tokenizer.fileInfo.size ?? Number.POSITIVE_INFINITY, element.len >= 0 ? this.tokenizer.position + element.len : posDone);
|
|
72
|
+
const res = await this.parseContainer(child, childEnd, listener);
|
|
72
73
|
if (child.multiple) {
|
|
73
74
|
if (!tree[child.name]) {
|
|
74
75
|
tree[child.name] = [];
|
|
@@ -83,6 +84,13 @@ export class EbmlIterator {
|
|
|
83
84
|
else {
|
|
84
85
|
const parser = this.parserMap.get(child.value);
|
|
85
86
|
if (typeof parser === 'function') {
|
|
87
|
+
// Validate before leaf readers allocate buffers or string tokens from the declared length.
|
|
88
|
+
const end = Math.min(posDone, this.tokenizer.fileInfo.size ?? Number.POSITIVE_INFINITY);
|
|
89
|
+
if (!Number.isSafeInteger(element.len) ||
|
|
90
|
+
element.len < 0 ||
|
|
91
|
+
element.len > end - this.tokenizer.position) {
|
|
92
|
+
throw new EbmlContentError(`Invalid element length: ${element.len}`);
|
|
93
|
+
}
|
|
86
94
|
const value = await parser(element);
|
|
87
95
|
tree[child.name] = value;
|
|
88
96
|
await listener.elementValue(child, value, elementPosition);
|
|
@@ -166,10 +174,30 @@ export class EbmlIterator {
|
|
|
166
174
|
return readUIntBE(buf, e.len);
|
|
167
175
|
}
|
|
168
176
|
async readString(e) {
|
|
169
|
-
const
|
|
177
|
+
const buf = await this.readBuffer(e);
|
|
178
|
+
const rawString = new StringType(e.len, 'utf-8').get(buf, 0);
|
|
170
179
|
return rawString.replace(/\x00.*$/g, '');
|
|
171
180
|
}
|
|
172
181
|
async readBuffer(e) {
|
|
182
|
+
const chunkSize = 64 * 1024;
|
|
183
|
+
if ((!this.tokenizer.supportsRandomAccess() || this.tokenizer.fileInfo.size === undefined) && e.len > chunkSize) {
|
|
184
|
+
// Neither a declared container size nor an advertised stream size proves these bytes exist.
|
|
185
|
+
// Allocate incrementally, and only assemble the leaf after reading its payload.
|
|
186
|
+
const chunks = [];
|
|
187
|
+
for (let remaining = e.len; remaining > 0;) {
|
|
188
|
+
const chunk = new Uint8Array(Math.min(remaining, chunkSize));
|
|
189
|
+
await this.tokenizer.readBuffer(chunk);
|
|
190
|
+
chunks.push(chunk);
|
|
191
|
+
remaining -= chunk.length;
|
|
192
|
+
}
|
|
193
|
+
const buf = new Uint8Array(e.len);
|
|
194
|
+
let offset = 0;
|
|
195
|
+
for (const chunk of chunks) {
|
|
196
|
+
buf.set(chunk, offset);
|
|
197
|
+
offset += chunk.length;
|
|
198
|
+
}
|
|
199
|
+
return buf;
|
|
200
|
+
}
|
|
173
201
|
const buf = new Uint8Array(e.len);
|
|
174
202
|
await this.tokenizer.readBuffer(buf);
|
|
175
203
|
return buf;
|
|
@@ -202,7 +230,8 @@ function linkParents(element) {
|
|
|
202
230
|
const child = element.container[id];
|
|
203
231
|
child.id = Number.parseInt(id, 10);
|
|
204
232
|
return child;
|
|
205
|
-
})
|
|
233
|
+
})
|
|
234
|
+
.forEach(child => {
|
|
206
235
|
child.parent = element;
|
|
207
236
|
linkParents(child);
|
|
208
237
|
});
|
|
@@ -9,7 +9,7 @@ export declare const DataType: {
|
|
|
9
9
|
readonly binary: 4;
|
|
10
10
|
readonly float: 5;
|
|
11
11
|
};
|
|
12
|
-
export type DataType = typeof DataType[keyof typeof DataType];
|
|
12
|
+
export type DataType = (typeof DataType)[keyof typeof DataType];
|
|
13
13
|
export type ValueType = string | number | Uint8Array | boolean | ITree | ITree[];
|
|
14
14
|
export interface IHeader {
|
|
15
15
|
id: number;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type IVorbisPicture } from '../ogg/vorbis/Vorbis.js';
|
|
2
1
|
import { AbstractID3Parser } from '../id3v2/AbstractID3Parser.js';
|
|
2
|
+
import { type IVorbisPicture } from '../ogg/vorbis/Vorbis.js';
|
|
3
3
|
import type { IBlockStreamInfo } from './FlacToken.js';
|
|
4
4
|
export declare class FlacParser extends AbstractID3Parser {
|
|
5
5
|
private vorbisParser;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import initDebug from 'debug';
|
|
2
2
|
import { Uint8ArrayType } from 'token-types';
|
|
3
|
-
import { VorbisPictureToken } from '../ogg/vorbis/Vorbis.js';
|
|
4
|
-
import { AbstractID3Parser } from '../id3v2/AbstractID3Parser.js';
|
|
5
3
|
import { FourCcToken } from '../common/FourCC.js';
|
|
6
|
-
import {
|
|
4
|
+
import { AbstractID3Parser } from '../id3v2/AbstractID3Parser.js';
|
|
5
|
+
import { VorbisPictureToken } from '../ogg/vorbis/Vorbis.js';
|
|
7
6
|
import { VorbisDecoder } from '../ogg/vorbis/VorbisDecoder.js';
|
|
7
|
+
import { VorbisStream } from '../ogg/vorbis/VorbisStream.js';
|
|
8
8
|
import { makeUnexpectedFileContentError } from '../ParseError.js';
|
|
9
9
|
import * as Flac from './FlacToken.js';
|
|
10
10
|
const debug = initDebug('music-metadata:parser:FLAC');
|
|
@@ -29,7 +29,7 @@ export class FlacParser extends AbstractID3Parser {
|
|
|
29
29
|
} while (!blockHeader.lastBlock);
|
|
30
30
|
if (this.tokenizer.fileInfo.size && this.metadata.format.duration) {
|
|
31
31
|
const dataSize = this.tokenizer.fileInfo.size - this.tokenizer.position;
|
|
32
|
-
this.metadata.setFormat('bitrate', 8 * dataSize / this.metadata.format.duration);
|
|
32
|
+
this.metadata.setFormat('bitrate', (8 * dataSize) / this.metadata.format.duration);
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
async parseDataBlock(blockHeader) {
|
|
@@ -60,8 +60,9 @@ export class FlacParser extends AbstractID3Parser {
|
|
|
60
60
|
* Parse STREAMINFO
|
|
61
61
|
*/
|
|
62
62
|
async readBlockStreamInfo(dataLen) {
|
|
63
|
-
if (dataLen !== Flac.BlockStreamInfo.len)
|
|
63
|
+
if (dataLen !== Flac.BlockStreamInfo.len) {
|
|
64
64
|
throw new FlacContentError('Unexpected block-stream-info length');
|
|
65
|
+
}
|
|
65
66
|
const streamInfo = await this.tokenizer.readToken(Flac.BlockStreamInfo);
|
|
66
67
|
this.metadata.setFormat('container', 'FLAC');
|
|
67
68
|
this.processsStreamInfo(streamInfo);
|
|
@@ -12,7 +12,7 @@ export declare const BlockType: {
|
|
|
12
12
|
CUESHEET: number;
|
|
13
13
|
PICTURE: number;
|
|
14
14
|
};
|
|
15
|
-
export type BlockType = typeof BlockType[keyof typeof BlockType];
|
|
15
|
+
export type BlockType = (typeof BlockType)[keyof typeof BlockType];
|
|
16
16
|
/**
|
|
17
17
|
* METADATA_BLOCK_DATA
|
|
18
18
|
* Ref: https://xiph.org/flac/format.html#metadata_block_streaminfo
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import * as util from '../common/Util.js';
|
|
2
1
|
import { UINT16_BE, UINT24_BE, Uint8ArrayType } from 'token-types';
|
|
2
|
+
import * as util from '../common/Util.js';
|
|
3
3
|
/**
|
|
4
4
|
* FLAC supports up to 128 kinds of metadata blocks; currently the following are defined:
|
|
5
5
|
* ref: https://xiph.org/flac/format.html#metadata_block
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { IRandomAccessTokenizer, ITokenizer } from 'strtok3';
|
|
2
2
|
import { BasicParser } from '../common/BasicParser.js';
|
|
3
|
-
import type { IPrivateOptions } from '../type.js';
|
|
4
3
|
import type { INativeMetadataCollector } from '../common/MetadataCollector.js';
|
|
4
|
+
import type { IPrivateOptions } from '../type.js';
|
|
5
5
|
/**
|
|
6
6
|
* ID3v1 Genre mappings
|
|
7
7
|
* Ref: https://de.wikipedia.org/wiki/Liste_der_ID3v1-Genres
|