music-metadata 11.10.4 → 11.10.6
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/lib/apev2/APEv2Parser.js +2 -2
- package/lib/asf/AsfGuid.d.ts +83 -0
- package/lib/asf/AsfGuid.js +109 -0
- package/lib/asf/AsfObject.d.ts +13 -13
- package/lib/asf/AsfObject.js +15 -15
- package/lib/asf/AsfParser.js +8 -8
- package/lib/common/Util.d.ts +3 -5
- package/lib/common/Util.js +15 -17
- package/lib/ebml/EbmlIterator.d.ts +0 -1
- package/lib/ebml/EbmlIterator.js +1 -4
- package/lib/flac/FlacParser.d.ts +0 -1
- package/lib/flac/FlacParser.js +0 -2
- package/lib/id3v2/FrameHeader.d.ts +31 -0
- package/lib/id3v2/FrameHeader.js +73 -0
- package/lib/id3v2/FrameParser.d.ts +1 -0
- package/lib/id3v2/FrameParser.js +87 -63
- package/lib/id3v2/ID3v2Parser.d.ts +0 -3
- package/lib/id3v2/ID3v2Parser.js +4 -60
- package/lib/mpeg/MpegParser.d.ts +0 -2
- package/lib/mpeg/MpegParser.js +2 -5
- package/lib/ogg/vorbis/VorbisStream.d.ts +1 -1
- package/lib/ogg/vorbis/VorbisStream.js +1 -1
- package/package.json +5 -4
- package/lib/asf/GUID.d.ts +0 -83
- package/lib/asf/GUID.js +0 -118
package/lib/apev2/APEv2Parser.js
CHANGED
|
@@ -113,7 +113,7 @@ export class APEv2Parser extends BasicParser {
|
|
|
113
113
|
const tagItemHeader = await this.tokenizer.readToken(TagItemHeader);
|
|
114
114
|
bytesRemaining -= TagItemHeader.len + tagItemHeader.size;
|
|
115
115
|
await this.tokenizer.peekBuffer(keyBuffer, { length: Math.min(keyBuffer.length, bytesRemaining) });
|
|
116
|
-
let zero = util.findZero(keyBuffer
|
|
116
|
+
let zero = util.findZero(keyBuffer);
|
|
117
117
|
const key = await this.tokenizer.readToken(new StringType(zero, 'ascii'));
|
|
118
118
|
await this.tokenizer.ignore(1);
|
|
119
119
|
bytesRemaining -= key.length + 1;
|
|
@@ -131,7 +131,7 @@ export class APEv2Parser extends BasicParser {
|
|
|
131
131
|
else {
|
|
132
132
|
const picData = new Uint8Array(tagItemHeader.size);
|
|
133
133
|
await this.tokenizer.readBuffer(picData);
|
|
134
|
-
zero = util.findZero(picData
|
|
134
|
+
zero = util.findZero(picData);
|
|
135
135
|
const description = textDecode(picData.subarray(0, zero), 'utf-8');
|
|
136
136
|
const data = picData.subarray(zero + 1);
|
|
137
137
|
await this.metadata.addTag(tagFormat, key, {
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ref:
|
|
3
|
+
* - https://tools.ietf.org/html/draft-fleischman-asf-01, Appendix A: ASF GUIDs
|
|
4
|
+
* - http://drang.s4.xrea.com/program/tips/id3tag/wmp/10_asf_guids.html
|
|
5
|
+
* - http://drang.s4.xrea.com/program/tips/id3tag/wmp/index.html
|
|
6
|
+
* - http://drang.s4.xrea.com/program/tips/id3tag/wmp/10_asf_guids.html
|
|
7
|
+
*
|
|
8
|
+
* ASF File Structure:
|
|
9
|
+
* - https://msdn.microsoft.com/en-us/library/windows/desktop/ee663575(v=vs.85).aspx
|
|
10
|
+
*
|
|
11
|
+
* ASF GUIDs:
|
|
12
|
+
* - http://drang.s4.xrea.com/program/tips/id3tag/wmp/10_asf_guids.html
|
|
13
|
+
* - https://github.com/dji-sdk/FFmpeg/blob/master/libavformat/asf.c
|
|
14
|
+
*/
|
|
15
|
+
export default class AsfGuid {
|
|
16
|
+
static HeaderObject: AsfGuid;
|
|
17
|
+
static DataObject: AsfGuid;
|
|
18
|
+
static SimpleIndexObject: AsfGuid;
|
|
19
|
+
static IndexObject: AsfGuid;
|
|
20
|
+
static MediaObjectIndexObject: AsfGuid;
|
|
21
|
+
static TimecodeIndexObject: AsfGuid;
|
|
22
|
+
static FilePropertiesObject: AsfGuid;
|
|
23
|
+
static StreamPropertiesObject: AsfGuid;
|
|
24
|
+
static HeaderExtensionObject: AsfGuid;
|
|
25
|
+
static CodecListObject: AsfGuid;
|
|
26
|
+
static ScriptCommandObject: AsfGuid;
|
|
27
|
+
static MarkerObject: AsfGuid;
|
|
28
|
+
static BitrateMutualExclusionObject: AsfGuid;
|
|
29
|
+
static ErrorCorrectionObject: AsfGuid;
|
|
30
|
+
static ContentDescriptionObject: AsfGuid;
|
|
31
|
+
static ExtendedContentDescriptionObject: AsfGuid;
|
|
32
|
+
static ContentBrandingObject: AsfGuid;
|
|
33
|
+
static StreamBitratePropertiesObject: AsfGuid;
|
|
34
|
+
static ContentEncryptionObject: AsfGuid;
|
|
35
|
+
static ExtendedContentEncryptionObject: AsfGuid;
|
|
36
|
+
static DigitalSignatureObject: AsfGuid;
|
|
37
|
+
static PaddingObject: AsfGuid;
|
|
38
|
+
static ExtendedStreamPropertiesObject: AsfGuid;
|
|
39
|
+
static AdvancedMutualExclusionObject: AsfGuid;
|
|
40
|
+
static GroupMutualExclusionObject: AsfGuid;
|
|
41
|
+
static StreamPrioritizationObject: AsfGuid;
|
|
42
|
+
static BandwidthSharingObject: AsfGuid;
|
|
43
|
+
static LanguageListObject: AsfGuid;
|
|
44
|
+
static MetadataObject: AsfGuid;
|
|
45
|
+
static MetadataLibraryObject: AsfGuid;
|
|
46
|
+
static IndexParametersObject: AsfGuid;
|
|
47
|
+
static MediaObjectIndexParametersObject: AsfGuid;
|
|
48
|
+
static TimecodeIndexParametersObject: AsfGuid;
|
|
49
|
+
static CompatibilityObject: AsfGuid;
|
|
50
|
+
static AdvancedContentEncryptionObject: AsfGuid;
|
|
51
|
+
static AudioMedia: AsfGuid;
|
|
52
|
+
static VideoMedia: AsfGuid;
|
|
53
|
+
static CommandMedia: AsfGuid;
|
|
54
|
+
static JFIF_Media: AsfGuid;
|
|
55
|
+
static Degradable_JPEG_Media: AsfGuid;
|
|
56
|
+
static FileTransferMedia: AsfGuid;
|
|
57
|
+
static BinaryMedia: AsfGuid;
|
|
58
|
+
static ASF_Index_Placeholder_Object: AsfGuid;
|
|
59
|
+
static fromBin(bin: Uint8Array, offset?: number): AsfGuid;
|
|
60
|
+
/**
|
|
61
|
+
* Decode GUID in format like "B503BF5F-2EA9-CF11-8EE3-00C00C205365"
|
|
62
|
+
* @param objectId Binary GUID
|
|
63
|
+
* @param offset Read offset in bytes, default 0
|
|
64
|
+
* @returns GUID as dashed hexadecimal representation
|
|
65
|
+
*/
|
|
66
|
+
static decode(objectId: Uint8Array, offset?: number): string;
|
|
67
|
+
/**
|
|
68
|
+
* Decode stream type
|
|
69
|
+
* @param mediaType Media type GUID
|
|
70
|
+
* @returns Media type
|
|
71
|
+
*/
|
|
72
|
+
static decodeMediaType(mediaType: AsfGuid): 'audio' | 'video' | 'command' | 'degradable-jpeg' | 'file-transfer' | 'binary' | undefined;
|
|
73
|
+
/**
|
|
74
|
+
* Encode GUID
|
|
75
|
+
* @param guid GUID like: "B503BF5F-2EA9-CF11-8EE3-00C00C205365"
|
|
76
|
+
* @returns Encoded Binary GUID
|
|
77
|
+
*/
|
|
78
|
+
static encode(guid: string): Uint8Array;
|
|
79
|
+
str: string;
|
|
80
|
+
constructor(str: string);
|
|
81
|
+
equals(guid: AsfGuid): boolean;
|
|
82
|
+
toBin(): Uint8Array;
|
|
83
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { parseWindowsGuid, Guid } from 'win-guid';
|
|
2
|
+
/**
|
|
3
|
+
* Ref:
|
|
4
|
+
* - https://tools.ietf.org/html/draft-fleischman-asf-01, Appendix A: ASF GUIDs
|
|
5
|
+
* - http://drang.s4.xrea.com/program/tips/id3tag/wmp/10_asf_guids.html
|
|
6
|
+
* - http://drang.s4.xrea.com/program/tips/id3tag/wmp/index.html
|
|
7
|
+
* - http://drang.s4.xrea.com/program/tips/id3tag/wmp/10_asf_guids.html
|
|
8
|
+
*
|
|
9
|
+
* ASF File Structure:
|
|
10
|
+
* - https://msdn.microsoft.com/en-us/library/windows/desktop/ee663575(v=vs.85).aspx
|
|
11
|
+
*
|
|
12
|
+
* ASF GUIDs:
|
|
13
|
+
* - http://drang.s4.xrea.com/program/tips/id3tag/wmp/10_asf_guids.html
|
|
14
|
+
* - https://github.com/dji-sdk/FFmpeg/blob/master/libavformat/asf.c
|
|
15
|
+
*/
|
|
16
|
+
class AsfGuid {
|
|
17
|
+
static fromBin(bin, offset = 0) {
|
|
18
|
+
return new AsfGuid(AsfGuid.decode(bin, offset));
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Decode GUID in format like "B503BF5F-2EA9-CF11-8EE3-00C00C205365"
|
|
22
|
+
* @param objectId Binary GUID
|
|
23
|
+
* @param offset Read offset in bytes, default 0
|
|
24
|
+
* @returns GUID as dashed hexadecimal representation
|
|
25
|
+
*/
|
|
26
|
+
static decode(objectId, offset = 0) {
|
|
27
|
+
return new Guid(objectId.subarray(offset, offset + 16)).toString();
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Decode stream type
|
|
31
|
+
* @param mediaType Media type GUID
|
|
32
|
+
* @returns Media type
|
|
33
|
+
*/
|
|
34
|
+
static decodeMediaType(mediaType) {
|
|
35
|
+
switch (mediaType.str) {
|
|
36
|
+
case AsfGuid.AudioMedia.str: return 'audio';
|
|
37
|
+
case AsfGuid.VideoMedia.str: return 'video';
|
|
38
|
+
case AsfGuid.CommandMedia.str: return 'command';
|
|
39
|
+
case AsfGuid.Degradable_JPEG_Media.str: return 'degradable-jpeg';
|
|
40
|
+
case AsfGuid.FileTransferMedia.str: return 'file-transfer';
|
|
41
|
+
case AsfGuid.BinaryMedia.str: return 'binary';
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Encode GUID
|
|
46
|
+
* @param guid GUID like: "B503BF5F-2EA9-CF11-8EE3-00C00C205365"
|
|
47
|
+
* @returns Encoded Binary GUID
|
|
48
|
+
*/
|
|
49
|
+
static encode(guid) {
|
|
50
|
+
return parseWindowsGuid(guid);
|
|
51
|
+
}
|
|
52
|
+
constructor(str) {
|
|
53
|
+
this.str = str;
|
|
54
|
+
}
|
|
55
|
+
equals(guid) {
|
|
56
|
+
return this.str === guid.str;
|
|
57
|
+
}
|
|
58
|
+
toBin() {
|
|
59
|
+
return AsfGuid.encode(this.str);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// 10.1 Top-level ASF object GUIDs
|
|
63
|
+
AsfGuid.HeaderObject = new AsfGuid("75B22630-668E-11CF-A6D9-00AA0062CE6C");
|
|
64
|
+
AsfGuid.DataObject = new AsfGuid("75B22636-668E-11CF-A6D9-00AA0062CE6C");
|
|
65
|
+
AsfGuid.SimpleIndexObject = new AsfGuid("33000890-E5B1-11CF-89F4-00A0C90349CB");
|
|
66
|
+
AsfGuid.IndexObject = new AsfGuid("D6E229D3-35DA-11D1-9034-00A0C90349BE");
|
|
67
|
+
AsfGuid.MediaObjectIndexObject = new AsfGuid("FEB103F8-12AD-4C64-840F-2A1D2F7AD48C");
|
|
68
|
+
AsfGuid.TimecodeIndexObject = new AsfGuid("3CB73FD0-0C4A-4803-953D-EDF7B6228F0C");
|
|
69
|
+
// 10.2 Header Object GUIDs
|
|
70
|
+
AsfGuid.FilePropertiesObject = new AsfGuid("8CABDCA1-A947-11CF-8EE4-00C00C205365");
|
|
71
|
+
AsfGuid.StreamPropertiesObject = new AsfGuid("B7DC0791-A9B7-11CF-8EE6-00C00C205365");
|
|
72
|
+
AsfGuid.HeaderExtensionObject = new AsfGuid("5FBF03B5-A92E-11CF-8EE3-00C00C205365");
|
|
73
|
+
AsfGuid.CodecListObject = new AsfGuid("86D15240-311D-11D0-A3A4-00A0C90348F6");
|
|
74
|
+
AsfGuid.ScriptCommandObject = new AsfGuid("1EFB1A30-0B62-11D0-A39B-00A0C90348F6");
|
|
75
|
+
AsfGuid.MarkerObject = new AsfGuid("F487CD01-A951-11CF-8EE6-00C00C205365");
|
|
76
|
+
AsfGuid.BitrateMutualExclusionObject = new AsfGuid("D6E229DC-35DA-11D1-9034-00A0C90349BE");
|
|
77
|
+
AsfGuid.ErrorCorrectionObject = new AsfGuid("75B22635-668E-11CF-A6D9-00AA0062CE6C");
|
|
78
|
+
AsfGuid.ContentDescriptionObject = new AsfGuid("75B22633-668E-11CF-A6D9-00AA0062CE6C");
|
|
79
|
+
AsfGuid.ExtendedContentDescriptionObject = new AsfGuid("D2D0A440-E307-11D2-97F0-00A0C95EA850");
|
|
80
|
+
AsfGuid.ContentBrandingObject = new AsfGuid("2211B3FA-BD23-11D2-B4B7-00A0C955FC6E");
|
|
81
|
+
AsfGuid.StreamBitratePropertiesObject = new AsfGuid("7BF875CE-468D-11D1-8D82-006097C9A2B2");
|
|
82
|
+
AsfGuid.ContentEncryptionObject = new AsfGuid("2211B3FB-BD23-11D2-B4B7-00A0C955FC6E");
|
|
83
|
+
AsfGuid.ExtendedContentEncryptionObject = new AsfGuid("298AE614-2622-4C17-B935-DAE07EE9289C");
|
|
84
|
+
AsfGuid.DigitalSignatureObject = new AsfGuid("2211B3FC-BD23-11D2-B4B7-00A0C955FC6E");
|
|
85
|
+
AsfGuid.PaddingObject = new AsfGuid("1806D474-CADF-4509-A4BA-9AABCB96AAE8");
|
|
86
|
+
// 10.3 Header Extension Object GUIDs
|
|
87
|
+
AsfGuid.ExtendedStreamPropertiesObject = new AsfGuid("14E6A5CB-C672-4332-8399-A96952065B5A");
|
|
88
|
+
AsfGuid.AdvancedMutualExclusionObject = new AsfGuid("A08649CF-4775-4670-8A16-6E35357566CD");
|
|
89
|
+
AsfGuid.GroupMutualExclusionObject = new AsfGuid("D1465A40-5A79-4338-B71B-E36B8FD6C249");
|
|
90
|
+
AsfGuid.StreamPrioritizationObject = new AsfGuid("D4FED15B-88D3-454F-81F0-ED5C45999E24");
|
|
91
|
+
AsfGuid.BandwidthSharingObject = new AsfGuid("A69609E6-517B-11D2-B6AF-00C04FD908E9");
|
|
92
|
+
AsfGuid.LanguageListObject = new AsfGuid("7C4346A9-EFE0-4BFC-B229-393EDE415C85");
|
|
93
|
+
AsfGuid.MetadataObject = new AsfGuid("C5F8CBEA-5BAF-4877-8467-AA8C44FA4CCA");
|
|
94
|
+
AsfGuid.MetadataLibraryObject = new AsfGuid("44231C94-9498-49D1-A141-1D134E457054");
|
|
95
|
+
AsfGuid.IndexParametersObject = new AsfGuid("D6E229DF-35DA-11D1-9034-00A0C90349BE");
|
|
96
|
+
AsfGuid.MediaObjectIndexParametersObject = new AsfGuid("6B203BAD-3F11-48E4-ACA8-D7613DE2CFA7");
|
|
97
|
+
AsfGuid.TimecodeIndexParametersObject = new AsfGuid("F55E496D-9797-4B5D-8C8B-604DFE9BFB24");
|
|
98
|
+
AsfGuid.CompatibilityObject = new AsfGuid("26F18B5D-4584-47EC-9F5F-0E651F0452C9");
|
|
99
|
+
AsfGuid.AdvancedContentEncryptionObject = new AsfGuid("43058533-6981-49E6-9B74-AD12CB86D58C");
|
|
100
|
+
// 10.4 Stream Properties Object Stream Type GUIDs
|
|
101
|
+
AsfGuid.AudioMedia = new AsfGuid("F8699E40-5B4D-11CF-A8FD-00805F5C442B");
|
|
102
|
+
AsfGuid.VideoMedia = new AsfGuid("BC19EFC0-5B4D-11CF-A8FD-00805F5C442B");
|
|
103
|
+
AsfGuid.CommandMedia = new AsfGuid("59DACFC0-59E6-11D0-A3AC-00A0C90348F6");
|
|
104
|
+
AsfGuid.JFIF_Media = new AsfGuid("B61BE100-5B4E-11CF-A8FD-00805F5C442B");
|
|
105
|
+
AsfGuid.Degradable_JPEG_Media = new AsfGuid("35907DE0-E415-11CF-A917-00805F5C442B");
|
|
106
|
+
AsfGuid.FileTransferMedia = new AsfGuid("91BD222C-F21C-497A-8B6D-5AA86BFC0185");
|
|
107
|
+
AsfGuid.BinaryMedia = new AsfGuid("3AFB65E2-47EF-40F2-AC2C-70A90D71D343");
|
|
108
|
+
AsfGuid.ASF_Index_Placeholder_Object = new AsfGuid("D9AADE20-7C17-4F9C-BC28-8555DD98E2A2");
|
|
109
|
+
export default AsfGuid;
|
package/lib/asf/AsfObject.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { IGetToken, ITokenizer } from 'strtok3';
|
|
2
2
|
import type { AnyTagValue, IPicture, ITag } from '../type.js';
|
|
3
|
-
import
|
|
3
|
+
import AsfGuid from './AsfGuid.js';
|
|
4
4
|
declare const AsfContentParseError_base: {
|
|
5
5
|
new (message: string): {
|
|
6
6
|
readonly fileType: string;
|
|
@@ -52,7 +52,7 @@ export interface IAsfObjectHeader {
|
|
|
52
52
|
/**
|
|
53
53
|
* A GUID that identifies the object. 128 bits
|
|
54
54
|
*/
|
|
55
|
-
objectId:
|
|
55
|
+
objectId: AsfGuid;
|
|
56
56
|
/**
|
|
57
57
|
* The size of the object (64-bits)
|
|
58
58
|
*/
|
|
@@ -95,7 +95,7 @@ export interface IFilePropertiesObject {
|
|
|
95
95
|
* The value of this field shall be regenerated every time the file is modified in any way.
|
|
96
96
|
* The value of this field shall be identical to the value of the File ID field of the Data Object.
|
|
97
97
|
*/
|
|
98
|
-
fileId:
|
|
98
|
+
fileId: AsfGuid;
|
|
99
99
|
/**
|
|
100
100
|
* Specifies the size, in bytes, of the entire file.
|
|
101
101
|
* The value of this field is invalid if the Broadcast Flag bit in the Flags field is set to 1.
|
|
@@ -186,7 +186,7 @@ export interface IFilePropertiesObject {
|
|
|
186
186
|
* Ref: http://drang.s4.xrea.com/program/tips/id3tag/wmp/03_asf_top_level_header_object.html#3_2
|
|
187
187
|
*/
|
|
188
188
|
export declare class FilePropertiesObject extends State<IFilePropertiesObject> {
|
|
189
|
-
static guid:
|
|
189
|
+
static guid: AsfGuid;
|
|
190
190
|
get(buf: Uint8Array, off: number): IFilePropertiesObject;
|
|
191
191
|
}
|
|
192
192
|
/**
|
|
@@ -200,18 +200,18 @@ export interface IStreamPropertiesObject {
|
|
|
200
200
|
/**
|
|
201
201
|
* Error Correction Type
|
|
202
202
|
*/
|
|
203
|
-
errorCorrectionType:
|
|
203
|
+
errorCorrectionType: AsfGuid;
|
|
204
204
|
}
|
|
205
205
|
/**
|
|
206
206
|
* Token for: 3.3 Stream Properties Object (mandatory, one per stream)
|
|
207
207
|
* Ref: http://drang.s4.xrea.com/program/tips/id3tag/wmp/03_asf_top_level_header_object.html#3_3
|
|
208
208
|
*/
|
|
209
209
|
export declare class StreamPropertiesObject extends State<IStreamPropertiesObject> {
|
|
210
|
-
static guid:
|
|
210
|
+
static guid: AsfGuid;
|
|
211
211
|
get(buf: Uint8Array, off: number): IStreamPropertiesObject;
|
|
212
212
|
}
|
|
213
213
|
export interface IHeaderExtensionObject {
|
|
214
|
-
reserved1:
|
|
214
|
+
reserved1: AsfGuid;
|
|
215
215
|
reserved2: number;
|
|
216
216
|
extensionDataSize: number;
|
|
217
217
|
}
|
|
@@ -220,7 +220,7 @@ export interface IHeaderExtensionObject {
|
|
|
220
220
|
* Ref: http://drang.s4.xrea.com/program/tips/id3tag/wmp/03_asf_top_level_header_object.html#3_4
|
|
221
221
|
*/
|
|
222
222
|
export declare class HeaderExtensionObject implements IGetToken<IHeaderExtensionObject> {
|
|
223
|
-
static guid:
|
|
223
|
+
static guid: AsfGuid;
|
|
224
224
|
len: number;
|
|
225
225
|
constructor();
|
|
226
226
|
get(buf: Uint8Array, off: number): IHeaderExtensionObject;
|
|
@@ -244,7 +244,7 @@ export declare function readCodecEntries(tokenizer: ITokenizer): Promise<ICodecE
|
|
|
244
244
|
* Ref: http://drang.s4.xrea.com/program/tips/id3tag/wmp/03_asf_top_level_header_object.html#3_10
|
|
245
245
|
*/
|
|
246
246
|
export declare class ContentDescriptionObjectState extends State<ITag[]> {
|
|
247
|
-
static guid:
|
|
247
|
+
static guid: AsfGuid;
|
|
248
248
|
private static contentDescTags;
|
|
249
249
|
get(buf: Uint8Array, off: number): ITag[];
|
|
250
250
|
}
|
|
@@ -253,7 +253,7 @@ export declare class ContentDescriptionObjectState extends State<ITag[]> {
|
|
|
253
253
|
* Ref: http://drang.s4.xrea.com/program/tips/id3tag/wmp/03_asf_top_level_header_object.html#3_11
|
|
254
254
|
*/
|
|
255
255
|
export declare class ExtendedContentDescriptionObjectState extends State<ITag[]> {
|
|
256
|
-
static guid:
|
|
256
|
+
static guid: AsfGuid;
|
|
257
257
|
get(buf: Uint8Array, off: number): ITag[];
|
|
258
258
|
}
|
|
259
259
|
export interface IStreamName {
|
|
@@ -292,7 +292,7 @@ export interface IExtendedStreamPropertiesObject {
|
|
|
292
292
|
* Ref: http://drang.s4.xrea.com/program/tips/id3tag/wmp/04_objects_in_the_asf_header_extension_object.html#4_1
|
|
293
293
|
*/
|
|
294
294
|
export declare class ExtendedStreamPropertiesObjectState extends State<IExtendedStreamPropertiesObject> {
|
|
295
|
-
static guid:
|
|
295
|
+
static guid: AsfGuid;
|
|
296
296
|
get(buf: Uint8Array, off: number): IExtendedStreamPropertiesObject;
|
|
297
297
|
}
|
|
298
298
|
/**
|
|
@@ -300,11 +300,11 @@ export declare class ExtendedStreamPropertiesObjectState extends State<IExtended
|
|
|
300
300
|
* Ref: http://drang.s4.xrea.com/program/tips/id3tag/wmp/04_objects_in_the_asf_header_extension_object.html#4_7
|
|
301
301
|
*/
|
|
302
302
|
export declare class MetadataObjectState extends State<ITag[]> {
|
|
303
|
-
static guid:
|
|
303
|
+
static guid: AsfGuid;
|
|
304
304
|
get(uint8Array: Uint8Array, off: number): ITag[];
|
|
305
305
|
}
|
|
306
306
|
export declare class MetadataLibraryObjectState extends MetadataObjectState {
|
|
307
|
-
static guid:
|
|
307
|
+
static guid: AsfGuid;
|
|
308
308
|
}
|
|
309
309
|
export interface IWmPicture extends IPicture {
|
|
310
310
|
type: string;
|
package/lib/asf/AsfObject.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// ASF Objects
|
|
2
2
|
import * as Token from 'token-types';
|
|
3
3
|
import * as util from '../common/Util.js';
|
|
4
|
-
import
|
|
4
|
+
import AsfGuid from './AsfGuid.js';
|
|
5
5
|
import { getParserForAttr, parseUnicodeAttr } from './AsfUtil.js';
|
|
6
6
|
import { AttachedPictureType } from '../id3v2/ID3v2Token.js';
|
|
7
7
|
import { makeUnexpectedFileContentError } from '../ParseError.js';
|
|
@@ -44,7 +44,7 @@ export const TopLevelHeaderObjectToken = {
|
|
|
44
44
|
len: 30,
|
|
45
45
|
get: (buf, off) => {
|
|
46
46
|
return {
|
|
47
|
-
objectId:
|
|
47
|
+
objectId: AsfGuid.fromBin(buf, off),
|
|
48
48
|
objectSize: Number(Token.UINT64_LE.get(buf, off + 16)),
|
|
49
49
|
numberOfHeaderObjects: Token.UINT32_LE.get(buf, off + 24)
|
|
50
50
|
// Reserved: 2 bytes
|
|
@@ -59,7 +59,7 @@ export const HeaderObjectToken = {
|
|
|
59
59
|
len: 24,
|
|
60
60
|
get: (buf, off) => {
|
|
61
61
|
return {
|
|
62
|
-
objectId:
|
|
62
|
+
objectId: AsfGuid.fromBin(buf, off),
|
|
63
63
|
objectSize: Number(Token.UINT64_LE.get(buf, off + 16))
|
|
64
64
|
};
|
|
65
65
|
}
|
|
@@ -94,7 +94,7 @@ export class IgnoreObjectState extends State {
|
|
|
94
94
|
export class FilePropertiesObject extends State {
|
|
95
95
|
get(buf, off) {
|
|
96
96
|
return {
|
|
97
|
-
fileId:
|
|
97
|
+
fileId: AsfGuid.fromBin(buf, off),
|
|
98
98
|
fileSize: Token.UINT64_LE.get(buf, off + 16),
|
|
99
99
|
creationDate: Token.UINT64_LE.get(buf, off + 24),
|
|
100
100
|
dataPacketsCount: Token.UINT64_LE.get(buf, off + 32),
|
|
@@ -112,7 +112,7 @@ export class FilePropertiesObject extends State {
|
|
|
112
112
|
};
|
|
113
113
|
}
|
|
114
114
|
}
|
|
115
|
-
FilePropertiesObject.guid =
|
|
115
|
+
FilePropertiesObject.guid = AsfGuid.FilePropertiesObject;
|
|
116
116
|
/**
|
|
117
117
|
* Token for: 3.3 Stream Properties Object (mandatory, one per stream)
|
|
118
118
|
* Ref: http://drang.s4.xrea.com/program/tips/id3tag/wmp/03_asf_top_level_header_object.html#3_3
|
|
@@ -120,13 +120,13 @@ FilePropertiesObject.guid = GUID.FilePropertiesObject;
|
|
|
120
120
|
export class StreamPropertiesObject extends State {
|
|
121
121
|
get(buf, off) {
|
|
122
122
|
return {
|
|
123
|
-
streamType:
|
|
124
|
-
errorCorrectionType:
|
|
123
|
+
streamType: AsfGuid.decodeMediaType(AsfGuid.fromBin(buf, off)),
|
|
124
|
+
errorCorrectionType: AsfGuid.fromBin(buf, off + 8)
|
|
125
125
|
// ToDo
|
|
126
126
|
};
|
|
127
127
|
}
|
|
128
128
|
}
|
|
129
|
-
StreamPropertiesObject.guid =
|
|
129
|
+
StreamPropertiesObject.guid = AsfGuid.StreamPropertiesObject;
|
|
130
130
|
/**
|
|
131
131
|
* 3.4: Header Extension Object (mandatory, one only)
|
|
132
132
|
* Ref: http://drang.s4.xrea.com/program/tips/id3tag/wmp/03_asf_top_level_header_object.html#3_4
|
|
@@ -138,13 +138,13 @@ export class HeaderExtensionObject {
|
|
|
138
138
|
get(buf, off) {
|
|
139
139
|
const view = new DataView(buf.buffer, off);
|
|
140
140
|
return {
|
|
141
|
-
reserved1:
|
|
141
|
+
reserved1: AsfGuid.fromBin(buf, off),
|
|
142
142
|
reserved2: view.getUint16(16, true),
|
|
143
143
|
extensionDataSize: view.getUint16(18, true)
|
|
144
144
|
};
|
|
145
145
|
}
|
|
146
146
|
}
|
|
147
|
-
HeaderExtensionObject.guid =
|
|
147
|
+
HeaderExtensionObject.guid = AsfGuid.HeaderExtensionObject;
|
|
148
148
|
/**
|
|
149
149
|
* 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.
|
|
150
150
|
* Ref: http://drang.s4.xrea.com/program/tips/id3tag/wmp/03_asf_top_level_header_object.html#3_5
|
|
@@ -217,7 +217,7 @@ export class ContentDescriptionObjectState extends State {
|
|
|
217
217
|
return tags;
|
|
218
218
|
}
|
|
219
219
|
}
|
|
220
|
-
ContentDescriptionObjectState.guid =
|
|
220
|
+
ContentDescriptionObjectState.guid = AsfGuid.ContentDescriptionObject;
|
|
221
221
|
ContentDescriptionObjectState.contentDescTags = ['Title', 'Author', 'Copyright', 'Description', 'Rating'];
|
|
222
222
|
/**
|
|
223
223
|
* 3.11 Extended Content Description Object (optional, one only)
|
|
@@ -245,7 +245,7 @@ export class ExtendedContentDescriptionObjectState extends State {
|
|
|
245
245
|
return tags;
|
|
246
246
|
}
|
|
247
247
|
}
|
|
248
|
-
ExtendedContentDescriptionObjectState.guid =
|
|
248
|
+
ExtendedContentDescriptionObjectState.guid = AsfGuid.ExtendedContentDescriptionObject;
|
|
249
249
|
/**
|
|
250
250
|
* 4.1 Extended Stream Properties Object (optional, 1 per media stream)
|
|
251
251
|
* Ref: http://drang.s4.xrea.com/program/tips/id3tag/wmp/04_objects_in_the_asf_header_extension_object.html#4_1
|
|
@@ -279,7 +279,7 @@ export class ExtendedStreamPropertiesObjectState extends State {
|
|
|
279
279
|
};
|
|
280
280
|
}
|
|
281
281
|
}
|
|
282
|
-
ExtendedStreamPropertiesObjectState.guid =
|
|
282
|
+
ExtendedStreamPropertiesObjectState.guid = AsfGuid.ExtendedStreamPropertiesObject;
|
|
283
283
|
/**
|
|
284
284
|
* 4.7 Metadata Object (optional, 0 or 1)
|
|
285
285
|
* Ref: http://drang.s4.xrea.com/program/tips/id3tag/wmp/04_objects_in_the_asf_header_extension_object.html#4_7
|
|
@@ -307,11 +307,11 @@ export class MetadataObjectState extends State {
|
|
|
307
307
|
return tags;
|
|
308
308
|
}
|
|
309
309
|
}
|
|
310
|
-
MetadataObjectState.guid =
|
|
310
|
+
MetadataObjectState.guid = AsfGuid.MetadataObject;
|
|
311
311
|
// 4.8 Metadata Library Object (optional, 0 or 1)
|
|
312
312
|
export class MetadataLibraryObjectState extends MetadataObjectState {
|
|
313
313
|
}
|
|
314
|
-
MetadataLibraryObjectState.guid =
|
|
314
|
+
MetadataLibraryObjectState.guid = AsfGuid.MetadataLibraryObject;
|
|
315
315
|
/**
|
|
316
316
|
* Ref: https://msdn.microsoft.com/en-us/library/windows/desktop/dd757977(v=vs.85).aspx
|
|
317
317
|
*/
|
package/lib/asf/AsfParser.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import initDebug from 'debug';
|
|
2
2
|
import { TrackType } from '../type.js';
|
|
3
|
-
import
|
|
3
|
+
import AsfGuid from './AsfGuid.js';
|
|
4
4
|
import * as AsfObject from './AsfObject.js';
|
|
5
5
|
import { BasicParser } from '../common/BasicParser.js';
|
|
6
6
|
import { AsfContentParseError } from './AsfObject.js';
|
|
@@ -19,7 +19,7 @@ const headerType = 'asf';
|
|
|
19
19
|
export class AsfParser extends BasicParser {
|
|
20
20
|
async parse() {
|
|
21
21
|
const header = await this.tokenizer.readToken(AsfObject.TopLevelHeaderObjectToken);
|
|
22
|
-
if (!header.objectId.equals(
|
|
22
|
+
if (!header.objectId.equals(AsfGuid.HeaderObject)) {
|
|
23
23
|
throw new AsfContentParseError(`expected asf header; but was not found; got: ${header.objectId.str}`);
|
|
24
24
|
}
|
|
25
25
|
try {
|
|
@@ -61,7 +61,7 @@ export class AsfParser extends BasicParser {
|
|
|
61
61
|
tags = await this.tokenizer.readToken(new AsfObject.ExtendedContentDescriptionObjectState(header));
|
|
62
62
|
await this.addTags(tags);
|
|
63
63
|
break;
|
|
64
|
-
case
|
|
64
|
+
case AsfGuid.CodecListObject.str: {
|
|
65
65
|
const codecs = await AsfObject.readCodecEntries(this.tokenizer);
|
|
66
66
|
codecs.forEach(codec => {
|
|
67
67
|
this.metadata.addStreamInfo({
|
|
@@ -73,11 +73,11 @@ export class AsfParser extends BasicParser {
|
|
|
73
73
|
this.metadata.setFormat('codec', audioCodecs);
|
|
74
74
|
break;
|
|
75
75
|
}
|
|
76
|
-
case
|
|
76
|
+
case AsfGuid.StreamBitratePropertiesObject.str:
|
|
77
77
|
// ToDo?
|
|
78
78
|
await this.tokenizer.ignore(header.objectSize - AsfObject.HeaderObjectToken.len);
|
|
79
79
|
break;
|
|
80
|
-
case
|
|
80
|
+
case AsfGuid.PaddingObject.str:
|
|
81
81
|
// ToDo: register bytes pad
|
|
82
82
|
debug('Padding: %s bytes', header.objectSize - AsfObject.HeaderObjectToken.len);
|
|
83
83
|
await this.tokenizer.ignore(header.objectSize - AsfObject.HeaderObjectToken.len);
|
|
@@ -114,14 +114,14 @@ export class AsfParser extends BasicParser {
|
|
|
114
114
|
await this.addTags(mlTags);
|
|
115
115
|
break;
|
|
116
116
|
}
|
|
117
|
-
case
|
|
117
|
+
case AsfGuid.PaddingObject.str:
|
|
118
118
|
// ToDo: register bytes pad
|
|
119
119
|
await this.tokenizer.ignore(remaining);
|
|
120
120
|
break;
|
|
121
|
-
case
|
|
121
|
+
case AsfGuid.CompatibilityObject.str:
|
|
122
122
|
await this.tokenizer.ignore(remaining);
|
|
123
123
|
break;
|
|
124
|
-
case
|
|
124
|
+
case AsfGuid.ASF_Index_Placeholder_Object.str:
|
|
125
125
|
await this.tokenizer.ignore(remaining);
|
|
126
126
|
break;
|
|
127
127
|
default:
|
package/lib/common/Util.d.ts
CHANGED
|
@@ -2,14 +2,12 @@ import type { IRatio } from '../type.js';
|
|
|
2
2
|
export type StringEncoding = 'ascii' | 'utf8' | 'utf-16le' | 'ucs2' | 'base64url' | 'latin1' | 'hex';
|
|
3
3
|
export declare function getBit(buf: Uint8Array, off: number, bit: number): boolean;
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
5
|
+
* Find delimiting zero in uint8Array
|
|
6
6
|
* @param uint8Array Uint8Array to find the zero delimiter in
|
|
7
|
-
* @param start Offset in uint8Array
|
|
8
|
-
* @param end Last position to parse in uint8Array
|
|
9
7
|
* @param encoding The string encoding used
|
|
10
|
-
* @return
|
|
8
|
+
* @return position in uint8Array where zero found, or uint8Array.length if not found
|
|
11
9
|
*/
|
|
12
|
-
export declare function findZero(uint8Array: Uint8Array,
|
|
10
|
+
export declare function findZero(uint8Array: Uint8Array, encoding?: StringEncoding): number;
|
|
13
11
|
export declare function trimRightNull(x: string): string;
|
|
14
12
|
/**
|
|
15
13
|
* Decode string
|
package/lib/common/Util.js
CHANGED
|
@@ -5,33 +5,31 @@ export function getBit(buf, off, bit) {
|
|
|
5
5
|
return (buf[off] & (1 << bit)) !== 0;
|
|
6
6
|
}
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
8
|
+
* Find delimiting zero in uint8Array
|
|
9
9
|
* @param uint8Array Uint8Array to find the zero delimiter in
|
|
10
|
-
* @param start Offset in uint8Array
|
|
11
|
-
* @param end Last position to parse in uint8Array
|
|
12
10
|
* @param encoding The string encoding used
|
|
13
|
-
* @return
|
|
11
|
+
* @return position in uint8Array where zero found, or uint8Array.length if not found
|
|
14
12
|
*/
|
|
15
|
-
export function findZero(uint8Array,
|
|
16
|
-
|
|
13
|
+
export function findZero(uint8Array, encoding) {
|
|
14
|
+
const len = uint8Array.length;
|
|
17
15
|
if (encoding === 'utf-16le') {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
16
|
+
// Look for 0x00 0x00 on 2-byte boundary
|
|
17
|
+
for (let i = 0; i + 1 < len; i += 2) {
|
|
18
|
+
if (uint8Array[i] === 0 && uint8Array[i + 1] === 0)
|
|
19
|
+
return i;
|
|
22
20
|
}
|
|
23
|
-
return
|
|
21
|
+
return len;
|
|
24
22
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
23
|
+
// latin1 / utf8 / utf16be (caller typically handles utf16be separately or via decode)
|
|
24
|
+
for (let i = 0; i < len; i++) {
|
|
25
|
+
if (uint8Array[i] === 0)
|
|
26
|
+
return i;
|
|
29
27
|
}
|
|
30
|
-
return
|
|
28
|
+
return len;
|
|
31
29
|
}
|
|
32
30
|
export function trimRightNull(x) {
|
|
33
31
|
const pos0 = x.indexOf('\0');
|
|
34
|
-
return pos0 === -1 ? x : x.
|
|
32
|
+
return pos0 === -1 ? x : x.substring(0, pos0);
|
|
35
33
|
}
|
|
36
34
|
function swapBytes(uint8Array) {
|
|
37
35
|
const l = uint8Array.length;
|
package/lib/ebml/EbmlIterator.js
CHANGED
|
@@ -27,7 +27,6 @@ export class EbmlIterator {
|
|
|
27
27
|
* @param tokenizer
|
|
28
28
|
*/
|
|
29
29
|
constructor(tokenizer) {
|
|
30
|
-
this.padding = 0;
|
|
31
30
|
this.parserMap = new Map();
|
|
32
31
|
this.ebmlMaxIDLength = 4;
|
|
33
32
|
this.ebmlMaxSizeLength = 8;
|
|
@@ -110,12 +109,10 @@ export class EbmlIterator {
|
|
|
110
109
|
else {
|
|
111
110
|
switch (element.id) {
|
|
112
111
|
case 0xec: // void
|
|
113
|
-
this.padding += element.len;
|
|
114
112
|
await this.tokenizer.ignore(element.len);
|
|
115
113
|
break;
|
|
116
114
|
default:
|
|
117
115
|
debug(`parseEbml: parent=${getElementPath(dtdElement)}, unknown child: id=${element.id.toString(16)} at position=${elementPosition}`);
|
|
118
|
-
this.padding += element.len;
|
|
119
116
|
await this.tokenizer.ignore(element.len);
|
|
120
117
|
}
|
|
121
118
|
}
|
|
@@ -203,7 +200,7 @@ function linkParents(element) {
|
|
|
203
200
|
Object.keys(element.container)
|
|
204
201
|
.map(id => {
|
|
205
202
|
const child = element.container[id];
|
|
206
|
-
child.id = Number.parseInt(id);
|
|
203
|
+
child.id = Number.parseInt(id, 10);
|
|
207
204
|
return child;
|
|
208
205
|
}).forEach(child => {
|
|
209
206
|
child.parent = element;
|
package/lib/flac/FlacParser.d.ts
CHANGED
|
@@ -3,7 +3,6 @@ import { AbstractID3Parser } from '../id3v2/AbstractID3Parser.js';
|
|
|
3
3
|
import type { IBlockStreamInfo } from './FlacToken.js';
|
|
4
4
|
export declare class FlacParser extends AbstractID3Parser {
|
|
5
5
|
private vorbisParser;
|
|
6
|
-
private padding;
|
|
7
6
|
postId3v2Parse(): Promise<void>;
|
|
8
7
|
private parseDataBlock;
|
|
9
8
|
/**
|
package/lib/flac/FlacParser.js
CHANGED
|
@@ -14,7 +14,6 @@ export class FlacParser extends AbstractID3Parser {
|
|
|
14
14
|
constructor() {
|
|
15
15
|
super(...arguments);
|
|
16
16
|
this.vorbisParser = new VorbisStream(this.metadata, this.options);
|
|
17
|
-
this.padding = 0;
|
|
18
17
|
}
|
|
19
18
|
async postId3v2Parse() {
|
|
20
19
|
const fourCC = await this.tokenizer.readToken(FourCcToken);
|
|
@@ -39,7 +38,6 @@ export class FlacParser extends AbstractID3Parser {
|
|
|
39
38
|
case Flac.BlockType.STREAMINFO:
|
|
40
39
|
return this.readBlockStreamInfo(blockHeader.length);
|
|
41
40
|
case Flac.BlockType.PADDING:
|
|
42
|
-
this.padding += blockHeader.length;
|
|
43
41
|
break;
|
|
44
42
|
case Flac.BlockType.APPLICATION:
|
|
45
43
|
break;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type ID3v2MajorVersion } from './ID3v2Token.js';
|
|
2
|
+
import type { IWarningCollector } from '../common/MetadataCollector.js';
|
|
3
|
+
export interface IFrameFlags {
|
|
4
|
+
status: {
|
|
5
|
+
tag_alter_preservation: boolean;
|
|
6
|
+
file_alter_preservation: boolean;
|
|
7
|
+
read_only: boolean;
|
|
8
|
+
};
|
|
9
|
+
format: {
|
|
10
|
+
grouping_identity: boolean;
|
|
11
|
+
compression: boolean;
|
|
12
|
+
encryption: boolean;
|
|
13
|
+
unsynchronisation: boolean;
|
|
14
|
+
data_length_indicator: boolean;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export interface IFrameHeader {
|
|
18
|
+
id: string;
|
|
19
|
+
length: number;
|
|
20
|
+
flags?: IFrameFlags;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Frame header length (bytes) depending on ID3v2 major version.
|
|
24
|
+
*/
|
|
25
|
+
export declare function getFrameHeaderLength(majorVer: number): 6 | 10;
|
|
26
|
+
/**
|
|
27
|
+
* Factory: parse a frame header from its header bytes (6 for v2.2, 10 for v2.3/v2.4).
|
|
28
|
+
*
|
|
29
|
+
* Note: It only *parses* and does light validation. It does not read payload bytes.
|
|
30
|
+
*/
|
|
31
|
+
export declare function readFrameHeader(uint8Array: Uint8Array, majorVer: ID3v2MajorVersion, warningCollector: IWarningCollector): IFrameHeader;
|