music-metadata 7.13.0 → 7.13.2
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/lib/asf/AsfObject.js +3 -3
- package/lib/asf/AsfUtil.d.ts +1 -1
- package/lib/asf/GUID.js +3 -3
- package/lib/common/GenericTagMapper.js +4 -4
- package/lib/common/GenericTagTypes.d.ts +2 -2
- package/lib/common/Util.d.ts +1 -1
- package/lib/id3v2/ID3v2Token.d.ts +1 -1
- package/lib/matroska/MatroskaParser.js +5 -3
- package/lib/mp4/Atom.d.ts +1 -1
- package/lib/mp4/Atom.js +7 -7
- package/lib/ogg/OggParser.js +3 -3
- package/lib/ogg/vorbis/Vorbis.js +3 -3
- package/lib/type.d.ts +3 -3
- package/lib/wav/WaveParser.js +6 -1
- package/package.json +12 -12
package/lib/asf/AsfObject.js
CHANGED
|
@@ -347,9 +347,6 @@ MetadataLibraryObjectState.guid = GUID_1.default.MetadataLibraryObject;
|
|
|
347
347
|
* Ref: https://msdn.microsoft.com/en-us/library/windows/desktop/dd757977(v=vs.85).aspx
|
|
348
348
|
*/
|
|
349
349
|
class WmPictureToken {
|
|
350
|
-
constructor(len) {
|
|
351
|
-
this.len = len;
|
|
352
|
-
}
|
|
353
350
|
static fromBase64(base64str) {
|
|
354
351
|
return this.fromBuffer(Buffer.from(base64str, 'base64'));
|
|
355
352
|
}
|
|
@@ -357,6 +354,9 @@ class WmPictureToken {
|
|
|
357
354
|
const pic = new WmPictureToken(buffer.length);
|
|
358
355
|
return pic.get(buffer, 0);
|
|
359
356
|
}
|
|
357
|
+
constructor(len) {
|
|
358
|
+
this.len = len;
|
|
359
|
+
}
|
|
360
360
|
get(buffer, offset) {
|
|
361
361
|
const typeId = buffer.readUInt8(offset++);
|
|
362
362
|
const size = buffer.readInt32LE(offset);
|
package/lib/asf/AsfUtil.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import { DataType } from './AsfObject';
|
|
3
|
-
export
|
|
3
|
+
export type AttributeParser = (buf: Buffer) => boolean | string | number | bigint | Buffer;
|
|
4
4
|
export declare class AsfUtil {
|
|
5
5
|
static getParserForAttr(i: DataType): AttributeParser;
|
|
6
6
|
static parseUnicodeAttr(uint8Array: Uint8Array): string;
|
package/lib/asf/GUID.js
CHANGED
|
@@ -15,9 +15,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
15
15
|
* - https://github.com/dji-sdk/FFmpeg/blob/master/libavformat/asf.c
|
|
16
16
|
*/
|
|
17
17
|
class GUID {
|
|
18
|
-
constructor(str) {
|
|
19
|
-
this.str = str;
|
|
20
|
-
}
|
|
21
18
|
static fromBin(bin, offset = 0) {
|
|
22
19
|
return new GUID(this.decode(bin, offset));
|
|
23
20
|
}
|
|
@@ -64,6 +61,9 @@ class GUID {
|
|
|
64
61
|
Buffer.from(str.slice(24), "hex").copy(bin, 10);
|
|
65
62
|
return bin;
|
|
66
63
|
}
|
|
64
|
+
constructor(str) {
|
|
65
|
+
this.str = str;
|
|
66
|
+
}
|
|
67
67
|
equals(guid) {
|
|
68
68
|
return this.str === guid.str;
|
|
69
69
|
}
|
|
@@ -2,10 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.CommonTagMapper = void 0;
|
|
4
4
|
class CommonTagMapper {
|
|
5
|
-
constructor(tagTypes, tagMap) {
|
|
6
|
-
this.tagTypes = tagTypes;
|
|
7
|
-
this.tagMap = tagMap;
|
|
8
|
-
}
|
|
9
5
|
static toIntOrNull(str) {
|
|
10
6
|
const cleaned = parseInt(str, 10);
|
|
11
7
|
return isNaN(cleaned) ? null : cleaned;
|
|
@@ -20,6 +16,10 @@ class CommonTagMapper {
|
|
|
20
16
|
of: parseInt(split[1], 10) || null
|
|
21
17
|
};
|
|
22
18
|
}
|
|
19
|
+
constructor(tagTypes, tagMap) {
|
|
20
|
+
this.tagTypes = tagTypes;
|
|
21
|
+
this.tagMap = tagMap;
|
|
22
|
+
}
|
|
23
23
|
/**
|
|
24
24
|
* Process and set common tags
|
|
25
25
|
* write common tags to
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
export
|
|
1
|
+
export type TagType = 'vorbis' | 'ID3v1' | 'ID3v2.2' | 'ID3v2.3' | 'ID3v2.4' | 'APEv2' | 'asf' | 'iTunes' | 'exif' | 'matroska' | 'AIFF';
|
|
2
2
|
export interface IGenericTag {
|
|
3
3
|
id: GenericTagId;
|
|
4
4
|
value: any;
|
|
5
5
|
}
|
|
6
|
-
export
|
|
6
|
+
export type GenericTagId = 'track' | 'disk' | 'year' | 'title' | 'artist' | 'artists' | 'albumartist' | 'album' | 'date' | 'originaldate' | 'originalyear' | 'comment' | 'genre' | 'picture' | 'composer' | 'lyrics' | 'albumsort' | 'titlesort' | 'work' | 'artistsort' | 'albumartistsort' | 'composersort' | 'lyricist' | 'writer' | 'conductor' | 'remixer' | 'arranger' | 'engineer' | 'technician' | 'producer' | 'djmixer' | 'mixer' | 'publisher' | 'label' | 'grouping' | 'subtitle' | 'discsubtitle' | 'totaltracks' | 'totaldiscs' | 'compilation' | 'rating' | 'bpm' | 'mood' | 'media' | 'catalognumber' | 'tvShow' | 'tvShowSort' | 'tvEpisode' | 'tvEpisodeId' | 'tvNetwork' | 'tvSeason' | 'podcast' | 'podcasturl' | 'releasestatus' | 'releasetype' | 'releasecountry' | 'script' | 'language' | 'copyright' | 'license' | 'encodedby' | 'encodersettings' | 'gapless' | 'barcode' | 'isrc' | 'asin' | 'musicbrainz_recordingid' | 'musicbrainz_trackid' | 'musicbrainz_albumid' | 'musicbrainz_artistid' | 'musicbrainz_albumartistid' | 'musicbrainz_releasegroupid' | 'musicbrainz_workid' | 'musicbrainz_trmid' | 'musicbrainz_discid' | 'acoustid_id' | 'acoustid_fingerprint' | 'musicip_puid' | 'musicip_fingerprint' | 'website' | 'performer:instrument' | 'peakLevel' | 'averageLevel' | 'notes' | 'key' | 'originalalbum' | 'originalartist' | 'discogs_artist_id' | 'discogs_label_id' | 'discogs_master_release_id' | 'discogs_rating' | 'discogs_release_id' | 'discogs_votes' | 'replaygain_track_gain' | 'replaygain_track_peak' | 'replaygain_album_gain' | 'replaygain_album_peak' | 'replaygain_track_minmax' | 'replaygain_album_minmax' | 'replaygain_undo' | 'description' | 'longDescription' | 'category' | 'hdVideo' | 'keywords' | 'movement' | 'movementIndex' | 'movementTotal' | 'podcastId' | 'showMovement' | 'stik';
|
|
7
7
|
export interface INativeTagMap {
|
|
8
8
|
[index: string]: GenericTagId;
|
|
9
9
|
}
|
package/lib/common/Util.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { IRatio } from '../type';
|
|
2
|
-
export
|
|
2
|
+
export type StringEncoding = 'ascii' | 'utf8' | 'utf16le' | 'ucs2' | 'base64url' | 'latin1' | 'hex';
|
|
3
3
|
export interface ITextEncoding {
|
|
4
4
|
encoding: StringEncoding;
|
|
5
5
|
bom?: boolean;
|
|
@@ -27,7 +27,7 @@ export declare enum AttachedPictureType {
|
|
|
27
27
|
'Band/artist logotype' = 19,
|
|
28
28
|
'Publisher/Studio logotype' = 20
|
|
29
29
|
}
|
|
30
|
-
export
|
|
30
|
+
export type ID3v2MajorVersion = 2 | 3 | 4;
|
|
31
31
|
export interface IExtendedHeader {
|
|
32
32
|
size: number;
|
|
33
33
|
extendedFlags: number;
|
|
@@ -45,9 +45,11 @@ class MatroskaParser extends BasicParser_1.BasicParser {
|
|
|
45
45
|
const info = matroska.segment.info;
|
|
46
46
|
if (info) {
|
|
47
47
|
const timecodeScale = info.timecodeScale ? info.timecodeScale : 1000000;
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
48
|
+
if (typeof info.duration === 'number') {
|
|
49
|
+
const duration = info.duration * timecodeScale / 1000000000;
|
|
50
|
+
this.addTag('segment:title', info.title);
|
|
51
|
+
this.metadata.setFormat('duration', duration);
|
|
52
|
+
}
|
|
51
53
|
}
|
|
52
54
|
const audioTracks = matroska.segment.tracks;
|
|
53
55
|
if (audioTracks && audioTracks.entries) {
|
package/lib/mp4/Atom.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ITokenizer } from 'strtok3/lib/core';
|
|
2
2
|
import * as AtomToken from './AtomToken';
|
|
3
|
-
export
|
|
3
|
+
export type AtomDataHandler = (atom: Atom, remaining: number) => Promise<void>;
|
|
4
4
|
export declare class Atom {
|
|
5
5
|
readonly header: AtomToken.IAtomHeader;
|
|
6
6
|
extended: boolean;
|
package/lib/mp4/Atom.js
CHANGED
|
@@ -5,13 +5,6 @@ const debug_1 = require("debug");
|
|
|
5
5
|
const AtomToken = require("./AtomToken");
|
|
6
6
|
const debug = (0, debug_1.default)('music-metadata:parser:MP4:Atom');
|
|
7
7
|
class Atom {
|
|
8
|
-
constructor(header, extended, parent) {
|
|
9
|
-
this.header = header;
|
|
10
|
-
this.extended = extended;
|
|
11
|
-
this.parent = parent;
|
|
12
|
-
this.children = [];
|
|
13
|
-
this.atomPath = (this.parent ? this.parent.atomPath + '.' : '') + this.header.name;
|
|
14
|
-
}
|
|
15
8
|
static async readAtom(tokenizer, dataHandler, parent, remaining) {
|
|
16
9
|
// Parse atom header
|
|
17
10
|
const offset = tokenizer.position;
|
|
@@ -27,6 +20,13 @@ class Atom {
|
|
|
27
20
|
await atomBean.readData(tokenizer, dataHandler, payloadLength);
|
|
28
21
|
return atomBean;
|
|
29
22
|
}
|
|
23
|
+
constructor(header, extended, parent) {
|
|
24
|
+
this.header = header;
|
|
25
|
+
this.extended = extended;
|
|
26
|
+
this.parent = parent;
|
|
27
|
+
this.children = [];
|
|
28
|
+
this.atomPath = (this.parent ? this.parent.atomPath + '.' : '') + this.header.name;
|
|
29
|
+
}
|
|
30
30
|
getHeaderLength() {
|
|
31
31
|
return this.extended ? 16 : 8;
|
|
32
32
|
}
|
package/lib/ogg/OggParser.js
CHANGED
|
@@ -13,9 +13,6 @@ const SpeexParser_1 = require("./speex/SpeexParser");
|
|
|
13
13
|
const TheoraParser_1 = require("./theora/TheoraParser");
|
|
14
14
|
const debug = (0, debug_1.default)('music-metadata:parser:ogg');
|
|
15
15
|
class SegmentTable {
|
|
16
|
-
constructor(header) {
|
|
17
|
-
this.len = header.page_segments;
|
|
18
|
-
}
|
|
19
16
|
static sum(buf, off, len) {
|
|
20
17
|
let s = 0;
|
|
21
18
|
for (let i = off; i < off + len; ++i) {
|
|
@@ -23,6 +20,9 @@ class SegmentTable {
|
|
|
23
20
|
}
|
|
24
21
|
return s;
|
|
25
22
|
}
|
|
23
|
+
constructor(header) {
|
|
24
|
+
this.len = header.page_segments;
|
|
25
|
+
}
|
|
26
26
|
get(buf, off) {
|
|
27
27
|
return {
|
|
28
28
|
totalPageSize: SegmentTable.sum(buf, off, this.len)
|
package/lib/ogg/vorbis/Vorbis.js
CHANGED
|
@@ -10,9 +10,6 @@ const ID3v2Token_1 = require("../../id3v2/ID3v2Token");
|
|
|
10
10
|
* // ToDo: move to ID3 / APIC?
|
|
11
11
|
*/
|
|
12
12
|
class VorbisPictureToken {
|
|
13
|
-
constructor(len) {
|
|
14
|
-
this.len = len;
|
|
15
|
-
}
|
|
16
13
|
static fromBase64(base64str) {
|
|
17
14
|
return this.fromBuffer(Buffer.from(base64str, 'base64'));
|
|
18
15
|
}
|
|
@@ -20,6 +17,9 @@ class VorbisPictureToken {
|
|
|
20
17
|
const pic = new VorbisPictureToken(buffer.length);
|
|
21
18
|
return pic.get(buffer, 0);
|
|
22
19
|
}
|
|
20
|
+
constructor(len) {
|
|
21
|
+
this.len = len;
|
|
22
|
+
}
|
|
23
23
|
get(buffer, offset) {
|
|
24
24
|
const type = ID3v2Token_1.AttachedPictureType[Token.UINT32_BE.get(buffer, offset)];
|
|
25
25
|
const mimeLen = Token.UINT32_BE.get(buffer, offset += 4);
|
package/lib/type.d.ts
CHANGED
|
@@ -356,7 +356,7 @@ export interface IRatio {
|
|
|
356
356
|
*/
|
|
357
357
|
dB: number;
|
|
358
358
|
}
|
|
359
|
-
export
|
|
359
|
+
export type FormatId = 'container' | 'duration' | 'bitrate' | 'sampleRate' | 'bitsPerSample' | 'codec' | 'tool' | 'codecProfile' | 'lossless' | 'numberOfChannels' | 'numberOfSamples' | 'audioMD5' | 'chapters' | 'modificationTime' | 'creationTime' | 'trackPeakLevel' | 'trackGain' | 'albumGain';
|
|
360
360
|
export interface IAudioTrack {
|
|
361
361
|
samplingFrequency?: number;
|
|
362
362
|
outputSamplingFrequency?: number;
|
|
@@ -507,7 +507,7 @@ export interface IAudioMetadata extends INativeAudioMetadata {
|
|
|
507
507
|
/**
|
|
508
508
|
* Corresponds with parser module name
|
|
509
509
|
*/
|
|
510
|
-
export
|
|
510
|
+
export type ParserType = 'mpeg' | 'apev2' | 'mp4' | 'asf' | 'flac' | 'ogg' | 'aiff' | 'wavpack' | 'riff' | 'musepack' | 'dsf' | 'dsdiff' | 'adts' | 'matroska';
|
|
511
511
|
export interface IOptions {
|
|
512
512
|
/**
|
|
513
513
|
* default: `false`, if set to `true`, it will parse the whole media file if required to determine the duration.
|
|
@@ -570,7 +570,7 @@ export interface IMetadataEvent {
|
|
|
570
570
|
*/
|
|
571
571
|
metadata: IAudioMetadata;
|
|
572
572
|
}
|
|
573
|
-
export
|
|
573
|
+
export type Observer = (update: IMetadataEvent) => void;
|
|
574
574
|
/**
|
|
575
575
|
* Provides random data read access
|
|
576
576
|
* Used read operations on file of buffers
|
package/lib/wav/WaveParser.js
CHANGED
|
@@ -99,7 +99,12 @@ class WaveParser extends BasicParser_1.BasicParser {
|
|
|
99
99
|
this.metadata.setFormat('numberOfSamples', numberOfSamples);
|
|
100
100
|
this.metadata.setFormat('duration', numberOfSamples / this.metadata.format.sampleRate);
|
|
101
101
|
}
|
|
102
|
-
|
|
102
|
+
if (this.metadata.format.codec === 'ADPCM') { // ADPCM is 4 bits lossy encoding resulting in 352kbps
|
|
103
|
+
this.metadata.setFormat('bitrate', 352000);
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
this.metadata.setFormat('bitrate', this.blockAlign * this.metadata.format.sampleRate * 8);
|
|
107
|
+
}
|
|
103
108
|
await this.tokenizer.ignore(header.chunkSize);
|
|
104
109
|
break;
|
|
105
110
|
case 'bext': // Broadcast Audio Extension chunk https://tech.ebu.ch/docs/tech/tech3285.pdf
|
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": "7.13.
|
|
4
|
+
"version": "7.13.2",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Borewit",
|
|
7
7
|
"url": "https://github.com/Borewit"
|
|
@@ -92,24 +92,24 @@
|
|
|
92
92
|
"token-types": "^4.2.1"
|
|
93
93
|
},
|
|
94
94
|
"devDependencies": {
|
|
95
|
-
"@types/chai": "^4.3.
|
|
95
|
+
"@types/chai": "^4.3.4",
|
|
96
96
|
"@types/chai-as-promised": "^7.1.5",
|
|
97
97
|
"@types/debug": "^4.1.7",
|
|
98
98
|
"@types/file-type": "^10.9.1",
|
|
99
99
|
"@types/mocha": "^9.1.0",
|
|
100
|
-
"@types/node": "^18.
|
|
101
|
-
"@typescript-eslint/eslint-plugin": "^5.
|
|
102
|
-
"@typescript-eslint/parser": "^5.
|
|
103
|
-
"chai": "^4.3.
|
|
100
|
+
"@types/node": "^18.11.9",
|
|
101
|
+
"@typescript-eslint/eslint-plugin": "^5.48.0",
|
|
102
|
+
"@typescript-eslint/parser": "^5.48.0",
|
|
103
|
+
"chai": "^4.3.7",
|
|
104
104
|
"chai-as-promised": "^7.1.1",
|
|
105
105
|
"del-cli": "5.0.0",
|
|
106
|
-
"eslint": "^8.
|
|
107
|
-
"eslint-config-prettier": "^8.
|
|
108
|
-
"eslint-import-resolver-typescript": "^3.5.
|
|
106
|
+
"eslint": "^8.31.0",
|
|
107
|
+
"eslint-config-prettier": "^8.6.0",
|
|
108
|
+
"eslint-import-resolver-typescript": "^3.5.2",
|
|
109
109
|
"eslint-plugin-import": "^2.26.0",
|
|
110
|
-
"eslint-plugin-jsdoc": "^39.
|
|
110
|
+
"eslint-plugin-jsdoc": "^39.6.4",
|
|
111
111
|
"eslint-plugin-node": "^11.1.0",
|
|
112
|
-
"eslint-plugin-unicorn": "^
|
|
112
|
+
"eslint-plugin-unicorn": "^45.0.2",
|
|
113
113
|
"mime": "^3.0.0",
|
|
114
114
|
"mocha": "^9.2.2",
|
|
115
115
|
"npm-run-all": "^4.1.5",
|
|
@@ -118,7 +118,7 @@
|
|
|
118
118
|
"remark-preset-lint-recommended": "^6.1.2",
|
|
119
119
|
"source-map-support": "^0.5.21",
|
|
120
120
|
"ts-node": "^10.9.1",
|
|
121
|
-
"typescript": "^4.
|
|
121
|
+
"typescript": "^4.9.4"
|
|
122
122
|
},
|
|
123
123
|
"engines": {
|
|
124
124
|
"node": ">=10"
|