music-metadata 7.12.1 → 7.12.4

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.
Files changed (155) hide show
  1. package/LICENSE.txt +9 -9
  2. package/README.md +434 -434
  3. package/lib/ParserFactory.d.ts +48 -48
  4. package/lib/ParserFactory.js +252 -252
  5. package/lib/aiff/AiffParser.d.ts +14 -14
  6. package/lib/aiff/AiffParser.js +84 -84
  7. package/lib/aiff/AiffToken.d.ts +22 -22
  8. package/lib/aiff/AiffToken.js +43 -43
  9. package/lib/apev2/APEv2Parser.d.ts +30 -30
  10. package/lib/apev2/APEv2Parser.js +164 -161
  11. package/lib/apev2/APEv2TagMapper.d.ts +4 -4
  12. package/lib/apev2/APEv2TagMapper.js +86 -86
  13. package/lib/apev2/APEv2Token.d.ts +100 -100
  14. package/lib/apev2/APEv2Token.js +126 -126
  15. package/lib/asf/AsfObject.d.ts +319 -319
  16. package/lib/asf/AsfObject.js +381 -381
  17. package/lib/asf/AsfParser.d.ts +17 -17
  18. package/lib/asf/AsfParser.js +135 -135
  19. package/lib/asf/AsfTagMapper.d.ts +7 -7
  20. package/lib/asf/AsfTagMapper.js +95 -95
  21. package/lib/asf/AsfUtil.d.ts +13 -13
  22. package/lib/asf/AsfUtil.js +38 -38
  23. package/lib/asf/GUID.d.ts +84 -84
  24. package/lib/asf/GUID.js +121 -121
  25. package/lib/common/BasicParser.d.ts +17 -17
  26. package/lib/common/BasicParser.js +18 -18
  27. package/lib/common/CaseInsensitiveTagMap.d.ts +10 -10
  28. package/lib/common/CaseInsensitiveTagMap.js +21 -21
  29. package/lib/common/CombinedTagMapper.d.ts +19 -19
  30. package/lib/common/CombinedTagMapper.js +51 -51
  31. package/lib/common/FourCC.d.ts +6 -6
  32. package/lib/common/FourCC.js +28 -28
  33. package/lib/common/GenericTagMapper.d.ts +51 -51
  34. package/lib/common/GenericTagMapper.js +55 -55
  35. package/lib/common/GenericTagTypes.d.ts +33 -33
  36. package/lib/common/GenericTagTypes.js +131 -131
  37. package/lib/common/MetadataCollector.d.ts +76 -76
  38. package/lib/common/MetadataCollector.js +275 -275
  39. package/lib/common/RandomFileReader.d.ts +22 -22
  40. package/lib/common/RandomFileReader.js +34 -34
  41. package/lib/common/RandomUint8ArrayReader.d.ts +18 -18
  42. package/lib/common/RandomUint8ArrayReader.js +25 -25
  43. package/lib/common/Util.d.ts +57 -57
  44. package/lib/common/Util.js +157 -157
  45. package/lib/core.d.ts +48 -48
  46. package/lib/core.js +90 -90
  47. package/lib/dsdiff/DsdiffParser.d.ts +14 -14
  48. package/lib/dsdiff/DsdiffParser.js +143 -143
  49. package/lib/dsdiff/DsdiffToken.d.ts +9 -9
  50. package/lib/dsdiff/DsdiffToken.js +21 -21
  51. package/lib/dsf/DsfChunk.d.ts +86 -86
  52. package/lib/dsf/DsfChunk.js +54 -54
  53. package/lib/dsf/DsfParser.d.ts +9 -9
  54. package/lib/dsf/DsfParser.js +56 -56
  55. package/lib/flac/FlacParser.d.ts +28 -28
  56. package/lib/flac/FlacParser.js +175 -175
  57. package/lib/id3v1/ID3v1Parser.d.ts +13 -13
  58. package/lib/id3v1/ID3v1Parser.js +134 -134
  59. package/lib/id3v1/ID3v1TagMap.d.ts +4 -4
  60. package/lib/id3v1/ID3v1TagMap.js +22 -22
  61. package/lib/id3v2/AbstractID3Parser.d.ts +17 -17
  62. package/lib/id3v2/AbstractID3Parser.js +60 -60
  63. package/lib/id3v2/FrameParser.d.ts +31 -31
  64. package/lib/id3v2/FrameParser.js +329 -329
  65. package/lib/id3v2/ID3v22TagMapper.d.ts +9 -9
  66. package/lib/id3v2/ID3v22TagMapper.js +55 -55
  67. package/lib/id3v2/ID3v24TagMapper.d.ts +14 -14
  68. package/lib/id3v2/ID3v24TagMapper.js +193 -193
  69. package/lib/id3v2/ID3v2Parser.d.ts +28 -28
  70. package/lib/id3v2/ID3v2Parser.js +182 -182
  71. package/lib/id3v2/ID3v2Token.d.ts +73 -73
  72. package/lib/id3v2/ID3v2Token.js +106 -106
  73. package/lib/iff/index.d.ts +33 -33
  74. package/lib/iff/index.js +19 -19
  75. package/lib/index.d.ts +45 -45
  76. package/lib/index.js +74 -74
  77. package/lib/lyrics3/Lyrics3.d.ts +3 -3
  78. package/lib/lyrics3/Lyrics3.js +17 -17
  79. package/lib/matroska/MatroskaDtd.d.ts +8 -8
  80. package/lib/matroska/MatroskaDtd.js +279 -279
  81. package/lib/matroska/MatroskaParser.d.ts +37 -37
  82. package/lib/matroska/MatroskaParser.js +235 -235
  83. package/lib/matroska/MatroskaTagMapper.d.ts +4 -4
  84. package/lib/matroska/MatroskaTagMapper.js +35 -35
  85. package/lib/matroska/types.d.ts +175 -175
  86. package/lib/matroska/types.js +32 -32
  87. package/lib/mp4/Atom.d.ts +16 -16
  88. package/lib/mp4/Atom.js +70 -70
  89. package/lib/mp4/AtomToken.d.ts +395 -395
  90. package/lib/mp4/AtomToken.js +406 -406
  91. package/lib/mp4/MP4Parser.d.ts +30 -30
  92. package/lib/mp4/MP4Parser.js +511 -511
  93. package/lib/mp4/MP4TagMapper.d.ts +5 -5
  94. package/lib/mp4/MP4TagMapper.js +115 -115
  95. package/lib/mpeg/ExtendedLameHeader.d.ts +27 -27
  96. package/lib/mpeg/ExtendedLameHeader.js +31 -31
  97. package/lib/mpeg/MpegParser.d.ts +49 -49
  98. package/lib/mpeg/MpegParser.js +524 -524
  99. package/lib/mpeg/ReplayGainDataFormat.d.ts +55 -55
  100. package/lib/mpeg/ReplayGainDataFormat.js +69 -69
  101. package/lib/mpeg/XingTag.d.ts +45 -45
  102. package/lib/mpeg/XingTag.js +69 -69
  103. package/lib/musepack/index.d.ts +5 -5
  104. package/lib/musepack/index.js +32 -32
  105. package/lib/musepack/sv7/BitReader.d.ts +13 -13
  106. package/lib/musepack/sv7/BitReader.js +54 -54
  107. package/lib/musepack/sv7/MpcSv7Parser.d.ts +8 -8
  108. package/lib/musepack/sv7/MpcSv7Parser.js +46 -46
  109. package/lib/musepack/sv7/StreamVersion7.d.ts +28 -28
  110. package/lib/musepack/sv7/StreamVersion7.js +41 -41
  111. package/lib/musepack/sv8/MpcSv8Parser.d.ts +6 -6
  112. package/lib/musepack/sv8/MpcSv8Parser.js +55 -55
  113. package/lib/musepack/sv8/StreamVersion8.d.ts +40 -40
  114. package/lib/musepack/sv8/StreamVersion8.js +80 -80
  115. package/lib/ogg/Ogg.d.ts +72 -72
  116. package/lib/ogg/Ogg.js +2 -2
  117. package/lib/ogg/OggParser.d.ts +23 -23
  118. package/lib/ogg/OggParser.js +126 -126
  119. package/lib/ogg/opus/Opus.d.ts +48 -48
  120. package/lib/ogg/opus/Opus.js +28 -28
  121. package/lib/ogg/opus/OpusParser.d.ts +25 -25
  122. package/lib/ogg/opus/OpusParser.js +56 -56
  123. package/lib/ogg/speex/Speex.d.ts +36 -36
  124. package/lib/ogg/speex/Speex.js +31 -31
  125. package/lib/ogg/speex/SpeexParser.d.ts +22 -22
  126. package/lib/ogg/speex/SpeexParser.js +35 -35
  127. package/lib/ogg/theora/Theora.d.ts +20 -20
  128. package/lib/ogg/theora/Theora.js +23 -23
  129. package/lib/ogg/theora/TheoraParser.d.ts +28 -28
  130. package/lib/ogg/theora/TheoraParser.js +44 -44
  131. package/lib/ogg/vorbis/Vorbis.d.ts +69 -69
  132. package/lib/ogg/vorbis/Vorbis.js +78 -78
  133. package/lib/ogg/vorbis/VorbisDecoder.d.ts +12 -12
  134. package/lib/ogg/vorbis/VorbisDecoder.js +32 -32
  135. package/lib/ogg/vorbis/VorbisParser.d.ts +36 -36
  136. package/lib/ogg/vorbis/VorbisParser.js +128 -128
  137. package/lib/ogg/vorbis/VorbisTagMapper.d.ts +7 -7
  138. package/lib/ogg/vorbis/VorbisTagMapper.js +132 -132
  139. package/lib/riff/RiffChunk.d.ts +16 -16
  140. package/lib/riff/RiffChunk.js +32 -32
  141. package/lib/riff/RiffInfoTagMap.d.ts +10 -10
  142. package/lib/riff/RiffInfoTagMap.js +37 -37
  143. package/lib/type.d.ts +592 -592
  144. package/lib/type.js +5 -5
  145. package/lib/wav/BwfChunk.d.ts +17 -17
  146. package/lib/wav/BwfChunk.js +29 -28
  147. package/lib/wav/WaveChunk.d.ts +64 -64
  148. package/lib/wav/WaveChunk.js +65 -65
  149. package/lib/wav/WaveParser.d.ts +24 -24
  150. package/lib/wav/WaveParser.js +158 -156
  151. package/lib/wavpack/WavPackParser.d.ts +14 -14
  152. package/lib/wavpack/WavPackParser.js +99 -99
  153. package/lib/wavpack/WavPackToken.d.ts +64 -64
  154. package/lib/wavpack/WavPackToken.js +76 -76
  155. package/package.json +150 -150
@@ -1,406 +1,406 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ChapterText = exports.StcoAtom = exports.StszAtom = exports.StscAtom = exports.SampleToChunkToken = exports.SttsAtom = exports.TimeToSampleToken = exports.SoundSampleDescriptionV0 = exports.SoundSampleDescriptionVersion = exports.StsdAtom = exports.TrackHeaderAtom = exports.NameAtom = exports.DataAtom = exports.MvhdAtom = exports.MdhdAtom = exports.FixedLengthAtom = exports.mhdr = exports.tkhd = exports.ftyp = exports.ExtendedSize = exports.Header = void 0;
4
- const Token = require("token-types");
5
- const initDebug = require("debug");
6
- const FourCC_1 = require("../common/FourCC");
7
- const debug = initDebug('music-metadata:parser:MP4:atom');
8
- exports.Header = {
9
- len: 8,
10
- get: (buf, off) => {
11
- const length = Token.UINT32_BE.get(buf, off);
12
- if (length < 0)
13
- throw new Error('Invalid atom header length');
14
- return {
15
- length: BigInt(length),
16
- name: new Token.StringType(4, 'binary').get(buf, off + 4)
17
- };
18
- },
19
- put: (buf, off, hdr) => {
20
- Token.UINT32_BE.put(buf, off, Number(hdr.length));
21
- return FourCC_1.FourCcToken.put(buf, off + 4, hdr.name);
22
- }
23
- };
24
- /**
25
- * Ref: https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFChap1/qtff1.html#//apple_ref/doc/uid/TP40000939-CH203-38190
26
- */
27
- exports.ExtendedSize = Token.UINT64_BE;
28
- exports.ftyp = {
29
- len: 4,
30
- get: (buf, off) => {
31
- return {
32
- type: new Token.StringType(4, 'ascii').get(buf, off)
33
- };
34
- }
35
- };
36
- exports.tkhd = {
37
- len: 4,
38
- get: (buf, off) => {
39
- return {
40
- type: new Token.StringType(4, 'ascii').get(buf, off)
41
- };
42
- }
43
- };
44
- /**
45
- * Token: Movie Header Atom
46
- */
47
- exports.mhdr = {
48
- len: 8,
49
- get: (buf, off) => {
50
- return {
51
- version: Token.UINT8.get(buf, off),
52
- flags: Token.UINT24_BE.get(buf, off + 1),
53
- nextItemID: Token.UINT32_BE.get(buf, off + 4)
54
- };
55
- }
56
- };
57
- /**
58
- * Base class for 'fixed' length atoms.
59
- * In some cases these atoms are longer then the sum of the described fields.
60
- * Issue: https://github.com/Borewit/music-metadata/issues/120
61
- */
62
- class FixedLengthAtom {
63
- /**
64
- *
65
- * @param {number} len Length as specified in the size field
66
- * @param {number} expLen Total length of sum of specified fields in the standard
67
- */
68
- constructor(len, expLen, atomId) {
69
- this.len = len;
70
- if (len < expLen) {
71
- throw new Error(`Atom ${atomId} expected to be ${expLen}, but specifies ${len} bytes long.`);
72
- }
73
- else if (len > expLen) {
74
- debug(`Warning: atom ${atomId} expected to be ${expLen}, but was actually ${len} bytes long.`);
75
- }
76
- }
77
- }
78
- exports.FixedLengthAtom = FixedLengthAtom;
79
- /**
80
- * Timestamp stored in seconds since Mac Epoch (1 January 1904)
81
- */
82
- const SecondsSinceMacEpoch = {
83
- len: 4,
84
- get: (buf, off) => {
85
- const secondsSinceUnixEpoch = Token.UINT32_BE.get(buf, off) - 2082844800;
86
- return new Date(secondsSinceUnixEpoch * 1000);
87
- }
88
- };
89
- /**
90
- * Token: Media Header Atom
91
- * Ref:
92
- * - https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html#//apple_ref/doc/uid/TP40000939-CH204-SW34
93
- * - https://wiki.multimedia.cx/index.php/QuickTime_container#mdhd
94
- */
95
- class MdhdAtom extends FixedLengthAtom {
96
- constructor(len) {
97
- super(len, 24, 'mdhd');
98
- this.len = len;
99
- }
100
- get(buf, off) {
101
- return {
102
- version: Token.UINT8.get(buf, off + 0),
103
- flags: Token.UINT24_BE.get(buf, off + 1),
104
- creationTime: SecondsSinceMacEpoch.get(buf, off + 4),
105
- modificationTime: SecondsSinceMacEpoch.get(buf, off + 8),
106
- timeScale: Token.UINT32_BE.get(buf, off + 12),
107
- duration: Token.UINT32_BE.get(buf, off + 16),
108
- language: Token.UINT16_BE.get(buf, off + 20),
109
- quality: Token.UINT16_BE.get(buf, off + 22)
110
- };
111
- }
112
- }
113
- exports.MdhdAtom = MdhdAtom;
114
- /**
115
- * Token: Movie Header Atom
116
- */
117
- class MvhdAtom extends FixedLengthAtom {
118
- constructor(len) {
119
- super(len, 100, 'mvhd');
120
- this.len = len;
121
- }
122
- get(buf, off) {
123
- return {
124
- version: Token.UINT8.get(buf, off),
125
- flags: Token.UINT24_BE.get(buf, off + 1),
126
- creationTime: SecondsSinceMacEpoch.get(buf, off + 4),
127
- modificationTime: SecondsSinceMacEpoch.get(buf, off + 8),
128
- timeScale: Token.UINT32_BE.get(buf, off + 12),
129
- duration: Token.UINT32_BE.get(buf, off + 16),
130
- preferredRate: Token.UINT32_BE.get(buf, off + 20),
131
- preferredVolume: Token.UINT16_BE.get(buf, off + 24),
132
- // ignore reserver: 10 bytes
133
- // ignore matrix structure: 36 bytes
134
- previewTime: Token.UINT32_BE.get(buf, off + 72),
135
- previewDuration: Token.UINT32_BE.get(buf, off + 76),
136
- posterTime: Token.UINT32_BE.get(buf, off + 80),
137
- selectionTime: Token.UINT32_BE.get(buf, off + 84),
138
- selectionDuration: Token.UINT32_BE.get(buf, off + 88),
139
- currentTime: Token.UINT32_BE.get(buf, off + 92),
140
- nextTrackID: Token.UINT32_BE.get(buf, off + 96)
141
- };
142
- }
143
- }
144
- exports.MvhdAtom = MvhdAtom;
145
- /**
146
- * Data Atom Structure
147
- */
148
- class DataAtom {
149
- constructor(len) {
150
- this.len = len;
151
- }
152
- get(buf, off) {
153
- return {
154
- type: {
155
- set: Token.UINT8.get(buf, off + 0),
156
- type: Token.UINT24_BE.get(buf, off + 1)
157
- },
158
- locale: Token.UINT24_BE.get(buf, off + 4),
159
- value: Buffer.from(new Token.Uint8ArrayType(this.len - 8).get(buf, off + 8))
160
- };
161
- }
162
- }
163
- exports.DataAtom = DataAtom;
164
- /**
165
- * Data Atom Structure
166
- * Ref: https://developer.apple.com/library/content/documentation/QuickTime/QTFF/Metadata/Metadata.html#//apple_ref/doc/uid/TP40000939-CH1-SW31
167
- */
168
- class NameAtom {
169
- constructor(len) {
170
- this.len = len;
171
- }
172
- get(buf, off) {
173
- return {
174
- version: Token.UINT8.get(buf, off),
175
- flags: Token.UINT24_BE.get(buf, off + 1),
176
- name: new Token.StringType(this.len - 4, 'utf-8').get(buf, off + 4)
177
- };
178
- }
179
- }
180
- exports.NameAtom = NameAtom;
181
- /**
182
- * Track Header Atoms structure
183
- * Ref: https://developer.apple.com/library/content/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html#//apple_ref/doc/uid/TP40000939-CH204-25550
184
- */
185
- class TrackHeaderAtom {
186
- constructor(len) {
187
- this.len = len;
188
- }
189
- get(buf, off) {
190
- return {
191
- version: Token.UINT8.get(buf, off),
192
- flags: Token.UINT24_BE.get(buf, off + 1),
193
- creationTime: SecondsSinceMacEpoch.get(buf, off + 4),
194
- modificationTime: SecondsSinceMacEpoch.get(buf, off + 8),
195
- trackId: Token.UINT32_BE.get(buf, off + 12),
196
- // reserved 4 bytes
197
- duration: Token.UINT32_BE.get(buf, off + 20),
198
- layer: Token.UINT16_BE.get(buf, off + 24),
199
- alternateGroup: Token.UINT16_BE.get(buf, off + 26),
200
- volume: Token.UINT16_BE.get(buf, off + 28) // ToDo: fixed point
201
- // ToDo: add remaining fields
202
- };
203
- }
204
- }
205
- exports.TrackHeaderAtom = TrackHeaderAtom;
206
- /**
207
- * Atom: Sample Description Atom ('stsd')
208
- * Ref: https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html#//apple_ref/doc/uid/TP40000939-CH204-25691
209
- */
210
- const stsdHeader = {
211
- len: 8,
212
- get: (buf, off) => {
213
- return {
214
- version: Token.UINT8.get(buf, off),
215
- flags: Token.UINT24_BE.get(buf, off + 1),
216
- numberOfEntries: Token.UINT32_BE.get(buf, off + 4)
217
- };
218
- }
219
- };
220
- /**
221
- * Atom: Sample Description Atom ('stsd')
222
- * Ref: https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html#//apple_ref/doc/uid/TP40000939-CH204-25691
223
- */
224
- class SampleDescriptionTable {
225
- constructor(len) {
226
- this.len = len;
227
- }
228
- get(buf, off) {
229
- return {
230
- dataFormat: FourCC_1.FourCcToken.get(buf, off),
231
- dataReferenceIndex: Token.UINT16_BE.get(buf, off + 10),
232
- description: new Token.Uint8ArrayType(this.len - 12).get(buf, off + 12)
233
- };
234
- }
235
- }
236
- /**
237
- * Atom: Sample-description Atom ('stsd')
238
- * Ref: https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html#//apple_ref/doc/uid/TP40000939-CH204-25691
239
- */
240
- class StsdAtom {
241
- constructor(len) {
242
- this.len = len;
243
- }
244
- get(buf, off) {
245
- const header = stsdHeader.get(buf, off);
246
- off += stsdHeader.len;
247
- const table = [];
248
- for (let n = 0; n < header.numberOfEntries; ++n) {
249
- const size = Token.UINT32_BE.get(buf, off); // Sample description size
250
- off += Token.UINT32_BE.len;
251
- table.push(new SampleDescriptionTable(size).get(buf, off));
252
- off += size;
253
- }
254
- return {
255
- header,
256
- table
257
- };
258
- }
259
- }
260
- exports.StsdAtom = StsdAtom;
261
- /**
262
- * Common Sound Sample Description (version & revision)
263
- * Ref: https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFChap3/qtff3.html#//apple_ref/doc/uid/TP40000939-CH205-57317
264
- */
265
- exports.SoundSampleDescriptionVersion = {
266
- len: 8,
267
- get(buf, off) {
268
- return {
269
- version: Token.INT16_BE.get(buf, off),
270
- revision: Token.INT16_BE.get(buf, off + 2),
271
- vendor: Token.INT32_BE.get(buf, off + 4)
272
- };
273
- }
274
- };
275
- /**
276
- * Sound Sample Description (Version 0)
277
- * Ref: https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFChap3/qtff3.html#//apple_ref/doc/uid/TP40000939-CH205-130736
278
- */
279
- exports.SoundSampleDescriptionV0 = {
280
- len: 12,
281
- get(buf, off) {
282
- return {
283
- numAudioChannels: Token.INT16_BE.get(buf, off + 0),
284
- sampleSize: Token.INT16_BE.get(buf, off + 2),
285
- compressionId: Token.INT16_BE.get(buf, off + 4),
286
- packetSize: Token.INT16_BE.get(buf, off + 6),
287
- sampleRate: Token.UINT16_BE.get(buf, off + 8) + Token.UINT16_BE.get(buf, off + 10) / 10000
288
- };
289
- }
290
- };
291
- class SimpleTableAtom {
292
- constructor(len, token) {
293
- this.len = len;
294
- this.token = token;
295
- }
296
- get(buf, off) {
297
- const nrOfEntries = Token.INT32_BE.get(buf, off + 4);
298
- return {
299
- version: Token.INT8.get(buf, off + 0),
300
- flags: Token.INT24_BE.get(buf, off + 1),
301
- numberOfEntries: nrOfEntries,
302
- entries: readTokenTable(buf, this.token, off + 8, this.len - 8, nrOfEntries)
303
- };
304
- }
305
- }
306
- exports.TimeToSampleToken = {
307
- len: 8,
308
- get(buf, off) {
309
- return {
310
- count: Token.INT32_BE.get(buf, off + 0),
311
- duration: Token.INT32_BE.get(buf, off + 4)
312
- };
313
- }
314
- };
315
- /**
316
- * Time-to-sample('stts') atom.
317
- * Store duration information for a media’s samples.
318
- * Ref: https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html#//apple_ref/doc/uid/TP40000939-CH204-25696
319
- */
320
- class SttsAtom extends SimpleTableAtom {
321
- constructor(len) {
322
- super(len, exports.TimeToSampleToken);
323
- this.len = len;
324
- }
325
- }
326
- exports.SttsAtom = SttsAtom;
327
- exports.SampleToChunkToken = {
328
- len: 12,
329
- get(buf, off) {
330
- return {
331
- firstChunk: Token.INT32_BE.get(buf, off),
332
- samplesPerChunk: Token.INT32_BE.get(buf, off + 4),
333
- sampleDescriptionId: Token.INT32_BE.get(buf, off + 8)
334
- };
335
- }
336
- };
337
- /**
338
- * Sample-to-Chunk ('stsc') atom interface
339
- * Ref: https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html#//apple_ref/doc/uid/TP40000939-CH204-25706
340
- */
341
- class StscAtom extends SimpleTableAtom {
342
- constructor(len) {
343
- super(len, exports.SampleToChunkToken);
344
- this.len = len;
345
- }
346
- }
347
- exports.StscAtom = StscAtom;
348
- /**
349
- * Sample-size ('stsz') atom
350
- * Ref: https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html#//apple_ref/doc/uid/TP40000939-CH204-25710
351
- */
352
- class StszAtom {
353
- constructor(len) {
354
- this.len = len;
355
- }
356
- get(buf, off) {
357
- const nrOfEntries = Token.INT32_BE.get(buf, off + 8);
358
- return {
359
- version: Token.INT8.get(buf, off),
360
- flags: Token.INT24_BE.get(buf, off + 1),
361
- sampleSize: Token.INT32_BE.get(buf, off + 4),
362
- numberOfEntries: nrOfEntries,
363
- entries: readTokenTable(buf, Token.INT32_BE, off + 12, this.len - 12, nrOfEntries)
364
- };
365
- }
366
- }
367
- exports.StszAtom = StszAtom;
368
- /**
369
- * Chunk offset atom, 'stco'
370
- * Ref: https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html#//apple_ref/doc/uid/TP40000939-CH204-25715
371
- */
372
- class StcoAtom extends SimpleTableAtom {
373
- constructor(len) {
374
- super(len, Token.INT32_BE);
375
- this.len = len;
376
- }
377
- }
378
- exports.StcoAtom = StcoAtom;
379
- /**
380
- * Token used to decode text-track from 'mdat' atom (raw data stream)
381
- */
382
- class ChapterText {
383
- constructor(len) {
384
- this.len = len;
385
- }
386
- get(buf, off) {
387
- const titleLen = Token.INT16_BE.get(buf, off + 0);
388
- const str = new Token.StringType(titleLen, 'utf-8');
389
- return str.get(buf, off + 2);
390
- }
391
- }
392
- exports.ChapterText = ChapterText;
393
- function readTokenTable(buf, token, off, remainingLen, numberOfEntries) {
394
- debug(`remainingLen=${remainingLen}, numberOfEntries=${numberOfEntries} * token-len=${token.len}`);
395
- if (remainingLen === 0)
396
- return [];
397
- if (remainingLen !== numberOfEntries * token.len)
398
- throw new Error('mismatch number-of-entries with remaining atom-length');
399
- const entries = [];
400
- // parse offset-table
401
- for (let n = 0; n < numberOfEntries; ++n) {
402
- entries.push(token.get(buf, off));
403
- off += token.len;
404
- }
405
- return entries;
406
- }
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ChapterText = exports.StcoAtom = exports.StszAtom = exports.StscAtom = exports.SampleToChunkToken = exports.SttsAtom = exports.TimeToSampleToken = exports.SoundSampleDescriptionV0 = exports.SoundSampleDescriptionVersion = exports.StsdAtom = exports.TrackHeaderAtom = exports.NameAtom = exports.DataAtom = exports.MvhdAtom = exports.MdhdAtom = exports.FixedLengthAtom = exports.mhdr = exports.tkhd = exports.ftyp = exports.ExtendedSize = exports.Header = void 0;
4
+ const Token = require("token-types");
5
+ const debug_1 = require("debug");
6
+ const FourCC_1 = require("../common/FourCC");
7
+ const debug = (0, debug_1.default)('music-metadata:parser:MP4:atom');
8
+ exports.Header = {
9
+ len: 8,
10
+ get: (buf, off) => {
11
+ const length = Token.UINT32_BE.get(buf, off);
12
+ if (length < 0)
13
+ throw new Error('Invalid atom header length');
14
+ return {
15
+ length: BigInt(length),
16
+ name: new Token.StringType(4, 'binary').get(buf, off + 4)
17
+ };
18
+ },
19
+ put: (buf, off, hdr) => {
20
+ Token.UINT32_BE.put(buf, off, Number(hdr.length));
21
+ return FourCC_1.FourCcToken.put(buf, off + 4, hdr.name);
22
+ }
23
+ };
24
+ /**
25
+ * Ref: https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFChap1/qtff1.html#//apple_ref/doc/uid/TP40000939-CH203-38190
26
+ */
27
+ exports.ExtendedSize = Token.UINT64_BE;
28
+ exports.ftyp = {
29
+ len: 4,
30
+ get: (buf, off) => {
31
+ return {
32
+ type: new Token.StringType(4, 'ascii').get(buf, off)
33
+ };
34
+ }
35
+ };
36
+ exports.tkhd = {
37
+ len: 4,
38
+ get: (buf, off) => {
39
+ return {
40
+ type: new Token.StringType(4, 'ascii').get(buf, off)
41
+ };
42
+ }
43
+ };
44
+ /**
45
+ * Token: Movie Header Atom
46
+ */
47
+ exports.mhdr = {
48
+ len: 8,
49
+ get: (buf, off) => {
50
+ return {
51
+ version: Token.UINT8.get(buf, off),
52
+ flags: Token.UINT24_BE.get(buf, off + 1),
53
+ nextItemID: Token.UINT32_BE.get(buf, off + 4)
54
+ };
55
+ }
56
+ };
57
+ /**
58
+ * Base class for 'fixed' length atoms.
59
+ * In some cases these atoms are longer then the sum of the described fields.
60
+ * Issue: https://github.com/Borewit/music-metadata/issues/120
61
+ */
62
+ class FixedLengthAtom {
63
+ /**
64
+ *
65
+ * @param {number} len Length as specified in the size field
66
+ * @param {number} expLen Total length of sum of specified fields in the standard
67
+ */
68
+ constructor(len, expLen, atomId) {
69
+ this.len = len;
70
+ if (len < expLen) {
71
+ throw new Error(`Atom ${atomId} expected to be ${expLen}, but specifies ${len} bytes long.`);
72
+ }
73
+ else if (len > expLen) {
74
+ debug(`Warning: atom ${atomId} expected to be ${expLen}, but was actually ${len} bytes long.`);
75
+ }
76
+ }
77
+ }
78
+ exports.FixedLengthAtom = FixedLengthAtom;
79
+ /**
80
+ * Timestamp stored in seconds since Mac Epoch (1 January 1904)
81
+ */
82
+ const SecondsSinceMacEpoch = {
83
+ len: 4,
84
+ get: (buf, off) => {
85
+ const secondsSinceUnixEpoch = Token.UINT32_BE.get(buf, off) - 2082844800;
86
+ return new Date(secondsSinceUnixEpoch * 1000);
87
+ }
88
+ };
89
+ /**
90
+ * Token: Media Header Atom
91
+ * Ref:
92
+ * - https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html#//apple_ref/doc/uid/TP40000939-CH204-SW34
93
+ * - https://wiki.multimedia.cx/index.php/QuickTime_container#mdhd
94
+ */
95
+ class MdhdAtom extends FixedLengthAtom {
96
+ constructor(len) {
97
+ super(len, 24, 'mdhd');
98
+ this.len = len;
99
+ }
100
+ get(buf, off) {
101
+ return {
102
+ version: Token.UINT8.get(buf, off + 0),
103
+ flags: Token.UINT24_BE.get(buf, off + 1),
104
+ creationTime: SecondsSinceMacEpoch.get(buf, off + 4),
105
+ modificationTime: SecondsSinceMacEpoch.get(buf, off + 8),
106
+ timeScale: Token.UINT32_BE.get(buf, off + 12),
107
+ duration: Token.UINT32_BE.get(buf, off + 16),
108
+ language: Token.UINT16_BE.get(buf, off + 20),
109
+ quality: Token.UINT16_BE.get(buf, off + 22)
110
+ };
111
+ }
112
+ }
113
+ exports.MdhdAtom = MdhdAtom;
114
+ /**
115
+ * Token: Movie Header Atom
116
+ */
117
+ class MvhdAtom extends FixedLengthAtom {
118
+ constructor(len) {
119
+ super(len, 100, 'mvhd');
120
+ this.len = len;
121
+ }
122
+ get(buf, off) {
123
+ return {
124
+ version: Token.UINT8.get(buf, off),
125
+ flags: Token.UINT24_BE.get(buf, off + 1),
126
+ creationTime: SecondsSinceMacEpoch.get(buf, off + 4),
127
+ modificationTime: SecondsSinceMacEpoch.get(buf, off + 8),
128
+ timeScale: Token.UINT32_BE.get(buf, off + 12),
129
+ duration: Token.UINT32_BE.get(buf, off + 16),
130
+ preferredRate: Token.UINT32_BE.get(buf, off + 20),
131
+ preferredVolume: Token.UINT16_BE.get(buf, off + 24),
132
+ // ignore reserver: 10 bytes
133
+ // ignore matrix structure: 36 bytes
134
+ previewTime: Token.UINT32_BE.get(buf, off + 72),
135
+ previewDuration: Token.UINT32_BE.get(buf, off + 76),
136
+ posterTime: Token.UINT32_BE.get(buf, off + 80),
137
+ selectionTime: Token.UINT32_BE.get(buf, off + 84),
138
+ selectionDuration: Token.UINT32_BE.get(buf, off + 88),
139
+ currentTime: Token.UINT32_BE.get(buf, off + 92),
140
+ nextTrackID: Token.UINT32_BE.get(buf, off + 96)
141
+ };
142
+ }
143
+ }
144
+ exports.MvhdAtom = MvhdAtom;
145
+ /**
146
+ * Data Atom Structure
147
+ */
148
+ class DataAtom {
149
+ constructor(len) {
150
+ this.len = len;
151
+ }
152
+ get(buf, off) {
153
+ return {
154
+ type: {
155
+ set: Token.UINT8.get(buf, off + 0),
156
+ type: Token.UINT24_BE.get(buf, off + 1)
157
+ },
158
+ locale: Token.UINT24_BE.get(buf, off + 4),
159
+ value: Buffer.from(new Token.Uint8ArrayType(this.len - 8).get(buf, off + 8))
160
+ };
161
+ }
162
+ }
163
+ exports.DataAtom = DataAtom;
164
+ /**
165
+ * Data Atom Structure
166
+ * Ref: https://developer.apple.com/library/content/documentation/QuickTime/QTFF/Metadata/Metadata.html#//apple_ref/doc/uid/TP40000939-CH1-SW31
167
+ */
168
+ class NameAtom {
169
+ constructor(len) {
170
+ this.len = len;
171
+ }
172
+ get(buf, off) {
173
+ return {
174
+ version: Token.UINT8.get(buf, off),
175
+ flags: Token.UINT24_BE.get(buf, off + 1),
176
+ name: new Token.StringType(this.len - 4, 'utf-8').get(buf, off + 4)
177
+ };
178
+ }
179
+ }
180
+ exports.NameAtom = NameAtom;
181
+ /**
182
+ * Track Header Atoms structure
183
+ * Ref: https://developer.apple.com/library/content/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html#//apple_ref/doc/uid/TP40000939-CH204-25550
184
+ */
185
+ class TrackHeaderAtom {
186
+ constructor(len) {
187
+ this.len = len;
188
+ }
189
+ get(buf, off) {
190
+ return {
191
+ version: Token.UINT8.get(buf, off),
192
+ flags: Token.UINT24_BE.get(buf, off + 1),
193
+ creationTime: SecondsSinceMacEpoch.get(buf, off + 4),
194
+ modificationTime: SecondsSinceMacEpoch.get(buf, off + 8),
195
+ trackId: Token.UINT32_BE.get(buf, off + 12),
196
+ // reserved 4 bytes
197
+ duration: Token.UINT32_BE.get(buf, off + 20),
198
+ layer: Token.UINT16_BE.get(buf, off + 24),
199
+ alternateGroup: Token.UINT16_BE.get(buf, off + 26),
200
+ volume: Token.UINT16_BE.get(buf, off + 28) // ToDo: fixed point
201
+ // ToDo: add remaining fields
202
+ };
203
+ }
204
+ }
205
+ exports.TrackHeaderAtom = TrackHeaderAtom;
206
+ /**
207
+ * Atom: Sample Description Atom ('stsd')
208
+ * Ref: https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html#//apple_ref/doc/uid/TP40000939-CH204-25691
209
+ */
210
+ const stsdHeader = {
211
+ len: 8,
212
+ get: (buf, off) => {
213
+ return {
214
+ version: Token.UINT8.get(buf, off),
215
+ flags: Token.UINT24_BE.get(buf, off + 1),
216
+ numberOfEntries: Token.UINT32_BE.get(buf, off + 4)
217
+ };
218
+ }
219
+ };
220
+ /**
221
+ * Atom: Sample Description Atom ('stsd')
222
+ * Ref: https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html#//apple_ref/doc/uid/TP40000939-CH204-25691
223
+ */
224
+ class SampleDescriptionTable {
225
+ constructor(len) {
226
+ this.len = len;
227
+ }
228
+ get(buf, off) {
229
+ return {
230
+ dataFormat: FourCC_1.FourCcToken.get(buf, off),
231
+ dataReferenceIndex: Token.UINT16_BE.get(buf, off + 10),
232
+ description: new Token.Uint8ArrayType(this.len - 12).get(buf, off + 12)
233
+ };
234
+ }
235
+ }
236
+ /**
237
+ * Atom: Sample-description Atom ('stsd')
238
+ * Ref: https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html#//apple_ref/doc/uid/TP40000939-CH204-25691
239
+ */
240
+ class StsdAtom {
241
+ constructor(len) {
242
+ this.len = len;
243
+ }
244
+ get(buf, off) {
245
+ const header = stsdHeader.get(buf, off);
246
+ off += stsdHeader.len;
247
+ const table = [];
248
+ for (let n = 0; n < header.numberOfEntries; ++n) {
249
+ const size = Token.UINT32_BE.get(buf, off); // Sample description size
250
+ off += Token.UINT32_BE.len;
251
+ table.push(new SampleDescriptionTable(size).get(buf, off));
252
+ off += size;
253
+ }
254
+ return {
255
+ header,
256
+ table
257
+ };
258
+ }
259
+ }
260
+ exports.StsdAtom = StsdAtom;
261
+ /**
262
+ * Common Sound Sample Description (version & revision)
263
+ * Ref: https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFChap3/qtff3.html#//apple_ref/doc/uid/TP40000939-CH205-57317
264
+ */
265
+ exports.SoundSampleDescriptionVersion = {
266
+ len: 8,
267
+ get(buf, off) {
268
+ return {
269
+ version: Token.INT16_BE.get(buf, off),
270
+ revision: Token.INT16_BE.get(buf, off + 2),
271
+ vendor: Token.INT32_BE.get(buf, off + 4)
272
+ };
273
+ }
274
+ };
275
+ /**
276
+ * Sound Sample Description (Version 0)
277
+ * Ref: https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFChap3/qtff3.html#//apple_ref/doc/uid/TP40000939-CH205-130736
278
+ */
279
+ exports.SoundSampleDescriptionV0 = {
280
+ len: 12,
281
+ get(buf, off) {
282
+ return {
283
+ numAudioChannels: Token.INT16_BE.get(buf, off + 0),
284
+ sampleSize: Token.INT16_BE.get(buf, off + 2),
285
+ compressionId: Token.INT16_BE.get(buf, off + 4),
286
+ packetSize: Token.INT16_BE.get(buf, off + 6),
287
+ sampleRate: Token.UINT16_BE.get(buf, off + 8) + Token.UINT16_BE.get(buf, off + 10) / 10000
288
+ };
289
+ }
290
+ };
291
+ class SimpleTableAtom {
292
+ constructor(len, token) {
293
+ this.len = len;
294
+ this.token = token;
295
+ }
296
+ get(buf, off) {
297
+ const nrOfEntries = Token.INT32_BE.get(buf, off + 4);
298
+ return {
299
+ version: Token.INT8.get(buf, off + 0),
300
+ flags: Token.INT24_BE.get(buf, off + 1),
301
+ numberOfEntries: nrOfEntries,
302
+ entries: readTokenTable(buf, this.token, off + 8, this.len - 8, nrOfEntries)
303
+ };
304
+ }
305
+ }
306
+ exports.TimeToSampleToken = {
307
+ len: 8,
308
+ get(buf, off) {
309
+ return {
310
+ count: Token.INT32_BE.get(buf, off + 0),
311
+ duration: Token.INT32_BE.get(buf, off + 4)
312
+ };
313
+ }
314
+ };
315
+ /**
316
+ * Time-to-sample('stts') atom.
317
+ * Store duration information for a media’s samples.
318
+ * Ref: https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html#//apple_ref/doc/uid/TP40000939-CH204-25696
319
+ */
320
+ class SttsAtom extends SimpleTableAtom {
321
+ constructor(len) {
322
+ super(len, exports.TimeToSampleToken);
323
+ this.len = len;
324
+ }
325
+ }
326
+ exports.SttsAtom = SttsAtom;
327
+ exports.SampleToChunkToken = {
328
+ len: 12,
329
+ get(buf, off) {
330
+ return {
331
+ firstChunk: Token.INT32_BE.get(buf, off),
332
+ samplesPerChunk: Token.INT32_BE.get(buf, off + 4),
333
+ sampleDescriptionId: Token.INT32_BE.get(buf, off + 8)
334
+ };
335
+ }
336
+ };
337
+ /**
338
+ * Sample-to-Chunk ('stsc') atom interface
339
+ * Ref: https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html#//apple_ref/doc/uid/TP40000939-CH204-25706
340
+ */
341
+ class StscAtom extends SimpleTableAtom {
342
+ constructor(len) {
343
+ super(len, exports.SampleToChunkToken);
344
+ this.len = len;
345
+ }
346
+ }
347
+ exports.StscAtom = StscAtom;
348
+ /**
349
+ * Sample-size ('stsz') atom
350
+ * Ref: https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html#//apple_ref/doc/uid/TP40000939-CH204-25710
351
+ */
352
+ class StszAtom {
353
+ constructor(len) {
354
+ this.len = len;
355
+ }
356
+ get(buf, off) {
357
+ const nrOfEntries = Token.INT32_BE.get(buf, off + 8);
358
+ return {
359
+ version: Token.INT8.get(buf, off),
360
+ flags: Token.INT24_BE.get(buf, off + 1),
361
+ sampleSize: Token.INT32_BE.get(buf, off + 4),
362
+ numberOfEntries: nrOfEntries,
363
+ entries: readTokenTable(buf, Token.INT32_BE, off + 12, this.len - 12, nrOfEntries)
364
+ };
365
+ }
366
+ }
367
+ exports.StszAtom = StszAtom;
368
+ /**
369
+ * Chunk offset atom, 'stco'
370
+ * Ref: https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html#//apple_ref/doc/uid/TP40000939-CH204-25715
371
+ */
372
+ class StcoAtom extends SimpleTableAtom {
373
+ constructor(len) {
374
+ super(len, Token.INT32_BE);
375
+ this.len = len;
376
+ }
377
+ }
378
+ exports.StcoAtom = StcoAtom;
379
+ /**
380
+ * Token used to decode text-track from 'mdat' atom (raw data stream)
381
+ */
382
+ class ChapterText {
383
+ constructor(len) {
384
+ this.len = len;
385
+ }
386
+ get(buf, off) {
387
+ const titleLen = Token.INT16_BE.get(buf, off + 0);
388
+ const str = new Token.StringType(titleLen, 'utf-8');
389
+ return str.get(buf, off + 2);
390
+ }
391
+ }
392
+ exports.ChapterText = ChapterText;
393
+ function readTokenTable(buf, token, off, remainingLen, numberOfEntries) {
394
+ debug(`remainingLen=${remainingLen}, numberOfEntries=${numberOfEntries} * token-len=${token.len}`);
395
+ if (remainingLen === 0)
396
+ return [];
397
+ if (remainingLen !== numberOfEntries * token.len)
398
+ throw new Error('mismatch number-of-entries with remaining atom-length');
399
+ const entries = [];
400
+ // parse offset-table
401
+ for (let n = 0; n < numberOfEntries; ++n) {
402
+ entries.push(token.get(buf, off));
403
+ off += token.len;
404
+ }
405
+ return entries;
406
+ }