taglib-wasm 2.1.0 → 2.2.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/dist/index.browser.js +48 -9
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -4
- package/dist/simple.browser.js +97 -10
- package/dist/src/constants/properties.d.ts +14 -0
- package/dist/src/constants/properties.d.ts.map +1 -1
- package/dist/src/constants/specialized-properties.d.ts +14 -0
- package/dist/src/constants/specialized-properties.d.ts.map +1 -1
- package/dist/src/constants/specialized-properties.js +22 -0
- package/dist/src/folder-api/folder-operations.d.ts +2 -30
- package/dist/src/folder-api/folder-operations.d.ts.map +1 -1
- package/dist/src/folder-api/folder-operations.js +1 -36
- package/dist/src/folder-api/index.d.ts +2 -2
- package/dist/src/folder-api/index.d.ts.map +1 -1
- package/dist/src/folder-api/index.js +2 -7
- package/dist/src/folder-api/types.d.ts +0 -21
- package/dist/src/folder-api/types.d.ts.map +1 -1
- package/dist/src/folder-api/types.js +1 -13
- package/dist/src/simple/batch-operations.d.ts +57 -2
- package/dist/src/simple/batch-operations.d.ts.map +1 -1
- package/dist/src/simple/batch-operations.js +55 -5
- package/dist/src/simple/index.d.ts +2 -2
- package/dist/src/simple/index.d.ts.map +1 -1
- package/dist/src/simple/index.js +6 -2
- package/dist/src/simple/tag-operations.d.ts +5 -1
- package/dist/src/simple/tag-operations.d.ts.map +1 -1
- package/dist/src/simple/tag-operations.js +5 -2
- package/dist/src/types/metadata-mappings.d.ts +1 -1
- package/dist/src/types/metadata-mappings.d.ts.map +1 -1
- package/dist/src/types/metadata-mappings.js +5 -0
- package/dist/src/types/tags.d.ts +13 -0
- package/dist/src/types/tags.d.ts.map +1 -1
- package/dist/src/utils/tag-mapping.d.ts +1 -1
- package/dist/src/utils/tag-mapping.d.ts.map +1 -1
- package/dist/src/utils/tag-mapping.js +16 -2
- package/dist/src/version.d.ts +1 -1
- package/dist/src/version.js +1 -1
- package/dist/taglib-wasi.wasm +0 -0
- package/dist/taglib-web.wasm +0 -0
- package/package.json +1 -1
package/dist/index.browser.js
CHANGED
|
@@ -1387,6 +1387,28 @@ var init_specialized_properties = __esm({
|
|
|
1387
1387
|
mp4: "----:com.apple.iTunes:MusicBrainz Album Type"
|
|
1388
1388
|
}
|
|
1389
1389
|
},
|
|
1390
|
+
releaseCountry: {
|
|
1391
|
+
key: "RELEASECOUNTRY",
|
|
1392
|
+
description: "Release country (ISO 3166-1 code, e.g. 'US'). TagLib 2.3.1 translates the RELEASECOUNTRY key per format: ID3v2 TXXX 'MUSICBRAINZ ALBUM RELEASE COUNTRY' (TagLib's description casing; an uppercase TXXX:RELEASECOUNTRY description also reads back), MP4 freeform atom 'MusicBrainz Album Release Country', APEv2 raw RELEASECOUNTRY, ASF 'MusicBrainz/Album Release Country', WAV ICNT, Vorbis/Matroska raw RELEASECOUNTRY",
|
|
1393
|
+
type: "string",
|
|
1394
|
+
supportedFormats: [
|
|
1395
|
+
"ID3v2",
|
|
1396
|
+
"MP4",
|
|
1397
|
+
"Vorbis",
|
|
1398
|
+
"APE",
|
|
1399
|
+
"ASF",
|
|
1400
|
+
"Matroska",
|
|
1401
|
+
"WAV"
|
|
1402
|
+
],
|
|
1403
|
+
mappings: {
|
|
1404
|
+
id3v2: {
|
|
1405
|
+
frame: "TXXX",
|
|
1406
|
+
description: "MusicBrainz Album Release Country"
|
|
1407
|
+
},
|
|
1408
|
+
vorbis: "RELEASECOUNTRY",
|
|
1409
|
+
mp4: "----:com.apple.iTunes:MusicBrainz Album Release Country"
|
|
1410
|
+
}
|
|
1411
|
+
},
|
|
1390
1412
|
itunesAdvisory: {
|
|
1391
1413
|
key: "ITUNESADVISORY",
|
|
1392
1414
|
description: "Content advisory in the ITUNESADVISORY convention ('1' = explicit, '2' = clean, '0' = unspecified). On MP4 the value is stored in the native rtng atom and surfaced here. The typed tri-state lives on ExtendedTag.advisory; aliases CONTENTADVISORY and EXPLICIT resolve here",
|
|
@@ -2765,8 +2787,9 @@ var init_mirror_fields = __esm({
|
|
|
2765
2787
|
});
|
|
2766
2788
|
|
|
2767
2789
|
// src/utils/tag-mapping.ts
|
|
2768
|
-
function readExtendedTag(audioFile) {
|
|
2769
|
-
const
|
|
2790
|
+
function readExtendedTag(audioFile, includeProperties) {
|
|
2791
|
+
const props = audioFile.properties();
|
|
2792
|
+
const tag = mapPropertiesToExtendedTag(props);
|
|
2770
2793
|
const pictures = audioFile.getPictures();
|
|
2771
2794
|
if (pictures.length > 0) tag.pictures = pictures;
|
|
2772
2795
|
const ratings = audioFile.getRatings();
|
|
@@ -2781,6 +2804,18 @@ function readExtendedTag(audioFile) {
|
|
|
2781
2804
|
if (bextData !== void 0) tag.bextData = bextData;
|
|
2782
2805
|
const ixml = audioFile.getIxml();
|
|
2783
2806
|
if (ixml !== void 0) tag.ixml = ixml;
|
|
2807
|
+
if (includeProperties !== void 0 && includeProperties.length > 0) {
|
|
2808
|
+
const extraProperties = {};
|
|
2809
|
+
for (const wireKey of includeProperties) {
|
|
2810
|
+
const values = props[fromTagLibKey(wireKey)]?.filter((v) => v !== "");
|
|
2811
|
+
if (values !== void 0 && values.length > 0) {
|
|
2812
|
+
extraProperties[wireKey] = values;
|
|
2813
|
+
}
|
|
2814
|
+
}
|
|
2815
|
+
if (Object.keys(extraProperties).length > 0) {
|
|
2816
|
+
tag.extraProperties = extraProperties;
|
|
2817
|
+
}
|
|
2818
|
+
}
|
|
2784
2819
|
return tag;
|
|
2785
2820
|
}
|
|
2786
2821
|
function mapPropertiesToExtendedTag(props) {
|
|
@@ -2900,6 +2935,7 @@ function normalizeTagInput(input) {
|
|
|
2900
2935
|
}
|
|
2901
2936
|
for (const [field, val] of Object.entries(input)) {
|
|
2902
2937
|
if (BASIC_FIELDS.has(field) || val === void 0) continue;
|
|
2938
|
+
if (field === "extraProperties") continue;
|
|
2903
2939
|
if (field === "compilation") {
|
|
2904
2940
|
props[field] = [val ? "1" : "0"];
|
|
2905
2941
|
} else if (field === "advisory") {
|
|
@@ -2966,7 +3002,7 @@ var VERSION;
|
|
|
2966
3002
|
var init_version = __esm({
|
|
2967
3003
|
"src/version.ts"() {
|
|
2968
3004
|
"use strict";
|
|
2969
|
-
VERSION = "2.
|
|
3005
|
+
VERSION = "2.2.0";
|
|
2970
3006
|
}
|
|
2971
3007
|
});
|
|
2972
3008
|
|
|
@@ -3321,8 +3357,11 @@ async function withAudioFileSaveToFile(file, fn) {
|
|
|
3321
3357
|
}
|
|
3322
3358
|
|
|
3323
3359
|
// src/simple/tag-operations.ts
|
|
3324
|
-
async function readTags(file) {
|
|
3325
|
-
return withAudioFile(
|
|
3360
|
+
async function readTags(file, options = {}) {
|
|
3361
|
+
return withAudioFile(
|
|
3362
|
+
file,
|
|
3363
|
+
(audioFile) => readExtendedTag(audioFile, options.includeProperties)
|
|
3364
|
+
);
|
|
3326
3365
|
}
|
|
3327
3366
|
async function applyTags(file, tags) {
|
|
3328
3367
|
return withAudioFileSave(file, (audioFile) => {
|
|
@@ -3500,7 +3539,7 @@ async function readTagsBatch(files, options = {}) {
|
|
|
3500
3539
|
return executeBatch(
|
|
3501
3540
|
files,
|
|
3502
3541
|
options,
|
|
3503
|
-
(audioFile) => readExtendedTag(audioFile)
|
|
3542
|
+
(audioFile) => readExtendedTag(audioFile, options.includeProperties)
|
|
3504
3543
|
);
|
|
3505
3544
|
}
|
|
3506
3545
|
async function readPropertiesBatch(files, options = {}) {
|
|
@@ -3529,7 +3568,7 @@ function extractDynamics(audioFile) {
|
|
|
3529
3568
|
if (appleSoundCheck) dynamics.appleSoundCheck = appleSoundCheck;
|
|
3530
3569
|
return Object.keys(dynamics).length > 0 ? dynamics : void 0;
|
|
3531
3570
|
}
|
|
3532
|
-
async function readMetadata(file) {
|
|
3571
|
+
async function readMetadata(file, options = {}) {
|
|
3533
3572
|
const taglib = await getTagLib();
|
|
3534
3573
|
const audioFile = await taglib.open(file);
|
|
3535
3574
|
try {
|
|
@@ -3550,7 +3589,7 @@ async function readMetadata(file) {
|
|
|
3550
3589
|
}
|
|
3551
3590
|
const dynamics = extractDynamics(audioFile);
|
|
3552
3591
|
return {
|
|
3553
|
-
tags: readExtendedTag(audioFile),
|
|
3592
|
+
tags: readExtendedTag(audioFile, options.includeProperties),
|
|
3554
3593
|
properties: audioFile.audioProperties(),
|
|
3555
3594
|
hasCoverArt: audioFile.getPictures().length > 0,
|
|
3556
3595
|
...dynamics !== void 0 ? { dynamics } : {}
|
|
@@ -3563,7 +3602,7 @@ async function readMetadataBatch(files, options = {}) {
|
|
|
3563
3602
|
return executeBatch(files, options, (audioFile) => {
|
|
3564
3603
|
const dynamics = extractDynamics(audioFile);
|
|
3565
3604
|
return {
|
|
3566
|
-
tags: readExtendedTag(audioFile),
|
|
3605
|
+
tags: readExtendedTag(audioFile, options.includeProperties),
|
|
3567
3606
|
properties: audioFile.audioProperties(),
|
|
3568
3607
|
hasCoverArt: audioFile.getPictures().length > 0,
|
|
3569
3608
|
...dynamics !== void 0 ? { dynamics } : {}
|
package/dist/index.d.ts
CHANGED
|
@@ -43,7 +43,7 @@ export { addPicture, applyCoverArt, applyPictures, applyTags, applyTagsToFile, t
|
|
|
43
43
|
export { FormatMappings, getAllProperties, getAllPropertyKeys, getPropertiesByFormat, getPropertyMetadata, isValidProperty, PROPERTIES, propertyValue, propertyValues, } from "./src/constants.js";
|
|
44
44
|
export type { PropertyMetadata } from "./src/constants/property-types.js";
|
|
45
45
|
export { copyCoverArt, exportAllPictures, exportCoverArt, exportPictureByType, findCoverArtFiles, importCoverArt, importPictureWithType, loadPictureFromFile, savePictureToFile, } from "./src/file-utils/index.js";
|
|
46
|
-
export { type AlbumDisc, type AlbumGroup, type AlbumGroupingResult, type AlbumGroupItem, type AlbumGroupKey, type AudioDynamics, type AudioFileMetadata, type DiscConfidence, type DiscFolderInfo, discFolderInfo, type DuplicateGroup, exportFolderMetadata, findDuplicates, type FolderScanItem, type FolderScanOptions, type FolderScanResult,
|
|
46
|
+
export { type AlbumDisc, type AlbumGroup, type AlbumGroupingResult, type AlbumGroupItem, type AlbumGroupKey, type AudioDynamics, type AudioFileMetadata, type DiscConfidence, type DiscFolderInfo, discFolderInfo, type DuplicateGroup, exportFolderMetadata, findDuplicates, type FolderScanItem, type FolderScanOptions, type FolderScanResult, groupAlbums, type GroupAlbumsOptions, scanFolder, scanForAlbums, type ScanForAlbumsOptions, } from "./src/folder-api/index.js";
|
|
47
47
|
export { canvasToPicture, createPictureDownloadURL, createPictureGallery, dataURLToPicture, displayPicture, imageFileToPicture, pictureToDataURL, setCoverArtFromCanvas, } from "./src/web-utils/index.js";
|
|
48
48
|
export type { AudioCodec, AudioFileInput, AudioProperties, BitrateControlMode, BroadcastAudioExtension, Chapter, ContainerFormat, ExtendedTag, FieldMapping, FileType, NamedAudioInput, OpenOptions, Picture, PictureType, PropertyMap, SetChaptersOptions, Tag, TagInput, } from "./src/types.js";
|
|
49
49
|
export { BITRATE_CONTROL_MODE_NAMES, BITRATE_CONTROL_MODE_VALUES, PICTURE_TYPE_NAMES, PICTURE_TYPE_VALUES, } from "./src/types.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAGH,YAAY,EACV,SAAS,EACT,cAAc,GACf,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACtE,YAAY,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAGjE,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,oBAAoB,EACpB,oBAAoB,EACpB,aAAa,EACb,eAAe,EACf,aAAa,EACb,wBAAwB,EACxB,WAAW,EACX,aAAa,EACb,iBAAiB,EACjB,WAAW,EACX,yBAAyB,EACzB,sBAAsB,GACvB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAGvD,OAAO,EACL,wBAAwB,EACxB,cAAc,EACd,uBAAuB,GACxB,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EACL,UAAU,EACV,aAAa,EACb,aAAa,EACb,SAAS,EACT,eAAe,EACf,KAAK,SAAS,EACd,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,aAAa,EACb,SAAS,EACT,KAAK,YAAY,EACjB,iBAAiB,EACjB,gBAAgB,EAChB,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,iBAAiB,EACjB,mBAAmB,EACnB,YAAY,EACZ,cAAc,EACd,mBAAmB,EACnB,QAAQ,EACR,aAAa,EACb,oBAAoB,EACpB,aAAa,GACd,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EAClB,qBAAqB,EACrB,mBAAmB,EACnB,eAAe,EACf,UAAU,EACV,aAAa,EACb,cAAc,GACf,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAG1E,OAAO,EACL,YAAY,EACZ,iBAAiB,EACjB,cAAc,EACd,mBAAmB,EACnB,iBAAiB,EACjB,cAAc,EACd,qBAAqB,EACrB,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EACL,KAAK,SAAS,EACd,KAAK,UAAU,EACf,KAAK,mBAAmB,EACxB,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,cAAc,EACd,KAAK,cAAc,EACnB,oBAAoB,EACpB,cAAc,EACd,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -75,8 +75,7 @@ import {
|
|
|
75
75
|
findDuplicates,
|
|
76
76
|
groupAlbums,
|
|
77
77
|
scanFolder,
|
|
78
|
-
scanForAlbums
|
|
79
|
-
updateFolderTags
|
|
78
|
+
scanForAlbums
|
|
80
79
|
} from "./src/folder-api/index.js";
|
|
81
80
|
import {
|
|
82
81
|
canvasToPicture,
|
|
@@ -180,6 +179,5 @@ export {
|
|
|
180
179
|
scanFolder,
|
|
181
180
|
scanForAlbums,
|
|
182
181
|
setBufferMode,
|
|
183
|
-
setCoverArtFromCanvas
|
|
184
|
-
updateFolderTags
|
|
182
|
+
setCoverArtFromCanvas
|
|
185
183
|
};
|
package/dist/simple.browser.js
CHANGED
|
@@ -1319,6 +1319,28 @@ var init_specialized_properties = __esm({
|
|
|
1319
1319
|
mp4: "----:com.apple.iTunes:MusicBrainz Album Type"
|
|
1320
1320
|
}
|
|
1321
1321
|
},
|
|
1322
|
+
releaseCountry: {
|
|
1323
|
+
key: "RELEASECOUNTRY",
|
|
1324
|
+
description: "Release country (ISO 3166-1 code, e.g. 'US'). TagLib 2.3.1 translates the RELEASECOUNTRY key per format: ID3v2 TXXX 'MUSICBRAINZ ALBUM RELEASE COUNTRY' (TagLib's description casing; an uppercase TXXX:RELEASECOUNTRY description also reads back), MP4 freeform atom 'MusicBrainz Album Release Country', APEv2 raw RELEASECOUNTRY, ASF 'MusicBrainz/Album Release Country', WAV ICNT, Vorbis/Matroska raw RELEASECOUNTRY",
|
|
1325
|
+
type: "string",
|
|
1326
|
+
supportedFormats: [
|
|
1327
|
+
"ID3v2",
|
|
1328
|
+
"MP4",
|
|
1329
|
+
"Vorbis",
|
|
1330
|
+
"APE",
|
|
1331
|
+
"ASF",
|
|
1332
|
+
"Matroska",
|
|
1333
|
+
"WAV"
|
|
1334
|
+
],
|
|
1335
|
+
mappings: {
|
|
1336
|
+
id3v2: {
|
|
1337
|
+
frame: "TXXX",
|
|
1338
|
+
description: "MusicBrainz Album Release Country"
|
|
1339
|
+
},
|
|
1340
|
+
vorbis: "RELEASECOUNTRY",
|
|
1341
|
+
mp4: "----:com.apple.iTunes:MusicBrainz Album Release Country"
|
|
1342
|
+
}
|
|
1343
|
+
},
|
|
1322
1344
|
itunesAdvisory: {
|
|
1323
1345
|
key: "ITUNESADVISORY",
|
|
1324
1346
|
description: "Content advisory in the ITUNESADVISORY convention ('1' = explicit, '2' = clean, '0' = unspecified). On MP4 the value is stored in the native rtng atom and surfaced here. The typed tri-state lives on ExtendedTag.advisory; aliases CONTENTADVISORY and EXPLICIT resolve here",
|
|
@@ -2697,8 +2719,9 @@ var init_mirror_fields = __esm({
|
|
|
2697
2719
|
});
|
|
2698
2720
|
|
|
2699
2721
|
// src/utils/tag-mapping.ts
|
|
2700
|
-
function readExtendedTag(audioFile) {
|
|
2701
|
-
const
|
|
2722
|
+
function readExtendedTag(audioFile, includeProperties) {
|
|
2723
|
+
const props = audioFile.properties();
|
|
2724
|
+
const tag = mapPropertiesToExtendedTag(props);
|
|
2702
2725
|
const pictures = audioFile.getPictures();
|
|
2703
2726
|
if (pictures.length > 0) tag.pictures = pictures;
|
|
2704
2727
|
const ratings = audioFile.getRatings();
|
|
@@ -2713,6 +2736,18 @@ function readExtendedTag(audioFile) {
|
|
|
2713
2736
|
if (bextData !== void 0) tag.bextData = bextData;
|
|
2714
2737
|
const ixml = audioFile.getIxml();
|
|
2715
2738
|
if (ixml !== void 0) tag.ixml = ixml;
|
|
2739
|
+
if (includeProperties !== void 0 && includeProperties.length > 0) {
|
|
2740
|
+
const extraProperties = {};
|
|
2741
|
+
for (const wireKey of includeProperties) {
|
|
2742
|
+
const values = props[fromTagLibKey(wireKey)]?.filter((v) => v !== "");
|
|
2743
|
+
if (values !== void 0 && values.length > 0) {
|
|
2744
|
+
extraProperties[wireKey] = values;
|
|
2745
|
+
}
|
|
2746
|
+
}
|
|
2747
|
+
if (Object.keys(extraProperties).length > 0) {
|
|
2748
|
+
tag.extraProperties = extraProperties;
|
|
2749
|
+
}
|
|
2750
|
+
}
|
|
2716
2751
|
return tag;
|
|
2717
2752
|
}
|
|
2718
2753
|
function mapPropertiesToExtendedTag(props) {
|
|
@@ -2832,6 +2867,7 @@ function normalizeTagInput(input) {
|
|
|
2832
2867
|
}
|
|
2833
2868
|
for (const [field, val] of Object.entries(input)) {
|
|
2834
2869
|
if (BASIC_FIELDS.has(field) || val === void 0) continue;
|
|
2870
|
+
if (field === "extraProperties") continue;
|
|
2835
2871
|
if (field === "compilation") {
|
|
2836
2872
|
props[field] = [val ? "1" : "0"];
|
|
2837
2873
|
} else if (field === "advisory") {
|
|
@@ -2898,7 +2934,7 @@ var VERSION;
|
|
|
2898
2934
|
var init_version = __esm({
|
|
2899
2935
|
"src/version.ts"() {
|
|
2900
2936
|
"use strict";
|
|
2901
|
-
VERSION = "2.
|
|
2937
|
+
VERSION = "2.2.0";
|
|
2902
2938
|
}
|
|
2903
2939
|
});
|
|
2904
2940
|
|
|
@@ -3247,8 +3283,11 @@ async function withAudioFileSaveToFile(file, fn) {
|
|
|
3247
3283
|
}
|
|
3248
3284
|
|
|
3249
3285
|
// src/simple/tag-operations.ts
|
|
3250
|
-
async function readTags(file) {
|
|
3251
|
-
return withAudioFile(
|
|
3286
|
+
async function readTags(file, options = {}) {
|
|
3287
|
+
return withAudioFile(
|
|
3288
|
+
file,
|
|
3289
|
+
(audioFile) => readExtendedTag(audioFile, options.includeProperties)
|
|
3290
|
+
);
|
|
3252
3291
|
}
|
|
3253
3292
|
async function applyTags(file, tags) {
|
|
3254
3293
|
return withAudioFileSave(file, (audioFile) => {
|
|
@@ -3426,7 +3465,7 @@ async function readTagsBatch(files, options = {}) {
|
|
|
3426
3465
|
return executeBatch(
|
|
3427
3466
|
files,
|
|
3428
3467
|
options,
|
|
3429
|
-
(audioFile) => readExtendedTag(audioFile)
|
|
3468
|
+
(audioFile) => readExtendedTag(audioFile, options.includeProperties)
|
|
3430
3469
|
);
|
|
3431
3470
|
}
|
|
3432
3471
|
async function readPropertiesBatch(files, options = {}) {
|
|
@@ -3455,7 +3494,7 @@ function extractDynamics(audioFile) {
|
|
|
3455
3494
|
if (appleSoundCheck) dynamics.appleSoundCheck = appleSoundCheck;
|
|
3456
3495
|
return Object.keys(dynamics).length > 0 ? dynamics : void 0;
|
|
3457
3496
|
}
|
|
3458
|
-
async function readMetadata(file) {
|
|
3497
|
+
async function readMetadata(file, options = {}) {
|
|
3459
3498
|
const taglib = await getTagLib();
|
|
3460
3499
|
const audioFile = await taglib.open(file);
|
|
3461
3500
|
try {
|
|
@@ -3476,7 +3515,7 @@ async function readMetadata(file) {
|
|
|
3476
3515
|
}
|
|
3477
3516
|
const dynamics = extractDynamics(audioFile);
|
|
3478
3517
|
return {
|
|
3479
|
-
tags: readExtendedTag(audioFile),
|
|
3518
|
+
tags: readExtendedTag(audioFile, options.includeProperties),
|
|
3480
3519
|
properties: audioFile.audioProperties(),
|
|
3481
3520
|
hasCoverArt: audioFile.getPictures().length > 0,
|
|
3482
3521
|
...dynamics !== void 0 ? { dynamics } : {}
|
|
@@ -3489,13 +3528,59 @@ async function readMetadataBatch(files, options = {}) {
|
|
|
3489
3528
|
return executeBatch(files, options, (audioFile) => {
|
|
3490
3529
|
const dynamics = extractDynamics(audioFile);
|
|
3491
3530
|
return {
|
|
3492
|
-
tags: readExtendedTag(audioFile),
|
|
3531
|
+
tags: readExtendedTag(audioFile, options.includeProperties),
|
|
3493
3532
|
properties: audioFile.audioProperties(),
|
|
3494
3533
|
hasCoverArt: audioFile.getPictures().length > 0,
|
|
3495
3534
|
...dynamics !== void 0 ? { dynamics } : {}
|
|
3496
3535
|
};
|
|
3497
3536
|
});
|
|
3498
3537
|
}
|
|
3538
|
+
function entryPath(entry) {
|
|
3539
|
+
return typeof entry === "string" ? entry : entry.path;
|
|
3540
|
+
}
|
|
3541
|
+
async function executeWriteBatch(entries, options, writer) {
|
|
3542
|
+
if (entries.length === 0) return { items: [], duration: 0 };
|
|
3543
|
+
await getTagLib();
|
|
3544
|
+
const startTime = Date.now();
|
|
3545
|
+
const { concurrency = 4, continueOnError = true, onProgress, signal } = options;
|
|
3546
|
+
const items = new Array(entries.length);
|
|
3547
|
+
let processed = 0;
|
|
3548
|
+
const total = entries.length;
|
|
3549
|
+
for (let i = 0; i < entries.length; i += concurrency) {
|
|
3550
|
+
signal?.throwIfAborted();
|
|
3551
|
+
const chunk = entries.slice(i, i + concurrency);
|
|
3552
|
+
const chunkPromises = chunk.map(async (entry, idx) => {
|
|
3553
|
+
const index = i + idx;
|
|
3554
|
+
const path = entryPath(entry);
|
|
3555
|
+
try {
|
|
3556
|
+
await writer(path);
|
|
3557
|
+
items[index] = { status: "ok", path, data: void 0 };
|
|
3558
|
+
} catch (error) {
|
|
3559
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
3560
|
+
items[index] = { status: "error", path, error: err };
|
|
3561
|
+
if (!continueOnError) throw err;
|
|
3562
|
+
}
|
|
3563
|
+
processed++;
|
|
3564
|
+
onProgress?.(processed, total, path);
|
|
3565
|
+
});
|
|
3566
|
+
await Promise.all(chunkPromises);
|
|
3567
|
+
}
|
|
3568
|
+
return { items, duration: Date.now() - startTime };
|
|
3569
|
+
}
|
|
3570
|
+
async function writeTagsBatch(updates, options = {}) {
|
|
3571
|
+
const byPath = new Map(updates.map((u) => [u.path, u]));
|
|
3572
|
+
return executeWriteBatch(updates, options, (path) => {
|
|
3573
|
+
const update = byPath.get(path);
|
|
3574
|
+
return applyTagsToFile(path, update.tags);
|
|
3575
|
+
});
|
|
3576
|
+
}
|
|
3577
|
+
async function editTagsBatch(files, mutator, options = {}) {
|
|
3578
|
+
return executeWriteBatch(
|
|
3579
|
+
files,
|
|
3580
|
+
options,
|
|
3581
|
+
(path) => withAudioFileSaveToFile(path, mutator)
|
|
3582
|
+
);
|
|
3583
|
+
}
|
|
3499
3584
|
|
|
3500
3585
|
// src/simple/index.ts
|
|
3501
3586
|
init_types2();
|
|
@@ -3509,6 +3594,7 @@ export {
|
|
|
3509
3594
|
applyTagsToFile,
|
|
3510
3595
|
clearPictures,
|
|
3511
3596
|
clearTags,
|
|
3597
|
+
editTagsBatch,
|
|
3512
3598
|
findPictureByType,
|
|
3513
3599
|
getTagLib,
|
|
3514
3600
|
isValidAudioFile,
|
|
@@ -3523,5 +3609,6 @@ export {
|
|
|
3523
3609
|
readTags,
|
|
3524
3610
|
readTagsBatch,
|
|
3525
3611
|
replacePictureByType,
|
|
3526
|
-
setBufferMode
|
|
3612
|
+
setBufferMode,
|
|
3613
|
+
writeTagsBatch
|
|
3527
3614
|
};
|
|
@@ -311,6 +311,20 @@ export declare const PROPERTIES: {
|
|
|
311
311
|
readonly mp4: "----:com.apple.iTunes:MusicBrainz Album Type";
|
|
312
312
|
};
|
|
313
313
|
};
|
|
314
|
+
readonly releaseCountry: {
|
|
315
|
+
readonly key: "RELEASECOUNTRY";
|
|
316
|
+
readonly description: "Release country (ISO 3166-1 code, e.g. 'US'). TagLib 2.3.1 translates the RELEASECOUNTRY key per format: ID3v2 TXXX 'MUSICBRAINZ ALBUM RELEASE COUNTRY' (TagLib's description casing; an uppercase TXXX:RELEASECOUNTRY description also reads back), MP4 freeform atom 'MusicBrainz Album Release Country', APEv2 raw RELEASECOUNTRY, ASF 'MusicBrainz/Album Release Country', WAV ICNT, Vorbis/Matroska raw RELEASECOUNTRY";
|
|
317
|
+
readonly type: "string";
|
|
318
|
+
readonly supportedFormats: readonly ["ID3v2", "MP4", "Vorbis", "APE", "ASF", "Matroska", "WAV"];
|
|
319
|
+
readonly mappings: {
|
|
320
|
+
readonly id3v2: {
|
|
321
|
+
readonly frame: "TXXX";
|
|
322
|
+
readonly description: "MusicBrainz Album Release Country";
|
|
323
|
+
};
|
|
324
|
+
readonly vorbis: "RELEASECOUNTRY";
|
|
325
|
+
readonly mp4: "----:com.apple.iTunes:MusicBrainz Album Release Country";
|
|
326
|
+
};
|
|
327
|
+
};
|
|
314
328
|
readonly itunesAdvisory: {
|
|
315
329
|
readonly key: "ITUNESADVISORY";
|
|
316
330
|
readonly description: "Content advisory in the ITUNESADVISORY convention ('1' = explicit, '2' = clean, '0' = unspecified). On MP4 the value is stored in the native rtng atom and surfaced here. The typed tri-state lives on ExtendedTag.advisory; aliases CONTENTADVISORY and EXPLICIT resolve here";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"properties.d.ts","sourceRoot":"","sources":["../../../src/constants/properties.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAQH,eAAO,MAAM,UAAU
|
|
1
|
+
{"version":3,"file":"properties.d.ts","sourceRoot":"","sources":["../../../src/constants/properties.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAQH,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAKb,CAAC;AAEX;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,OAAO,UAAU,CAAC;AAElD;;;GAGG;AACH,MAAM,MAAM,aAAa,CAAC,CAAC,SAAS,WAAW,IAC7C,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,QAAQ,GAAG,MAAM,GAClD,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,QAAQ,GAAG,MAAM,GACtD,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,SAAS,GAAG,OAAO,GACxD,MAAM,CAAC;AAkDb,mGAAmG;AACnG,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE/C;AAsDD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAE/D;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,MAAM,EAAE,CAOzE;AAED,mGAAmG;AACnG,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED,qEAAqE;AACrE,wBAAgB,mBAAmB,CAAC,CAAC,EACnC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,GACrB,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CASnB;AAGD,YAAY,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC"}
|
|
@@ -73,6 +73,20 @@ export declare const SPECIALIZED_PROPERTIES: {
|
|
|
73
73
|
readonly mp4: "----:com.apple.iTunes:MusicBrainz Album Type";
|
|
74
74
|
};
|
|
75
75
|
};
|
|
76
|
+
readonly releaseCountry: {
|
|
77
|
+
readonly key: "RELEASECOUNTRY";
|
|
78
|
+
readonly description: "Release country (ISO 3166-1 code, e.g. 'US'). TagLib 2.3.1 translates the RELEASECOUNTRY key per format: ID3v2 TXXX 'MUSICBRAINZ ALBUM RELEASE COUNTRY' (TagLib's description casing; an uppercase TXXX:RELEASECOUNTRY description also reads back), MP4 freeform atom 'MusicBrainz Album Release Country', APEv2 raw RELEASECOUNTRY, ASF 'MusicBrainz/Album Release Country', WAV ICNT, Vorbis/Matroska raw RELEASECOUNTRY";
|
|
79
|
+
readonly type: "string";
|
|
80
|
+
readonly supportedFormats: readonly ["ID3v2", "MP4", "Vorbis", "APE", "ASF", "Matroska", "WAV"];
|
|
81
|
+
readonly mappings: {
|
|
82
|
+
readonly id3v2: {
|
|
83
|
+
readonly frame: "TXXX";
|
|
84
|
+
readonly description: "MusicBrainz Album Release Country";
|
|
85
|
+
};
|
|
86
|
+
readonly vorbis: "RELEASECOUNTRY";
|
|
87
|
+
readonly mp4: "----:com.apple.iTunes:MusicBrainz Album Release Country";
|
|
88
|
+
};
|
|
89
|
+
};
|
|
76
90
|
readonly itunesAdvisory: {
|
|
77
91
|
readonly key: "ITUNESADVISORY";
|
|
78
92
|
readonly description: "Content advisory in the ITUNESADVISORY convention ('1' = explicit, '2' = clean, '0' = unspecified). On MP4 the value is stored in the native rtng atom and surfaced here. The typed tri-state lives on ExtendedTag.advisory; aliases CONTENTADVISORY and EXPLICIT resolve here";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"specialized-properties.d.ts","sourceRoot":"","sources":["../../../src/constants/specialized-properties.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,sBAAsB
|
|
1
|
+
{"version":3,"file":"specialized-properties.d.ts","sourceRoot":"","sources":["../../../src/constants/specialized-properties.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA+MjC;;;;;;;;OAQG;;;;;;;;;;;;;;;CAYK,CAAC"}
|
|
@@ -62,6 +62,28 @@ const SPECIALIZED_PROPERTIES = {
|
|
|
62
62
|
mp4: "----:com.apple.iTunes:MusicBrainz Album Type"
|
|
63
63
|
}
|
|
64
64
|
},
|
|
65
|
+
releaseCountry: {
|
|
66
|
+
key: "RELEASECOUNTRY",
|
|
67
|
+
description: "Release country (ISO 3166-1 code, e.g. 'US'). TagLib 2.3.1 translates the RELEASECOUNTRY key per format: ID3v2 TXXX 'MUSICBRAINZ ALBUM RELEASE COUNTRY' (TagLib's description casing; an uppercase TXXX:RELEASECOUNTRY description also reads back), MP4 freeform atom 'MusicBrainz Album Release Country', APEv2 raw RELEASECOUNTRY, ASF 'MusicBrainz/Album Release Country', WAV ICNT, Vorbis/Matroska raw RELEASECOUNTRY",
|
|
68
|
+
type: "string",
|
|
69
|
+
supportedFormats: [
|
|
70
|
+
"ID3v2",
|
|
71
|
+
"MP4",
|
|
72
|
+
"Vorbis",
|
|
73
|
+
"APE",
|
|
74
|
+
"ASF",
|
|
75
|
+
"Matroska",
|
|
76
|
+
"WAV"
|
|
77
|
+
],
|
|
78
|
+
mappings: {
|
|
79
|
+
id3v2: {
|
|
80
|
+
frame: "TXXX",
|
|
81
|
+
description: "MusicBrainz Album Release Country"
|
|
82
|
+
},
|
|
83
|
+
vorbis: "RELEASECOUNTRY",
|
|
84
|
+
mp4: "----:com.apple.iTunes:MusicBrainz Album Release Country"
|
|
85
|
+
}
|
|
86
|
+
},
|
|
65
87
|
itunesAdvisory: {
|
|
66
88
|
key: "ITUNESADVISORY",
|
|
67
89
|
description: "Content advisory in the ITUNESADVISORY convention ('1' = explicit, '2' = clean, '0' = unspecified). On MP4 the value is stored in the native rtng atom and surfaced here. The typed tri-state lives on ExtendedTag.advisory; aliases CONTENTADVISORY and EXPLICIT resolve here",
|
|
@@ -1,35 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Folder-level operations:
|
|
2
|
+
* Folder-level operations: duplicates, metadata export
|
|
3
3
|
*/
|
|
4
|
-
import type {
|
|
5
|
-
import type { DuplicateGroup, FolderScanOptions, FolderUpdateResult } from "./types.js";
|
|
6
|
-
/**
|
|
7
|
-
* Update metadata for multiple files in a folder
|
|
8
|
-
*
|
|
9
|
-
* @param updates - Array of objects containing path and tags to update
|
|
10
|
-
* @param options - Update options
|
|
11
|
-
* @returns Results of the update operation
|
|
12
|
-
*
|
|
13
|
-
* @example
|
|
14
|
-
* ```typescript
|
|
15
|
-
* const updates = [
|
|
16
|
-
* { path: "/music/song1.mp3", tags: { artist: "New Artist" } },
|
|
17
|
-
* { path: "/music/song2.mp3", tags: { album: "New Album" } }
|
|
18
|
-
* ];
|
|
19
|
-
*
|
|
20
|
-
* const result = await updateFolderTags(updates);
|
|
21
|
-
* const updated = result.items.filter((i) => i.status === "ok").length;
|
|
22
|
-
* console.log(`Updated ${updated} files`);
|
|
23
|
-
* ```
|
|
24
|
-
*/
|
|
25
|
-
export declare function updateFolderTags(updates: Array<{
|
|
26
|
-
path: string;
|
|
27
|
-
tags: Partial<TagInput>;
|
|
28
|
-
}>, options?: {
|
|
29
|
-
continueOnError?: boolean;
|
|
30
|
-
concurrency?: number;
|
|
31
|
-
signal?: AbortSignal;
|
|
32
|
-
}): Promise<FolderUpdateResult>;
|
|
4
|
+
import type { DuplicateGroup, FolderScanOptions } from "./types.js";
|
|
33
5
|
/**
|
|
34
6
|
* Find duplicate audio files based on metadata
|
|
35
7
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"folder-operations.d.ts","sourceRoot":"","sources":["../../../src/folder-api/folder-operations.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"folder-operations.d.ts","sourceRoot":"","sources":["../../../src/folder-api/folder-operations.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAEV,cAAc,EACd,iBAAiB,EAClB,MAAM,YAAY,CAAC;AAiBpB;;;;;;GAMG;AACH,wBAAsB,cAAc,CAClC,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,cAAc,EAAE,CAAC,CAuB3B;AAED;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAoBf"}
|
|
@@ -1,39 +1,5 @@
|
|
|
1
|
-
import { applyTagsToFile } from "../simple/index.js";
|
|
2
1
|
import { writeFileData } from "../utils/write.js";
|
|
3
|
-
import { processBatch } from "./file-processors.js";
|
|
4
2
|
import { scanFolder } from "./scan-operations.js";
|
|
5
|
-
import { EMPTY_TAG } from "./types.js";
|
|
6
|
-
async function updateFolderTags(updates, options = {}) {
|
|
7
|
-
const startTime = Date.now();
|
|
8
|
-
const { continueOnError = true, concurrency = 4, signal } = options;
|
|
9
|
-
const items = [];
|
|
10
|
-
const batchSize = concurrency * 10;
|
|
11
|
-
for (let i = 0; i < updates.length; i += batchSize) {
|
|
12
|
-
signal?.throwIfAborted();
|
|
13
|
-
const batch = updates.slice(i, Math.min(i + batchSize, updates.length));
|
|
14
|
-
const updateMap = new Map(batch.map((u) => [u.path, u]));
|
|
15
|
-
await processBatch(
|
|
16
|
-
batch.map((u) => u.path),
|
|
17
|
-
async (path) => {
|
|
18
|
-
const update = updateMap.get(path);
|
|
19
|
-
try {
|
|
20
|
-
await applyTagsToFile(update.path, update.tags);
|
|
21
|
-
items.push({ status: "ok", path: update.path });
|
|
22
|
-
} catch (error) {
|
|
23
|
-
const err = error instanceof Error ? error : new Error(String(error));
|
|
24
|
-
if (continueOnError) {
|
|
25
|
-
items.push({ status: "error", path: update.path, error: err });
|
|
26
|
-
} else {
|
|
27
|
-
throw err;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
return { path, tags: EMPTY_TAG };
|
|
31
|
-
},
|
|
32
|
-
concurrency
|
|
33
|
-
);
|
|
34
|
-
}
|
|
35
|
-
return { items, duration: Date.now() - startTime };
|
|
36
|
-
}
|
|
37
3
|
function buildCriteriaKey(tags, criteria) {
|
|
38
4
|
const record = {};
|
|
39
5
|
for (const field of criteria) {
|
|
@@ -84,6 +50,5 @@ async function exportFolderMetadata(folderPath, outputPath, options) {
|
|
|
84
50
|
}
|
|
85
51
|
export {
|
|
86
52
|
exportFolderMetadata,
|
|
87
|
-
findDuplicates
|
|
88
|
-
updateFolderTags
|
|
53
|
+
findDuplicates
|
|
89
54
|
};
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
* Batch folder operations for TagLib-Wasm
|
|
3
3
|
* Provides APIs for scanning directories and processing multiple audio files
|
|
4
4
|
*/
|
|
5
|
-
export type { AudioDynamics, AudioFileMetadata, DuplicateGroup, FolderScanItem, FolderScanOptions, FolderScanResult,
|
|
5
|
+
export type { AudioDynamics, AudioFileMetadata, DuplicateGroup, FolderScanItem, FolderScanOptions, FolderScanResult, } from "./types.js";
|
|
6
6
|
export { scanFolder } from "./scan-operations.js";
|
|
7
|
-
export { exportFolderMetadata, findDuplicates
|
|
7
|
+
export { exportFolderMetadata, findDuplicates } from "./folder-operations.js";
|
|
8
8
|
export { type AlbumDisc, type AlbumGroup, type AlbumGroupingResult, type AlbumGroupItem, type AlbumGroupKey, type DiscConfidence, type DiscFolderInfo, discFolderInfo, groupAlbums, type GroupAlbumsOptions, } from "./group-albums.js";
|
|
9
9
|
export { scanForAlbums, type ScanForAlbumsOptions } from "./scan-for-albums.js";
|
|
10
10
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/folder-api/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,YAAY,EACV,aAAa,EACb,iBAAiB,EACjB,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,gBAAgB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/folder-api/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,YAAY,EACV,aAAa,EACb,iBAAiB,EACjB,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAElD,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAE9E,OAAO,EACL,KAAK,SAAS,EACd,KAAK,UAAU,EACf,KAAK,mBAAmB,EACxB,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,cAAc,EACd,WAAW,EACX,KAAK,kBAAkB,GACxB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,aAAa,EAAE,KAAK,oBAAoB,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
import { scanFolder } from "./scan-operations.js";
|
|
2
|
-
import {
|
|
3
|
-
exportFolderMetadata,
|
|
4
|
-
findDuplicates,
|
|
5
|
-
updateFolderTags
|
|
6
|
-
} from "./folder-operations.js";
|
|
2
|
+
import { exportFolderMetadata, findDuplicates } from "./folder-operations.js";
|
|
7
3
|
import {
|
|
8
4
|
discFolderInfo,
|
|
9
5
|
groupAlbums
|
|
@@ -15,6 +11,5 @@ export {
|
|
|
15
11
|
findDuplicates,
|
|
16
12
|
groupAlbums,
|
|
17
13
|
scanFolder,
|
|
18
|
-
scanForAlbums
|
|
19
|
-
updateFolderTags
|
|
14
|
+
scanForAlbums
|
|
20
15
|
};
|
|
@@ -4,15 +4,6 @@
|
|
|
4
4
|
import type { ExtendedTag, Tag, TagInput } from "../simple/index.js";
|
|
5
5
|
import type { AudioProperties } from "../types.js";
|
|
6
6
|
export type { AudioProperties, ExtendedTag, Tag, TagInput };
|
|
7
|
-
export declare const EMPTY_TAG: Readonly<{
|
|
8
|
-
title: never[];
|
|
9
|
-
artist: never[];
|
|
10
|
-
album: never[];
|
|
11
|
-
comment: never[];
|
|
12
|
-
genre: never[];
|
|
13
|
-
year: number;
|
|
14
|
-
track: number;
|
|
15
|
-
}>;
|
|
16
7
|
export declare const DEFAULT_AUDIO_EXTENSIONS: string[];
|
|
17
8
|
/**
|
|
18
9
|
* Audio dynamics data (ReplayGain and Apple Sound Check)
|
|
@@ -87,18 +78,6 @@ export interface FolderScanResult {
|
|
|
87
78
|
/** Time taken in milliseconds */
|
|
88
79
|
duration: number;
|
|
89
80
|
}
|
|
90
|
-
export type FolderUpdateItem = {
|
|
91
|
-
status: "ok";
|
|
92
|
-
path: string;
|
|
93
|
-
} | {
|
|
94
|
-
status: "error";
|
|
95
|
-
path: string;
|
|
96
|
-
error: Error;
|
|
97
|
-
};
|
|
98
|
-
export interface FolderUpdateResult {
|
|
99
|
-
items: FolderUpdateItem[];
|
|
100
|
-
duration: number;
|
|
101
|
-
}
|
|
102
81
|
export interface DuplicateGroup {
|
|
103
82
|
criteria: Record<string, string>;
|
|
104
83
|
files: AudioFileMetadata[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/folder-api/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC;AAE5D,eAAO,MAAM,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/folder-api/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC;AAE5D,eAAO,MAAM,wBAAwB,UAiBpC,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,qDAAqD;IACrD,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,4CAA4C;IAC5C,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,kCAAkC;IAClC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,4CAA4C;IAC5C,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,sDAAsD;IACtD,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAC;IACb,8EAA8E;IAC9E,IAAI,EAAE,WAAW,CAAC;IAClB,8DAA8D;IAC9D,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B,mDAAmD;IACnD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,uDAAuD;IACvD,QAAQ,CAAC,EAAE,aAAa,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,iEAAiE;IACjE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,iEAAiE;IACjE,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4DAA4D;IAC5D,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7E,0DAA0D;IAC1D,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,oDAAoD;IACpD,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,mFAAmF;IACnF,QAAQ,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;IAC5B,qEAAqE;IACrE,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED;;;GAGG;AACH,MAAM,MAAM,cAAc,GACtB,CAAC;IAAE,MAAM,EAAE,IAAI,CAAA;CAAE,GAAG,iBAAiB,CAAC,GACtC;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,KAAK,CAAA;CAAE,CAAC;AAEpD;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,sDAAsD;IACtD,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,iCAAiC;IACjC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,KAAK,EAAE,iBAAiB,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,kBAAkB;IACjC,iBAAiB,EAAE,OAAO,CAAC;IAC3B,eAAe,EAAE,OAAO,CAAC;IACzB,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7E,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB"}
|
|
@@ -1,14 +1,3 @@
|
|
|
1
|
-
const EMPTY_TAG = Object.freeze(
|
|
2
|
-
{
|
|
3
|
-
title: [],
|
|
4
|
-
artist: [],
|
|
5
|
-
album: [],
|
|
6
|
-
comment: [],
|
|
7
|
-
genre: [],
|
|
8
|
-
year: 0,
|
|
9
|
-
track: 0
|
|
10
|
-
}
|
|
11
|
-
);
|
|
12
1
|
const DEFAULT_AUDIO_EXTENSIONS = [
|
|
13
2
|
".mp3",
|
|
14
3
|
".m4a",
|
|
@@ -28,6 +17,5 @@ const DEFAULT_AUDIO_EXTENSIONS = [
|
|
|
28
17
|
".webm"
|
|
29
18
|
];
|
|
30
19
|
export {
|
|
31
|
-
DEFAULT_AUDIO_EXTENSIONS
|
|
32
|
-
EMPTY_TAG
|
|
20
|
+
DEFAULT_AUDIO_EXTENSIONS
|
|
33
21
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import type { AudioFile } from "../taglib.js";
|
|
1
2
|
import type { AudioDynamics } from "../folder-api/types.js";
|
|
2
|
-
import type { AudioFileInput, AudioProperties, ExtendedTag } from "../types.js";
|
|
3
|
+
import type { AudioFileInput, AudioProperties, ExtendedTag, TagInput } from "../types.js";
|
|
3
4
|
/** Configuration for batch processing operations. */
|
|
4
5
|
export interface BatchOptions {
|
|
5
6
|
concurrency?: number;
|
|
@@ -7,6 +8,13 @@ export interface BatchOptions {
|
|
|
7
8
|
onProgress?: (processed: number, total: number, currentFile: string) => void;
|
|
8
9
|
/** AbortSignal to cancel the batch operation between chunks. */
|
|
9
10
|
signal?: AbortSignal;
|
|
11
|
+
/**
|
|
12
|
+
* Raw WIRE keys (e.g. "CATALOGNUMBER") to surface per item under
|
|
13
|
+
* `extraProperties`, for keys outside the modeled typed set (taglib-3s1f).
|
|
14
|
+
* The PropertyMap is already fetched per file, so this costs no extra
|
|
15
|
+
* opens on either backend. Absent keys are omitted, not empty arrays.
|
|
16
|
+
*/
|
|
17
|
+
includeProperties?: string[];
|
|
10
18
|
}
|
|
11
19
|
/** Discriminated union result for a single file in a batch operation. */
|
|
12
20
|
export type BatchItem<T> = {
|
|
@@ -52,10 +60,14 @@ export interface FileMetadata {
|
|
|
52
60
|
* Read complete metadata (tags, properties, cover art, dynamics) from a single file.
|
|
53
61
|
*
|
|
54
62
|
* @param file - A file path, Uint8Array, ArrayBuffer, File object, or NamedAudioInput.
|
|
63
|
+
* @param options - Read options; `includeProperties` (wire keys) surfaces raw
|
|
64
|
+
* values in `tags.extraProperties` (taglib-3s1f).
|
|
55
65
|
* @returns The file's complete metadata.
|
|
56
66
|
* @throws `InvalidFormatError` if the file is corrupted or in an unsupported format.
|
|
57
67
|
*/
|
|
58
|
-
export declare function readMetadata(file: AudioFileInput
|
|
68
|
+
export declare function readMetadata(file: AudioFileInput, options?: {
|
|
69
|
+
includeProperties?: string[];
|
|
70
|
+
}): Promise<FileMetadata>;
|
|
59
71
|
/**
|
|
60
72
|
* Read complete metadata from multiple files with configurable concurrency.
|
|
61
73
|
*
|
|
@@ -65,4 +77,47 @@ export declare function readMetadata(file: AudioFileInput): Promise<FileMetadata
|
|
|
65
77
|
* @throws If `continueOnError` is `false` and any file fails to process.
|
|
66
78
|
*/
|
|
67
79
|
export declare function readMetadataBatch(files: AudioFileInput[], options?: BatchOptions): Promise<BatchResult<FileMetadata>>;
|
|
80
|
+
/** One file to update in a {@link writeTagsBatch} call. */
|
|
81
|
+
export interface WriteTagUpdate {
|
|
82
|
+
/** File path on disk; the file is updated in place. */
|
|
83
|
+
path: string;
|
|
84
|
+
/**
|
|
85
|
+
* Partial tag fields to merge with the file's existing metadata. An empty
|
|
86
|
+
* object performs a save with no tag changes (a no-op rewrite).
|
|
87
|
+
*/
|
|
88
|
+
tags: Partial<TagInput>;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Apply tag updates to multiple files with configurable concurrency.
|
|
92
|
+
*
|
|
93
|
+
* The batch write counterpart to {@link readTagsBatch}: same
|
|
94
|
+
* {@link BatchOptions} contract (concurrency, continueOnError, onProgress,
|
|
95
|
+
* signal). Each file is updated via the same path as
|
|
96
|
+
* {@link applyTagsToFile} — merge semantics, atomic temp-file save, so a
|
|
97
|
+
* failed file is left in its pre-write state.
|
|
98
|
+
*
|
|
99
|
+
* @param updates - Per-file tag updates; a path may appear more than once
|
|
100
|
+
* (the last update for a path wins).
|
|
101
|
+
* @param options - Batch processing options (concurrency, error handling,
|
|
102
|
+
* progress, abort).
|
|
103
|
+
* @returns A `BatchItem` per update in input order plus total duration in ms.
|
|
104
|
+
* @throws If `continueOnError` is `false` and any file fails to process.
|
|
105
|
+
*/
|
|
106
|
+
export declare function writeTagsBatch(updates: WriteTagUpdate[], options?: BatchOptions): Promise<BatchResult<void>>;
|
|
107
|
+
/**
|
|
108
|
+
* Open, mutate, and save multiple files with configurable concurrency.
|
|
109
|
+
*
|
|
110
|
+
* Mutator-callback variant of {@link writeTagsBatch}: the callback receives
|
|
111
|
+
* the open {@link AudioFile} (Full-API style) and its changes are saved per
|
|
112
|
+
* file. Same {@link BatchOptions} contract and atomicity guarantees.
|
|
113
|
+
*
|
|
114
|
+
* @param files - File paths on disk, updated in place.
|
|
115
|
+
* @param mutator - Called once per file with the open audio file; changes are
|
|
116
|
+
* saved automatically.
|
|
117
|
+
* @param options - Batch processing options (concurrency, error handling,
|
|
118
|
+
* progress, abort).
|
|
119
|
+
* @returns A `BatchItem` per file in input order plus total duration in ms.
|
|
120
|
+
* @throws If `continueOnError` is `false` and any file fails to process.
|
|
121
|
+
*/
|
|
122
|
+
export declare function editTagsBatch(files: string[], mutator: (audioFile: AudioFile) => void, options?: BatchOptions): Promise<BatchResult<void>>;
|
|
68
123
|
//# sourceMappingURL=batch-operations.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"batch-operations.d.ts","sourceRoot":"","sources":["../../../src/simple/batch-operations.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"batch-operations.d.ts","sourceRoot":"","sources":["../../../src/simple/batch-operations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,KAAK,EACV,cAAc,EACd,eAAe,EACf,WAAW,EACX,QAAQ,EACT,MAAM,aAAa,CAAC;AAQrB,qDAAqD;AACrD,MAAM,WAAW,YAAY;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7E,gEAAgE;IAChE,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC9B;AAED,yEAAyE;AACzE,MAAM,MAAM,SAAS,CAAC,CAAC,IACnB;IAAE,MAAM,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,CAAC,CAAA;CAAE,GACvC;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,KAAK,CAAA;CAAE,CAAC;AAEpD,mEAAmE;AACnE,MAAM,WAAW,WAAW,CAAC,CAAC;IAC5B,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAyDD;;;;;;;GAOG;AACH,wBAAsB,aAAa,CACjC,KAAK,EAAE,cAAc,EAAE,EACvB,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,CAMnC;AAED;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,cAAc,EAAE,EACvB,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,WAAW,CAAC,eAAe,GAAG,SAAS,CAAC,CAAC,CAMnD;AAED,oHAAoH;AACpH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,WAAW,CAAC;IAClB,UAAU,EAAE,eAAe,GAAG,SAAS,CAAC;IACxC,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,aAAa,CAAC;CAC1B;AAsBD;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,cAAc,EACpB,OAAO,GAAE;IAAE,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAA;CAAO,GAC7C,OAAO,CAAC,YAAY,CAAC,CA6BvB;AAED;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,cAAc,EAAE,EACvB,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC,CAUpC;AAED,2DAA2D;AAC3D,MAAM,WAAW,cAAc;IAC7B,uDAAuD;IACvD,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;CACzB;AAsDD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,cAAc,EAAE,EACzB,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAM5B;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,aAAa,CACjC,KAAK,EAAE,MAAM,EAAE,EACf,OAAO,EAAE,CAAC,SAAS,EAAE,SAAS,KAAK,IAAI,EACvC,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAM5B"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { isNamedAudioInput } from "../types/audio-formats.js";
|
|
2
2
|
import { InvalidFormatError } from "../errors.js";
|
|
3
3
|
import { readExtendedTag } from "../utils/tag-mapping.js";
|
|
4
|
+
import { applyTagsToFile } from "./tag-operations.js";
|
|
5
|
+
import { withAudioFileSaveToFile } from "./with-audio-file.js";
|
|
4
6
|
import { getTagLib } from "./config.js";
|
|
5
7
|
async function executeBatch(files, options, processor) {
|
|
6
8
|
if (files.length === 0) return { items: [], duration: 0 };
|
|
@@ -48,7 +50,7 @@ async function readTagsBatch(files, options = {}) {
|
|
|
48
50
|
return executeBatch(
|
|
49
51
|
files,
|
|
50
52
|
options,
|
|
51
|
-
(audioFile) => readExtendedTag(audioFile)
|
|
53
|
+
(audioFile) => readExtendedTag(audioFile, options.includeProperties)
|
|
52
54
|
);
|
|
53
55
|
}
|
|
54
56
|
async function readPropertiesBatch(files, options = {}) {
|
|
@@ -77,7 +79,7 @@ function extractDynamics(audioFile) {
|
|
|
77
79
|
if (appleSoundCheck) dynamics.appleSoundCheck = appleSoundCheck;
|
|
78
80
|
return Object.keys(dynamics).length > 0 ? dynamics : void 0;
|
|
79
81
|
}
|
|
80
|
-
async function readMetadata(file) {
|
|
82
|
+
async function readMetadata(file, options = {}) {
|
|
81
83
|
const taglib = await getTagLib();
|
|
82
84
|
const audioFile = await taglib.open(file);
|
|
83
85
|
try {
|
|
@@ -98,7 +100,7 @@ async function readMetadata(file) {
|
|
|
98
100
|
}
|
|
99
101
|
const dynamics = extractDynamics(audioFile);
|
|
100
102
|
return {
|
|
101
|
-
tags: readExtendedTag(audioFile),
|
|
103
|
+
tags: readExtendedTag(audioFile, options.includeProperties),
|
|
102
104
|
properties: audioFile.audioProperties(),
|
|
103
105
|
hasCoverArt: audioFile.getPictures().length > 0,
|
|
104
106
|
...dynamics !== void 0 ? { dynamics } : {}
|
|
@@ -111,16 +113,64 @@ async function readMetadataBatch(files, options = {}) {
|
|
|
111
113
|
return executeBatch(files, options, (audioFile) => {
|
|
112
114
|
const dynamics = extractDynamics(audioFile);
|
|
113
115
|
return {
|
|
114
|
-
tags: readExtendedTag(audioFile),
|
|
116
|
+
tags: readExtendedTag(audioFile, options.includeProperties),
|
|
115
117
|
properties: audioFile.audioProperties(),
|
|
116
118
|
hasCoverArt: audioFile.getPictures().length > 0,
|
|
117
119
|
...dynamics !== void 0 ? { dynamics } : {}
|
|
118
120
|
};
|
|
119
121
|
});
|
|
120
122
|
}
|
|
123
|
+
function entryPath(entry) {
|
|
124
|
+
return typeof entry === "string" ? entry : entry.path;
|
|
125
|
+
}
|
|
126
|
+
async function executeWriteBatch(entries, options, writer) {
|
|
127
|
+
if (entries.length === 0) return { items: [], duration: 0 };
|
|
128
|
+
await getTagLib();
|
|
129
|
+
const startTime = Date.now();
|
|
130
|
+
const { concurrency = 4, continueOnError = true, onProgress, signal } = options;
|
|
131
|
+
const items = new Array(entries.length);
|
|
132
|
+
let processed = 0;
|
|
133
|
+
const total = entries.length;
|
|
134
|
+
for (let i = 0; i < entries.length; i += concurrency) {
|
|
135
|
+
signal?.throwIfAborted();
|
|
136
|
+
const chunk = entries.slice(i, i + concurrency);
|
|
137
|
+
const chunkPromises = chunk.map(async (entry, idx) => {
|
|
138
|
+
const index = i + idx;
|
|
139
|
+
const path = entryPath(entry);
|
|
140
|
+
try {
|
|
141
|
+
await writer(path);
|
|
142
|
+
items[index] = { status: "ok", path, data: void 0 };
|
|
143
|
+
} catch (error) {
|
|
144
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
145
|
+
items[index] = { status: "error", path, error: err };
|
|
146
|
+
if (!continueOnError) throw err;
|
|
147
|
+
}
|
|
148
|
+
processed++;
|
|
149
|
+
onProgress?.(processed, total, path);
|
|
150
|
+
});
|
|
151
|
+
await Promise.all(chunkPromises);
|
|
152
|
+
}
|
|
153
|
+
return { items, duration: Date.now() - startTime };
|
|
154
|
+
}
|
|
155
|
+
async function writeTagsBatch(updates, options = {}) {
|
|
156
|
+
const byPath = new Map(updates.map((u) => [u.path, u]));
|
|
157
|
+
return executeWriteBatch(updates, options, (path) => {
|
|
158
|
+
const update = byPath.get(path);
|
|
159
|
+
return applyTagsToFile(path, update.tags);
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
async function editTagsBatch(files, mutator, options = {}) {
|
|
163
|
+
return executeWriteBatch(
|
|
164
|
+
files,
|
|
165
|
+
options,
|
|
166
|
+
(path) => withAudioFileSaveToFile(path, mutator)
|
|
167
|
+
);
|
|
168
|
+
}
|
|
121
169
|
export {
|
|
170
|
+
editTagsBatch,
|
|
122
171
|
readMetadata,
|
|
123
172
|
readMetadataBatch,
|
|
124
173
|
readPropertiesBatch,
|
|
125
|
-
readTagsBatch
|
|
174
|
+
readTagsBatch,
|
|
175
|
+
writeTagsBatch
|
|
126
176
|
};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export { getTagLib, setBufferMode } from "./config.js";
|
|
2
2
|
export { applyTags, applyTagsToFile, clearTags, isValidAudioFile, readFormat, readProperties, readTags, } from "./tag-operations.js";
|
|
3
3
|
export { addPicture, applyCoverArt, applyPictures, clearPictures, findPictureByType, readCoverArt, readPictureMetadata, readPictures, replacePictureByType, } from "./picture-operations.js";
|
|
4
|
-
export { readMetadata, readMetadataBatch, readPropertiesBatch, readTagsBatch, } from "./batch-operations.js";
|
|
5
|
-
export type { BatchItem, BatchOptions, BatchResult, FileMetadata, } from "./batch-operations.js";
|
|
4
|
+
export { editTagsBatch, readMetadata, readMetadataBatch, readPropertiesBatch, readTagsBatch, writeTagsBatch, } from "./batch-operations.js";
|
|
5
|
+
export type { BatchItem, BatchOptions, BatchResult, FileMetadata, WriteTagUpdate, } from "./batch-operations.js";
|
|
6
6
|
export type { AudioProperties, ExtendedTag, Picture, PictureType, Tag, TagInput, } from "../types.js";
|
|
7
7
|
export { PICTURE_TYPE_NAMES, PICTURE_TYPE_VALUES } from "../types.js";
|
|
8
8
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/simple/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEvD,OAAO,EACL,SAAS,EACT,eAAe,EACf,SAAS,EACT,gBAAgB,EAChB,UAAU,EACV,cAAc,EACd,QAAQ,GACT,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,UAAU,EACV,aAAa,EACb,aAAa,EACb,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,mBAAmB,EACnB,YAAY,EACZ,oBAAoB,GACrB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,YAAY,EACZ,iBAAiB,EACjB,mBAAmB,EACnB,aAAa,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/simple/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEvD,OAAO,EACL,SAAS,EACT,eAAe,EACf,SAAS,EACT,gBAAgB,EAChB,UAAU,EACV,cAAc,EACd,QAAQ,GACT,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,UAAU,EACV,aAAa,EACb,aAAa,EACb,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,mBAAmB,EACnB,YAAY,EACZ,oBAAoB,GACrB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,aAAa,EACb,YAAY,EACZ,iBAAiB,EACjB,mBAAmB,EACnB,aAAa,EACb,cAAc,GACf,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,SAAS,EACT,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,cAAc,GACf,MAAM,uBAAuB,CAAC;AAE/B,YAAY,EACV,eAAe,EACf,WAAW,EACX,OAAO,EACP,WAAW,EACX,GAAG,EACH,QAAQ,GACT,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/src/simple/index.js
CHANGED
|
@@ -20,10 +20,12 @@ import {
|
|
|
20
20
|
replacePictureByType
|
|
21
21
|
} from "./picture-operations.js";
|
|
22
22
|
import {
|
|
23
|
+
editTagsBatch,
|
|
23
24
|
readMetadata,
|
|
24
25
|
readMetadataBatch,
|
|
25
26
|
readPropertiesBatch,
|
|
26
|
-
readTagsBatch
|
|
27
|
+
readTagsBatch,
|
|
28
|
+
writeTagsBatch
|
|
27
29
|
} from "./batch-operations.js";
|
|
28
30
|
import { PICTURE_TYPE_NAMES, PICTURE_TYPE_VALUES } from "../types.js";
|
|
29
31
|
export {
|
|
@@ -36,6 +38,7 @@ export {
|
|
|
36
38
|
applyTagsToFile,
|
|
37
39
|
clearPictures,
|
|
38
40
|
clearTags,
|
|
41
|
+
editTagsBatch,
|
|
39
42
|
findPictureByType,
|
|
40
43
|
getTagLib,
|
|
41
44
|
isValidAudioFile,
|
|
@@ -50,5 +53,6 @@ export {
|
|
|
50
53
|
readTags,
|
|
51
54
|
readTagsBatch,
|
|
52
55
|
replacePictureByType,
|
|
53
|
-
setBufferMode
|
|
56
|
+
setBufferMode,
|
|
57
|
+
writeTagsBatch
|
|
54
58
|
};
|
|
@@ -3,11 +3,15 @@ import type { AudioFileInput, AudioProperties, ExtendedTag, FileType, TagInput }
|
|
|
3
3
|
* Reads all metadata tags from an audio file.
|
|
4
4
|
*
|
|
5
5
|
* @param file - File path, Uint8Array, ArrayBuffer, or File object
|
|
6
|
+
* @param options - Read options; `includeProperties` (wire keys) surfaces raw
|
|
7
|
+
* values in `extraProperties` (taglib-3s1f)
|
|
6
8
|
* @returns Parsed tag fields including extended metadata from the audio file
|
|
7
9
|
* @throws {TagLibInitializationError} If the Wasm module fails to initialize
|
|
8
10
|
* @throws {InvalidFormatError} If the file is corrupted or in an unsupported format
|
|
9
11
|
*/
|
|
10
|
-
export declare function readTags(file: AudioFileInput
|
|
12
|
+
export declare function readTags(file: AudioFileInput, options?: {
|
|
13
|
+
includeProperties?: string[];
|
|
14
|
+
}): Promise<ExtendedTag>;
|
|
11
15
|
/**
|
|
12
16
|
* Applies metadata tag changes to an audio file and returns the modified content as a buffer.
|
|
13
17
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tag-operations.d.ts","sourceRoot":"","sources":["../../../src/simple/tag-operations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,eAAe,EACf,WAAW,EACX,QAAQ,EAER,QAAQ,EACT,MAAM,aAAa,CAAC;AAWrB
|
|
1
|
+
{"version":3,"file":"tag-operations.d.ts","sourceRoot":"","sources":["../../../src/simple/tag-operations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,eAAe,EACf,WAAW,EACX,QAAQ,EAER,QAAQ,EACT,MAAM,aAAa,CAAC;AAWrB;;;;;;;;;GASG;AACH,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,cAAc,EACpB,OAAO,GAAE;IAAE,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAA;CAAO,GAC7C,OAAO,CAAC,WAAW,CAAC,CAKtB;AAED;;;;;;;;;GASG;AACH,wBAAsB,SAAS,CAC7B,IAAI,EAAE,cAAc,EACpB,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,GACtB,OAAO,CAAC,UAAU,CAAC,CAIrB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,GACtB,OAAO,CAAC,IAAI,CAAC,CAWf;AAED;;;;;;;;GAQG;AACH,wBAAsB,cAAc,CAClC,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,eAAe,CAAC,CAY1B;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,OAAO,CAAC,CAYlB;AAED;;;;;;GAMG;AACH,wBAAsB,UAAU,CAC9B,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,CAW/B;AAED;;;;;;;;GAQG;AACH,wBAAsB,SAAS,CAC7B,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,UAAU,CAAC,CAsBrB"}
|
|
@@ -6,8 +6,11 @@ import {
|
|
|
6
6
|
withAudioFileSave,
|
|
7
7
|
withAudioFileSaveToFile
|
|
8
8
|
} from "./with-audio-file.js";
|
|
9
|
-
async function readTags(file) {
|
|
10
|
-
return withAudioFile(
|
|
9
|
+
async function readTags(file, options = {}) {
|
|
10
|
+
return withAudioFile(
|
|
11
|
+
file,
|
|
12
|
+
(audioFile) => readExtendedTag(audioFile, options.includeProperties)
|
|
13
|
+
);
|
|
11
14
|
}
|
|
12
15
|
async function applyTags(file, tags) {
|
|
13
16
|
return withAudioFileSave(file, (audioFile) => {
|
|
@@ -42,5 +42,5 @@ export interface FieldMapping {
|
|
|
42
42
|
* const vorbisField = METADATA_MAPPINGS.albumArtist.vorbis; // "ALBUMARTIST"
|
|
43
43
|
* ```
|
|
44
44
|
*/
|
|
45
|
-
export declare const METADATA_MAPPINGS: Record<Exclude<keyof ExtendedTag, "pictures" | "ratings" | "lyrics" | "chapters" | "bext" | "bextData" | "ixml" | "id3v2Frames" | "advisory">, FieldMapping>;
|
|
45
|
+
export declare const METADATA_MAPPINGS: Record<Exclude<keyof ExtendedTag, "pictures" | "ratings" | "lyrics" | "chapters" | "bext" | "bextData" | "ixml" | "id3v2Frames" | "advisory" | "extraProperties">, FieldMapping>;
|
|
46
46
|
//# sourceMappingURL=metadata-mappings.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metadata-mappings.d.ts","sourceRoot":"","sources":["../../../src/types/metadata-mappings.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAE7C;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,YAAY;IAC3B,wBAAwB;IACxB,KAAK,CAAC,EAAE;QACN,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,uCAAuC;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2BAA2B;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,6BAA6B;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,iBAAiB,EAAE,MAAM,CACpC,OAAO,CACL,MAAM,WAAW,EACf,UAAU,GACV,SAAS,GACT,QAAQ,GACR,UAAU,GACV,MAAM,GACN,UAAU,GACV,MAAM,GACN,aAAa,GAGb,UAAU,
|
|
1
|
+
{"version":3,"file":"metadata-mappings.d.ts","sourceRoot":"","sources":["../../../src/types/metadata-mappings.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAE7C;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,YAAY;IAC3B,wBAAwB;IACxB,KAAK,CAAC,EAAE;QACN,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,uCAAuC;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2BAA2B;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,6BAA6B;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,iBAAiB,EAAE,MAAM,CACpC,OAAO,CACL,MAAM,WAAW,EACf,UAAU,GACV,SAAS,GACT,QAAQ,GACR,UAAU,GACV,MAAM,GACN,UAAU,GACV,MAAM,GACN,aAAa,GAGb,UAAU,GAGV,iBAAiB,CACpB,EACD,YAAY,CAuPb,CAAC"}
|
|
@@ -223,6 +223,11 @@ const METADATA_MAPPINGS = {
|
|
|
223
223
|
vorbis: "RELEASETYPE",
|
|
224
224
|
mp4: "----:com.apple.iTunes:MusicBrainz Album Type"
|
|
225
225
|
},
|
|
226
|
+
releaseCountry: {
|
|
227
|
+
id3v2: { frame: "TXXX", description: "MUSICBRAINZ ALBUM RELEASE COUNTRY" },
|
|
228
|
+
vorbis: "RELEASECOUNTRY",
|
|
229
|
+
mp4: "----:com.apple.iTunes:MusicBrainz Album Release Country"
|
|
230
|
+
},
|
|
226
231
|
itunesAdvisory: {
|
|
227
232
|
id3v2: { frame: "TXXX", description: "ITUNESADVISORY" },
|
|
228
233
|
vorbis: "ITUNESADVISORY",
|
package/dist/src/types/tags.d.ts
CHANGED
|
@@ -111,6 +111,8 @@ export interface TagInput {
|
|
|
111
111
|
readonly musicbrainzReleaseGroupId?: string | string[];
|
|
112
112
|
/** Release type (album, single, EP, compilation, ...); multi-value allowed */
|
|
113
113
|
readonly releaseType?: string | string[];
|
|
114
|
+
/** Release country (ISO 3166-1 code, e.g. "US"); multi-value allowed */
|
|
115
|
+
readonly releaseCountry?: string | string[];
|
|
114
116
|
/** Content advisory in the ITUNESADVISORY convention ('1' = explicit, '2' = clean, '0' = unspecified) */
|
|
115
117
|
readonly itunesAdvisory?: string | string[];
|
|
116
118
|
/**
|
|
@@ -176,6 +178,8 @@ export interface ExtendedTag extends Tag {
|
|
|
176
178
|
readonly musicbrainzReleaseGroupId?: string[];
|
|
177
179
|
/** Release type (album, single, EP, compilation, ...); multi-value */
|
|
178
180
|
readonly releaseType?: string[];
|
|
181
|
+
/** Release country (ISO 3166-1 code, e.g. "US"); multi-value */
|
|
182
|
+
readonly releaseCountry?: string[];
|
|
179
183
|
/** Content advisory in the ITUNESADVISORY convention ('1' = explicit, '2' = clean, '0' = unspecified) */
|
|
180
184
|
readonly itunesAdvisory?: string[];
|
|
181
185
|
/**
|
|
@@ -261,6 +265,15 @@ export interface ExtendedTag extends Tag {
|
|
|
261
265
|
readonly bextData?: Uint8Array;
|
|
262
266
|
/** Raw iXML chunk as a string. WAV and FLAC only. */
|
|
263
267
|
readonly ixml?: string;
|
|
268
|
+
/**
|
|
269
|
+
* Raw wire-key values requested via `includeProperties` (taglib-3s1f):
|
|
270
|
+
* keys outside the modeled typed set surface here under their exact WIRE
|
|
271
|
+
* names (e.g. `{ CATALOGNUMBER: ["LC1234"] }`). Present only when the read
|
|
272
|
+
* was asked for them; absent keys are omitted. Never written back —
|
|
273
|
+
* `normalizeTagInput` ignores it, so a readTags() -> applyTags() round-trip
|
|
274
|
+
* cannot create an EXTRAPROPERTIES tag.
|
|
275
|
+
*/
|
|
276
|
+
readonly extraProperties?: Record<string, string[]>;
|
|
264
277
|
/** Staged raw ID3v2 frame replacements: frame ID → list of body byte arrays. */
|
|
265
278
|
id3v2Frames?: Record<string, Uint8Array[]>;
|
|
266
279
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tags.d.ts","sourceRoot":"","sources":["../../../src/types/tags.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAE9D;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,GAAG;IAClB,kBAAkB;IAClB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,kBAAkB;IAClB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,iBAAiB;IACjB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,cAAc;IACd,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,YAAY;IACZ,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,WAAW;IACX,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,mBAAmB;IACnB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,QAAQ;IACvB,kBAAkB;IAClB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACnC,kBAAkB;IAClB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACpC,iBAAiB;IACjB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACnC,cAAc;IACd,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACrC,YAAY;IACZ,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACnC,WAAW;IACX,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAClC,mBAAmB;IACnB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB;;;;OAIG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAGzC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC7C,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC9C,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACzC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACvC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACvC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACvC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACvC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACxC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACvC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC7C,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC1C,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACnC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC5C,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC3C,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC1C,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACjD,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACxC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAChD,QAAQ,CAAC,oBAAoB,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAClD,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACjD,QAAQ,CAAC,yBAAyB,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACvD,8EAA8E;IAC9E,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACzC,yGAAyG;IACzG,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC5C;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,UAAU,GAAG,OAAO,GAAG,aAAa,CAAC;IACzD,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACjD,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACjD,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACjD,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAIjD,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC3C,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAG3C,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAGtB,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;CAChC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,WAAY,SAAQ,GAAG;IACtC;;;OAGG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAClC;;;;;OAKG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACzC,yCAAyC;IACzC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IACxC,oBAAoB;IACpB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,2BAA2B;IAC3B,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IACvC,6BAA6B;IAC7B,QAAQ,CAAC,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IACzC,4BAA4B;IAC5B,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IACxC,mCAAmC;IACnC,QAAQ,CAAC,yBAAyB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9C,sEAAsE;IACtE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC,yGAAyG;IACzG,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IACnC;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,UAAU,GAAG,OAAO,GAAG,aAAa,CAAC;IACzD,iDAAiD;IACjD,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC,eAAe;IACf,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,kBAAkB;IAClB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,4BAA4B;IAC5B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,6BAA6B;IAC7B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,6BAA6B;IAC7B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,uBAAuB;IACvB,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B,qCAAqC;IACrC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,sCAAsC;IACtC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,qCAAqC;IACrC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,4CAA4C;IAC5C,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IACpC,wCAAwC;IACxC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACjC,gBAAgB;IAChB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,gBAAgB;IAChB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,iBAAiB;IACjB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,mDAAmD;IACnD,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,eAAe;IACf,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,mBAAmB;IACnB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,yCAAyC;IACzC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,eAAe;IACf,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,0CAA0C;IAC1C,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IACnC,yCAAyC;IACzC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IAClC,4BAA4B;IAC5B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IAGjC,qDAAqD;IACrD,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IACxC,4CAA4C;IAC5C,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IACxC,kCAAkC;IAClC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IACxC,4CAA4C;IAC5C,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAKxC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAGhC,sDAAsD;IACtD,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IACpC,wEAAwE;IACxE,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IACrC,gCAAgC;IAChC,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,eAAe,EAAE,OAAO,EAAE,CAAC;IACtD,0EAA0E;IAC1E,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,oCAAoC,EAAE,MAAM,EAAE,CAAC;IACzE,wEAAwE;IACxE,QAAQ,CAAC,MAAM,CAAC,EACd,OAAO,oCAAoC,EAAE,cAAc,EAAE,CAAC;IAChE;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,eAAe,EAAE,OAAO,EAAE,CAAC;IACtD,8EAA8E;IAC9E,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,UAAU,EAAE,uBAAuB,CAAC;IAC3D,qDAAqD;IACrD,QAAQ,CAAC,QAAQ,CAAC,EAAE,UAAU,CAAC;IAC/B,qDAAqD;IACrD,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,gFAAgF;IAChF,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;CAC5C;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,WAAW,GACnB;KAAG,CAAC,IAAI,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE;CAAE,GACjC;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAA;CAAE,CAAC"}
|
|
1
|
+
{"version":3,"file":"tags.d.ts","sourceRoot":"","sources":["../../../src/types/tags.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,7 +8,7 @@ import type { ExtendedTag, PropertyMap, TagInput } from "../types.js";
|
|
|
8
8
|
* (taglib-0co). Each field is included only when present, mirroring how
|
|
9
9
|
* {@link mapPropertiesToExtendedTag} omits absent text properties.
|
|
10
10
|
*/
|
|
11
|
-
export declare function readExtendedTag(audioFile: AudioFile): ExtendedTag;
|
|
11
|
+
export declare function readExtendedTag(audioFile: AudioFile, includeProperties?: string[]): ExtendedTag;
|
|
12
12
|
export declare function mapPropertiesToExtendedTag(props: PropertyMap): ExtendedTag;
|
|
13
13
|
export declare function mergeTagUpdates(file: AudioFile, tags: Partial<TagInput>): void;
|
|
14
14
|
export declare function normalizeTagInput(input: Partial<TagInput>): PropertyMap;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tag-mapping.d.ts","sourceRoot":"","sources":["../../../src/utils/tag-mapping.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mCAAmC,CAAC;AACnE,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAqCtE;;;;;;;GAOG;AACH,wBAAgB,eAAe,
|
|
1
|
+
{"version":3,"file":"tag-mapping.d.ts","sourceRoot":"","sources":["../../../src/utils/tag-mapping.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mCAAmC,CAAC;AACnE,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAqCtE;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,SAAS,EAAE,SAAS,EACpB,iBAAiB,CAAC,EAAE,MAAM,EAAE,GAC3B,WAAW,CA2Cb;AAED,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,WAAW,GAAG,WAAW,CAiG1E;AAED,wBAAgB,eAAe,CAC7B,IAAI,EAAE,SAAS,EACf,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,GACtB,IAAI,CAaN;AAoDD,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,OAAO,CAAC,QAAQ,CAAC,GACvB,WAAW,CA+Eb"}
|
|
@@ -28,8 +28,9 @@ const NUMERIC_FIELDS = /* @__PURE__ */ new Set([
|
|
|
28
28
|
"totalDiscs",
|
|
29
29
|
"bpm"
|
|
30
30
|
]);
|
|
31
|
-
function readExtendedTag(audioFile) {
|
|
32
|
-
const
|
|
31
|
+
function readExtendedTag(audioFile, includeProperties) {
|
|
32
|
+
const props = audioFile.properties();
|
|
33
|
+
const tag = mapPropertiesToExtendedTag(props);
|
|
33
34
|
const pictures = audioFile.getPictures();
|
|
34
35
|
if (pictures.length > 0) tag.pictures = pictures;
|
|
35
36
|
const ratings = audioFile.getRatings();
|
|
@@ -44,6 +45,18 @@ function readExtendedTag(audioFile) {
|
|
|
44
45
|
if (bextData !== void 0) tag.bextData = bextData;
|
|
45
46
|
const ixml = audioFile.getIxml();
|
|
46
47
|
if (ixml !== void 0) tag.ixml = ixml;
|
|
48
|
+
if (includeProperties !== void 0 && includeProperties.length > 0) {
|
|
49
|
+
const extraProperties = {};
|
|
50
|
+
for (const wireKey of includeProperties) {
|
|
51
|
+
const values = props[fromTagLibKey(wireKey)]?.filter((v) => v !== "");
|
|
52
|
+
if (values !== void 0 && values.length > 0) {
|
|
53
|
+
extraProperties[wireKey] = values;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (Object.keys(extraProperties).length > 0) {
|
|
57
|
+
tag.extraProperties = extraProperties;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
47
60
|
return tag;
|
|
48
61
|
}
|
|
49
62
|
function mapPropertiesToExtendedTag(props) {
|
|
@@ -163,6 +176,7 @@ function normalizeTagInput(input) {
|
|
|
163
176
|
}
|
|
164
177
|
for (const [field, val] of Object.entries(input)) {
|
|
165
178
|
if (BASIC_FIELDS.has(field) || val === void 0) continue;
|
|
179
|
+
if (field === "extraProperties") continue;
|
|
166
180
|
if (field === "compilation") {
|
|
167
181
|
props[field] = [val ? "1" : "0"];
|
|
168
182
|
} else if (field === "advisory") {
|
package/dist/src/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const VERSION = "2.
|
|
1
|
+
export declare const VERSION = "2.2.0";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/src/version.js
CHANGED
package/dist/taglib-wasi.wasm
CHANGED
|
Binary file
|
package/dist/taglib-web.wasm
CHANGED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "taglib-wasm",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "TagLib-Wasm is the universal tagging library for TypeScript/JavaScript platforms: Browsers, Node.js, Deno, Bun, Cloudflare Workers, and Electron apps",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|