taglib-wasm 1.2.1 → 1.3.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 +232 -102
- package/dist/simple.browser.js +232 -102
- package/dist/src/constants/complex-properties.d.ts +0 -14
- package/dist/src/constants/complex-properties.d.ts.map +1 -1
- package/dist/src/errors/base.js +5 -2
- package/dist/src/errors/classes.js +13 -10
- package/dist/src/msgpack/encoder.d.ts +6 -0
- package/dist/src/msgpack/encoder.d.ts.map +1 -1
- package/dist/src/msgpack/encoder.js +15 -0
- package/dist/src/runtime/unified-loader/types.js +4 -1
- package/dist/src/runtime/wasi-adapter/file-handle.d.ts +3 -1
- package/dist/src/runtime/wasi-adapter/file-handle.d.ts.map +1 -1
- package/dist/src/runtime/wasi-adapter/file-handle.js +41 -4
- package/dist/src/runtime/wasi-memory.d.ts +0 -5
- package/dist/src/runtime/wasi-memory.d.ts.map +1 -1
- package/dist/src/runtime/wasi-memory.js +6 -10
- package/dist/src/taglib/audio-file-base.d.ts.map +1 -1
- package/dist/src/taglib/audio-file-base.js +13 -1
- package/dist/src/taglib/audio-file-impl.d.ts.map +1 -1
- package/dist/src/taglib/audio-file-impl.js +22 -39
- package/dist/src/taglib/embind-adapter.d.ts.map +1 -1
- package/dist/src/taglib/embind-adapter.js +18 -0
- package/dist/src/taglib/extra-state-registry.d.ts +26 -0
- package/dist/src/taglib/extra-state-registry.d.ts.map +1 -0
- package/dist/src/taglib/extra-state-registry.js +59 -0
- package/dist/src/taglib/mutable-tag.d.ts +7 -0
- package/dist/src/taglib/mutable-tag.d.ts.map +1 -1
- package/dist/src/taglib/save-reconstruct.d.ts +13 -0
- package/dist/src/taglib/save-reconstruct.d.ts.map +1 -0
- package/dist/src/taglib/save-reconstruct.js +39 -0
- package/dist/src/types/metadata-mappings.d.ts.map +1 -1
- package/dist/src/types/metadata-mappings.js +8 -0
- package/dist/src/types/tags.d.ts +10 -0
- package/dist/src/types/tags.d.ts.map +1 -1
- package/dist/src/utils/tag-mapping.d.ts.map +1 -1
- package/dist/src/utils/tag-mapping.js +7 -0
- package/dist/src/version.d.ts +1 -1
- package/dist/src/version.js +1 -1
- package/dist/src/wasm.d.ts +14 -0
- package/dist/src/wasm.d.ts.map +1 -1
- package/dist/taglib-wasi.wasm +0 -0
- package/package.json +7 -8
package/dist/index.browser.js
CHANGED
|
@@ -304,8 +304,8 @@ var init_base = __esm({
|
|
|
304
304
|
*/
|
|
305
305
|
constructor(code, message, details) {
|
|
306
306
|
super(message);
|
|
307
|
-
this
|
|
308
|
-
this
|
|
307
|
+
__publicField(this, "code", code);
|
|
308
|
+
__publicField(this, "details", details);
|
|
309
309
|
this.name = "TagLibError";
|
|
310
310
|
Object.setPrototypeOf(this, _TagLibError.prototype);
|
|
311
311
|
}
|
|
@@ -365,7 +365,7 @@ var init_classes = __esm({
|
|
|
365
365
|
errorDetails.join(". "),
|
|
366
366
|
{ ...details, bufferSize }
|
|
367
367
|
);
|
|
368
|
-
this
|
|
368
|
+
__publicField(this, "bufferSize", bufferSize);
|
|
369
369
|
this.name = "InvalidFormatError";
|
|
370
370
|
Object.setPrototypeOf(this, _InvalidFormatError.prototype);
|
|
371
371
|
}
|
|
@@ -383,8 +383,8 @@ var init_classes = __esm({
|
|
|
383
383
|
`Unsupported audio format: ${format}. Supported formats: ${supportedFormats.join(", ")}`,
|
|
384
384
|
{ ...details, format, supportedFormats }
|
|
385
385
|
);
|
|
386
|
-
this
|
|
387
|
-
this
|
|
386
|
+
__publicField(this, "format", format);
|
|
387
|
+
__publicField(this, "supportedFormats", supportedFormats);
|
|
388
388
|
this.name = "UnsupportedFormatError";
|
|
389
389
|
Object.setPrototypeOf(this, _UnsupportedFormatError.prototype);
|
|
390
390
|
}
|
|
@@ -408,8 +408,8 @@ var init_classes = __esm({
|
|
|
408
408
|
errorDetails.join(". "),
|
|
409
409
|
{ ...details, operation, path }
|
|
410
410
|
);
|
|
411
|
-
this
|
|
412
|
-
this
|
|
411
|
+
__publicField(this, "operation", operation);
|
|
412
|
+
__publicField(this, "path", path);
|
|
413
413
|
this.name = "FileOperationError";
|
|
414
414
|
Object.setPrototypeOf(this, _FileOperationError.prototype);
|
|
415
415
|
}
|
|
@@ -433,8 +433,8 @@ var init_classes = __esm({
|
|
|
433
433
|
errorDetails.join(". "),
|
|
434
434
|
{ ...details, operation, field }
|
|
435
435
|
);
|
|
436
|
-
this
|
|
437
|
-
this
|
|
436
|
+
__publicField(this, "operation", operation);
|
|
437
|
+
__publicField(this, "field", field);
|
|
438
438
|
this.name = "MetadataError";
|
|
439
439
|
Object.setPrototypeOf(this, _MetadataError.prototype);
|
|
440
440
|
}
|
|
@@ -465,9 +465,9 @@ var init_classes = __esm({
|
|
|
465
465
|
constructor(environment, reason, requiredFeature) {
|
|
466
466
|
const message = requiredFeature ? `Environment '${environment}' ${reason}. Required feature: ${requiredFeature}.` : `Environment '${environment}' ${reason}.`;
|
|
467
467
|
super("ENVIRONMENT", message);
|
|
468
|
-
this
|
|
469
|
-
this
|
|
470
|
-
this
|
|
468
|
+
__publicField(this, "environment", environment);
|
|
469
|
+
__publicField(this, "reason", reason);
|
|
470
|
+
__publicField(this, "requiredFeature", requiredFeature);
|
|
471
471
|
this.name = "EnvironmentError";
|
|
472
472
|
Object.setPrototypeOf(this, _EnvironmentError.prototype);
|
|
473
473
|
}
|
|
@@ -573,60 +573,6 @@ var init_platform_io_browser_stub = __esm({
|
|
|
573
573
|
}
|
|
574
574
|
});
|
|
575
575
|
|
|
576
|
-
// src/utils/file.ts
|
|
577
|
-
async function readFileData(file) {
|
|
578
|
-
if (file instanceof Uint8Array) return file;
|
|
579
|
-
if (file instanceof ArrayBuffer) return new Uint8Array(file);
|
|
580
|
-
if (typeof File !== "undefined" && file instanceof File) {
|
|
581
|
-
return new Uint8Array(await file.arrayBuffer());
|
|
582
|
-
}
|
|
583
|
-
if (typeof file === "string") {
|
|
584
|
-
try {
|
|
585
|
-
return await getPlatformIO().readFile(file);
|
|
586
|
-
} catch (error) {
|
|
587
|
-
if (error instanceof EnvironmentError) throw error;
|
|
588
|
-
throw new FileOperationError("read", error.message, file);
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
const inputType = Object.prototype.toString.call(file);
|
|
592
|
-
throw new FileOperationError(
|
|
593
|
-
"read",
|
|
594
|
-
`Invalid file input type: ${inputType}. Expected string path, Uint8Array, ArrayBuffer, or File object.`
|
|
595
|
-
);
|
|
596
|
-
}
|
|
597
|
-
async function getFileSize(path) {
|
|
598
|
-
try {
|
|
599
|
-
const s = await getPlatformIO().stat(path);
|
|
600
|
-
return s.size;
|
|
601
|
-
} catch (error) {
|
|
602
|
-
if (error instanceof EnvironmentError) throw error;
|
|
603
|
-
throw new FileOperationError("stat", error.message, path);
|
|
604
|
-
}
|
|
605
|
-
}
|
|
606
|
-
async function readPartialFileData(path, headerSize, footerSize) {
|
|
607
|
-
const io = getPlatformIO();
|
|
608
|
-
if (!io.readPartial) {
|
|
609
|
-
throw new EnvironmentError(
|
|
610
|
-
"current runtime",
|
|
611
|
-
"does not support partial file reading",
|
|
612
|
-
"filesystem access with seek support"
|
|
613
|
-
);
|
|
614
|
-
}
|
|
615
|
-
try {
|
|
616
|
-
return await io.readPartial(path, headerSize, footerSize);
|
|
617
|
-
} catch (error) {
|
|
618
|
-
if (error instanceof EnvironmentError) throw error;
|
|
619
|
-
throw new FileOperationError("read", error.message, path);
|
|
620
|
-
}
|
|
621
|
-
}
|
|
622
|
-
var init_file = __esm({
|
|
623
|
-
"src/utils/file.ts"() {
|
|
624
|
-
"use strict";
|
|
625
|
-
init_errors2();
|
|
626
|
-
init_platform_io_browser_stub();
|
|
627
|
-
}
|
|
628
|
-
});
|
|
629
|
-
|
|
630
576
|
// src/utils/write.ts
|
|
631
577
|
async function writeFileData(path, data) {
|
|
632
578
|
try {
|
|
@@ -1395,7 +1341,7 @@ var init_audio_file_base = __esm({
|
|
|
1395
1341
|
init_errors2();
|
|
1396
1342
|
BaseAudioFileImpl = class {
|
|
1397
1343
|
constructor(module, fileHandle, sourcePath, originalSource, isPartiallyLoaded = false, partialLoadOptions) {
|
|
1398
|
-
this
|
|
1344
|
+
__publicField(this, "module", module);
|
|
1399
1345
|
__publicField(this, "fileHandle");
|
|
1400
1346
|
__publicField(this, "cachedAudioProperties", null);
|
|
1401
1347
|
__publicField(this, "sourcePath");
|
|
@@ -1445,6 +1391,9 @@ var init_audio_file_base = __esm({
|
|
|
1445
1391
|
get track() {
|
|
1446
1392
|
return data.track;
|
|
1447
1393
|
},
|
|
1394
|
+
get date() {
|
|
1395
|
+
return handle.getProperty("DATE") || void 0;
|
|
1396
|
+
},
|
|
1448
1397
|
setTitle: (value) => {
|
|
1449
1398
|
handle.setTagData({ title: value });
|
|
1450
1399
|
data = handle.getTagData();
|
|
@@ -1479,6 +1428,15 @@ var init_audio_file_base = __esm({
|
|
|
1479
1428
|
handle.setTagData({ track: value });
|
|
1480
1429
|
data = handle.getTagData();
|
|
1481
1430
|
return tag;
|
|
1431
|
+
},
|
|
1432
|
+
setDate: (value) => {
|
|
1433
|
+
if (value === "") {
|
|
1434
|
+
handle.setTagData({ year: 0 });
|
|
1435
|
+
} else {
|
|
1436
|
+
handle.setProperty("DATE", value);
|
|
1437
|
+
}
|
|
1438
|
+
data = handle.getTagData();
|
|
1439
|
+
return tag;
|
|
1482
1440
|
}
|
|
1483
1441
|
};
|
|
1484
1442
|
return tag;
|
|
@@ -1545,6 +1503,60 @@ var init_audio_file_base = __esm({
|
|
|
1545
1503
|
}
|
|
1546
1504
|
});
|
|
1547
1505
|
|
|
1506
|
+
// src/utils/file.ts
|
|
1507
|
+
async function readFileData(file) {
|
|
1508
|
+
if (file instanceof Uint8Array) return file;
|
|
1509
|
+
if (file instanceof ArrayBuffer) return new Uint8Array(file);
|
|
1510
|
+
if (typeof File !== "undefined" && file instanceof File) {
|
|
1511
|
+
return new Uint8Array(await file.arrayBuffer());
|
|
1512
|
+
}
|
|
1513
|
+
if (typeof file === "string") {
|
|
1514
|
+
try {
|
|
1515
|
+
return await getPlatformIO().readFile(file);
|
|
1516
|
+
} catch (error) {
|
|
1517
|
+
if (error instanceof EnvironmentError) throw error;
|
|
1518
|
+
throw new FileOperationError("read", error.message, file);
|
|
1519
|
+
}
|
|
1520
|
+
}
|
|
1521
|
+
const inputType = Object.prototype.toString.call(file);
|
|
1522
|
+
throw new FileOperationError(
|
|
1523
|
+
"read",
|
|
1524
|
+
`Invalid file input type: ${inputType}. Expected string path, Uint8Array, ArrayBuffer, or File object.`
|
|
1525
|
+
);
|
|
1526
|
+
}
|
|
1527
|
+
async function getFileSize(path) {
|
|
1528
|
+
try {
|
|
1529
|
+
const s = await getPlatformIO().stat(path);
|
|
1530
|
+
return s.size;
|
|
1531
|
+
} catch (error) {
|
|
1532
|
+
if (error instanceof EnvironmentError) throw error;
|
|
1533
|
+
throw new FileOperationError("stat", error.message, path);
|
|
1534
|
+
}
|
|
1535
|
+
}
|
|
1536
|
+
async function readPartialFileData(path, headerSize, footerSize) {
|
|
1537
|
+
const io = getPlatformIO();
|
|
1538
|
+
if (!io.readPartial) {
|
|
1539
|
+
throw new EnvironmentError(
|
|
1540
|
+
"current runtime",
|
|
1541
|
+
"does not support partial file reading",
|
|
1542
|
+
"filesystem access with seek support"
|
|
1543
|
+
);
|
|
1544
|
+
}
|
|
1545
|
+
try {
|
|
1546
|
+
return await io.readPartial(path, headerSize, footerSize);
|
|
1547
|
+
} catch (error) {
|
|
1548
|
+
if (error instanceof EnvironmentError) throw error;
|
|
1549
|
+
throw new FileOperationError("read", error.message, path);
|
|
1550
|
+
}
|
|
1551
|
+
}
|
|
1552
|
+
var init_file = __esm({
|
|
1553
|
+
"src/utils/file.ts"() {
|
|
1554
|
+
"use strict";
|
|
1555
|
+
init_errors2();
|
|
1556
|
+
init_platform_io_browser_stub();
|
|
1557
|
+
}
|
|
1558
|
+
});
|
|
1559
|
+
|
|
1548
1560
|
// src/taglib/embind-adapter.ts
|
|
1549
1561
|
function isValidBitrateMode(value) {
|
|
1550
1562
|
return value === "CBR" || value === "VBR" || value === "ABR";
|
|
@@ -1591,6 +1603,24 @@ function wrapEmbindHandle(raw) {
|
|
|
1591
1603
|
data ?? null
|
|
1592
1604
|
);
|
|
1593
1605
|
},
|
|
1606
|
+
// Emscripten exposes USLT only through the PropertyMap "LYRICS" key (no
|
|
1607
|
+
// dedicated Embind binding), so bridge get/setLyrics to get/setProperties.
|
|
1608
|
+
// Text only — language/description are not surfaced by the PropertyMap.
|
|
1609
|
+
getLyrics() {
|
|
1610
|
+
const props = raw.getProperties();
|
|
1611
|
+
return (props["LYRICS"] ?? []).map((text) => ({
|
|
1612
|
+
text,
|
|
1613
|
+
description: "",
|
|
1614
|
+
language: ""
|
|
1615
|
+
}));
|
|
1616
|
+
},
|
|
1617
|
+
setLyrics(lyrics) {
|
|
1618
|
+
const handle = raw;
|
|
1619
|
+
const props = handle.getProperties();
|
|
1620
|
+
if (lyrics.length > 0) props["LYRICS"] = lyrics.map((l) => l.text);
|
|
1621
|
+
else delete props["LYRICS"];
|
|
1622
|
+
handle.setProperties(props);
|
|
1623
|
+
},
|
|
1594
1624
|
hasId3Tags() {
|
|
1595
1625
|
const v = raw.hasId3Tags();
|
|
1596
1626
|
if (!v || typeof v !== "object") return { v1: false, v2: false };
|
|
@@ -1640,6 +1670,112 @@ var init_embind_adapter = __esm({
|
|
|
1640
1670
|
}
|
|
1641
1671
|
});
|
|
1642
1672
|
|
|
1673
|
+
// src/taglib/extra-state-registry.ts
|
|
1674
|
+
function chapterStyle(chapters) {
|
|
1675
|
+
const s = chapters[0]?.source;
|
|
1676
|
+
return s === "nero" || s === "both" ? s : "quicktime";
|
|
1677
|
+
}
|
|
1678
|
+
function copyExtraState(target, source, sourceComplete) {
|
|
1679
|
+
for (const field of EXTRA_FIELDS) {
|
|
1680
|
+
field.copy(target, source, sourceComplete);
|
|
1681
|
+
}
|
|
1682
|
+
}
|
|
1683
|
+
var EXTRA_FIELDS;
|
|
1684
|
+
var init_extra_state_registry = __esm({
|
|
1685
|
+
"src/taglib/extra-state-registry.ts"() {
|
|
1686
|
+
"use strict";
|
|
1687
|
+
EXTRA_FIELDS = [
|
|
1688
|
+
{
|
|
1689
|
+
name: "pictures",
|
|
1690
|
+
copy(target, source, complete) {
|
|
1691
|
+
const v = source.getPictures();
|
|
1692
|
+
if (complete || v.length > 0) target.setPictures(v);
|
|
1693
|
+
}
|
|
1694
|
+
},
|
|
1695
|
+
{
|
|
1696
|
+
name: "ratings",
|
|
1697
|
+
copy(target, source, complete) {
|
|
1698
|
+
const v = source.getRatings();
|
|
1699
|
+
if (complete || v.length > 0) target.setRatings(v);
|
|
1700
|
+
}
|
|
1701
|
+
},
|
|
1702
|
+
{
|
|
1703
|
+
name: "lyrics",
|
|
1704
|
+
copy(target, source, complete) {
|
|
1705
|
+
const v = source.getLyrics();
|
|
1706
|
+
if (complete || v.length > 0) target.setLyrics(v);
|
|
1707
|
+
}
|
|
1708
|
+
},
|
|
1709
|
+
{
|
|
1710
|
+
name: "chapters",
|
|
1711
|
+
copy(target, source, complete) {
|
|
1712
|
+
const v = source.getChapters();
|
|
1713
|
+
if (complete || v.length > 0) target.setChapters(v, chapterStyle(v));
|
|
1714
|
+
}
|
|
1715
|
+
},
|
|
1716
|
+
{
|
|
1717
|
+
name: "bextData",
|
|
1718
|
+
copy(target, source, complete) {
|
|
1719
|
+
const v = source.getBextData();
|
|
1720
|
+
if (v !== void 0) target.setBextData(v);
|
|
1721
|
+
else if (complete) target.setBextData(null);
|
|
1722
|
+
}
|
|
1723
|
+
},
|
|
1724
|
+
{
|
|
1725
|
+
name: "ixml",
|
|
1726
|
+
copy(target, source, complete) {
|
|
1727
|
+
const v = source.getIxml();
|
|
1728
|
+
if (v !== void 0) target.setIxml(v);
|
|
1729
|
+
else if (complete) target.setIxml(null);
|
|
1730
|
+
}
|
|
1731
|
+
}
|
|
1732
|
+
];
|
|
1733
|
+
}
|
|
1734
|
+
});
|
|
1735
|
+
|
|
1736
|
+
// src/taglib/save-reconstruct.ts
|
|
1737
|
+
function copyEditedState(target, source, sourceComplete) {
|
|
1738
|
+
target.setTagData(source.getTagData());
|
|
1739
|
+
target.setProperties(
|
|
1740
|
+
sourceComplete ? source.getProperties() : { ...target.getProperties(), ...source.getProperties() }
|
|
1741
|
+
);
|
|
1742
|
+
copyExtraState(target, source, sourceComplete);
|
|
1743
|
+
}
|
|
1744
|
+
async function saveViaFreshHandle(module, editing, source, targetPath, sourceComplete) {
|
|
1745
|
+
const rawFullHandle = module.createFileHandle();
|
|
1746
|
+
const fullFileHandle = module.isWasi ? rawFullHandle : wrapEmbindHandle(rawFullHandle);
|
|
1747
|
+
try {
|
|
1748
|
+
{
|
|
1749
|
+
const data = await readFileData(source);
|
|
1750
|
+
if (!fullFileHandle.loadFromBuffer(data)) {
|
|
1751
|
+
throw new InvalidFormatError(
|
|
1752
|
+
"Failed to load full audio file for saving"
|
|
1753
|
+
);
|
|
1754
|
+
}
|
|
1755
|
+
}
|
|
1756
|
+
copyEditedState(fullFileHandle, editing, sourceComplete);
|
|
1757
|
+
if (!fullFileHandle.save()) {
|
|
1758
|
+
throw new FileOperationError(
|
|
1759
|
+
"save",
|
|
1760
|
+
"Failed to save changes to full file"
|
|
1761
|
+
);
|
|
1762
|
+
}
|
|
1763
|
+
await writeFileData(targetPath, fullFileHandle.getBuffer());
|
|
1764
|
+
} finally {
|
|
1765
|
+
fullFileHandle.destroy();
|
|
1766
|
+
}
|
|
1767
|
+
}
|
|
1768
|
+
var init_save_reconstruct = __esm({
|
|
1769
|
+
"src/taglib/save-reconstruct.ts"() {
|
|
1770
|
+
"use strict";
|
|
1771
|
+
init_errors2();
|
|
1772
|
+
init_file();
|
|
1773
|
+
init_write();
|
|
1774
|
+
init_embind_adapter();
|
|
1775
|
+
init_extra_state_registry();
|
|
1776
|
+
}
|
|
1777
|
+
});
|
|
1778
|
+
|
|
1643
1779
|
// src/taglib/audio-file-impl.ts
|
|
1644
1780
|
function sortChapters(list) {
|
|
1645
1781
|
return [...list].sort((a, b) => a.startTimeMs - b.startTimeMs);
|
|
@@ -1669,10 +1805,9 @@ var init_audio_file_impl = __esm({
|
|
|
1669
1805
|
init_types2();
|
|
1670
1806
|
init_audio_file_bwf();
|
|
1671
1807
|
init_errors2();
|
|
1672
|
-
init_file();
|
|
1673
1808
|
init_write();
|
|
1674
1809
|
init_audio_file_base();
|
|
1675
|
-
|
|
1810
|
+
init_save_reconstruct();
|
|
1676
1811
|
AudioFileImpl = class extends BaseAudioFileImpl {
|
|
1677
1812
|
constructor(module, fileHandle, sourcePath, originalSource, isPartiallyLoaded = false, partialLoadOptions) {
|
|
1678
1813
|
super(
|
|
@@ -1718,38 +1853,23 @@ var init_audio_file_impl = __esm({
|
|
|
1718
1853
|
);
|
|
1719
1854
|
}
|
|
1720
1855
|
if (this.isPartiallyLoaded && this.originalSource) {
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
if (!success) {
|
|
1729
|
-
throw new InvalidFormatError(
|
|
1730
|
-
"Failed to load full audio file for saving"
|
|
1731
|
-
);
|
|
1732
|
-
}
|
|
1733
|
-
fullFileHandle.setTagData(this.handle.getTagData());
|
|
1734
|
-
fullFileHandle.setProperties(this.handle.getProperties());
|
|
1735
|
-
fullFileHandle.setPictures(this.handle.getPictures());
|
|
1736
|
-
const bextBytes = this.handle.getBextData();
|
|
1737
|
-
if (bextBytes !== void 0) fullFileHandle.setBextData(bextBytes);
|
|
1738
|
-
const ixmlStr = this.handle.getIxml();
|
|
1739
|
-
if (ixmlStr !== void 0) fullFileHandle.setIxml(ixmlStr);
|
|
1740
|
-
if (!fullFileHandle.save()) {
|
|
1741
|
-
throw new FileOperationError(
|
|
1742
|
-
"save",
|
|
1743
|
-
"Failed to save changes to full file"
|
|
1744
|
-
);
|
|
1745
|
-
}
|
|
1746
|
-
const buffer = fullFileHandle.getBuffer();
|
|
1747
|
-
await writeFileData(targetPath, buffer);
|
|
1748
|
-
} finally {
|
|
1749
|
-
fullFileHandle.destroy();
|
|
1750
|
-
}
|
|
1856
|
+
await saveViaFreshHandle(
|
|
1857
|
+
this.module,
|
|
1858
|
+
this.handle,
|
|
1859
|
+
this.originalSource,
|
|
1860
|
+
targetPath,
|
|
1861
|
+
false
|
|
1862
|
+
);
|
|
1751
1863
|
this.isPartiallyLoaded = false;
|
|
1752
1864
|
this.originalSource = void 0;
|
|
1865
|
+
} else if (this.module.isWasi && this.sourcePath && targetPath !== this.sourcePath) {
|
|
1866
|
+
await saveViaFreshHandle(
|
|
1867
|
+
this.module,
|
|
1868
|
+
this.handle,
|
|
1869
|
+
this.sourcePath,
|
|
1870
|
+
targetPath,
|
|
1871
|
+
true
|
|
1872
|
+
);
|
|
1753
1873
|
} else {
|
|
1754
1874
|
if (!this.save()) {
|
|
1755
1875
|
throw new FileOperationError(
|
|
@@ -1811,13 +1931,16 @@ var init_audio_file_impl = __esm({
|
|
|
1811
1931
|
}
|
|
1812
1932
|
const sorted = sortChapters(chapters);
|
|
1813
1933
|
const trackEndMs = this.audioProperties()?.durationMs;
|
|
1934
|
+
const style = options?.mp4ChapterStyle ?? "quicktime";
|
|
1935
|
+
const source = fmt === "MP4" ? style : "id3";
|
|
1814
1936
|
const raw = sorted.map((c, i) => ({
|
|
1815
1937
|
id: c.id,
|
|
1816
1938
|
startTimeMs: c.startTimeMs,
|
|
1817
1939
|
endTimeMs: inferEndTimeMs(sorted, i, trackEndMs) ?? c.startTimeMs,
|
|
1818
|
-
title: c.title
|
|
1940
|
+
title: c.title,
|
|
1941
|
+
source
|
|
1819
1942
|
}));
|
|
1820
|
-
this.handle.setChapters(raw,
|
|
1943
|
+
this.handle.setChapters(raw, style);
|
|
1821
1944
|
}
|
|
1822
1945
|
getBext() {
|
|
1823
1946
|
return getBext(this.handle);
|
|
@@ -1923,6 +2046,9 @@ function mapPropertiesToExtendedTag(props) {
|
|
|
1923
2046
|
if (tagField === "year" || tagField === "track") {
|
|
1924
2047
|
const num = parseNumeric(values[0]);
|
|
1925
2048
|
if (num !== void 0) tag[tagField] = num;
|
|
2049
|
+
if (propKey === "date") {
|
|
2050
|
+
tag.date = values.length === 1 ? values[0] : values;
|
|
2051
|
+
}
|
|
1926
2052
|
} else {
|
|
1927
2053
|
tag[tagField] = values;
|
|
1928
2054
|
}
|
|
@@ -1963,6 +2089,9 @@ function normalizeTagInput(input) {
|
|
|
1963
2089
|
if (input.year !== void 0) {
|
|
1964
2090
|
props.date = [String(input.year)];
|
|
1965
2091
|
}
|
|
2092
|
+
if (input.date !== void 0) {
|
|
2093
|
+
props.date = Array.isArray(input.date) ? input.date : [input.date];
|
|
2094
|
+
}
|
|
1966
2095
|
if (input.track !== void 0) {
|
|
1967
2096
|
props.trackNumber = [String(input.track)];
|
|
1968
2097
|
}
|
|
@@ -2001,6 +2130,7 @@ var init_tag_mapping = __esm({
|
|
|
2001
2130
|
"comment",
|
|
2002
2131
|
"genre",
|
|
2003
2132
|
"year",
|
|
2133
|
+
"date",
|
|
2004
2134
|
"track"
|
|
2005
2135
|
]);
|
|
2006
2136
|
NUMERIC_FIELDS = /* @__PURE__ */ new Set([
|
|
@@ -2019,7 +2149,7 @@ var VERSION;
|
|
|
2019
2149
|
var init_version = __esm({
|
|
2020
2150
|
"src/version.ts"() {
|
|
2021
2151
|
"use strict";
|
|
2022
|
-
VERSION = "1.
|
|
2152
|
+
VERSION = "1.3.0";
|
|
2023
2153
|
}
|
|
2024
2154
|
});
|
|
2025
2155
|
|