music-metadata 7.12.4 → 8.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 +47 -31
- package/lib/ParserFactory.js +37 -41
- package/lib/aiff/AiffParser.js +25 -17
- package/lib/aiff/AiffToken.js +13 -12
- package/lib/apev2/APEv2Parser.js +29 -32
- package/lib/apev2/APEv2TagMapper.js +2 -6
- package/lib/apev2/APEv2Token.js +13 -19
- package/lib/asf/AsfObject.js +42 -56
- package/lib/asf/AsfParser.js +15 -19
- package/lib/asf/AsfTagMapper.js +2 -6
- package/lib/asf/AsfUtil.js +4 -7
- package/lib/asf/GUID.js +1 -4
- package/lib/common/BasicParser.js +1 -5
- package/lib/common/CaseInsensitiveTagMap.js +2 -6
- package/lib/common/CombinedTagMapper.js +20 -24
- package/lib/common/FourCC.js +3 -6
- package/lib/common/GenericTagMapper.js +2 -6
- package/lib/common/GenericTagTypes.js +5 -10
- package/lib/common/MetadataCollector.js +20 -25
- package/lib/common/RandomFileReader.js +2 -6
- package/lib/common/RandomUint8ArrayReader.js +1 -5
- package/lib/common/Util.js +11 -25
- package/lib/core.js +18 -28
- package/lib/dsdiff/DsdiffParser.js +24 -28
- package/lib/dsdiff/DsdiffToken.js +4 -7
- package/lib/dsf/DsfChunk.js +8 -11
- package/lib/dsf/DsfParser.js +13 -17
- package/lib/flac/FlacParser.js +22 -26
- package/lib/id3v1/ID3v1Parser.js +16 -21
- package/lib/id3v1/ID3v1TagMap.js +2 -6
- package/lib/id3v2/AbstractID3Parser.js +13 -17
- package/lib/id3v2/FrameParser.js +12 -17
- package/lib/id3v2/ID3v22TagMapper.js +4 -8
- package/lib/id3v2/ID3v24TagMapper.js +5 -9
- package/lib/id3v2/ID3v2Parser.js +10 -14
- package/lib/id3v2/ID3v2Token.js +9 -12
- package/lib/iff/index.js +4 -7
- package/lib/index.js +14 -44
- package/lib/lyrics3/Lyrics3.js +3 -7
- package/lib/matroska/MatroskaDtd.js +111 -114
- package/lib/matroska/MatroskaParser.js +20 -24
- package/lib/matroska/MatroskaTagMapper.js +2 -6
- package/lib/matroska/types.js +6 -9
- package/lib/mp4/Atom.js +4 -8
- package/lib/mp4/AtomToken.js +29 -44
- package/lib/mp4/MP4Parser.js +12 -16
- package/lib/mp4/MP4TagMapper.js +4 -8
- package/lib/mpeg/ExtendedLameHeader.js +6 -9
- package/lib/mpeg/MpegParser.js +17 -21
- package/lib/mpeg/ReplayGainDataFormat.js +2 -5
- package/lib/mpeg/XingTag.js +9 -13
- package/lib/musepack/index.js +10 -12
- package/lib/musepack/sv7/BitReader.js +2 -6
- package/lib/musepack/sv7/MpcSv7Parser.js +9 -13
- package/lib/musepack/sv7/StreamVersion7.js +3 -6
- package/lib/musepack/sv8/MpcSv8Parser.js +9 -13
- package/lib/musepack/sv8/StreamVersion8.js +5 -9
- package/lib/ogg/Ogg.js +1 -2
- package/lib/ogg/OggParser.js +19 -24
- package/lib/ogg/opus/Opus.js +2 -6
- package/lib/ogg/opus/OpusParser.js +4 -8
- package/lib/ogg/speex/Speex.js +3 -6
- package/lib/ogg/speex/SpeexParser.js +5 -9
- package/lib/ogg/theora/Theora.js +2 -5
- package/lib/ogg/theora/TheoraParser.js +5 -9
- package/lib/ogg/vorbis/Vorbis.js +6 -10
- package/lib/ogg/vorbis/VorbisDecoder.js +2 -6
- package/lib/ogg/vorbis/VorbisParser.js +18 -22
- package/lib/ogg/vorbis/VorbisTagMapper.js +3 -7
- package/lib/riff/RiffChunk.js +3 -7
- package/lib/riff/RiffInfoTagMap.js +4 -8
- package/lib/type.js +1 -5
- package/lib/wav/BwfChunk.js +8 -11
- package/lib/wav/WaveChunk.js +4 -9
- package/lib/wav/WaveParser.js +17 -21
- package/lib/wavpack/WavPackParser.js +17 -21
- package/lib/wavpack/WavPackToken.js +4 -8
- package/package.json +34 -44
- package/lib/ParserFactory.d.ts +0 -48
- package/lib/aiff/AiffParser.d.ts +0 -14
- package/lib/aiff/AiffToken.d.ts +0 -22
- package/lib/apev2/APEv2Parser.d.ts +0 -30
- package/lib/apev2/APEv2TagMapper.d.ts +0 -4
- package/lib/apev2/APEv2Token.d.ts +0 -100
- package/lib/asf/AsfObject.d.ts +0 -319
- package/lib/asf/AsfParser.d.ts +0 -17
- package/lib/asf/AsfTagMapper.d.ts +0 -7
- package/lib/asf/AsfUtil.d.ts +0 -13
- package/lib/asf/GUID.d.ts +0 -84
- package/lib/common/BasicParser.d.ts +0 -17
- package/lib/common/CaseInsensitiveTagMap.d.ts +0 -10
- package/lib/common/CombinedTagMapper.d.ts +0 -19
- package/lib/common/FourCC.d.ts +0 -6
- package/lib/common/GenericTagMapper.d.ts +0 -51
- package/lib/common/GenericTagTypes.d.ts +0 -33
- package/lib/common/MetadataCollector.d.ts +0 -76
- package/lib/common/RandomFileReader.d.ts +0 -22
- package/lib/common/RandomUint8ArrayReader.d.ts +0 -18
- package/lib/common/Util.d.ts +0 -57
- package/lib/core.d.ts +0 -48
- package/lib/dsdiff/DsdiffParser.d.ts +0 -14
- package/lib/dsdiff/DsdiffToken.d.ts +0 -9
- package/lib/dsf/DsfChunk.d.ts +0 -86
- package/lib/dsf/DsfParser.d.ts +0 -9
- package/lib/flac/FlacParser.d.ts +0 -28
- package/lib/id3v1/ID3v1Parser.d.ts +0 -13
- package/lib/id3v1/ID3v1TagMap.d.ts +0 -4
- package/lib/id3v2/AbstractID3Parser.d.ts +0 -17
- package/lib/id3v2/FrameParser.d.ts +0 -31
- package/lib/id3v2/ID3v22TagMapper.d.ts +0 -9
- package/lib/id3v2/ID3v24TagMapper.d.ts +0 -14
- package/lib/id3v2/ID3v2Parser.d.ts +0 -28
- package/lib/id3v2/ID3v2Token.d.ts +0 -73
- package/lib/iff/index.d.ts +0 -33
- package/lib/index.d.ts +0 -45
- package/lib/lyrics3/Lyrics3.d.ts +0 -3
- package/lib/matroska/MatroskaDtd.d.ts +0 -8
- package/lib/matroska/MatroskaParser.d.ts +0 -37
- package/lib/matroska/MatroskaTagMapper.d.ts +0 -4
- package/lib/matroska/types.d.ts +0 -175
- package/lib/mp4/Atom.d.ts +0 -16
- package/lib/mp4/AtomToken.d.ts +0 -395
- package/lib/mp4/MP4Parser.d.ts +0 -30
- package/lib/mp4/MP4TagMapper.d.ts +0 -5
- package/lib/mpeg/ExtendedLameHeader.d.ts +0 -27
- package/lib/mpeg/MpegParser.d.ts +0 -49
- package/lib/mpeg/ReplayGainDataFormat.d.ts +0 -55
- package/lib/mpeg/XingTag.d.ts +0 -45
- package/lib/musepack/index.d.ts +0 -5
- package/lib/musepack/sv7/BitReader.d.ts +0 -13
- package/lib/musepack/sv7/MpcSv7Parser.d.ts +0 -8
- package/lib/musepack/sv7/StreamVersion7.d.ts +0 -28
- package/lib/musepack/sv8/MpcSv8Parser.d.ts +0 -6
- package/lib/musepack/sv8/StreamVersion8.d.ts +0 -40
- package/lib/ogg/Ogg.d.ts +0 -72
- package/lib/ogg/OggParser.d.ts +0 -23
- package/lib/ogg/opus/Opus.d.ts +0 -48
- package/lib/ogg/opus/OpusParser.d.ts +0 -25
- package/lib/ogg/speex/Speex.d.ts +0 -36
- package/lib/ogg/speex/SpeexParser.d.ts +0 -22
- package/lib/ogg/theora/Theora.d.ts +0 -20
- package/lib/ogg/theora/TheoraParser.d.ts +0 -28
- package/lib/ogg/vorbis/Vorbis.d.ts +0 -69
- package/lib/ogg/vorbis/VorbisDecoder.d.ts +0 -12
- package/lib/ogg/vorbis/VorbisParser.d.ts +0 -36
- package/lib/ogg/vorbis/VorbisTagMapper.d.ts +0 -7
- package/lib/riff/RiffChunk.d.ts +0 -16
- package/lib/riff/RiffInfoTagMap.d.ts +0 -10
- package/lib/type.d.ts +0 -592
- package/lib/wav/BwfChunk.d.ts +0 -17
- package/lib/wav/WaveChunk.d.ts +0 -64
- package/lib/wav/WaveParser.d.ts +0 -24
- package/lib/wavpack/WavPackParser.d.ts +0 -14
- package/lib/wavpack/WavPackToken.d.ts +0 -64
package/lib/apev2/APEv2Token.js
CHANGED
|
@@ -1,24 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const Token = require("token-types");
|
|
5
|
-
const FourCC_1 = require("../common/FourCC");
|
|
6
|
-
var DataType;
|
|
1
|
+
import * as Token from 'token-types';
|
|
2
|
+
import { FourCcToken } from '../common/FourCC.js';
|
|
3
|
+
export var DataType;
|
|
7
4
|
(function (DataType) {
|
|
8
5
|
DataType[DataType["text_utf8"] = 0] = "text_utf8";
|
|
9
6
|
DataType[DataType["binary"] = 1] = "binary";
|
|
10
7
|
DataType[DataType["external_info"] = 2] = "external_info";
|
|
11
8
|
DataType[DataType["reserved"] = 3] = "reserved";
|
|
12
|
-
})(DataType =
|
|
9
|
+
})(DataType = DataType || (DataType = {}));
|
|
13
10
|
/**
|
|
14
11
|
* APE_DESCRIPTOR: defines the sizes (and offsets) of all the pieces, as well as the MD5 checksum
|
|
15
12
|
*/
|
|
16
|
-
|
|
13
|
+
export const DescriptorParser = {
|
|
17
14
|
len: 52,
|
|
18
15
|
get: (buf, off) => {
|
|
19
16
|
return {
|
|
20
17
|
// should equal 'MAC '
|
|
21
|
-
ID:
|
|
18
|
+
ID: FourCcToken.get(buf, off),
|
|
22
19
|
// versionIndex number * 1000 (3.81 = 3810) (remember that 4-byte alignment causes this to take 4-bytes)
|
|
23
20
|
version: Token.UINT32_LE.get(buf, off + 4) / 1000,
|
|
24
21
|
// the number of descriptor bytes (allows later expansion of this header)
|
|
@@ -43,7 +40,7 @@ exports.DescriptorParser = {
|
|
|
43
40
|
/**
|
|
44
41
|
* APE_HEADER: describes all of the necessary information about the APE file
|
|
45
42
|
*/
|
|
46
|
-
|
|
43
|
+
export const Header = {
|
|
47
44
|
len: 24,
|
|
48
45
|
get: (buf, off) => {
|
|
49
46
|
return {
|
|
@@ -70,7 +67,7 @@ exports.Header = {
|
|
|
70
67
|
* APE Tag Header/Footer Version 2.0
|
|
71
68
|
* TAG: describes all the properties of the file [optional]
|
|
72
69
|
*/
|
|
73
|
-
|
|
70
|
+
export const TagFooter = {
|
|
74
71
|
len: 32,
|
|
75
72
|
get: (buf, off) => {
|
|
76
73
|
return {
|
|
@@ -90,7 +87,7 @@ exports.TagFooter = {
|
|
|
90
87
|
/**
|
|
91
88
|
* APE Tag v2.0 Item Header
|
|
92
89
|
*/
|
|
93
|
-
|
|
90
|
+
export const TagItemHeader = {
|
|
94
91
|
len: 8,
|
|
95
92
|
get: (buf, off) => {
|
|
96
93
|
return {
|
|
@@ -101,11 +98,10 @@ exports.TagItemHeader = {
|
|
|
101
98
|
};
|
|
102
99
|
}
|
|
103
100
|
};
|
|
104
|
-
const TagField = footer => {
|
|
105
|
-
return new Token.Uint8ArrayType(footer.size -
|
|
101
|
+
export const TagField = footer => {
|
|
102
|
+
return new Token.Uint8ArrayType(footer.size - TagFooter.len);
|
|
106
103
|
};
|
|
107
|
-
|
|
108
|
-
function parseTagFlags(flags) {
|
|
104
|
+
export function parseTagFlags(flags) {
|
|
109
105
|
return {
|
|
110
106
|
containsHeader: isBitSet(flags, 31),
|
|
111
107
|
containsFooter: isBitSet(flags, 30),
|
|
@@ -114,14 +110,12 @@ function parseTagFlags(flags) {
|
|
|
114
110
|
dataType: (flags & 6) >> 1
|
|
115
111
|
};
|
|
116
112
|
}
|
|
117
|
-
exports.parseTagFlags = parseTagFlags;
|
|
118
113
|
/**
|
|
119
114
|
* @param num {number}
|
|
120
115
|
* @param bit 0 is least significant bit (LSB)
|
|
121
116
|
* @return {boolean} true if bit is 1; otherwise false
|
|
122
117
|
*/
|
|
123
|
-
function isBitSet(num, bit) {
|
|
118
|
+
export function isBitSet(num, bit) {
|
|
124
119
|
return (num & 1 << bit) !== 0;
|
|
125
120
|
}
|
|
126
|
-
exports.isBitSet = isBitSet;
|
|
127
121
|
//# sourceMappingURL=APEv2Token.js.map
|
package/lib/asf/AsfObject.js
CHANGED
|
@@ -1,16 +1,14 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
// ASF Objects
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const ID3v2Token_1 = require("../id3v2/ID3v2Token");
|
|
2
|
+
import * as Token from 'token-types';
|
|
3
|
+
import { Buffer } from 'node:buffer';
|
|
4
|
+
import * as util from '../common/Util.js';
|
|
5
|
+
import GUID from './GUID.js';
|
|
6
|
+
import { AsfUtil } from './AsfUtil.js';
|
|
7
|
+
import { AttachedPictureType } from '../id3v2/ID3v2Token.js';
|
|
10
8
|
/**
|
|
11
9
|
* Data Type: Specifies the type of information being stored. The following values are recognized.
|
|
12
10
|
*/
|
|
13
|
-
var DataType;
|
|
11
|
+
export var DataType;
|
|
14
12
|
(function (DataType) {
|
|
15
13
|
/**
|
|
16
14
|
* Unicode string. The data consists of a sequence of Unicode characters.
|
|
@@ -36,16 +34,16 @@ var DataType;
|
|
|
36
34
|
* WORD. The data is 2 bytes long and should be interpreted as a 16-bit unsigned integer.
|
|
37
35
|
*/
|
|
38
36
|
DataType[DataType["Word"] = 5] = "Word";
|
|
39
|
-
})(DataType =
|
|
37
|
+
})(DataType = DataType || (DataType = {}));
|
|
40
38
|
/**
|
|
41
39
|
* Token for: 3. ASF top-level Header Object
|
|
42
40
|
* Ref: http://drang.s4.xrea.com/program/tips/id3tag/wmp/03_asf_top_level_header_object.html#3
|
|
43
41
|
*/
|
|
44
|
-
|
|
42
|
+
export const TopLevelHeaderObjectToken = {
|
|
45
43
|
len: 30,
|
|
46
44
|
get: (buf, off) => {
|
|
47
45
|
return {
|
|
48
|
-
objectId:
|
|
46
|
+
objectId: GUID.fromBin(new Token.BufferType(16).get(buf, off)),
|
|
49
47
|
objectSize: Number(Token.UINT64_LE.get(buf, off + 16)),
|
|
50
48
|
numberOfHeaderObjects: Token.UINT32_LE.get(buf, off + 24)
|
|
51
49
|
// Reserved: 2 bytes
|
|
@@ -56,25 +54,25 @@ exports.TopLevelHeaderObjectToken = {
|
|
|
56
54
|
* Token for: 3.1 Header Object (mandatory, one only)
|
|
57
55
|
* Ref: http://drang.s4.xrea.com/program/tips/id3tag/wmp/03_asf_top_level_header_object.html#3_1
|
|
58
56
|
*/
|
|
59
|
-
|
|
57
|
+
export const HeaderObjectToken = {
|
|
60
58
|
len: 24,
|
|
61
59
|
get: (buf, off) => {
|
|
62
60
|
return {
|
|
63
|
-
objectId:
|
|
61
|
+
objectId: GUID.fromBin(new Token.BufferType(16).get(buf, off)),
|
|
64
62
|
objectSize: Number(Token.UINT64_LE.get(buf, off + 16))
|
|
65
63
|
};
|
|
66
64
|
}
|
|
67
65
|
};
|
|
68
|
-
class State {
|
|
66
|
+
export class State {
|
|
69
67
|
constructor(header) {
|
|
70
|
-
this.len = Number(header.objectSize) -
|
|
68
|
+
this.len = Number(header.objectSize) - HeaderObjectToken.len;
|
|
71
69
|
}
|
|
72
70
|
postProcessTag(tags, name, valueType, data) {
|
|
73
71
|
if (name === 'WM/Picture') {
|
|
74
72
|
tags.push({ id: name, value: WmPictureToken.fromBuffer(data) });
|
|
75
73
|
}
|
|
76
74
|
else {
|
|
77
|
-
const parseAttr =
|
|
75
|
+
const parseAttr = AsfUtil.getParserForAttr(valueType);
|
|
78
76
|
if (!parseAttr) {
|
|
79
77
|
throw new Error('unexpected value headerType: ' + valueType);
|
|
80
78
|
}
|
|
@@ -82,9 +80,8 @@ class State {
|
|
|
82
80
|
}
|
|
83
81
|
}
|
|
84
82
|
}
|
|
85
|
-
exports.State = State;
|
|
86
83
|
// ToDo: use ignore type
|
|
87
|
-
class IgnoreObjectState extends State {
|
|
84
|
+
export class IgnoreObjectState extends State {
|
|
88
85
|
constructor(header) {
|
|
89
86
|
super(header);
|
|
90
87
|
}
|
|
@@ -92,18 +89,17 @@ class IgnoreObjectState extends State {
|
|
|
92
89
|
return null;
|
|
93
90
|
}
|
|
94
91
|
}
|
|
95
|
-
exports.IgnoreObjectState = IgnoreObjectState;
|
|
96
92
|
/**
|
|
97
93
|
* Token for: 3.2: File Properties Object (mandatory, one only)
|
|
98
94
|
* Ref: http://drang.s4.xrea.com/program/tips/id3tag/wmp/03_asf_top_level_header_object.html#3_2
|
|
99
95
|
*/
|
|
100
|
-
class FilePropertiesObject extends State {
|
|
96
|
+
export class FilePropertiesObject extends State {
|
|
101
97
|
constructor(header) {
|
|
102
98
|
super(header);
|
|
103
99
|
}
|
|
104
100
|
get(buf, off) {
|
|
105
101
|
return {
|
|
106
|
-
fileId:
|
|
102
|
+
fileId: GUID.fromBin(buf, off),
|
|
107
103
|
fileSize: Token.UINT64_LE.get(buf, off + 16),
|
|
108
104
|
creationDate: Token.UINT64_LE.get(buf, off + 24),
|
|
109
105
|
dataPacketsCount: Token.UINT64_LE.get(buf, off + 32),
|
|
@@ -121,44 +117,41 @@ class FilePropertiesObject extends State {
|
|
|
121
117
|
};
|
|
122
118
|
}
|
|
123
119
|
}
|
|
124
|
-
|
|
125
|
-
FilePropertiesObject.guid = GUID_1.default.FilePropertiesObject;
|
|
120
|
+
FilePropertiesObject.guid = GUID.FilePropertiesObject;
|
|
126
121
|
/**
|
|
127
122
|
* Token for: 3.3 Stream Properties Object (mandatory, one per stream)
|
|
128
123
|
* Ref: http://drang.s4.xrea.com/program/tips/id3tag/wmp/03_asf_top_level_header_object.html#3_3
|
|
129
124
|
*/
|
|
130
|
-
class StreamPropertiesObject extends State {
|
|
125
|
+
export class StreamPropertiesObject extends State {
|
|
131
126
|
constructor(header) {
|
|
132
127
|
super(header);
|
|
133
128
|
}
|
|
134
129
|
get(buf, off) {
|
|
135
130
|
return {
|
|
136
|
-
streamType:
|
|
137
|
-
errorCorrectionType:
|
|
131
|
+
streamType: GUID.decodeMediaType(GUID.fromBin(buf, off)),
|
|
132
|
+
errorCorrectionType: GUID.fromBin(buf, off + 8)
|
|
138
133
|
// ToDo
|
|
139
134
|
};
|
|
140
135
|
}
|
|
141
136
|
}
|
|
142
|
-
|
|
143
|
-
StreamPropertiesObject.guid = GUID_1.default.StreamPropertiesObject;
|
|
137
|
+
StreamPropertiesObject.guid = GUID.StreamPropertiesObject;
|
|
144
138
|
/**
|
|
145
139
|
* 3.4: Header Extension Object (mandatory, one only)
|
|
146
140
|
* Ref: http://drang.s4.xrea.com/program/tips/id3tag/wmp/03_asf_top_level_header_object.html#3_4
|
|
147
141
|
*/
|
|
148
|
-
class HeaderExtensionObject {
|
|
142
|
+
export class HeaderExtensionObject {
|
|
149
143
|
constructor() {
|
|
150
144
|
this.len = 22;
|
|
151
145
|
}
|
|
152
146
|
get(buf, off) {
|
|
153
147
|
return {
|
|
154
|
-
reserved1:
|
|
148
|
+
reserved1: GUID.fromBin(buf, off),
|
|
155
149
|
reserved2: buf.readUInt16LE(off + 16),
|
|
156
150
|
extensionDataSize: buf.readUInt32LE(off + 18)
|
|
157
151
|
};
|
|
158
152
|
}
|
|
159
153
|
}
|
|
160
|
-
|
|
161
|
-
HeaderExtensionObject.guid = GUID_1.default.HeaderExtensionObject;
|
|
154
|
+
HeaderExtensionObject.guid = GUID.HeaderExtensionObject;
|
|
162
155
|
/**
|
|
163
156
|
* 3.5: The Codec List Object provides user-friendly information about the codecs and formats used to encode the content found in the ASF file.
|
|
164
157
|
* Ref: http://drang.s4.xrea.com/program/tips/id3tag/wmp/03_asf_top_level_header_object.html#3_5
|
|
@@ -179,7 +172,7 @@ async function readString(tokenizer) {
|
|
|
179
172
|
* 3.5: Read the Codec-List-Object, which provides user-friendly information about the codecs and formats used to encode the content found in the ASF file.
|
|
180
173
|
* Ref: http://drang.s4.xrea.com/program/tips/id3tag/wmp/03_asf_top_level_header_object.html#3_5
|
|
181
174
|
*/
|
|
182
|
-
async function readCodecEntries(tokenizer) {
|
|
175
|
+
export async function readCodecEntries(tokenizer) {
|
|
183
176
|
const codecHeader = await tokenizer.readToken(CodecListObjectHeader);
|
|
184
177
|
const entries = [];
|
|
185
178
|
for (let i = 0; i < codecHeader.entryCount; ++i) {
|
|
@@ -187,7 +180,6 @@ async function readCodecEntries(tokenizer) {
|
|
|
187
180
|
}
|
|
188
181
|
return entries;
|
|
189
182
|
}
|
|
190
|
-
exports.readCodecEntries = readCodecEntries;
|
|
191
183
|
async function readInformation(tokenizer) {
|
|
192
184
|
const length = await tokenizer.readNumber(Token.UINT16_LE);
|
|
193
185
|
const buf = Buffer.alloc(length);
|
|
@@ -214,7 +206,7 @@ async function readCodecEntry(tokenizer) {
|
|
|
214
206
|
* 3.10 Content Description Object (optional, one only)
|
|
215
207
|
* Ref: http://drang.s4.xrea.com/program/tips/id3tag/wmp/03_asf_top_level_header_object.html#3_10
|
|
216
208
|
*/
|
|
217
|
-
class ContentDescriptionObjectState extends State {
|
|
209
|
+
export class ContentDescriptionObjectState extends State {
|
|
218
210
|
constructor(header) {
|
|
219
211
|
super(header);
|
|
220
212
|
}
|
|
@@ -226,21 +218,20 @@ class ContentDescriptionObjectState extends State {
|
|
|
226
218
|
if (length > 0) {
|
|
227
219
|
const tagName = ContentDescriptionObjectState.contentDescTags[i];
|
|
228
220
|
const end = pos + length;
|
|
229
|
-
tags.push({ id: tagName, value:
|
|
221
|
+
tags.push({ id: tagName, value: AsfUtil.parseUnicodeAttr(buf.slice(pos, end)) });
|
|
230
222
|
pos = end;
|
|
231
223
|
}
|
|
232
224
|
}
|
|
233
225
|
return tags;
|
|
234
226
|
}
|
|
235
227
|
}
|
|
236
|
-
|
|
237
|
-
ContentDescriptionObjectState.guid = GUID_1.default.ContentDescriptionObject;
|
|
228
|
+
ContentDescriptionObjectState.guid = GUID.ContentDescriptionObject;
|
|
238
229
|
ContentDescriptionObjectState.contentDescTags = ['Title', 'Author', 'Copyright', 'Description', 'Rating'];
|
|
239
230
|
/**
|
|
240
231
|
* 3.11 Extended Content Description Object (optional, one only)
|
|
241
232
|
* Ref: http://drang.s4.xrea.com/program/tips/id3tag/wmp/03_asf_top_level_header_object.html#3_11
|
|
242
233
|
*/
|
|
243
|
-
class ExtendedContentDescriptionObjectState extends State {
|
|
234
|
+
export class ExtendedContentDescriptionObjectState extends State {
|
|
244
235
|
constructor(header) {
|
|
245
236
|
super(header);
|
|
246
237
|
}
|
|
@@ -251,7 +242,7 @@ class ExtendedContentDescriptionObjectState extends State {
|
|
|
251
242
|
for (let i = 0; i < attrCount; i += 1) {
|
|
252
243
|
const nameLen = buf.readUInt16LE(pos);
|
|
253
244
|
pos += 2;
|
|
254
|
-
const name =
|
|
245
|
+
const name = AsfUtil.parseUnicodeAttr(buf.slice(pos, pos + nameLen));
|
|
255
246
|
pos += nameLen;
|
|
256
247
|
const valueType = buf.readUInt16LE(pos);
|
|
257
248
|
pos += 2;
|
|
@@ -264,13 +255,12 @@ class ExtendedContentDescriptionObjectState extends State {
|
|
|
264
255
|
return tags;
|
|
265
256
|
}
|
|
266
257
|
}
|
|
267
|
-
|
|
268
|
-
ExtendedContentDescriptionObjectState.guid = GUID_1.default.ExtendedContentDescriptionObject;
|
|
258
|
+
ExtendedContentDescriptionObjectState.guid = GUID.ExtendedContentDescriptionObject;
|
|
269
259
|
/**
|
|
270
260
|
* 4.1 Extended Stream Properties Object (optional, 1 per media stream)
|
|
271
261
|
* Ref: http://drang.s4.xrea.com/program/tips/id3tag/wmp/04_objects_in_the_asf_header_extension_object.html#4_1
|
|
272
262
|
*/
|
|
273
|
-
class ExtendedStreamPropertiesObjectState extends State {
|
|
263
|
+
export class ExtendedStreamPropertiesObjectState extends State {
|
|
274
264
|
constructor(header) {
|
|
275
265
|
super(header);
|
|
276
266
|
}
|
|
@@ -301,13 +291,12 @@ class ExtendedStreamPropertiesObjectState extends State {
|
|
|
301
291
|
};
|
|
302
292
|
}
|
|
303
293
|
}
|
|
304
|
-
|
|
305
|
-
ExtendedStreamPropertiesObjectState.guid = GUID_1.default.ExtendedStreamPropertiesObject;
|
|
294
|
+
ExtendedStreamPropertiesObjectState.guid = GUID.ExtendedStreamPropertiesObject;
|
|
306
295
|
/**
|
|
307
296
|
* 4.7 Metadata Object (optional, 0 or 1)
|
|
308
297
|
* Ref: http://drang.s4.xrea.com/program/tips/id3tag/wmp/04_objects_in_the_asf_header_extension_object.html#4_7
|
|
309
298
|
*/
|
|
310
|
-
class MetadataObjectState extends State {
|
|
299
|
+
export class MetadataObjectState extends State {
|
|
311
300
|
constructor(header) {
|
|
312
301
|
super(header);
|
|
313
302
|
}
|
|
@@ -324,7 +313,7 @@ class MetadataObjectState extends State {
|
|
|
324
313
|
pos += 2;
|
|
325
314
|
const dataLen = buf.readUInt32LE(pos);
|
|
326
315
|
pos += 4;
|
|
327
|
-
const name =
|
|
316
|
+
const name = AsfUtil.parseUnicodeAttr(buf.slice(pos, pos + nameLen));
|
|
328
317
|
pos += nameLen;
|
|
329
318
|
const data = buf.slice(pos, pos + dataLen);
|
|
330
319
|
pos += dataLen;
|
|
@@ -333,20 +322,18 @@ class MetadataObjectState extends State {
|
|
|
333
322
|
return tags;
|
|
334
323
|
}
|
|
335
324
|
}
|
|
336
|
-
|
|
337
|
-
MetadataObjectState.guid = GUID_1.default.MetadataObject;
|
|
325
|
+
MetadataObjectState.guid = GUID.MetadataObject;
|
|
338
326
|
// 4.8 Metadata Library Object (optional, 0 or 1)
|
|
339
|
-
class MetadataLibraryObjectState extends MetadataObjectState {
|
|
327
|
+
export class MetadataLibraryObjectState extends MetadataObjectState {
|
|
340
328
|
constructor(header) {
|
|
341
329
|
super(header);
|
|
342
330
|
}
|
|
343
331
|
}
|
|
344
|
-
|
|
345
|
-
MetadataLibraryObjectState.guid = GUID_1.default.MetadataLibraryObject;
|
|
332
|
+
MetadataLibraryObjectState.guid = GUID.MetadataLibraryObject;
|
|
346
333
|
/**
|
|
347
334
|
* Ref: https://msdn.microsoft.com/en-us/library/windows/desktop/dd757977(v=vs.85).aspx
|
|
348
335
|
*/
|
|
349
|
-
class WmPictureToken {
|
|
336
|
+
export class WmPictureToken {
|
|
350
337
|
constructor(len) {
|
|
351
338
|
this.len = len;
|
|
352
339
|
}
|
|
@@ -370,7 +357,7 @@ class WmPictureToken {
|
|
|
370
357
|
}
|
|
371
358
|
const description = buffer.slice(5, index).toString('utf16le');
|
|
372
359
|
return {
|
|
373
|
-
type:
|
|
360
|
+
type: AttachedPictureType[typeId],
|
|
374
361
|
format,
|
|
375
362
|
description,
|
|
376
363
|
size,
|
|
@@ -378,4 +365,3 @@ class WmPictureToken {
|
|
|
378
365
|
};
|
|
379
366
|
}
|
|
380
367
|
}
|
|
381
|
-
exports.WmPictureToken = WmPictureToken;
|
package/lib/asf/AsfParser.js
CHANGED
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const
|
|
7
|
-
const AsfObject = require("./AsfObject");
|
|
8
|
-
const BasicParser_1 = require("../common/BasicParser");
|
|
9
|
-
const debug = (0, debug_1.default)('music-metadata:parser:ASF');
|
|
1
|
+
import initDebug from 'debug';
|
|
2
|
+
import { TrackType } from '../type.js';
|
|
3
|
+
import GUID from './GUID.js';
|
|
4
|
+
import * as AsfObject from './AsfObject.js';
|
|
5
|
+
import { BasicParser } from '../common/BasicParser.js';
|
|
6
|
+
const debug = initDebug('music-metadata:parser:ASF');
|
|
10
7
|
const headerType = 'asf';
|
|
11
8
|
/**
|
|
12
9
|
* Windows Media Metadata Usage Guidelines
|
|
@@ -18,10 +15,10 @@ const headerType = 'asf';
|
|
|
18
15
|
* - http://drang.s4.xrea.com/program/tips/id3tag/wmp/index.html
|
|
19
16
|
* - https://msdn.microsoft.com/en-us/library/windows/desktop/ee663575(v=vs.85).aspx
|
|
20
17
|
*/
|
|
21
|
-
class AsfParser extends
|
|
18
|
+
export class AsfParser extends BasicParser {
|
|
22
19
|
async parse() {
|
|
23
20
|
const header = await this.tokenizer.readToken(AsfObject.TopLevelHeaderObjectToken);
|
|
24
|
-
if (!header.objectId.equals(
|
|
21
|
+
if (!header.objectId.equals(GUID.HeaderObject)) {
|
|
25
22
|
throw new Error('expected asf header; but was not found; got: ' + header.objectId.str);
|
|
26
23
|
}
|
|
27
24
|
try {
|
|
@@ -60,22 +57,22 @@ class AsfParser extends BasicParser_1.BasicParser {
|
|
|
60
57
|
tags = await this.tokenizer.readToken(new AsfObject.ExtendedContentDescriptionObjectState(header));
|
|
61
58
|
this.addTags(tags);
|
|
62
59
|
break;
|
|
63
|
-
case
|
|
60
|
+
case GUID.CodecListObject.str:
|
|
64
61
|
const codecs = await AsfObject.readCodecEntries(this.tokenizer);
|
|
65
62
|
codecs.forEach(codec => {
|
|
66
63
|
this.metadata.addStreamInfo({
|
|
67
|
-
type: codec.type.videoCodec ?
|
|
64
|
+
type: codec.type.videoCodec ? TrackType.video : TrackType.audio,
|
|
68
65
|
codecName: codec.codecName
|
|
69
66
|
});
|
|
70
67
|
});
|
|
71
68
|
const audioCodecs = codecs.filter(codec => codec.type.audioCodec).map(codec => codec.codecName).join('/');
|
|
72
69
|
this.metadata.setFormat('codec', audioCodecs);
|
|
73
70
|
break;
|
|
74
|
-
case
|
|
71
|
+
case GUID.StreamBitratePropertiesObject.str:
|
|
75
72
|
// ToDo?
|
|
76
73
|
await this.tokenizer.ignore(header.objectSize - AsfObject.HeaderObjectToken.len);
|
|
77
74
|
break;
|
|
78
|
-
case
|
|
75
|
+
case GUID.PaddingObject.str:
|
|
79
76
|
// ToDo: register bytes pad
|
|
80
77
|
debug('Padding: %s bytes', header.objectSize - AsfObject.HeaderObjectToken.len);
|
|
81
78
|
await this.tokenizer.ignore(header.objectSize - AsfObject.HeaderObjectToken.len);
|
|
@@ -112,14 +109,14 @@ class AsfParser extends BasicParser_1.BasicParser {
|
|
|
112
109
|
const mlTags = await this.tokenizer.readToken(new AsfObject.MetadataLibraryObjectState(header));
|
|
113
110
|
this.addTags(mlTags);
|
|
114
111
|
break;
|
|
115
|
-
case
|
|
112
|
+
case GUID.PaddingObject.str:
|
|
116
113
|
// ToDo: register bytes pad
|
|
117
114
|
await this.tokenizer.ignore(remaining);
|
|
118
115
|
break;
|
|
119
|
-
case
|
|
116
|
+
case GUID.CompatibilityObject.str:
|
|
120
117
|
this.tokenizer.ignore(remaining);
|
|
121
118
|
break;
|
|
122
|
-
case
|
|
119
|
+
case GUID.ASF_Index_Placeholder_Object.str:
|
|
123
120
|
await this.tokenizer.ignore(remaining);
|
|
124
121
|
break;
|
|
125
122
|
default:
|
|
@@ -132,4 +129,3 @@ class AsfParser extends BasicParser_1.BasicParser {
|
|
|
132
129
|
} while (extensionSize > 0);
|
|
133
130
|
}
|
|
134
131
|
}
|
|
135
|
-
exports.AsfParser = AsfParser;
|
package/lib/asf/AsfTagMapper.js
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.AsfTagMapper = void 0;
|
|
4
|
-
const GenericTagMapper_1 = require("../common/GenericTagMapper");
|
|
1
|
+
import { CommonTagMapper } from '../common/GenericTagMapper.js';
|
|
5
2
|
/**
|
|
6
3
|
* ASF Metadata tag mappings.
|
|
7
4
|
* See http://msdn.microsoft.com/en-us/library/ms867702.aspx
|
|
@@ -73,7 +70,7 @@ const asfTagMap = {
|
|
|
73
70
|
'WM/AuthorURL': 'website',
|
|
74
71
|
'WM/Picture': 'picture'
|
|
75
72
|
};
|
|
76
|
-
class AsfTagMapper extends
|
|
73
|
+
export class AsfTagMapper extends CommonTagMapper {
|
|
77
74
|
static toRating(rating) {
|
|
78
75
|
return {
|
|
79
76
|
rating: parseFloat(rating + 1) / 5
|
|
@@ -92,5 +89,4 @@ class AsfTagMapper extends GenericTagMapper_1.CommonTagMapper {
|
|
|
92
89
|
}
|
|
93
90
|
}
|
|
94
91
|
}
|
|
95
|
-
exports.AsfTagMapper = AsfTagMapper;
|
|
96
92
|
//# sourceMappingURL=AsfTagMapper.js.map
|
package/lib/asf/AsfUtil.js
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const util = require("../common/Util");
|
|
6
|
-
class AsfUtil {
|
|
1
|
+
import * as Token from 'token-types';
|
|
2
|
+
import { Buffer } from 'node:buffer';
|
|
3
|
+
import * as util from '../common/Util.js';
|
|
4
|
+
export class AsfUtil {
|
|
7
5
|
static getParserForAttr(i) {
|
|
8
6
|
return AsfUtil.attributeParsers[i];
|
|
9
7
|
}
|
|
@@ -26,7 +24,6 @@ class AsfUtil {
|
|
|
26
24
|
return buf.readUInt16LE(offset);
|
|
27
25
|
}
|
|
28
26
|
}
|
|
29
|
-
exports.AsfUtil = AsfUtil;
|
|
30
27
|
AsfUtil.attributeParsers = [
|
|
31
28
|
AsfUtil.parseUnicodeAttr,
|
|
32
29
|
AsfUtil.parseByteArrayAttr,
|
package/lib/asf/GUID.js
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
1
|
/**
|
|
4
2
|
* Ref:
|
|
5
3
|
* - https://tools.ietf.org/html/draft-fleischman-asf-01, Appendix A: ASF GUIDs
|
|
@@ -14,7 +12,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
14
12
|
* - http://drang.s4.xrea.com/program/tips/id3tag/wmp/10_asf_guids.html
|
|
15
13
|
* - https://github.com/dji-sdk/FFmpeg/blob/master/libavformat/asf.c
|
|
16
14
|
*/
|
|
17
|
-
class GUID {
|
|
15
|
+
export default class GUID {
|
|
18
16
|
constructor(str) {
|
|
19
17
|
this.str = str;
|
|
20
18
|
}
|
|
@@ -71,7 +69,6 @@ class GUID {
|
|
|
71
69
|
return GUID.encode(this.str);
|
|
72
70
|
}
|
|
73
71
|
}
|
|
74
|
-
exports.default = GUID;
|
|
75
72
|
// 10.1 Top-level ASF object GUIDs
|
|
76
73
|
GUID.HeaderObject = new GUID("75B22630-668E-11CF-A6D9-00AA0062CE6C");
|
|
77
74
|
GUID.DataObject = new GUID("75B22636-668E-11CF-A6D9-00AA0062CE6C");
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.BasicParser = void 0;
|
|
4
|
-
class BasicParser {
|
|
1
|
+
export class BasicParser {
|
|
5
2
|
/**
|
|
6
3
|
* Initialize parser with output (metadata), input (tokenizer) & parsing options (options).
|
|
7
4
|
* @param {INativeMetadataCollector} metadata Output
|
|
@@ -15,4 +12,3 @@ class BasicParser {
|
|
|
15
12
|
return this;
|
|
16
13
|
}
|
|
17
14
|
}
|
|
18
|
-
exports.BasicParser = BasicParser;
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.CaseInsensitiveTagMap = void 0;
|
|
4
|
-
const GenericTagMapper_1 = require("./GenericTagMapper");
|
|
5
|
-
class CaseInsensitiveTagMap extends GenericTagMapper_1.CommonTagMapper {
|
|
1
|
+
import { CommonTagMapper } from './GenericTagMapper.js';
|
|
2
|
+
export class CaseInsensitiveTagMap extends CommonTagMapper {
|
|
6
3
|
constructor(tagTypes, tagMap) {
|
|
7
4
|
const upperCaseMap = {};
|
|
8
5
|
for (const tag of Object.keys(tagMap)) {
|
|
@@ -18,5 +15,4 @@ class CaseInsensitiveTagMap extends GenericTagMapper_1.CommonTagMapper {
|
|
|
18
15
|
return this.tagMap[tag.toUpperCase()];
|
|
19
16
|
}
|
|
20
17
|
}
|
|
21
|
-
exports.CaseInsensitiveTagMap = CaseInsensitiveTagMap;
|
|
22
18
|
//# sourceMappingURL=CaseInsensitiveTagMap.js.map
|
|
@@ -1,29 +1,26 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const RiffInfoTagMap_1 = require("../riff/RiffInfoTagMap");
|
|
12
|
-
const MatroskaTagMapper_1 = require("../matroska/MatroskaTagMapper");
|
|
13
|
-
class CombinedTagMapper {
|
|
1
|
+
import { ID3v1TagMapper } from '../id3v1/ID3v1TagMap.js';
|
|
2
|
+
import { ID3v24TagMapper } from '../id3v2/ID3v24TagMapper.js';
|
|
3
|
+
import { AsfTagMapper } from '../asf/AsfTagMapper.js';
|
|
4
|
+
import { ID3v22TagMapper } from '../id3v2/ID3v22TagMapper.js';
|
|
5
|
+
import { APEv2TagMapper } from '../apev2/APEv2TagMapper.js';
|
|
6
|
+
import { MP4TagMapper } from '../mp4/MP4TagMapper.js';
|
|
7
|
+
import { VorbisTagMapper } from '../ogg/vorbis/VorbisTagMapper.js';
|
|
8
|
+
import { RiffInfoTagMapper } from '../riff/RiffInfoTagMap.js';
|
|
9
|
+
import { MatroskaTagMapper } from '../matroska/MatroskaTagMapper.js';
|
|
10
|
+
export class CombinedTagMapper {
|
|
14
11
|
constructor() {
|
|
15
12
|
this.tagMappers = {};
|
|
16
13
|
[
|
|
17
|
-
new
|
|
18
|
-
new
|
|
19
|
-
new
|
|
20
|
-
new
|
|
21
|
-
new
|
|
22
|
-
new
|
|
23
|
-
new
|
|
24
|
-
new
|
|
25
|
-
new
|
|
26
|
-
new
|
|
14
|
+
new ID3v1TagMapper(),
|
|
15
|
+
new ID3v22TagMapper(),
|
|
16
|
+
new ID3v24TagMapper(),
|
|
17
|
+
new MP4TagMapper(),
|
|
18
|
+
new MP4TagMapper(),
|
|
19
|
+
new VorbisTagMapper(),
|
|
20
|
+
new APEv2TagMapper(),
|
|
21
|
+
new AsfTagMapper(),
|
|
22
|
+
new RiffInfoTagMapper(),
|
|
23
|
+
new MatroskaTagMapper()
|
|
27
24
|
].forEach(mapper => {
|
|
28
25
|
this.registerTagMapper(mapper);
|
|
29
26
|
});
|
|
@@ -48,5 +45,4 @@ class CombinedTagMapper {
|
|
|
48
45
|
}
|
|
49
46
|
}
|
|
50
47
|
}
|
|
51
|
-
exports.CombinedTagMapper = CombinedTagMapper;
|
|
52
48
|
//# sourceMappingURL=CombinedTagMapper.js.map
|
package/lib/common/FourCC.js
CHANGED
|
@@ -1,16 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.FourCcToken = void 0;
|
|
4
|
-
const util = require("./Util");
|
|
1
|
+
import * as util from './Util.js';
|
|
5
2
|
const validFourCC = /^[\x21-\x7e©][\x20-\x7e\x00()]{3}/;
|
|
6
3
|
/**
|
|
7
4
|
* Token for read FourCC
|
|
8
5
|
* Ref: https://en.wikipedia.org/wiki/FourCC
|
|
9
6
|
*/
|
|
10
|
-
|
|
7
|
+
export const FourCcToken = {
|
|
11
8
|
len: 4,
|
|
12
9
|
get: (buf, off) => {
|
|
13
|
-
const id = buf.toString('binary', off, off +
|
|
10
|
+
const id = buf.toString('binary', off, off + FourCcToken.len);
|
|
14
11
|
switch (id) {
|
|
15
12
|
default:
|
|
16
13
|
if (!id.match(validFourCC)) {
|