music-metadata 8.3.0 → 9.0.0
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/README.md +152 -132
- 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 +0 -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 +6 -6
- 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 +1 -1
- package/lib/matroska/MatroskaParser.d.ts +1 -1
- package/lib/matroska/MatroskaParser.js +16 -20
- package/lib/matroska/types.d.ts +0 -1
- package/lib/mp4/Atom.d.ts +1 -1
- package/lib/mp4/AtomToken.d.ts +2 -3
- package/lib/mp4/AtomToken.js +2 -2
- package/lib/mp4/MP4Parser.js +20 -19
- package/lib/mpeg/ExtendedLameHeader.d.ts +1 -1
- package/lib/mpeg/MpegParser.js +1 -1
- package/lib/mpeg/ReplayGainDataFormat.d.ts +1 -1
- package/lib/mpeg/XingTag.d.ts +1 -2
- 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 +2 -3
- package/lib/ogg/opus/OpusParser.js +2 -2
- package/lib/ogg/speex/Speex.d.ts +1 -1
- package/lib/ogg/speex/Speex.js +13 -13
- package/lib/ogg/speex/SpeexParser.d.ts +1 -2
- 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 +6 -7
- package/lib/ogg/vorbis/VorbisParser.js +11 -11
- 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 +2 -3
- package/lib/wav/WaveChunk.js +8 -7
- package/lib/wav/WaveParser.js +2 -2
- package/lib/wavpack/WavPackParser.js +1 -1
- package/lib/wavpack/WavPackToken.d.ts +1 -1
- package/package.json +26 -25
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';
|
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;
|
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
|
}
|
package/lib/ogg/OggParser.d.ts
CHANGED
package/lib/ogg/OggParser.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 util from '../common/Util.js';
|
|
5
5
|
import { FourCcToken } from '../common/FourCC.js';
|
|
@@ -51,7 +51,7 @@ export class OggParser extends BasicParser {
|
|
|
51
51
|
const pageData = await this.tokenizer.readToken(new Token.Uint8ArrayType(segmentTable.totalPageSize));
|
|
52
52
|
debug('firstPage=%s, lastPage=%s, continued=%s', header.headerType.firstPage, header.headerType.lastPage, header.headerType.continued);
|
|
53
53
|
if (header.headerType.firstPage) {
|
|
54
|
-
const id = new
|
|
54
|
+
const id = new TextDecoder('ascii').decode(pageData.subarray(0, 7));
|
|
55
55
|
switch (id) {
|
|
56
56
|
case '\x01vorbis': // Ogg/Vorbis
|
|
57
57
|
debug('Set page consumer to Ogg/Vorbis');
|
|
@@ -74,7 +74,7 @@ export class OggParser extends BasicParser {
|
|
|
74
74
|
throw new Error('gg audio-codec not recognized (id=' + id + ')');
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
|
-
this.pageConsumer.parsePage(header, pageData);
|
|
77
|
+
await this.pageConsumer.parsePage(header, pageData);
|
|
78
78
|
} while (!header.headerType.lastPage);
|
|
79
79
|
}
|
|
80
80
|
catch (err) {
|
|
@@ -90,7 +90,7 @@ export class OggParser extends BasicParser {
|
|
|
90
90
|
if (this.pageNumber > 0) {
|
|
91
91
|
// ignore this error: work-around if last OGG-page is not marked with last-page flag
|
|
92
92
|
this.metadata.addWarning('Invalid FourCC ID, maybe last OGG-page is not marked with last-page flag');
|
|
93
|
-
this.pageConsumer.flush();
|
|
93
|
+
await this.pageConsumer.flush();
|
|
94
94
|
}
|
|
95
95
|
}
|
|
96
96
|
else {
|
|
@@ -110,7 +110,7 @@ OggParser.Header = {
|
|
|
110
110
|
firstPage: util.getBit(buf, off + 5, 1),
|
|
111
111
|
lastPage: util.getBit(buf, off + 5, 2)
|
|
112
112
|
},
|
|
113
|
-
// packet_flag:
|
|
113
|
+
// packet_flag: Token.UINT8.get(buf, off + 5),
|
|
114
114
|
absoluteGranulePosition: Number(Token.UINT64_LE.get(buf, off + 6)),
|
|
115
115
|
streamSerialNumber: Token.UINT32_LE.get(buf, off + 14),
|
|
116
116
|
pageSequenceNo: Token.UINT32_LE.get(buf, off + 18),
|
package/lib/ogg/opus/Opus.d.ts
CHANGED
package/lib/ogg/opus/Opus.js
CHANGED
|
@@ -13,12 +13,12 @@ export class IdHeader {
|
|
|
13
13
|
get(buf, off) {
|
|
14
14
|
return {
|
|
15
15
|
magicSignature: new Token.StringType(8, 'ascii').get(buf, off + 0),
|
|
16
|
-
version:
|
|
17
|
-
channelCount:
|
|
18
|
-
preSkip:
|
|
19
|
-
inputSampleRate:
|
|
20
|
-
outputGain:
|
|
21
|
-
channelMapping:
|
|
16
|
+
version: Token.UINT8.get(buf, off + 8),
|
|
17
|
+
channelCount: Token.UINT8.get(buf, off + 9),
|
|
18
|
+
preSkip: Token.UINT16_LE.get(buf, off + 10),
|
|
19
|
+
inputSampleRate: Token.UINT32_LE.get(buf, off + 12),
|
|
20
|
+
outputGain: Token.UINT16_LE.get(buf, off + 16),
|
|
21
|
+
channelMapping: Token.UINT8.get(buf, off + 18)
|
|
22
22
|
};
|
|
23
23
|
}
|
|
24
24
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
import { ITokenizer } from 'strtok3/core';
|
|
1
|
+
import { ITokenizer } from 'strtok3';
|
|
3
2
|
import { IPageHeader } from '../Ogg.js';
|
|
4
3
|
import { VorbisParser } from '../vorbis/VorbisParser.js';
|
|
5
4
|
import { IOptions } from '../../type.js';
|
|
@@ -20,6 +19,6 @@ export declare class OpusParser extends VorbisParser {
|
|
|
20
19
|
* @param {Buffer} pageData
|
|
21
20
|
*/
|
|
22
21
|
protected parseFirstPage(header: IPageHeader, pageData: Buffer): void;
|
|
23
|
-
protected parseFullPage(pageData: Buffer): void
|
|
22
|
+
protected parseFullPage(pageData: Buffer): Promise<void>;
|
|
24
23
|
calculateDuration(header: IPageHeader): void;
|
|
25
24
|
}
|
|
@@ -26,11 +26,11 @@ export class OpusParser extends VorbisParser {
|
|
|
26
26
|
this.metadata.setFormat('sampleRate', this.idHeader.inputSampleRate);
|
|
27
27
|
this.metadata.setFormat('numberOfChannels', this.idHeader.channelCount);
|
|
28
28
|
}
|
|
29
|
-
parseFullPage(pageData) {
|
|
29
|
+
async parseFullPage(pageData) {
|
|
30
30
|
const magicSignature = new Token.StringType(8, 'ascii').get(pageData, 0);
|
|
31
31
|
switch (magicSignature) {
|
|
32
32
|
case 'OpusTags':
|
|
33
|
-
this.parseUserCommentList(pageData, 8);
|
|
33
|
+
await this.parseUserCommentList(pageData, 8);
|
|
34
34
|
this.lastPos = this.tokenizer.position - pageData.length;
|
|
35
35
|
break;
|
|
36
36
|
default:
|
package/lib/ogg/speex/Speex.d.ts
CHANGED
package/lib/ogg/speex/Speex.js
CHANGED
|
@@ -10,19 +10,19 @@ export const Header = {
|
|
|
10
10
|
return {
|
|
11
11
|
speex: new Token.StringType(8, 'ascii').get(buf, off + 0),
|
|
12
12
|
version: util.trimRightNull(new Token.StringType(20, 'ascii').get(buf, off + 8)),
|
|
13
|
-
version_id:
|
|
14
|
-
header_size:
|
|
15
|
-
rate:
|
|
16
|
-
mode:
|
|
17
|
-
mode_bitstream_version:
|
|
18
|
-
nb_channels:
|
|
19
|
-
bitrate:
|
|
20
|
-
frame_size:
|
|
21
|
-
vbr:
|
|
22
|
-
frames_per_packet:
|
|
23
|
-
extra_headers:
|
|
24
|
-
reserved1:
|
|
25
|
-
reserved2:
|
|
13
|
+
version_id: Token.INT32_LE.get(buf, off + 28),
|
|
14
|
+
header_size: Token.INT32_LE.get(buf, off + 32),
|
|
15
|
+
rate: Token.INT32_LE.get(buf, off + 36),
|
|
16
|
+
mode: Token.INT32_LE.get(buf, off + 40),
|
|
17
|
+
mode_bitstream_version: Token.INT32_LE.get(buf, off + 44),
|
|
18
|
+
nb_channels: Token.INT32_LE.get(buf, off + 48),
|
|
19
|
+
bitrate: Token.INT32_LE.get(buf, off + 52),
|
|
20
|
+
frame_size: Token.INT32_LE.get(buf, off + 56),
|
|
21
|
+
vbr: Token.INT32_LE.get(buf, off + 60),
|
|
22
|
+
frames_per_packet: Token.INT32_LE.get(buf, off + 64),
|
|
23
|
+
extra_headers: Token.INT32_LE.get(buf, off + 68),
|
|
24
|
+
reserved1: Token.INT32_LE.get(buf, off + 72),
|
|
25
|
+
reserved2: Token.INT32_LE.get(buf, off + 76)
|
|
26
26
|
};
|
|
27
27
|
}
|
|
28
28
|
};
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
import { ITokenizer } from 'strtok3/core';
|
|
1
|
+
import { ITokenizer } from 'strtok3';
|
|
3
2
|
import { IPageHeader } from '../Ogg.js';
|
|
4
3
|
import { VorbisParser } from '../vorbis/VorbisParser.js';
|
|
5
4
|
import { IOptions } from '../../type.js';
|
package/lib/ogg/theora/Theora.js
CHANGED
|
@@ -8,13 +8,13 @@ export const IdentificationHeader = {
|
|
|
8
8
|
get: (buf, off) => {
|
|
9
9
|
return {
|
|
10
10
|
id: new Token.StringType(7, 'ascii').get(buf, off),
|
|
11
|
-
vmaj:
|
|
12
|
-
vmin:
|
|
13
|
-
vrev:
|
|
14
|
-
vmbw:
|
|
15
|
-
vmbh:
|
|
11
|
+
vmaj: Token.UINT8.get(buf, off + 7),
|
|
12
|
+
vmin: Token.UINT8.get(buf, off + 8),
|
|
13
|
+
vrev: Token.UINT8.get(buf, off + 9),
|
|
14
|
+
vmbw: Token.UINT16_BE.get(buf, off + 10),
|
|
15
|
+
vmbh: Token.UINT16_BE.get(buf, off + 17),
|
|
16
16
|
nombr: Token.UINT24_BE.get(buf, off + 37),
|
|
17
|
-
nqual:
|
|
17
|
+
nqual: Token.UINT8.get(buf, off + 40)
|
|
18
18
|
};
|
|
19
19
|
}
|
|
20
20
|
};
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
import { ITokenizer } from 'strtok3/core';
|
|
1
|
+
import { ITokenizer } from 'strtok3';
|
|
3
2
|
import * as Ogg from '../Ogg.js';
|
|
4
3
|
import { IOptions } from '../../type.js';
|
|
5
4
|
import { INativeMetadataCollector } from '../../common/MetadataCollector.js';
|
|
@@ -16,13 +15,13 @@ export declare class TheoraParser implements Ogg.IPageConsumer {
|
|
|
16
15
|
* @param header Ogg Page Header
|
|
17
16
|
* @param pageData Page data
|
|
18
17
|
*/
|
|
19
|
-
parsePage(header: Ogg.IPageHeader, pageData: Buffer): void
|
|
20
|
-
flush(): void
|
|
18
|
+
parsePage(header: Ogg.IPageHeader, pageData: Buffer): Promise<void>;
|
|
19
|
+
flush(): Promise<void>;
|
|
21
20
|
calculateDuration(header: Ogg.IPageHeader): void;
|
|
22
21
|
/**
|
|
23
22
|
* Parse first Theora Ogg page. the initial identification header packet
|
|
24
23
|
* @param {IPageHeader} header
|
|
25
24
|
* @param {Buffer} pageData
|
|
26
25
|
*/
|
|
27
|
-
protected parseFirstPage(header: Ogg.IPageHeader, pageData: Buffer): void
|
|
26
|
+
protected parseFirstPage(header: Ogg.IPageHeader, pageData: Buffer): Promise<void>;
|
|
28
27
|
}
|
|
@@ -15,12 +15,12 @@ export class TheoraParser {
|
|
|
15
15
|
* @param header Ogg Page Header
|
|
16
16
|
* @param pageData Page data
|
|
17
17
|
*/
|
|
18
|
-
parsePage(header, pageData) {
|
|
18
|
+
async parsePage(header, pageData) {
|
|
19
19
|
if (header.headerType.firstPage) {
|
|
20
|
-
this.parseFirstPage(header, pageData);
|
|
20
|
+
await this.parseFirstPage(header, pageData);
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
|
-
flush() {
|
|
23
|
+
async flush() {
|
|
24
24
|
debug('flush');
|
|
25
25
|
}
|
|
26
26
|
calculateDuration(header) {
|
|
@@ -31,7 +31,7 @@ export class TheoraParser {
|
|
|
31
31
|
* @param {IPageHeader} header
|
|
32
32
|
* @param {Buffer} pageData
|
|
33
33
|
*/
|
|
34
|
-
parseFirstPage(header, pageData) {
|
|
34
|
+
async parseFirstPage(header, pageData) {
|
|
35
35
|
debug('First Ogg/Theora page');
|
|
36
36
|
this.metadata.setFormat('codec', 'Theora');
|
|
37
37
|
const idHeader = IdentificationHeader.get(pageData, 0);
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
/// <reference types="node" resolution-mode="require"/>
|
|
2
1
|
import { IPicture } from '../../type.js';
|
|
3
|
-
import { IGetToken } from 'strtok3
|
|
2
|
+
import type { IGetToken } from 'strtok3';
|
|
4
3
|
/**
|
|
5
4
|
* Interface to parsed result of METADATA_BLOCK_PICTURE
|
|
6
5
|
* Ref: https://wiki.xiph.org/VorbisComment#METADATA_BLOCK_PICTURE
|
|
@@ -23,9 +22,9 @@ export interface IVorbisPicture extends IPicture {
|
|
|
23
22
|
export declare class VorbisPictureToken implements IGetToken<IVorbisPicture> {
|
|
24
23
|
len: any;
|
|
25
24
|
static fromBase64(base64str: string): IVorbisPicture;
|
|
26
|
-
static fromBuffer(buffer:
|
|
25
|
+
static fromBuffer(buffer: Uint8Array): IVorbisPicture;
|
|
27
26
|
constructor(len: any);
|
|
28
|
-
get(buffer:
|
|
27
|
+
get(buffer: Uint8Array, offset: number): IVorbisPicture;
|
|
29
28
|
}
|
|
30
29
|
/**
|
|
31
30
|
* Vorbis 1 decoding tokens
|
package/lib/ogg/vorbis/Vorbis.js
CHANGED
|
@@ -8,7 +8,7 @@ import { AttachedPictureType } from '../../id3v2/ID3v2Token.js';
|
|
|
8
8
|
*/
|
|
9
9
|
export class VorbisPictureToken {
|
|
10
10
|
static fromBase64(base64str) {
|
|
11
|
-
return this.fromBuffer(
|
|
11
|
+
return this.fromBuffer(Uint8Array.from(atob(base64str), c => c.charCodeAt(0)));
|
|
12
12
|
}
|
|
13
13
|
static fromBuffer(buffer) {
|
|
14
14
|
const pic = new VorbisPictureToken(buffer.length);
|
|
@@ -20,15 +20,15 @@ export class VorbisPictureToken {
|
|
|
20
20
|
get(buffer, offset) {
|
|
21
21
|
const type = AttachedPictureType[Token.UINT32_BE.get(buffer, offset)];
|
|
22
22
|
const mimeLen = Token.UINT32_BE.get(buffer, offset += 4);
|
|
23
|
-
const format =
|
|
23
|
+
const format = new Token.StringType(mimeLen, 'utf-8').get(buffer, offset += 4);
|
|
24
24
|
const descLen = Token.UINT32_BE.get(buffer, offset += mimeLen);
|
|
25
|
-
const description =
|
|
25
|
+
const description = new Token.StringType(descLen, 'utf-8').get(buffer, offset += 4);
|
|
26
26
|
const width = Token.UINT32_BE.get(buffer, offset += descLen);
|
|
27
27
|
const height = Token.UINT32_BE.get(buffer, offset += 4);
|
|
28
28
|
const colour_depth = Token.UINT32_BE.get(buffer, offset += 4);
|
|
29
29
|
const indexed_color = Token.UINT32_BE.get(buffer, offset += 4);
|
|
30
30
|
const picDataLen = Token.UINT32_BE.get(buffer, offset += 4);
|
|
31
|
-
const data =
|
|
31
|
+
const data = Uint8Array.from(buffer.slice(offset += 4, offset + picDataLen));
|
|
32
32
|
return {
|
|
33
33
|
type,
|
|
34
34
|
format,
|
|
@@ -49,7 +49,7 @@ export const CommonHeader = {
|
|
|
49
49
|
len: 7,
|
|
50
50
|
get: (buf, off) => {
|
|
51
51
|
return {
|
|
52
|
-
packetType:
|
|
52
|
+
packetType: Token.UINT8.get(buf, off),
|
|
53
53
|
vorbis: new Token.StringType(6, 'ascii').get(buf, off + 1)
|
|
54
54
|
};
|
|
55
55
|
}
|
|
@@ -61,14 +61,13 @@ export const CommonHeader = {
|
|
|
61
61
|
export const IdentificationHeader = {
|
|
62
62
|
len: 23,
|
|
63
63
|
get: (uint8Array, off) => {
|
|
64
|
-
const dataView = new DataView(uint8Array.buffer, uint8Array.byteOffset);
|
|
65
64
|
return {
|
|
66
|
-
version:
|
|
67
|
-
channelMode:
|
|
68
|
-
sampleRate:
|
|
69
|
-
bitrateMax:
|
|
70
|
-
bitrateNominal:
|
|
71
|
-
bitrateMin:
|
|
65
|
+
version: Token.UINT32_LE.get(uint8Array, off + 0),
|
|
66
|
+
channelMode: Token.UINT8.get(uint8Array, off + 4),
|
|
67
|
+
sampleRate: Token.UINT32_LE.get(uint8Array, off + 5),
|
|
68
|
+
bitrateMax: Token.UINT32_LE.get(uint8Array, off + 9),
|
|
69
|
+
bitrateNominal: Token.UINT32_LE.get(uint8Array, off + 13),
|
|
70
|
+
bitrateMin: Token.UINT32_LE.get(uint8Array, off + 17)
|
|
72
71
|
};
|
|
73
72
|
}
|
|
74
73
|
};
|
|
@@ -11,7 +11,7 @@ export class VorbisDecoder {
|
|
|
11
11
|
}
|
|
12
12
|
readStringUtf8() {
|
|
13
13
|
const len = this.readInt32();
|
|
14
|
-
const value =
|
|
14
|
+
const value = new TextDecoder('utf-8').decode(this.data.subarray(this.offset, this.offset + len));
|
|
15
15
|
this.offset += len;
|
|
16
16
|
return value;
|
|
17
17
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/// <reference types="node" resolution-mode="require"/>
|
|
2
1
|
import { IVorbisPicture } from './Vorbis.js';
|
|
3
2
|
import { IPageConsumer, IPageHeader } from '../Ogg.js';
|
|
4
3
|
import { IOptions } from '../../type.js';
|
|
@@ -17,10 +16,10 @@ export declare class VorbisParser implements IPageConsumer {
|
|
|
17
16
|
* @param header Ogg Page Header
|
|
18
17
|
* @param pageData Page data
|
|
19
18
|
*/
|
|
20
|
-
parsePage(header: IPageHeader, pageData: Buffer): void
|
|
21
|
-
flush(): void
|
|
22
|
-
parseUserComment(pageData: Buffer, offset: number): number
|
|
23
|
-
addTag(id: string, value: string | IVorbisPicture): void
|
|
19
|
+
parsePage(header: IPageHeader, pageData: Buffer): Promise<void>;
|
|
20
|
+
flush(): Promise<void>;
|
|
21
|
+
parseUserComment(pageData: Buffer, offset: number): Promise<number>;
|
|
22
|
+
addTag(id: string, value: string | IVorbisPicture): Promise<void>;
|
|
24
23
|
calculateDuration(header: IPageHeader): void;
|
|
25
24
|
/**
|
|
26
25
|
* Parse first Ogg/Vorbis page
|
|
@@ -28,9 +27,9 @@ export declare class VorbisParser implements IPageConsumer {
|
|
|
28
27
|
* @param pageData
|
|
29
28
|
*/
|
|
30
29
|
protected parseFirstPage(header: IPageHeader, pageData: Buffer): void;
|
|
31
|
-
protected parseFullPage(pageData: Buffer): void
|
|
30
|
+
protected parseFullPage(pageData: Buffer): Promise<void>;
|
|
32
31
|
/**
|
|
33
32
|
* Ref: https://xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-840005.2
|
|
34
33
|
*/
|
|
35
|
-
protected parseUserCommentList(pageData: Buffer, offset: number): void
|
|
34
|
+
protected parseUserCommentList(pageData: Buffer, offset: number): Promise<void>;
|
|
36
35
|
}
|