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.
@@ -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, 0, keyBuffer.length);
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, 0, picData.length);
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;
@@ -1,6 +1,6 @@
1
1
  import type { IGetToken, ITokenizer } from 'strtok3';
2
2
  import type { AnyTagValue, IPicture, ITag } from '../type.js';
3
- import GUID from './GUID.js';
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: GUID;
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: GUID;
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: 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: GUID;
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: GUID;
210
+ static guid: AsfGuid;
211
211
  get(buf: Uint8Array, off: number): IStreamPropertiesObject;
212
212
  }
213
213
  export interface IHeaderExtensionObject {
214
- reserved1: GUID;
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: 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: 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: 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: 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: 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: GUID;
307
+ static guid: AsfGuid;
308
308
  }
309
309
  export interface IWmPicture extends IPicture {
310
310
  type: string;
@@ -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 GUID from './GUID.js';
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: GUID.fromBin(buf, off),
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: GUID.fromBin(buf, off),
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: GUID.fromBin(buf, off),
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 = GUID.FilePropertiesObject;
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: GUID.decodeMediaType(GUID.fromBin(buf, off)),
124
- errorCorrectionType: GUID.fromBin(buf, off + 8)
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 = GUID.StreamPropertiesObject;
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: GUID.fromBin(buf, off),
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 = GUID.HeaderExtensionObject;
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 = GUID.ContentDescriptionObject;
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 = GUID.ExtendedContentDescriptionObject;
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 = GUID.ExtendedStreamPropertiesObject;
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 = GUID.MetadataObject;
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 = GUID.MetadataLibraryObject;
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
  */
@@ -1,6 +1,6 @@
1
1
  import initDebug from 'debug';
2
2
  import { TrackType } from '../type.js';
3
- import GUID from './GUID.js';
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(GUID.HeaderObject)) {
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 GUID.CodecListObject.str: {
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 GUID.StreamBitratePropertiesObject.str:
76
+ case AsfGuid.StreamBitratePropertiesObject.str:
77
77
  // ToDo?
78
78
  await this.tokenizer.ignore(header.objectSize - AsfObject.HeaderObjectToken.len);
79
79
  break;
80
- case GUID.PaddingObject.str:
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 GUID.PaddingObject.str:
117
+ case AsfGuid.PaddingObject.str:
118
118
  // ToDo: register bytes pad
119
119
  await this.tokenizer.ignore(remaining);
120
120
  break;
121
- case GUID.CompatibilityObject.str:
121
+ case AsfGuid.CompatibilityObject.str:
122
122
  await this.tokenizer.ignore(remaining);
123
123
  break;
124
- case GUID.ASF_Index_Placeholder_Object.str:
124
+ case AsfGuid.ASF_Index_Placeholder_Object.str:
125
125
  await this.tokenizer.ignore(remaining);
126
126
  break;
127
127
  default:
@@ -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
- * Found delimiting zero in uint8Array
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 Absolute position on uint8Array where zero found
8
+ * @return position in uint8Array where zero found, or uint8Array.length if not found
11
9
  */
12
- export declare function findZero(uint8Array: Uint8Array, start: number, end: number, encoding?: StringEncoding): number;
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
@@ -5,33 +5,31 @@ export function getBit(buf, off, bit) {
5
5
  return (buf[off] & (1 << bit)) !== 0;
6
6
  }
7
7
  /**
8
- * Found delimiting zero in uint8Array
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 Absolute position on uint8Array where zero found
11
+ * @return position in uint8Array where zero found, or uint8Array.length if not found
14
12
  */
15
- export function findZero(uint8Array, start, end, encoding) {
16
- let i = start;
13
+ export function findZero(uint8Array, encoding) {
14
+ const len = uint8Array.length;
17
15
  if (encoding === 'utf-16le') {
18
- while (uint8Array[i] !== 0 || uint8Array[i + 1] !== 0) {
19
- if (i >= end)
20
- return end;
21
- i += 2;
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 i;
21
+ return len;
24
22
  }
25
- while (uint8Array[i] !== 0) {
26
- if (i >= end)
27
- return end;
28
- i++;
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 i;
28
+ return len;
31
29
  }
32
30
  export function trimRightNull(x) {
33
31
  const pos0 = x.indexOf('\0');
34
- return pos0 === -1 ? x : x.substr(0, pos0);
32
+ return pos0 === -1 ? x : x.substring(0, pos0);
35
33
  }
36
34
  function swapBytes(uint8Array) {
37
35
  const l = uint8Array.length;
@@ -44,7 +44,6 @@ export type IElementListener = {
44
44
  * WEBM VP8 AUDIO FILE
45
45
  */
46
46
  export declare class EbmlIterator {
47
- private padding;
48
47
  private parserMap;
49
48
  private ebmlMaxIDLength;
50
49
  private ebmlMaxSizeLength;
@@ -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;
@@ -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
  /**
@@ -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;