taglib-wasm 1.0.5 → 1.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +38 -443
- package/dist/index.browser.d.ts +2 -1
- package/dist/index.browser.d.ts.map +1 -1
- package/dist/index.browser.js +76 -103
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/simple.browser.js +74 -103
- package/dist/src/errors/base.d.ts +1 -1
- package/dist/src/errors/base.d.ts.map +1 -1
- package/dist/src/errors/base.js +2 -1
- package/dist/src/folder-api/folder-operations.d.ts +2 -1
- package/dist/src/folder-api/folder-operations.d.ts.map +1 -1
- package/dist/src/folder-api/types.d.ts.map +1 -1
- package/dist/src/folder-api/types.js +4 -1
- package/dist/src/runtime/wasi-adapter/file-handle.d.ts.map +1 -1
- package/dist/src/runtime/wasi-adapter/file-handle.js +12 -2
- package/dist/src/runtime/wasi-adapter/wasm-io.d.ts.map +1 -1
- package/dist/src/runtime/wasi-adapter/wasm-io.js +9 -0
- package/dist/src/runtime/wasi-host.d.ts.map +1 -1
- package/dist/src/runtime/wasi-host.js +5 -0
- package/dist/src/simple/batch-operations.d.ts +4 -4
- package/dist/src/simple/batch-operations.d.ts.map +1 -1
- package/dist/src/simple/batch-operations.js +4 -1
- package/dist/src/simple/picture-operations.d.ts.map +1 -1
- package/dist/src/simple/picture-operations.js +6 -50
- package/dist/src/simple/tag-operations.d.ts.map +1 -1
- package/dist/src/simple/tag-operations.js +12 -65
- package/dist/src/simple/with-audio-file.d.ts +5 -0
- package/dist/src/simple/with-audio-file.d.ts.map +1 -0
- package/dist/src/simple/with-audio-file.js +32 -0
- package/dist/src/taglib/audio-file-base.d.ts +3 -3
- package/dist/src/taglib/audio-file-base.d.ts.map +1 -1
- package/dist/src/taglib/audio-file-base.js +8 -2
- package/dist/src/taglib/audio-file-impl.d.ts +2 -2
- package/dist/src/taglib/audio-file-impl.d.ts.map +1 -1
- package/dist/src/taglib/audio-file-interface.d.ts +3 -1
- package/dist/src/taglib/audio-file-interface.d.ts.map +1 -1
- package/dist/src/taglib/taglib-class.d.ts +4 -2
- package/dist/src/taglib/taglib-class.d.ts.map +1 -1
- package/dist/src/taglib/taglib-class.js +19 -5
- package/dist/src/types/audio-formats.d.ts +37 -3
- package/dist/src/types/audio-formats.d.ts.map +1 -1
- package/dist/src/types/audio-formats.js +6 -0
- package/dist/src/types/format-property-keys.d.ts +1 -1
- package/dist/src/types/format-property-keys.d.ts.map +1 -1
- package/dist/src/version.d.ts +2 -0
- package/dist/src/version.d.ts.map +1 -0
- package/dist/src/version.js +4 -0
- package/dist/src/wasm.d.ts +8 -0
- package/dist/src/wasm.d.ts.map +1 -1
- package/dist/taglib-web.wasm +0 -0
- package/dist/taglib-wrapper.js +1 -1
- package/package.json +1 -1
package/dist/simple.browser.js
CHANGED
|
@@ -11,6 +11,9 @@ var __export = (target, all) => {
|
|
|
11
11
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
12
12
|
|
|
13
13
|
// src/types/audio-formats.ts
|
|
14
|
+
function isNamedAudioInput(input) {
|
|
15
|
+
return typeof input === "object" && input !== null && "name" in input && "data" in input && !(input instanceof File) && !(input instanceof Uint8Array) && !(input instanceof ArrayBuffer);
|
|
16
|
+
}
|
|
14
17
|
var init_audio_formats = __esm({
|
|
15
18
|
"src/types/audio-formats.ts"() {
|
|
16
19
|
"use strict";
|
|
@@ -131,7 +134,8 @@ var init_base = __esm({
|
|
|
131
134
|
"M4A",
|
|
132
135
|
"FLAC",
|
|
133
136
|
"OGG",
|
|
134
|
-
"WAV"
|
|
137
|
+
"WAV",
|
|
138
|
+
"MKA"
|
|
135
139
|
];
|
|
136
140
|
TagLibError = class _TagLibError extends Error {
|
|
137
141
|
/**
|
|
@@ -1071,6 +1075,9 @@ var init_audio_file_base = __esm({
|
|
|
1071
1075
|
if (!propsWrapper) {
|
|
1072
1076
|
return void 0;
|
|
1073
1077
|
}
|
|
1078
|
+
const containerFormat = propsWrapper.containerFormat() || "unknown";
|
|
1079
|
+
const mpegVersion = propsWrapper.mpegVersion();
|
|
1080
|
+
const formatVersion = propsWrapper.formatVersion();
|
|
1074
1081
|
this.cachedAudioProperties = {
|
|
1075
1082
|
duration: propsWrapper.lengthInSeconds(),
|
|
1076
1083
|
bitrate: propsWrapper.bitrate(),
|
|
@@ -1078,8 +1085,11 @@ var init_audio_file_base = __esm({
|
|
|
1078
1085
|
channels: propsWrapper.channels(),
|
|
1079
1086
|
bitsPerSample: propsWrapper.bitsPerSample(),
|
|
1080
1087
|
codec: propsWrapper.codec() || "unknown",
|
|
1081
|
-
containerFormat
|
|
1082
|
-
isLossless: propsWrapper.isLossless()
|
|
1088
|
+
containerFormat,
|
|
1089
|
+
isLossless: propsWrapper.isLossless(),
|
|
1090
|
+
...mpegVersion > 0 ? { mpegVersion, mpegLayer: propsWrapper.mpegLayer() } : {},
|
|
1091
|
+
...containerFormat === "MP4" || containerFormat === "ASF" ? { isEncrypted: propsWrapper.isEncrypted() } : {},
|
|
1092
|
+
...formatVersion > 0 ? { formatVersion } : {}
|
|
1083
1093
|
};
|
|
1084
1094
|
}
|
|
1085
1095
|
return this.cachedAudioProperties;
|
|
@@ -1426,6 +1436,15 @@ var init_tag_mapping = __esm({
|
|
|
1426
1436
|
}
|
|
1427
1437
|
});
|
|
1428
1438
|
|
|
1439
|
+
// src/version.ts
|
|
1440
|
+
var VERSION;
|
|
1441
|
+
var init_version = __esm({
|
|
1442
|
+
"src/version.ts"() {
|
|
1443
|
+
"use strict";
|
|
1444
|
+
VERSION = "1.0.7";
|
|
1445
|
+
}
|
|
1446
|
+
});
|
|
1447
|
+
|
|
1429
1448
|
// src/runtime/module-loader-browser.ts
|
|
1430
1449
|
var module_loader_browser_exports = {};
|
|
1431
1450
|
__export(module_loader_browser_exports, {
|
|
@@ -1478,10 +1497,12 @@ var TagLib;
|
|
|
1478
1497
|
var init_taglib_class = __esm({
|
|
1479
1498
|
"src/taglib/taglib-class.ts"() {
|
|
1480
1499
|
"use strict";
|
|
1500
|
+
init_audio_formats();
|
|
1481
1501
|
init_errors2();
|
|
1482
1502
|
init_audio_file_impl();
|
|
1483
1503
|
init_load_audio_data();
|
|
1484
1504
|
init_tag_mapping();
|
|
1505
|
+
init_version();
|
|
1485
1506
|
TagLib = class _TagLib {
|
|
1486
1507
|
constructor(module) {
|
|
1487
1508
|
__publicField(this, "module");
|
|
@@ -1500,7 +1521,7 @@ var init_taglib_class = __esm({
|
|
|
1500
1521
|
}
|
|
1501
1522
|
/**
|
|
1502
1523
|
* Open an audio file for reading and writing metadata.
|
|
1503
|
-
* @param input - File path, Uint8Array, ArrayBuffer,
|
|
1524
|
+
* @param input - File path, Uint8Array, ArrayBuffer, File object, or NamedAudioInput.
|
|
1504
1525
|
* @param options - Partial-loading options for large files.
|
|
1505
1526
|
* @returns An AudioFile instance (use `using` for automatic cleanup).
|
|
1506
1527
|
* @throws {TagLibInitializationError} If the module is not properly initialized.
|
|
@@ -1512,7 +1533,8 @@ var init_taglib_class = __esm({
|
|
|
1512
1533
|
"TagLib module not properly initialized: createFileHandle not found. Make sure the module is fully loaded before calling open."
|
|
1513
1534
|
);
|
|
1514
1535
|
}
|
|
1515
|
-
const
|
|
1536
|
+
const actualInput = isNamedAudioInput(input) ? input.data : input;
|
|
1537
|
+
const sourcePath = typeof actualInput === "string" ? actualInput : void 0;
|
|
1516
1538
|
const opts = {
|
|
1517
1539
|
partial: false,
|
|
1518
1540
|
maxHeaderSize: 1024 * 1024,
|
|
@@ -1520,7 +1542,7 @@ var init_taglib_class = __esm({
|
|
|
1520
1542
|
...options
|
|
1521
1543
|
};
|
|
1522
1544
|
const { data: audioData, isPartiallyLoaded } = await loadAudioData(
|
|
1523
|
-
|
|
1545
|
+
actualInput,
|
|
1524
1546
|
opts
|
|
1525
1547
|
);
|
|
1526
1548
|
const buffer = audioData.buffer.slice(
|
|
@@ -1541,7 +1563,7 @@ var init_taglib_class = __esm({
|
|
|
1541
1563
|
this.module,
|
|
1542
1564
|
fileHandle,
|
|
1543
1565
|
sourcePath,
|
|
1544
|
-
|
|
1566
|
+
actualInput,
|
|
1545
1567
|
isPartiallyLoaded,
|
|
1546
1568
|
opts
|
|
1547
1569
|
);
|
|
@@ -1601,7 +1623,16 @@ var init_taglib_class = __esm({
|
|
|
1601
1623
|
}
|
|
1602
1624
|
/** Returns the taglib-wasm version with embedded TagLib version. */
|
|
1603
1625
|
version() {
|
|
1604
|
-
return
|
|
1626
|
+
return `${VERSION} (TagLib ${this.taglibVersion()})`;
|
|
1627
|
+
}
|
|
1628
|
+
taglibVersion() {
|
|
1629
|
+
if (this.module.getVersion) {
|
|
1630
|
+
return this.module.getVersion();
|
|
1631
|
+
}
|
|
1632
|
+
if (this.module.version) {
|
|
1633
|
+
return this.module.version();
|
|
1634
|
+
}
|
|
1635
|
+
return "unknown";
|
|
1605
1636
|
}
|
|
1606
1637
|
};
|
|
1607
1638
|
}
|
|
@@ -1667,7 +1698,10 @@ async function getTagLib() {
|
|
|
1667
1698
|
init_errors2();
|
|
1668
1699
|
init_write();
|
|
1669
1700
|
init_tag_mapping();
|
|
1670
|
-
|
|
1701
|
+
|
|
1702
|
+
// src/simple/with-audio-file.ts
|
|
1703
|
+
init_errors2();
|
|
1704
|
+
async function withAudioFile(file, fn) {
|
|
1671
1705
|
const taglib = await getTagLib();
|
|
1672
1706
|
const audioFile = await taglib.open(file);
|
|
1673
1707
|
try {
|
|
@@ -1676,22 +1710,14 @@ async function readTags(file) {
|
|
|
1676
1710
|
"File may be corrupted or in an unsupported format"
|
|
1677
1711
|
);
|
|
1678
1712
|
}
|
|
1679
|
-
|
|
1680
|
-
return mapPropertiesToExtendedTag(props);
|
|
1713
|
+
return fn(audioFile);
|
|
1681
1714
|
} finally {
|
|
1682
1715
|
audioFile.dispose();
|
|
1683
1716
|
}
|
|
1684
1717
|
}
|
|
1685
|
-
async function
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
try {
|
|
1689
|
-
if (!audioFile.isValid()) {
|
|
1690
|
-
throw new InvalidFormatError(
|
|
1691
|
-
"File may be corrupted or in an unsupported format"
|
|
1692
|
-
);
|
|
1693
|
-
}
|
|
1694
|
-
mergeTagUpdates(audioFile, tags);
|
|
1718
|
+
async function withAudioFileSave(file, fn) {
|
|
1719
|
+
return withAudioFile(file, (audioFile) => {
|
|
1720
|
+
fn(audioFile);
|
|
1695
1721
|
if (!audioFile.save()) {
|
|
1696
1722
|
throw new FileOperationError(
|
|
1697
1723
|
"save",
|
|
@@ -1699,9 +1725,20 @@ async function applyTags(file, tags) {
|
|
|
1699
1725
|
);
|
|
1700
1726
|
}
|
|
1701
1727
|
return audioFile.getFileBuffer();
|
|
1702
|
-
}
|
|
1703
|
-
|
|
1704
|
-
|
|
1728
|
+
});
|
|
1729
|
+
}
|
|
1730
|
+
|
|
1731
|
+
// src/simple/tag-operations.ts
|
|
1732
|
+
async function readTags(file) {
|
|
1733
|
+
return withAudioFile(
|
|
1734
|
+
file,
|
|
1735
|
+
(audioFile) => mapPropertiesToExtendedTag(audioFile.properties())
|
|
1736
|
+
);
|
|
1737
|
+
}
|
|
1738
|
+
async function applyTags(file, tags) {
|
|
1739
|
+
return withAudioFileSave(file, (audioFile) => {
|
|
1740
|
+
mergeTagUpdates(audioFile, tags);
|
|
1741
|
+
});
|
|
1705
1742
|
}
|
|
1706
1743
|
async function applyTagsToFile(file, tags) {
|
|
1707
1744
|
if (typeof file !== "string") {
|
|
@@ -1714,14 +1751,7 @@ async function applyTagsToFile(file, tags) {
|
|
|
1714
1751
|
await writeFileData(file, modifiedBuffer);
|
|
1715
1752
|
}
|
|
1716
1753
|
async function readProperties(file) {
|
|
1717
|
-
|
|
1718
|
-
const audioFile = await taglib.open(file);
|
|
1719
|
-
try {
|
|
1720
|
-
if (!audioFile.isValid()) {
|
|
1721
|
-
throw new InvalidFormatError(
|
|
1722
|
-
"File may be corrupted or in an unsupported format"
|
|
1723
|
-
);
|
|
1724
|
-
}
|
|
1754
|
+
return withAudioFile(file, (audioFile) => {
|
|
1725
1755
|
const props = audioFile.audioProperties();
|
|
1726
1756
|
if (!props) {
|
|
1727
1757
|
throw new MetadataError(
|
|
@@ -1731,9 +1761,7 @@ async function readProperties(file) {
|
|
|
1731
1761
|
);
|
|
1732
1762
|
}
|
|
1733
1763
|
return props;
|
|
1734
|
-
}
|
|
1735
|
-
audioFile.dispose();
|
|
1736
|
-
}
|
|
1764
|
+
});
|
|
1737
1765
|
}
|
|
1738
1766
|
async function isValidAudioFile(file) {
|
|
1739
1767
|
try {
|
|
@@ -1761,85 +1789,25 @@ async function readFormat(file) {
|
|
|
1761
1789
|
}
|
|
1762
1790
|
}
|
|
1763
1791
|
async function clearTags(file) {
|
|
1764
|
-
|
|
1765
|
-
const audioFile = await taglib.open(file);
|
|
1766
|
-
try {
|
|
1767
|
-
if (!audioFile.isValid()) {
|
|
1768
|
-
throw new InvalidFormatError(
|
|
1769
|
-
"File may be corrupted or in an unsupported format"
|
|
1770
|
-
);
|
|
1771
|
-
}
|
|
1792
|
+
return withAudioFileSave(file, (audioFile) => {
|
|
1772
1793
|
audioFile.setProperties({});
|
|
1773
1794
|
audioFile.removePictures();
|
|
1774
|
-
|
|
1775
|
-
throw new FileOperationError(
|
|
1776
|
-
"save",
|
|
1777
|
-
"Failed to save metadata changes. The file may be read-only or corrupted."
|
|
1778
|
-
);
|
|
1779
|
-
}
|
|
1780
|
-
return audioFile.getFileBuffer();
|
|
1781
|
-
} finally {
|
|
1782
|
-
audioFile.dispose();
|
|
1783
|
-
}
|
|
1795
|
+
});
|
|
1784
1796
|
}
|
|
1785
1797
|
|
|
1786
1798
|
// src/simple/picture-operations.ts
|
|
1787
|
-
init_errors2();
|
|
1788
1799
|
async function readPictures(file) {
|
|
1789
|
-
|
|
1790
|
-
const audioFile = await taglib.open(file);
|
|
1791
|
-
try {
|
|
1792
|
-
if (!audioFile.isValid()) {
|
|
1793
|
-
throw new InvalidFormatError(
|
|
1794
|
-
"File may be corrupted or in an unsupported format"
|
|
1795
|
-
);
|
|
1796
|
-
}
|
|
1797
|
-
return audioFile.getPictures();
|
|
1798
|
-
} finally {
|
|
1799
|
-
audioFile.dispose();
|
|
1800
|
-
}
|
|
1800
|
+
return withAudioFile(file, (audioFile) => audioFile.getPictures());
|
|
1801
1801
|
}
|
|
1802
1802
|
async function applyPictures(file, pictures) {
|
|
1803
|
-
|
|
1804
|
-
const audioFile = await taglib.open(file);
|
|
1805
|
-
try {
|
|
1806
|
-
if (!audioFile.isValid()) {
|
|
1807
|
-
throw new InvalidFormatError(
|
|
1808
|
-
"File may be corrupted or in an unsupported format"
|
|
1809
|
-
);
|
|
1810
|
-
}
|
|
1803
|
+
return withAudioFileSave(file, (audioFile) => {
|
|
1811
1804
|
audioFile.setPictures(pictures);
|
|
1812
|
-
|
|
1813
|
-
throw new FileOperationError(
|
|
1814
|
-
"save",
|
|
1815
|
-
"Failed to save picture changes. The file may be read-only or corrupted."
|
|
1816
|
-
);
|
|
1817
|
-
}
|
|
1818
|
-
return audioFile.getFileBuffer();
|
|
1819
|
-
} finally {
|
|
1820
|
-
audioFile.dispose();
|
|
1821
|
-
}
|
|
1805
|
+
});
|
|
1822
1806
|
}
|
|
1823
1807
|
async function addPicture(file, picture) {
|
|
1824
|
-
|
|
1825
|
-
const audioFile = await taglib.open(file);
|
|
1826
|
-
try {
|
|
1827
|
-
if (!audioFile.isValid()) {
|
|
1828
|
-
throw new InvalidFormatError(
|
|
1829
|
-
"File may be corrupted or in an unsupported format"
|
|
1830
|
-
);
|
|
1831
|
-
}
|
|
1808
|
+
return withAudioFileSave(file, (audioFile) => {
|
|
1832
1809
|
audioFile.addPicture(picture);
|
|
1833
|
-
|
|
1834
|
-
throw new FileOperationError(
|
|
1835
|
-
"save",
|
|
1836
|
-
"Failed to save picture changes. The file may be read-only or corrupted."
|
|
1837
|
-
);
|
|
1838
|
-
}
|
|
1839
|
-
return audioFile.getFileBuffer();
|
|
1840
|
-
} finally {
|
|
1841
|
-
audioFile.dispose();
|
|
1842
|
-
}
|
|
1810
|
+
});
|
|
1843
1811
|
}
|
|
1844
1812
|
async function clearPictures(file) {
|
|
1845
1813
|
return applyPictures(file, []);
|
|
@@ -1886,6 +1854,7 @@ async function readPictureMetadata(file) {
|
|
|
1886
1854
|
}
|
|
1887
1855
|
|
|
1888
1856
|
// src/simple/batch-operations.ts
|
|
1857
|
+
init_audio_formats();
|
|
1889
1858
|
init_errors2();
|
|
1890
1859
|
init_tag_mapping();
|
|
1891
1860
|
async function executeBatch(files, options, processor) {
|
|
@@ -1901,7 +1870,7 @@ async function executeBatch(files, options, processor) {
|
|
|
1901
1870
|
const chunk = files.slice(i, i + concurrency);
|
|
1902
1871
|
const chunkPromises = chunk.map(async (file, idx) => {
|
|
1903
1872
|
const index = i + idx;
|
|
1904
|
-
const fileName = typeof file === "string" ? file : `
|
|
1873
|
+
const fileName = typeof file === "string" ? file : file instanceof File ? file.name : isNamedAudioInput(file) ? file.name : `buffer-${index}`;
|
|
1905
1874
|
try {
|
|
1906
1875
|
const audioFile = await taglib.open(file);
|
|
1907
1876
|
try {
|
|
@@ -1973,6 +1942,8 @@ async function readMetadata(file) {
|
|
|
1973
1942
|
name = file;
|
|
1974
1943
|
} else if (file instanceof File) {
|
|
1975
1944
|
name = file.name;
|
|
1945
|
+
} else if (isNamedAudioInput(file)) {
|
|
1946
|
+
name = file.name;
|
|
1976
1947
|
} else {
|
|
1977
1948
|
name = `buffer (${file.byteLength} bytes)`;
|
|
1978
1949
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* List of audio formats supported by TagLib-Wasm
|
|
3
3
|
*/
|
|
4
|
-
export declare const SUPPORTED_FORMATS: readonly ["MP3", "MP4", "M4A", "FLAC", "OGG", "WAV"];
|
|
4
|
+
export declare const SUPPORTED_FORMATS: readonly ["MP3", "MP4", "M4A", "FLAC", "OGG", "WAV", "MKA"];
|
|
5
5
|
/**
|
|
6
6
|
* Error codes for programmatic error handling
|
|
7
7
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../src/errors/base.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,iBAAiB,
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../src/errors/base.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,iBAAiB,6DAQpB,CAAC;AAEX;;GAEG;AACH,MAAM,MAAM,eAAe,GACvB,gBAAgB,GAChB,gBAAgB,GAChB,oBAAoB,GACpB,gBAAgB,GAChB,UAAU,GACV,QAAQ,GACR,aAAa,GACb,aAAa,GACb,aAAa,GACb,WAAW,CAAC;AAEhB;;GAEG;AACH,qBAAa,WAAY,SAAQ,KAAK;aAQlB,IAAI,EAAE,eAAe;aAErB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IATnD;;;;;OAKG;gBAEe,IAAI,EAAE,eAAe,EACrC,OAAO,EAAE,MAAM,EACC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,YAAA;CAMpD"}
|
package/dist/src/errors/base.js
CHANGED
|
@@ -18,7 +18,8 @@ import type { DuplicateGroup, FolderScanOptions, FolderUpdateResult } from "./ty
|
|
|
18
18
|
* ];
|
|
19
19
|
*
|
|
20
20
|
* const result = await updateFolderTags(updates);
|
|
21
|
-
*
|
|
21
|
+
* const updated = result.items.filter((i) => i.status === "ok").length;
|
|
22
|
+
* console.log(`Updated ${updated} files`);
|
|
22
23
|
* ```
|
|
23
24
|
*/
|
|
24
25
|
export declare function updateFolderTags(updates: Array<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"folder-operations.d.ts","sourceRoot":"","sources":["../../../src/folder-api/folder-operations.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAO,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAKxD,OAAO,KAAK,EAEV,cAAc,EACd,iBAAiB,EAEjB,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAGpB
|
|
1
|
+
{"version":3,"file":"folder-operations.d.ts","sourceRoot":"","sources":["../../../src/folder-api/folder-operations.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAO,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAKxD,OAAO,KAAK,EAEV,cAAc,EACd,iBAAiB,EAEjB,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAGpB;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAA;CAAE,CAAC,EACzD,OAAO,GAAE;IACP,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,WAAW,CAAC;CACjB,GACL,OAAO,CAAC,kBAAkB,CAAC,CAgC7B;AAiBD;;;;;;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 +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,SAAS;;;;;;;;EAUrB,CAAC;AAEF,eAAO,MAAM,wBAAwB,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/folder-api/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-handle.d.ts","sourceRoot":"","sources":["../../../../src/runtime/wasi-adapter/file-handle.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,sBAAsB,EACtB,UAAU,EACV,UAAU,EACV,UAAU,EACX,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"file-handle.d.ts","sourceRoot":"","sources":["../../../../src/runtime/wasi-adapter/file-handle.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,sBAAsB,EACtB,UAAU,EACV,UAAU,EACV,UAAU,EACX,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AA2ChE,qBAAa,cAAe,YAAW,UAAU;IAC/C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAa;IAClC,OAAO,CAAC,QAAQ,CAA2B;IAC3C,OAAO,CAAC,OAAO,CAAwC;IACvD,OAAO,CAAC,SAAS,CAAS;gBAEd,UAAU,EAAE,UAAU;IAIlC,OAAO,CAAC,iBAAiB;IAQzB,cAAc,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO;IAW3C,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAOpC,OAAO,IAAI,OAAO;IAKlB,IAAI,IAAI,OAAO;IAcf,MAAM,IAAI,UAAU;IASpB,OAAO,CAAC,gBAAgB;IAsCxB,kBAAkB,IAAI,sBAAsB,GAAG,IAAI;IAqBnD,SAAS,IAAI,MAAM;IAyDnB,OAAO,CAAC,cAAc;IAiBtB,SAAS,IAAI,UAAU;IAKvB,aAAa,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;IAuBzC,aAAa,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,IAAI;IAgBpD,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;IAOhC,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAc7C,KAAK,IAAI,OAAO;IAYhB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;IAK/B,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAK5C,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAShC,WAAW,IAAI,UAAU,EAAE;IAK3B,WAAW,CAAC,QAAQ,EAAE,UAAU,EAAE,GAAG,IAAI;IAKzC,UAAU,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI;IAOrC,cAAc,IAAI,IAAI;IAKtB,UAAU,IAAI;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE;IAOlE,UAAU,CACR,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,GAC9D,IAAI;IAaP,OAAO,IAAI,IAAI;CAKhB"}
|
|
@@ -11,10 +11,14 @@ const AUDIO_KEYS = /* @__PURE__ */ new Set([
|
|
|
11
11
|
"channels",
|
|
12
12
|
"codec",
|
|
13
13
|
"containerFormat",
|
|
14
|
+
"formatVersion",
|
|
15
|
+
"isEncrypted",
|
|
14
16
|
"isLossless",
|
|
15
17
|
"duration",
|
|
16
18
|
"length",
|
|
17
19
|
"lengthMs",
|
|
20
|
+
"mpegLayer",
|
|
21
|
+
"mpegVersion",
|
|
18
22
|
"sampleRate"
|
|
19
23
|
]);
|
|
20
24
|
const INTERNAL_KEYS = /* @__PURE__ */ new Set(["pictures", "ratings"]);
|
|
@@ -27,7 +31,8 @@ const CONTAINER_TO_FORMAT = {
|
|
|
27
31
|
AIFF: "AIFF",
|
|
28
32
|
WavPack: "WV",
|
|
29
33
|
TTA: "TTA",
|
|
30
|
-
ASF: "ASF"
|
|
34
|
+
ASF: "ASF",
|
|
35
|
+
Matroska: "MATROSKA"
|
|
31
36
|
};
|
|
32
37
|
const NUMERIC_FIELD_ALIASES = {
|
|
33
38
|
date: "year",
|
|
@@ -133,7 +138,11 @@ class WasiFileHandle {
|
|
|
133
138
|
bitsPerSample: () => data.bitsPerSample ?? 0,
|
|
134
139
|
codec: () => data.codec ?? "",
|
|
135
140
|
containerFormat: () => data.containerFormat ?? "",
|
|
136
|
-
isLossless: () => data.isLossless ?? false
|
|
141
|
+
isLossless: () => data.isLossless ?? false,
|
|
142
|
+
mpegVersion: () => data.mpegVersion ?? 0,
|
|
143
|
+
mpegLayer: () => data.mpegLayer ?? 0,
|
|
144
|
+
isEncrypted: () => data.isEncrypted ?? false,
|
|
145
|
+
formatVersion: () => data.formatVersion ?? 0
|
|
137
146
|
};
|
|
138
147
|
}
|
|
139
148
|
getFormat() {
|
|
@@ -156,6 +165,7 @@ class WasiFileHandle {
|
|
|
156
165
|
if (magic[0] === 119 && magic[1] === 118 && magic[2] === 112 && magic[3] === 107) return "WV";
|
|
157
166
|
if (magic[0] === 84 && magic[1] === 84 && magic[2] === 65 && magic[3] === 49) return "TTA";
|
|
158
167
|
if (this.fileData.length >= 16 && magic[0] === 48 && magic[1] === 38 && magic[2] === 178 && magic[3] === 117) return "ASF";
|
|
168
|
+
if (magic[0] === 26 && magic[1] === 69 && magic[2] === 223 && magic[3] === 163) return "MATROSKA";
|
|
159
169
|
const ftyp = this.fileData.slice(4, 8);
|
|
160
170
|
if (ftyp[0] === 102 && ftyp[1] === 116 && ftyp[2] === 121 && ftyp[3] === 112) return "MP4";
|
|
161
171
|
return "unknown";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wasm-io.d.ts","sourceRoot":"","sources":["../../../../src/runtime/wasi-adapter/wasm-io.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"wasm-io.d.ts","sourceRoot":"","sources":["../../../../src/runtime/wasi-adapter/wasm-io.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAQhE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAKlD,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,UAAU,GACjB,UAAU,CAoCZ;AAED,wBAAgB,eAAe,CAC7B,IAAI,EAAE,UAAU,EAChB,QAAQ,EAAE,UAAU,EACpB,OAAO,EAAE,WAAW,GACnB,UAAU,GAAG,IAAI,CA8BnB"}
|
|
@@ -47,7 +47,10 @@ import {
|
|
|
47
47
|
WasmArena,
|
|
48
48
|
WasmMemoryError
|
|
49
49
|
} from "../wasi-memory.js";
|
|
50
|
+
import { InvalidFormatError } from "../../errors/classes.js";
|
|
50
51
|
import { encodeTagData } from "../../msgpack/encoder.js";
|
|
52
|
+
const TL_ERROR_UNSUPPORTED_FORMAT = -2;
|
|
53
|
+
const TL_ERROR_PARSE_FAILED = -6;
|
|
51
54
|
function readTagsFromWasm(wasi, buffer) {
|
|
52
55
|
var _stack = [];
|
|
53
56
|
try {
|
|
@@ -62,6 +65,12 @@ function readTagsFromWasm(wasi, buffer) {
|
|
|
62
65
|
);
|
|
63
66
|
if (resultPtr === 0) {
|
|
64
67
|
const errorCode = wasi.tl_get_last_error_code();
|
|
68
|
+
if (errorCode === TL_ERROR_UNSUPPORTED_FORMAT || errorCode === TL_ERROR_PARSE_FAILED) {
|
|
69
|
+
throw new InvalidFormatError(
|
|
70
|
+
"File may be corrupted or in an unsupported format",
|
|
71
|
+
buffer.length
|
|
72
|
+
);
|
|
73
|
+
}
|
|
65
74
|
throw new WasmMemoryError(
|
|
66
75
|
`error code ${errorCode}. Buffer size: ${buffer.length} bytes`,
|
|
67
76
|
"read tags",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wasi-host.d.ts","sourceRoot":"","sources":["../../../src/runtime/wasi-host.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAkB,MAAM,uBAAuB,CAAC;AAGhF,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,EAAE,EAAE,kBAAkB,CAAC;IACvB,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAC;IACpC,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAC;CACrC;AAgBD,KAAK,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,MAAM,GAAG,IAAI,CAAC,CAAC;AAErE,MAAM,MAAM,oBAAoB,GAAG,WAAW,GAAG;IAAE,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI,CAAA;CAAE,CAAC;AAE9E,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE;IAAE,MAAM,EAAE,WAAW,CAAA;CAAE,EAC/B,MAAM,EAAE,cAAc,GACrB,oBAAoB,
|
|
1
|
+
{"version":3,"file":"wasi-host.d.ts","sourceRoot":"","sources":["../../../src/runtime/wasi-host.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAkB,MAAM,uBAAuB,CAAC;AAGhF,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,EAAE,EAAE,kBAAkB,CAAC;IACvB,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAC;IACpC,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAC;CACrC;AAgBD,KAAK,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,MAAM,GAAG,IAAI,CAAC,CAAC;AAErE,MAAM,MAAM,oBAAoB,GAAG,WAAW,GAAG;IAAE,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI,CAAA;CAAE,CAAC;AAE9E,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE;IAAE,MAAM,EAAE,WAAW,CAAA;CAAE,EAC/B,MAAM,EAAE,cAAc,GACrB,oBAAoB,CA+NtB"}
|
|
@@ -176,6 +176,11 @@ function createWasiImports(memory, config) {
|
|
|
176
176
|
dv.setBigUint64(timePtr, BigInt(Date.now()) * 1000000n, true);
|
|
177
177
|
return WASI_ESUCCESS;
|
|
178
178
|
},
|
|
179
|
+
random_get: (bufPtr, bufLen) => {
|
|
180
|
+
const buf = new Uint8Array(memory.buffer, bufPtr, bufLen);
|
|
181
|
+
crypto.getRandomValues(buf);
|
|
182
|
+
return WASI_ESUCCESS;
|
|
183
|
+
},
|
|
179
184
|
proc_exit: (code) => {
|
|
180
185
|
throw new Error(`WASI proc_exit called: code ${code}`);
|
|
181
186
|
},
|
|
@@ -26,7 +26,7 @@ export interface BatchResult<T> {
|
|
|
26
26
|
/**
|
|
27
27
|
* Read tags from multiple files with configurable concurrency.
|
|
28
28
|
*
|
|
29
|
-
* @param files - Array of file paths, Uint8Arrays, ArrayBuffers,
|
|
29
|
+
* @param files - Array of file paths, Uint8Arrays, ArrayBuffers, File objects, or NamedAudioInputs.
|
|
30
30
|
* @param options - Batch processing options (concurrency, error handling, progress).
|
|
31
31
|
* @returns Batch result containing a `BatchItem` per file and total duration in ms.
|
|
32
32
|
* @throws If `continueOnError` is `false` and any file fails to process.
|
|
@@ -35,7 +35,7 @@ export declare function readTagsBatch(files: AudioFileInput[], options?: BatchOp
|
|
|
35
35
|
/**
|
|
36
36
|
* Read audio properties from multiple files with configurable concurrency.
|
|
37
37
|
*
|
|
38
|
-
* @param files - Array of file paths, Uint8Arrays, ArrayBuffers,
|
|
38
|
+
* @param files - Array of file paths, Uint8Arrays, ArrayBuffers, File objects, or NamedAudioInputs.
|
|
39
39
|
* @param options - Batch processing options (concurrency, error handling, progress).
|
|
40
40
|
* @returns Batch result containing a `BatchItem` per file and total duration in ms.
|
|
41
41
|
* @throws If `continueOnError` is `false` and any file fails to process.
|
|
@@ -51,7 +51,7 @@ export interface FileMetadata {
|
|
|
51
51
|
/**
|
|
52
52
|
* Read complete metadata (tags, properties, cover art, dynamics) from a single file.
|
|
53
53
|
*
|
|
54
|
-
* @param file - A file path, Uint8Array, ArrayBuffer,
|
|
54
|
+
* @param file - A file path, Uint8Array, ArrayBuffer, File object, or NamedAudioInput.
|
|
55
55
|
* @returns The file's complete metadata.
|
|
56
56
|
* @throws `InvalidFormatError` if the file is corrupted or in an unsupported format.
|
|
57
57
|
*/
|
|
@@ -59,7 +59,7 @@ export declare function readMetadata(file: AudioFileInput): Promise<FileMetadata
|
|
|
59
59
|
/**
|
|
60
60
|
* Read complete metadata from multiple files with configurable concurrency.
|
|
61
61
|
*
|
|
62
|
-
* @param files - Array of file paths, Uint8Arrays, ArrayBuffers,
|
|
62
|
+
* @param files - Array of file paths, Uint8Arrays, ArrayBuffers, File objects, or NamedAudioInputs.
|
|
63
63
|
* @param options - Batch processing options (concurrency, error handling, progress).
|
|
64
64
|
* @returns Batch result containing a `BatchItem` per file and total duration in ms.
|
|
65
65
|
* @throws If `continueOnError` is `false` and any file fails to process.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"batch-operations.d.ts","sourceRoot":"","sources":["../../../src/simple/batch-operations.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"batch-operations.d.ts","sourceRoot":"","sources":["../../../src/simple/batch-operations.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAMhF,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;CACtB;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;AAwBD;;;;;;GAMG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,YAAY,CAAC,CA4BvB;AAED;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,cAAc,EAAE,EACvB,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC,CAOpC"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isNamedAudioInput } from "../types/audio-formats.js";
|
|
1
2
|
import { InvalidFormatError } from "../errors.js";
|
|
2
3
|
import { mapPropertiesToExtendedTag } from "../utils/tag-mapping.js";
|
|
3
4
|
import { getTagLib } from "./config.js";
|
|
@@ -14,7 +15,7 @@ async function executeBatch(files, options, processor) {
|
|
|
14
15
|
const chunk = files.slice(i, i + concurrency);
|
|
15
16
|
const chunkPromises = chunk.map(async (file, idx) => {
|
|
16
17
|
const index = i + idx;
|
|
17
|
-
const fileName = typeof file === "string" ? file : `
|
|
18
|
+
const fileName = typeof file === "string" ? file : file instanceof File ? file.name : isNamedAudioInput(file) ? file.name : `buffer-${index}`;
|
|
18
19
|
try {
|
|
19
20
|
const audioFile = await taglib.open(file);
|
|
20
21
|
try {
|
|
@@ -86,6 +87,8 @@ async function readMetadata(file) {
|
|
|
86
87
|
name = file;
|
|
87
88
|
} else if (file instanceof File) {
|
|
88
89
|
name = file.name;
|
|
90
|
+
} else if (isNamedAudioInput(file)) {
|
|
91
|
+
name = file.name;
|
|
89
92
|
} else {
|
|
90
93
|
name = `buffer (${file.byteLength} bytes)`;
|
|
91
94
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"picture-operations.d.ts","sourceRoot":"","sources":["../../../src/simple/picture-operations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"picture-operations.d.ts","sourceRoot":"","sources":["../../../src/simple/picture-operations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAGxE;;;;;;;GAOG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,OAAO,EAAE,CAAC,CAEpB;AAED;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,cAAc,EACpB,QAAQ,EAAE,OAAO,EAAE,GAClB,OAAO,CAAC,UAAU,CAAC,CAIrB;AAED;;;;;;;;;GASG;AACH,wBAAsB,UAAU,CAC9B,IAAI,EAAE,cAAc,EACpB,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,UAAU,CAAC,CAIrB;AAED;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,UAAU,CAAC,CAErB;AAED;;;;;;;GAOG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAYjC;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,cAAc,EACpB,SAAS,EAAE,UAAU,EACrB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,UAAU,CAAC,CAQrB;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,OAAO,EAAE,EACnB,IAAI,EAAE,WAAW,GAChB,OAAO,GAAG,SAAS,CAErB;AAED;;;;;;;;;GASG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,cAAc,EACpB,UAAU,EAAE,OAAO,GAClB,OAAO,CAAC,UAAU,CAAC,CAUrB;AAED;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,cAAc,GACnB,OAAO,CACR,KAAK,CAAC;IACJ,IAAI,EAAE,WAAW,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC,CACH,CAQA"}
|
|
@@ -1,60 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { getTagLib } from "./config.js";
|
|
1
|
+
import { withAudioFile, withAudioFileSave } from "./with-audio-file.js";
|
|
3
2
|
async function readPictures(file) {
|
|
4
|
-
|
|
5
|
-
const audioFile = await taglib.open(file);
|
|
6
|
-
try {
|
|
7
|
-
if (!audioFile.isValid()) {
|
|
8
|
-
throw new InvalidFormatError(
|
|
9
|
-
"File may be corrupted or in an unsupported format"
|
|
10
|
-
);
|
|
11
|
-
}
|
|
12
|
-
return audioFile.getPictures();
|
|
13
|
-
} finally {
|
|
14
|
-
audioFile.dispose();
|
|
15
|
-
}
|
|
3
|
+
return withAudioFile(file, (audioFile) => audioFile.getPictures());
|
|
16
4
|
}
|
|
17
5
|
async function applyPictures(file, pictures) {
|
|
18
|
-
|
|
19
|
-
const audioFile = await taglib.open(file);
|
|
20
|
-
try {
|
|
21
|
-
if (!audioFile.isValid()) {
|
|
22
|
-
throw new InvalidFormatError(
|
|
23
|
-
"File may be corrupted or in an unsupported format"
|
|
24
|
-
);
|
|
25
|
-
}
|
|
6
|
+
return withAudioFileSave(file, (audioFile) => {
|
|
26
7
|
audioFile.setPictures(pictures);
|
|
27
|
-
|
|
28
|
-
throw new FileOperationError(
|
|
29
|
-
"save",
|
|
30
|
-
"Failed to save picture changes. The file may be read-only or corrupted."
|
|
31
|
-
);
|
|
32
|
-
}
|
|
33
|
-
return audioFile.getFileBuffer();
|
|
34
|
-
} finally {
|
|
35
|
-
audioFile.dispose();
|
|
36
|
-
}
|
|
8
|
+
});
|
|
37
9
|
}
|
|
38
10
|
async function addPicture(file, picture) {
|
|
39
|
-
|
|
40
|
-
const audioFile = await taglib.open(file);
|
|
41
|
-
try {
|
|
42
|
-
if (!audioFile.isValid()) {
|
|
43
|
-
throw new InvalidFormatError(
|
|
44
|
-
"File may be corrupted or in an unsupported format"
|
|
45
|
-
);
|
|
46
|
-
}
|
|
11
|
+
return withAudioFileSave(file, (audioFile) => {
|
|
47
12
|
audioFile.addPicture(picture);
|
|
48
|
-
|
|
49
|
-
throw new FileOperationError(
|
|
50
|
-
"save",
|
|
51
|
-
"Failed to save picture changes. The file may be read-only or corrupted."
|
|
52
|
-
);
|
|
53
|
-
}
|
|
54
|
-
return audioFile.getFileBuffer();
|
|
55
|
-
} finally {
|
|
56
|
-
audioFile.dispose();
|
|
57
|
-
}
|
|
13
|
+
});
|
|
58
14
|
}
|
|
59
15
|
async function clearPictures(file) {
|
|
60
16
|
return applyPictures(file, []);
|