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.
@@ -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,2 @@
1
+ import type { IParserLoader } from '../ParserFactory.js';
2
+ export declare const amrParserLoader: IParserLoader;
@@ -0,0 +1,8 @@
1
+ export const amrParserLoader = {
2
+ parserType: 'amr',
3
+ extensions: ['.amr'],
4
+ async load(metadata, tokenizer, options) {
5
+ return new (await import('./AmrParser.js')).AmrParser(metadata, tokenizer, options);
6
+ }
7
+ };
8
+ //# sourceMappingURL=AmrLoader.js.map
@@ -0,0 +1,7 @@
1
+ import { BasicParser } from '../common/BasicParser.js';
2
+ /**
3
+ * Adaptive Multi-Rate audio codec
4
+ */
5
+ export declare class AmrParser extends BasicParser {
6
+ parse(): Promise<void>;
7
+ }
@@ -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,11 @@
1
+ import type { IGetToken } from 'strtok3';
2
+ interface IFrameHeader {
3
+ frameType: number;
4
+ }
5
+ /**
6
+ * ID3v2 header
7
+ * Ref: http://id3.org/id3v2.3.0#ID3v2_header
8
+ * ToDo
9
+ */
10
+ export declare const FrameHeader: IGetToken<IFrameHeader>;
11
+ export {};
@@ -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.4.0",
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.4",
109
- "file-type": "^19.4.1",
110
- "media-typer": "^1.1.0",
111
- "strtok3": "^9.0.0",
112
- "token-types": "^6.0.0",
113
- "uint8array-extras": "^1.4.0"
114
- },
115
- "devDependencies": {
116
- "@biomejs/biome": "1.8.3",
117
- "@types/chai": "^4.3.19",
118
- "@types/chai-as-promised": "^8.0.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.7",
123
- "@types/node": "^22.5.4",
124
- "c8": "^10.1.2",
125
- "chai": "^5.1.1",
126
- "chai-as-promised": "^8.0.0",
127
- "del-cli": "^5.1.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.5.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
- }
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
+ }