music-metadata 10.4.0 → 10.5.1
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/LICENSE.txt +9 -9
- package/README.md +845 -844
- package/lib/ParserFactory.js +5 -1
- package/lib/amr/AmrLoader.d.ts +2 -0
- package/lib/amr/AmrLoader.js +8 -0
- package/lib/amr/AmrParser.d.ts +7 -0
- package/lib/amr/AmrParser.js +49 -0
- package/lib/amr/AmrToken.d.ts +11 -0
- package/lib/amr/AmrToken.js +15 -0
- package/lib/default.cjs +5 -5
- package/lib/node.cjs +5 -5
- package/lib/type.d.ts +1 -1
- package/package.json +148 -148
package/lib/ParserFactory.js
CHANGED
|
@@ -17,6 +17,7 @@ import { musepackParserLoader } from './musepack/MusepackLoader.js';
|
|
|
17
17
|
import { oggParserLoader } from './ogg/OggLoader.js';
|
|
18
18
|
import { wavpackParserLoader } from './wavpack/WavPackLoader.js';
|
|
19
19
|
import { riffParserLoader } from './wav/WaveLoader.js';
|
|
20
|
+
import { amrParserLoader } from './amr/AmrLoader.js';
|
|
20
21
|
const debug = initDebug('music-metadata:parser:factory');
|
|
21
22
|
export function parseHttpContentType(contentType) {
|
|
22
23
|
const type = ContentType.parse(contentType);
|
|
@@ -44,7 +45,8 @@ export class ParserFactory {
|
|
|
44
45
|
wavpackParserLoader,
|
|
45
46
|
musepackParserLoader,
|
|
46
47
|
dsfParserLoader,
|
|
47
|
-
dsdiffParserLoader
|
|
48
|
+
dsdiffParserLoader,
|
|
49
|
+
amrParserLoader
|
|
48
50
|
].forEach(parser => this.registerParser(parser));
|
|
49
51
|
}
|
|
50
52
|
registerParser(parser) {
|
|
@@ -158,6 +160,8 @@ function getParserIdForMimeType(httpContentType) {
|
|
|
158
160
|
return 'matroska';
|
|
159
161
|
case 'dsf':
|
|
160
162
|
return 'dsf';
|
|
163
|
+
case 'amr':
|
|
164
|
+
return 'amr';
|
|
161
165
|
}
|
|
162
166
|
break;
|
|
163
167
|
case 'video':
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { BasicParser } from '../common/BasicParser.js';
|
|
2
|
+
import { AnsiStringType } from 'token-types';
|
|
3
|
+
import initDebug from 'debug';
|
|
4
|
+
import { FrameHeader } from './AmrToken.js';
|
|
5
|
+
const debug = initDebug('music-metadata:parser:AMR');
|
|
6
|
+
/**
|
|
7
|
+
* There are 8 varying levels of compression. First byte of the frame specifies CMR
|
|
8
|
+
* (codec mode request), values 0-7 are valid for AMR. Each mode have different frame size.
|
|
9
|
+
* This table reflects that fact.
|
|
10
|
+
*/
|
|
11
|
+
const m_block_size = [12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 0];
|
|
12
|
+
/**
|
|
13
|
+
* Adaptive Multi-Rate audio codec
|
|
14
|
+
*/
|
|
15
|
+
export class AmrParser extends BasicParser {
|
|
16
|
+
async parse() {
|
|
17
|
+
const magicNr = await this.tokenizer.readToken(new AnsiStringType(5));
|
|
18
|
+
if (magicNr !== '#!AMR') {
|
|
19
|
+
throw new Error('Invalid AMR file: invalid MAGIC number');
|
|
20
|
+
}
|
|
21
|
+
this.metadata.setFormat('container', 'AMR');
|
|
22
|
+
this.metadata.setFormat('codec', 'AMR');
|
|
23
|
+
this.metadata.setFormat('sampleRate', 8000);
|
|
24
|
+
this.metadata.setFormat('bitrate', 64000);
|
|
25
|
+
this.metadata.setFormat('numberOfChannels', 1);
|
|
26
|
+
let total_size = 0;
|
|
27
|
+
let frames = 0;
|
|
28
|
+
const assumedFileLength = this.tokenizer.fileInfo?.size ?? Number.MAX_SAFE_INTEGER;
|
|
29
|
+
if (this.options.duration) {
|
|
30
|
+
while (this.tokenizer.position < assumedFileLength) {
|
|
31
|
+
const header = await this.tokenizer.readToken(FrameHeader);
|
|
32
|
+
/* first byte is rate mode. each rate mode has frame of given length. look it up. */
|
|
33
|
+
const size = m_block_size[header.frameType];
|
|
34
|
+
if (size > 0) {
|
|
35
|
+
total_size += size + 1;
|
|
36
|
+
if (total_size > assumedFileLength)
|
|
37
|
+
break;
|
|
38
|
+
await this.tokenizer.ignore(size);
|
|
39
|
+
++frames;
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
debug(`Found no-data frame, frame-type: ${header.frameType}. Skipping`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
this.metadata.setFormat('duration', frames * 0.02);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=AmrParser.js.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { getBitAllignedNumber } from '../common/Util.js';
|
|
2
|
+
/**
|
|
3
|
+
* ID3v2 header
|
|
4
|
+
* Ref: http://id3.org/id3v2.3.0#ID3v2_header
|
|
5
|
+
* ToDo
|
|
6
|
+
*/
|
|
7
|
+
export const FrameHeader = {
|
|
8
|
+
len: 1,
|
|
9
|
+
get: (buf, off) => {
|
|
10
|
+
return {
|
|
11
|
+
frameType: getBitAllignedNumber(buf, off, 1, 4)
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=AmrToken.js.map
|
package/lib/default.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
// CommonJS core (default) entry point
|
|
2
|
-
"use strict";
|
|
3
|
-
module.exports = {
|
|
4
|
-
loadMusicMetadata: () => import('./core.js'),
|
|
5
|
-
};
|
|
1
|
+
// CommonJS core (default) entry point
|
|
2
|
+
"use strict";
|
|
3
|
+
module.exports = {
|
|
4
|
+
loadMusicMetadata: () => import('./core.js'),
|
|
5
|
+
};
|
package/lib/node.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
// CommonJS Node entry point
|
|
2
|
-
"use strict";
|
|
3
|
-
module.exports = {
|
|
4
|
-
loadMusicMetadata: () => import('./index.js'),
|
|
5
|
-
};
|
|
1
|
+
// CommonJS Node entry point
|
|
2
|
+
"use strict";
|
|
3
|
+
module.exports = {
|
|
4
|
+
loadMusicMetadata: () => import('./index.js'),
|
|
5
|
+
};
|
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' | 'amr';
|
|
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/package.json
CHANGED
|
@@ -1,148 +1,148 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "music-metadata",
|
|
3
|
-
"description": "Music metadata parser for Node.js, supporting virtual any audio and tag format.",
|
|
4
|
-
"version": "10.
|
|
5
|
-
"author": {
|
|
6
|
-
"name": "Borewit",
|
|
7
|
-
"url": "https://github.com/Borewit"
|
|
8
|
-
},
|
|
9
|
-
"funding": [
|
|
10
|
-
{
|
|
11
|
-
"type": "github",
|
|
12
|
-
"url": "https://github.com/sponsors/Borewit"
|
|
13
|
-
},
|
|
14
|
-
{
|
|
15
|
-
"type": "buymeacoffee",
|
|
16
|
-
"url": "https://buymeacoffee.com/borewit"
|
|
17
|
-
}
|
|
18
|
-
],
|
|
19
|
-
"type": "module",
|
|
20
|
-
"exports": {
|
|
21
|
-
".": {
|
|
22
|
-
"node": {
|
|
23
|
-
"import": "./lib/index.js",
|
|
24
|
-
"require": "./lib/node.cjs",
|
|
25
|
-
"types": "./lib/index.d.ts"
|
|
26
|
-
},
|
|
27
|
-
"default": {
|
|
28
|
-
"import": "./lib/core.js",
|
|
29
|
-
"require": "./lib/default.cjs",
|
|
30
|
-
"types": "./lib/core.d.ts"
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
},
|
|
34
|
-
"types": "lib/index.d.ts",
|
|
35
|
-
"files": [
|
|
36
|
-
"lib/**/*.js",
|
|
37
|
-
"lib/**/*.d.ts",
|
|
38
|
-
"lib/*.cjs"
|
|
39
|
-
],
|
|
40
|
-
"keywords": [
|
|
41
|
-
"music",
|
|
42
|
-
"metadata",
|
|
43
|
-
"meta",
|
|
44
|
-
"audio",
|
|
45
|
-
"tag",
|
|
46
|
-
"tags",
|
|
47
|
-
"duration",
|
|
48
|
-
"MusicBrainz",
|
|
49
|
-
"Discogs",
|
|
50
|
-
"Picard",
|
|
51
|
-
"ID3",
|
|
52
|
-
"ID3v1",
|
|
53
|
-
"ID3v2",
|
|
54
|
-
"m4a",
|
|
55
|
-
"m4b",
|
|
56
|
-
"mp3",
|
|
57
|
-
"mp4",
|
|
58
|
-
"Vorbis",
|
|
59
|
-
"ogg",
|
|
60
|
-
"flac",
|
|
61
|
-
"Matroska",
|
|
62
|
-
"WebM",
|
|
63
|
-
"EBML",
|
|
64
|
-
"asf",
|
|
65
|
-
"wma",
|
|
66
|
-
"wmv",
|
|
67
|
-
"ape",
|
|
68
|
-
"MonkeyAudio",
|
|
69
|
-
"aiff",
|
|
70
|
-
"wav",
|
|
71
|
-
"WavPack",
|
|
72
|
-
"Opus",
|
|
73
|
-
"speex",
|
|
74
|
-
"musepack",
|
|
75
|
-
"mpc",
|
|
76
|
-
"dsd",
|
|
77
|
-
"dsf",
|
|
78
|
-
"mpc",
|
|
79
|
-
"dff",
|
|
80
|
-
"dsdiff",
|
|
81
|
-
"aac",
|
|
82
|
-
"adts",
|
|
83
|
-
"length",
|
|
84
|
-
"chapter",
|
|
85
|
-
"info",
|
|
86
|
-
"parse",
|
|
87
|
-
"parser",
|
|
88
|
-
"bwf"
|
|
89
|
-
],
|
|
90
|
-
"scripts": {
|
|
91
|
-
"clean": "del-cli 'lib/**/*.js' 'lib/**/*.js.map' 'lib/**/*.d.ts' 'src/**/*.d.ts' 'test/**/*.js' 'test/**/*.js.map' 'test/**/*.js' 'test/**/*.js.map' 'doc-gen/**/*.js' 'doc-gen/**/*.js.map'",
|
|
92
|
-
"compile-src": "tsc -p lib",
|
|
93
|
-
"compile-test": "tsc -p test",
|
|
94
|
-
"compile-doc": "tsc -p doc-gen",
|
|
95
|
-
"compile": "yarn run compile-src && yarn compile-test && yarn compile-doc",
|
|
96
|
-
"lint-ts": "biome check",
|
|
97
|
-
"lint-md": "yarn run remark -u remark-preset-lint-consistent .",
|
|
98
|
-
"lint": "yarn run lint-ts && yarn run lint-md",
|
|
99
|
-
"test": "mocha",
|
|
100
|
-
"build": "yarn run clean && yarn compile && yarn run doc-gen",
|
|
101
|
-
"test-coverage": "c8 yarn run test",
|
|
102
|
-
"send-codacy": "c8 report --reporter=text-lcov | codacy-coverage",
|
|
103
|
-
"doc-gen": "yarn node doc-gen/gen.js"
|
|
104
|
-
},
|
|
105
|
-
"dependencies": {
|
|
106
|
-
"@tokenizer/token": "^0.3.0",
|
|
107
|
-
"content-type": "^1.0.5",
|
|
108
|
-
"debug": "^4.3.
|
|
109
|
-
"file-type": "^19.
|
|
110
|
-
"media-typer": "^1.1.0",
|
|
111
|
-
"strtok3": "^9.0.
|
|
112
|
-
"token-types": "^6.0.0",
|
|
113
|
-
"uint8array-extras": "^1.4.0"
|
|
114
|
-
},
|
|
115
|
-
"devDependencies": {
|
|
116
|
-
"@biomejs/biome": "1.
|
|
117
|
-
"@types/chai": "^
|
|
118
|
-
"@types/chai-as-promised": "^8.0.
|
|
119
|
-
"@types/content-type": "^1.1.8",
|
|
120
|
-
"@types/debug": "^4.1.12",
|
|
121
|
-
"@types/media-typer": "^1.1.3",
|
|
122
|
-
"@types/mocha": "^10.0.
|
|
123
|
-
"@types/node": "^22.5
|
|
124
|
-
"c8": "^10.1.2",
|
|
125
|
-
"chai": "^5.1.1",
|
|
126
|
-
"chai-as-promised": "^8.0.0",
|
|
127
|
-
"del-cli": "^
|
|
128
|
-
"mime": "^4.0.4",
|
|
129
|
-
"mocha": "^10.7.3",
|
|
130
|
-
"prettier": "^3.3.3",
|
|
131
|
-
"remark-cli": "^12.0.1",
|
|
132
|
-
"remark-preset-lint-consistent": "^6.0.0",
|
|
133
|
-
"ts-node": "^10.9.2",
|
|
134
|
-
"typescript": "^5.
|
|
135
|
-
},
|
|
136
|
-
"engines": {
|
|
137
|
-
"node": ">=16.0.0"
|
|
138
|
-
},
|
|
139
|
-
"repository": {
|
|
140
|
-
"type": "git",
|
|
141
|
-
"url": "git+https://github.com/borewit/music-metadata.git"
|
|
142
|
-
},
|
|
143
|
-
"license": "MIT",
|
|
144
|
-
"bugs": {
|
|
145
|
-
"url": "https://github.com/Borewit/music-metadata/issues"
|
|
146
|
-
},
|
|
147
|
-
"packageManager": "yarn@4.3.1"
|
|
148
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "music-metadata",
|
|
3
|
+
"description": "Music metadata parser for Node.js, supporting virtual any audio and tag format.",
|
|
4
|
+
"version": "10.5.1",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "Borewit",
|
|
7
|
+
"url": "https://github.com/Borewit"
|
|
8
|
+
},
|
|
9
|
+
"funding": [
|
|
10
|
+
{
|
|
11
|
+
"type": "github",
|
|
12
|
+
"url": "https://github.com/sponsors/Borewit"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"type": "buymeacoffee",
|
|
16
|
+
"url": "https://buymeacoffee.com/borewit"
|
|
17
|
+
}
|
|
18
|
+
],
|
|
19
|
+
"type": "module",
|
|
20
|
+
"exports": {
|
|
21
|
+
".": {
|
|
22
|
+
"node": {
|
|
23
|
+
"import": "./lib/index.js",
|
|
24
|
+
"require": "./lib/node.cjs",
|
|
25
|
+
"types": "./lib/index.d.ts"
|
|
26
|
+
},
|
|
27
|
+
"default": {
|
|
28
|
+
"import": "./lib/core.js",
|
|
29
|
+
"require": "./lib/default.cjs",
|
|
30
|
+
"types": "./lib/core.d.ts"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"types": "lib/index.d.ts",
|
|
35
|
+
"files": [
|
|
36
|
+
"lib/**/*.js",
|
|
37
|
+
"lib/**/*.d.ts",
|
|
38
|
+
"lib/*.cjs"
|
|
39
|
+
],
|
|
40
|
+
"keywords": [
|
|
41
|
+
"music",
|
|
42
|
+
"metadata",
|
|
43
|
+
"meta",
|
|
44
|
+
"audio",
|
|
45
|
+
"tag",
|
|
46
|
+
"tags",
|
|
47
|
+
"duration",
|
|
48
|
+
"MusicBrainz",
|
|
49
|
+
"Discogs",
|
|
50
|
+
"Picard",
|
|
51
|
+
"ID3",
|
|
52
|
+
"ID3v1",
|
|
53
|
+
"ID3v2",
|
|
54
|
+
"m4a",
|
|
55
|
+
"m4b",
|
|
56
|
+
"mp3",
|
|
57
|
+
"mp4",
|
|
58
|
+
"Vorbis",
|
|
59
|
+
"ogg",
|
|
60
|
+
"flac",
|
|
61
|
+
"Matroska",
|
|
62
|
+
"WebM",
|
|
63
|
+
"EBML",
|
|
64
|
+
"asf",
|
|
65
|
+
"wma",
|
|
66
|
+
"wmv",
|
|
67
|
+
"ape",
|
|
68
|
+
"MonkeyAudio",
|
|
69
|
+
"aiff",
|
|
70
|
+
"wav",
|
|
71
|
+
"WavPack",
|
|
72
|
+
"Opus",
|
|
73
|
+
"speex",
|
|
74
|
+
"musepack",
|
|
75
|
+
"mpc",
|
|
76
|
+
"dsd",
|
|
77
|
+
"dsf",
|
|
78
|
+
"mpc",
|
|
79
|
+
"dff",
|
|
80
|
+
"dsdiff",
|
|
81
|
+
"aac",
|
|
82
|
+
"adts",
|
|
83
|
+
"length",
|
|
84
|
+
"chapter",
|
|
85
|
+
"info",
|
|
86
|
+
"parse",
|
|
87
|
+
"parser",
|
|
88
|
+
"bwf"
|
|
89
|
+
],
|
|
90
|
+
"scripts": {
|
|
91
|
+
"clean": "del-cli 'lib/**/*.js' 'lib/**/*.js.map' 'lib/**/*.d.ts' 'src/**/*.d.ts' 'test/**/*.js' 'test/**/*.js.map' 'test/**/*.js' 'test/**/*.js.map' 'doc-gen/**/*.js' 'doc-gen/**/*.js.map'",
|
|
92
|
+
"compile-src": "tsc -p lib",
|
|
93
|
+
"compile-test": "tsc -p test",
|
|
94
|
+
"compile-doc": "tsc -p doc-gen",
|
|
95
|
+
"compile": "yarn run compile-src && yarn compile-test && yarn compile-doc",
|
|
96
|
+
"lint-ts": "biome check",
|
|
97
|
+
"lint-md": "yarn run remark -u remark-preset-lint-consistent .",
|
|
98
|
+
"lint": "yarn run lint-ts && yarn run lint-md",
|
|
99
|
+
"test": "mocha",
|
|
100
|
+
"build": "yarn run clean && yarn compile && yarn run doc-gen",
|
|
101
|
+
"test-coverage": "c8 yarn run test",
|
|
102
|
+
"send-codacy": "c8 report --reporter=text-lcov | codacy-coverage",
|
|
103
|
+
"doc-gen": "yarn node doc-gen/gen.js"
|
|
104
|
+
},
|
|
105
|
+
"dependencies": {
|
|
106
|
+
"@tokenizer/token": "^0.3.0",
|
|
107
|
+
"content-type": "^1.0.5",
|
|
108
|
+
"debug": "^4.3.7",
|
|
109
|
+
"file-type": "^19.6.0",
|
|
110
|
+
"media-typer": "^1.1.0",
|
|
111
|
+
"strtok3": "^9.0.1",
|
|
112
|
+
"token-types": "^6.0.0",
|
|
113
|
+
"uint8array-extras": "^1.4.0"
|
|
114
|
+
},
|
|
115
|
+
"devDependencies": {
|
|
116
|
+
"@biomejs/biome": "1.9.3",
|
|
117
|
+
"@types/chai": "^5.0.0",
|
|
118
|
+
"@types/chai-as-promised": "^8.0.1",
|
|
119
|
+
"@types/content-type": "^1.1.8",
|
|
120
|
+
"@types/debug": "^4.1.12",
|
|
121
|
+
"@types/media-typer": "^1.1.3",
|
|
122
|
+
"@types/mocha": "^10.0.9",
|
|
123
|
+
"@types/node": "^22.7.5",
|
|
124
|
+
"c8": "^10.1.2",
|
|
125
|
+
"chai": "^5.1.1",
|
|
126
|
+
"chai-as-promised": "^8.0.0",
|
|
127
|
+
"del-cli": "^6.0.0",
|
|
128
|
+
"mime": "^4.0.4",
|
|
129
|
+
"mocha": "^10.7.3",
|
|
130
|
+
"prettier": "^3.3.3",
|
|
131
|
+
"remark-cli": "^12.0.1",
|
|
132
|
+
"remark-preset-lint-consistent": "^6.0.0",
|
|
133
|
+
"ts-node": "^10.9.2",
|
|
134
|
+
"typescript": "^5.6.3"
|
|
135
|
+
},
|
|
136
|
+
"engines": {
|
|
137
|
+
"node": ">=16.0.0"
|
|
138
|
+
},
|
|
139
|
+
"repository": {
|
|
140
|
+
"type": "git",
|
|
141
|
+
"url": "git+https://github.com/borewit/music-metadata.git"
|
|
142
|
+
},
|
|
143
|
+
"license": "MIT",
|
|
144
|
+
"bugs": {
|
|
145
|
+
"url": "https://github.com/Borewit/music-metadata/issues"
|
|
146
|
+
},
|
|
147
|
+
"packageManager": "yarn@4.3.1"
|
|
148
|
+
}
|