music-metadata 11.0.4 → 11.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/lib/ParserFactory.d.ts +3 -1
- package/lib/ParserFactory.js +25 -91
- package/lib/aiff/AiffLoader.js +1 -0
- package/lib/apev2/Apev2Loader.js +1 -0
- package/lib/asf/AsfLoader.js +1 -0
- package/lib/core.d.ts +4 -0
- package/lib/core.js +6 -0
- package/lib/dsdiff/DsdiffLoader.js +1 -0
- package/lib/dsf/DsfLoader.js +1 -0
- package/lib/flac/FlacLoader.js +1 -0
- package/lib/matroska/MatroskaLoader.js +1 -0
- package/lib/mp4/Mp4Loader.js +1 -0
- package/lib/mpeg/MpegLoader.js +1 -0
- package/lib/musepack/MusepackLoader.js +1 -0
- package/lib/ogg/OggLoader.js +1 -0
- package/lib/type.d.ts +1 -1
- package/lib/wav/WaveLoader.js +1 -0
- package/lib/wavpack/WavPackLoader.js +1 -0
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -584,6 +584,10 @@ import { parseFile, selectCover } from 'music-metadata';
|
|
|
584
584
|
)();
|
|
585
585
|
```
|
|
586
586
|
|
|
587
|
+
#### `getSupportedMimeTypes` function
|
|
588
|
+
|
|
589
|
+
Returns a list of supported MIME-types. This may include some MIME-types which are not formally recognized.
|
|
590
|
+
|
|
587
591
|
### `IOptions` Interface
|
|
588
592
|
- `duration`: `boolean` (default: `false`)
|
|
589
593
|
|
package/lib/ParserFactory.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export interface IParserLoader {
|
|
|
7
7
|
* Returns a list of supported file extensions
|
|
8
8
|
*/
|
|
9
9
|
extensions: string[];
|
|
10
|
+
mimeTypes: string[];
|
|
10
11
|
parserType: ParserType;
|
|
11
12
|
/**
|
|
12
13
|
* Lazy load the parser implementation class.
|
|
@@ -37,6 +38,7 @@ export declare class ParserFactory {
|
|
|
37
38
|
* @return Parser submodule name
|
|
38
39
|
*/
|
|
39
40
|
findLoaderForExtension(filePath: string | undefined): IParserLoader | undefined;
|
|
40
|
-
|
|
41
|
+
findLoaderForContentType(httpContentType: string): IParserLoader | undefined;
|
|
42
|
+
getSupportedMimeTypes(): string[];
|
|
41
43
|
}
|
|
42
44
|
export {};
|
package/lib/ParserFactory.js
CHANGED
|
@@ -62,7 +62,7 @@ export class ParserFactory {
|
|
|
62
62
|
if (!parserLoader) {
|
|
63
63
|
const buf = new Uint8Array(4100);
|
|
64
64
|
if (tokenizer.fileInfo.mimeType) {
|
|
65
|
-
parserLoader = this.
|
|
65
|
+
parserLoader = this.findLoaderForContentType(tokenizer.fileInfo.mimeType);
|
|
66
66
|
}
|
|
67
67
|
if (!parserLoader && tokenizer.fileInfo.path) {
|
|
68
68
|
parserLoader = this.findLoaderForExtension(tokenizer.fileInfo.path);
|
|
@@ -76,7 +76,7 @@ export class ParserFactory {
|
|
|
76
76
|
throw new CouldNotDetermineFileTypeError('Failed to determine audio format');
|
|
77
77
|
}
|
|
78
78
|
debug(`Guessed file type is mime=${guessedType.mime}, extension=${guessedType.ext}`);
|
|
79
|
-
parserLoader = this.
|
|
79
|
+
parserLoader = this.findLoaderForContentType(guessedType.mime);
|
|
80
80
|
if (!parserLoader) {
|
|
81
81
|
throw new UnsupportedFileTypeError(`Guessed MIME-type not supported: ${guessedType.mime}`);
|
|
82
82
|
}
|
|
@@ -101,99 +101,33 @@ export class ParserFactory {
|
|
|
101
101
|
const extension = getExtension(filePath).toLocaleLowerCase() || filePath;
|
|
102
102
|
return this.parsers.find(parser => parser.extensions.indexOf(extension) !== -1);
|
|
103
103
|
}
|
|
104
|
-
|
|
105
|
-
|
|
104
|
+
findLoaderForContentType(httpContentType) {
|
|
105
|
+
let mime;
|
|
106
|
+
if (!httpContentType)
|
|
107
|
+
return;
|
|
108
|
+
try {
|
|
109
|
+
mime = parseHttpContentType(httpContentType);
|
|
110
|
+
}
|
|
111
|
+
catch (err) {
|
|
112
|
+
debug(`Invalid HTTP Content-Type header value: ${httpContentType}`);
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
const subType = mime.subtype.indexOf('x-') === 0 ? mime.subtype.substring(2) : mime.subtype;
|
|
116
|
+
return this.parsers.find(parser => parser.mimeTypes.find(loader => loader.indexOf(`${mime.type}/${subType}`) !== -1));
|
|
117
|
+
}
|
|
118
|
+
getSupportedMimeTypes() {
|
|
119
|
+
const mimeTypeSet = new Set();
|
|
120
|
+
this.parsers.forEach(loader => {
|
|
121
|
+
loader.mimeTypes.forEach(mimeType => {
|
|
122
|
+
mimeTypeSet.add(mimeType);
|
|
123
|
+
mimeTypeSet.add(mimeType.replace('/', '/x-'));
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
return Array.from(mimeTypeSet);
|
|
106
127
|
}
|
|
107
128
|
}
|
|
108
129
|
function getExtension(fname) {
|
|
109
130
|
const i = fname.lastIndexOf('.');
|
|
110
131
|
return i === -1 ? '' : fname.slice(i);
|
|
111
132
|
}
|
|
112
|
-
/**
|
|
113
|
-
* @param httpContentType - HTTP Content-Type, extension, path or filename
|
|
114
|
-
* @returns Parser submodule name
|
|
115
|
-
*/
|
|
116
|
-
function getParserIdForMimeType(httpContentType) {
|
|
117
|
-
let mime;
|
|
118
|
-
if (!httpContentType)
|
|
119
|
-
return;
|
|
120
|
-
try {
|
|
121
|
-
mime = parseHttpContentType(httpContentType);
|
|
122
|
-
}
|
|
123
|
-
catch (err) {
|
|
124
|
-
debug(`Invalid HTTP Content-Type header value: ${httpContentType}`);
|
|
125
|
-
return;
|
|
126
|
-
}
|
|
127
|
-
const subType = mime.subtype.indexOf('x-') === 0 ? mime.subtype.substring(2) : mime.subtype;
|
|
128
|
-
switch (mime.type) {
|
|
129
|
-
case 'audio':
|
|
130
|
-
switch (subType) {
|
|
131
|
-
case 'mp3': // Incorrect MIME-type, Chrome, in Web API File object
|
|
132
|
-
case 'mpeg':
|
|
133
|
-
return 'mpeg';
|
|
134
|
-
case 'aac':
|
|
135
|
-
case 'aacp':
|
|
136
|
-
return 'mpeg'; // adts
|
|
137
|
-
case 'flac':
|
|
138
|
-
return 'flac';
|
|
139
|
-
case 'ape':
|
|
140
|
-
case 'monkeys-audio':
|
|
141
|
-
return 'apev2';
|
|
142
|
-
case 'mp4':
|
|
143
|
-
case 'm4a':
|
|
144
|
-
return 'mp4';
|
|
145
|
-
case 'ogg': // RFC 7845
|
|
146
|
-
case 'opus': // RFC 6716
|
|
147
|
-
case 'speex': // RFC 5574
|
|
148
|
-
return 'ogg';
|
|
149
|
-
case 'ms-wma':
|
|
150
|
-
case 'ms-wmv':
|
|
151
|
-
case 'ms-asf':
|
|
152
|
-
return 'asf';
|
|
153
|
-
case 'aiff':
|
|
154
|
-
case 'aif':
|
|
155
|
-
case 'aifc':
|
|
156
|
-
return 'aiff';
|
|
157
|
-
case 'vnd.wave':
|
|
158
|
-
case 'wav':
|
|
159
|
-
case 'wave':
|
|
160
|
-
return 'riff';
|
|
161
|
-
case 'wavpack':
|
|
162
|
-
return 'wavpack';
|
|
163
|
-
case 'musepack':
|
|
164
|
-
return 'musepack';
|
|
165
|
-
case 'matroska':
|
|
166
|
-
case 'webm':
|
|
167
|
-
return 'matroska';
|
|
168
|
-
case 'dsf':
|
|
169
|
-
return 'dsf';
|
|
170
|
-
case 'amr':
|
|
171
|
-
return 'amr';
|
|
172
|
-
}
|
|
173
|
-
break;
|
|
174
|
-
case 'video':
|
|
175
|
-
switch (subType) {
|
|
176
|
-
case 'ms-asf':
|
|
177
|
-
case 'ms-wmv':
|
|
178
|
-
return 'asf';
|
|
179
|
-
case 'm4v':
|
|
180
|
-
case 'mp4':
|
|
181
|
-
return 'mp4';
|
|
182
|
-
case 'ogg':
|
|
183
|
-
return 'ogg';
|
|
184
|
-
case 'matroska':
|
|
185
|
-
case 'webm':
|
|
186
|
-
return 'matroska';
|
|
187
|
-
}
|
|
188
|
-
break;
|
|
189
|
-
case 'application':
|
|
190
|
-
switch (subType) {
|
|
191
|
-
case 'vnd.ms-asf':
|
|
192
|
-
return 'asf';
|
|
193
|
-
case 'ogg':
|
|
194
|
-
return 'ogg';
|
|
195
|
-
}
|
|
196
|
-
break;
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
133
|
//# sourceMappingURL=ParserFactory.js.map
|
package/lib/aiff/AiffLoader.js
CHANGED
package/lib/apev2/Apev2Loader.js
CHANGED
package/lib/asf/AsfLoader.js
CHANGED
package/lib/core.d.ts
CHANGED
|
@@ -63,3 +63,7 @@ export declare function scanAppendingHeaders(tokenizer: IRandomAccessTokenizer,
|
|
|
63
63
|
* This method will throw an Error, always.
|
|
64
64
|
*/
|
|
65
65
|
export declare function parseFile(filePath: string, options?: IOptions): Promise<IAudioMetadata>;
|
|
66
|
+
/**
|
|
67
|
+
* Return a list of supported mime-types
|
|
68
|
+
*/
|
|
69
|
+
export declare function getSupportedMimeTypes(): string[];
|
package/lib/core.js
CHANGED
|
@@ -111,4 +111,10 @@ export async function scanAppendingHeaders(tokenizer, options = {}) {
|
|
|
111
111
|
export async function parseFile(filePath, options = {}) {
|
|
112
112
|
throw new Error('To load Web API File objects use parseBlob instead. For loading files, you need to import with the "node" condition is set.');
|
|
113
113
|
}
|
|
114
|
+
/**
|
|
115
|
+
* Return a list of supported mime-types
|
|
116
|
+
*/
|
|
117
|
+
export function getSupportedMimeTypes() {
|
|
118
|
+
return new ParserFactory().getSupportedMimeTypes();
|
|
119
|
+
}
|
|
114
120
|
//# sourceMappingURL=core.js.map
|
package/lib/dsf/DsfLoader.js
CHANGED
package/lib/flac/FlacLoader.js
CHANGED
package/lib/mp4/Mp4Loader.js
CHANGED
package/lib/mpeg/MpegLoader.js
CHANGED
package/lib/ogg/OggLoader.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export const oggParserLoader = {
|
|
2
2
|
parserType: 'ogg',
|
|
3
3
|
extensions: ['.ogg', '.ogv', '.oga', '.ogm', '.ogx', '.opus', '.spx'],
|
|
4
|
+
mimeTypes: ['audio/ogg', 'audio/opus', 'audio/speex', 'video/ogg'], // RFC 7845, RFC 6716, RFC 5574
|
|
4
5
|
async load() {
|
|
5
6
|
return (await import('./OggParser.js')).OggParser;
|
|
6
7
|
}
|
package/lib/type.d.ts
CHANGED
|
@@ -521,7 +521,7 @@ export interface IAudioMetadata extends INativeAudioMetadata {
|
|
|
521
521
|
/**
|
|
522
522
|
* Corresponds with parser module name
|
|
523
523
|
*/
|
|
524
|
-
export type ParserType = 'mpeg' | 'apev2' | 'mp4' | 'asf' | 'flac' | 'ogg' | 'aiff' | 'wavpack' | 'riff' | 'musepack' | 'dsf' | 'dsdiff' | 'adts' | 'matroska'
|
|
524
|
+
export type ParserType = 'mpeg' | 'apev2' | 'mp4' | 'asf' | 'flac' | 'ogg' | 'aiff' | 'wavpack' | 'riff' | 'musepack' | 'dsf' | 'dsdiff' | 'adts' | 'matroska';
|
|
525
525
|
export interface IOptions {
|
|
526
526
|
/**
|
|
527
527
|
* default: `false`, if set to `true`, it will parse the whole media file if required to determine the duration.
|
package/lib/wav/WaveLoader.js
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "music-metadata",
|
|
3
3
|
"description": "Music metadata parser for Node.js, supporting virtual any audio and tag format.",
|
|
4
|
-
"version": "11.0
|
|
4
|
+
"version": "11.1.0",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Borewit",
|
|
7
7
|
"url": "https://github.com/Borewit"
|
|
@@ -122,12 +122,12 @@
|
|
|
122
122
|
"@types/debug": "^4.1.12",
|
|
123
123
|
"@types/media-typer": "^1.1.3",
|
|
124
124
|
"@types/mocha": "^10.0.10",
|
|
125
|
-
"@types/node": "^22.
|
|
125
|
+
"@types/node": "^22.14.0",
|
|
126
126
|
"c8": "^10.1.3",
|
|
127
127
|
"chai": "^5.2.0",
|
|
128
128
|
"chai-as-promised": "^8.0.1",
|
|
129
129
|
"del-cli": "^6.0.0",
|
|
130
|
-
"mime": "^4.0.
|
|
130
|
+
"mime": "^4.0.7",
|
|
131
131
|
"mocha": "^11.1.0",
|
|
132
132
|
"node-readable-to-web-readable-stream": "^0.4.2",
|
|
133
133
|
"remark-cli": "^12.0.1",
|
|
@@ -139,7 +139,7 @@
|
|
|
139
139
|
"node": ">=18"
|
|
140
140
|
},
|
|
141
141
|
"repository": {
|
|
142
|
-
"type": "
|
|
142
|
+
"type": "github:Borewit/music-metadata"
|
|
143
143
|
},
|
|
144
144
|
"license": "MIT",
|
|
145
145
|
"bugs": {
|