taglib-wasm 1.1.0 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.browser.js +121 -57
- package/dist/simple.browser.js +121 -57
- package/dist/src/runtime/unified-loader/module-loading.d.ts.map +1 -1
- package/dist/src/runtime/unified-loader/module-loading.js +22 -1
- package/dist/src/runtime/wasi-adapter/adapter.d.ts +0 -2
- package/dist/src/runtime/wasi-adapter/adapter.d.ts.map +1 -1
- package/dist/src/runtime/wasi-adapter/adapter.js +0 -12
- package/dist/src/runtime/wasi-adapter/file-handle.d.ts +6 -4
- package/dist/src/runtime/wasi-adapter/file-handle.d.ts.map +1 -1
- package/dist/src/runtime/wasi-adapter/file-handle.js +33 -53
- package/dist/src/taglib/audio-file-base.d.ts.map +1 -1
- package/dist/src/taglib/audio-file-base.js +25 -42
- package/dist/src/taglib/audio-file-impl.d.ts.map +1 -1
- package/dist/src/taglib/audio-file-impl.js +4 -12
- package/dist/src/taglib/embind-adapter.d.ts +51 -0
- package/dist/src/taglib/embind-adapter.d.ts.map +1 -0
- package/dist/src/taglib/embind-adapter.js +57 -0
- package/dist/src/taglib/taglib-class.d.ts.map +1 -1
- package/dist/src/taglib/taglib-class.js +30 -2
- package/dist/src/types/audio-formats.d.ts +2 -0
- package/dist/src/types/audio-formats.d.ts.map +1 -1
- package/dist/src/types/tags.d.ts +14 -0
- package/dist/src/types/tags.d.ts.map +1 -1
- package/dist/src/version.d.ts +1 -1
- package/dist/src/version.js +1 -1
- package/dist/src/wasm.d.ts +3 -37
- package/dist/src/wasm.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.browser.js
CHANGED
|
@@ -1234,61 +1234,63 @@ var init_audio_file_base = __esm({
|
|
|
1234
1234
|
return this.getFormat() === format;
|
|
1235
1235
|
}
|
|
1236
1236
|
tag() {
|
|
1237
|
-
const
|
|
1238
|
-
|
|
1239
|
-
throw new MetadataError(
|
|
1240
|
-
"read",
|
|
1241
|
-
"Tag may be corrupted or format not fully supported"
|
|
1242
|
-
);
|
|
1243
|
-
}
|
|
1237
|
+
const handle = this.handle;
|
|
1238
|
+
let data = handle.getTagData();
|
|
1244
1239
|
const tag = {
|
|
1245
1240
|
get title() {
|
|
1246
|
-
return
|
|
1241
|
+
return data.title;
|
|
1247
1242
|
},
|
|
1248
1243
|
get artist() {
|
|
1249
|
-
return
|
|
1244
|
+
return data.artist;
|
|
1250
1245
|
},
|
|
1251
1246
|
get album() {
|
|
1252
|
-
return
|
|
1247
|
+
return data.album;
|
|
1253
1248
|
},
|
|
1254
1249
|
get comment() {
|
|
1255
|
-
return
|
|
1250
|
+
return data.comment;
|
|
1256
1251
|
},
|
|
1257
1252
|
get genre() {
|
|
1258
|
-
return
|
|
1253
|
+
return data.genre;
|
|
1259
1254
|
},
|
|
1260
1255
|
get year() {
|
|
1261
|
-
return
|
|
1256
|
+
return data.year;
|
|
1262
1257
|
},
|
|
1263
1258
|
get track() {
|
|
1264
|
-
return
|
|
1259
|
+
return data.track;
|
|
1265
1260
|
},
|
|
1266
1261
|
setTitle: (value) => {
|
|
1267
|
-
|
|
1262
|
+
handle.setTagData({ title: value });
|
|
1263
|
+
data = handle.getTagData();
|
|
1268
1264
|
return tag;
|
|
1269
1265
|
},
|
|
1270
1266
|
setArtist: (value) => {
|
|
1271
|
-
|
|
1267
|
+
handle.setTagData({ artist: value });
|
|
1268
|
+
data = handle.getTagData();
|
|
1272
1269
|
return tag;
|
|
1273
1270
|
},
|
|
1274
1271
|
setAlbum: (value) => {
|
|
1275
|
-
|
|
1272
|
+
handle.setTagData({ album: value });
|
|
1273
|
+
data = handle.getTagData();
|
|
1276
1274
|
return tag;
|
|
1277
1275
|
},
|
|
1278
1276
|
setComment: (value) => {
|
|
1279
|
-
|
|
1277
|
+
handle.setTagData({ comment: value });
|
|
1278
|
+
data = handle.getTagData();
|
|
1280
1279
|
return tag;
|
|
1281
1280
|
},
|
|
1282
1281
|
setGenre: (value) => {
|
|
1283
|
-
|
|
1282
|
+
handle.setTagData({ genre: value });
|
|
1283
|
+
data = handle.getTagData();
|
|
1284
1284
|
return tag;
|
|
1285
1285
|
},
|
|
1286
1286
|
setYear: (value) => {
|
|
1287
|
-
|
|
1287
|
+
handle.setTagData({ year: value });
|
|
1288
|
+
data = handle.getTagData();
|
|
1288
1289
|
return tag;
|
|
1289
1290
|
},
|
|
1290
1291
|
setTrack: (value) => {
|
|
1291
|
-
|
|
1292
|
+
handle.setTagData({ track: value });
|
|
1293
|
+
data = handle.getTagData();
|
|
1292
1294
|
return tag;
|
|
1293
1295
|
}
|
|
1294
1296
|
};
|
|
@@ -1296,28 +1298,9 @@ var init_audio_file_base = __esm({
|
|
|
1296
1298
|
}
|
|
1297
1299
|
audioProperties() {
|
|
1298
1300
|
if (!this.cachedAudioProperties) {
|
|
1299
|
-
|
|
1300
|
-
if (!propsWrapper) {
|
|
1301
|
-
return void 0;
|
|
1302
|
-
}
|
|
1303
|
-
const containerFormat = propsWrapper.containerFormat() || "unknown";
|
|
1304
|
-
const mpegVersion = propsWrapper.mpegVersion();
|
|
1305
|
-
const formatVersion = propsWrapper.formatVersion();
|
|
1306
|
-
this.cachedAudioProperties = {
|
|
1307
|
-
duration: propsWrapper.lengthInSeconds(),
|
|
1308
|
-
bitrate: propsWrapper.bitrate(),
|
|
1309
|
-
sampleRate: propsWrapper.sampleRate(),
|
|
1310
|
-
channels: propsWrapper.channels(),
|
|
1311
|
-
bitsPerSample: propsWrapper.bitsPerSample(),
|
|
1312
|
-
codec: propsWrapper.codec() || "unknown",
|
|
1313
|
-
containerFormat,
|
|
1314
|
-
isLossless: propsWrapper.isLossless(),
|
|
1315
|
-
...mpegVersion > 0 ? { mpegVersion, mpegLayer: propsWrapper.mpegLayer() } : {},
|
|
1316
|
-
...containerFormat === "MP4" || containerFormat === "ASF" ? { isEncrypted: propsWrapper.isEncrypted() } : {},
|
|
1317
|
-
...formatVersion > 0 ? { formatVersion } : {}
|
|
1318
|
-
};
|
|
1301
|
+
this.cachedAudioProperties = this.handle.getAudioProperties() ?? null;
|
|
1319
1302
|
}
|
|
1320
|
-
return this.cachedAudioProperties;
|
|
1303
|
+
return this.cachedAudioProperties ?? void 0;
|
|
1321
1304
|
}
|
|
1322
1305
|
properties() {
|
|
1323
1306
|
return remapKeysFromTagLib(this.handle.getProperties());
|
|
@@ -1375,6 +1358,67 @@ var init_audio_file_base = __esm({
|
|
|
1375
1358
|
}
|
|
1376
1359
|
});
|
|
1377
1360
|
|
|
1361
|
+
// src/taglib/embind-adapter.ts
|
|
1362
|
+
function wrapEmbindHandle(raw) {
|
|
1363
|
+
const overrides = {
|
|
1364
|
+
getTagData() {
|
|
1365
|
+
const tw = raw.getTag();
|
|
1366
|
+
return {
|
|
1367
|
+
title: tw.title(),
|
|
1368
|
+
artist: tw.artist(),
|
|
1369
|
+
album: tw.album(),
|
|
1370
|
+
comment: tw.comment(),
|
|
1371
|
+
genre: tw.genre(),
|
|
1372
|
+
year: tw.year(),
|
|
1373
|
+
track: tw.track()
|
|
1374
|
+
};
|
|
1375
|
+
},
|
|
1376
|
+
setTagData(data) {
|
|
1377
|
+
const tw = raw.getTag();
|
|
1378
|
+
if (data.title !== void 0) tw.setTitle(data.title);
|
|
1379
|
+
if (data.artist !== void 0) tw.setArtist(data.artist);
|
|
1380
|
+
if (data.album !== void 0) tw.setAlbum(data.album);
|
|
1381
|
+
if (data.comment !== void 0) tw.setComment(data.comment);
|
|
1382
|
+
if (data.genre !== void 0) tw.setGenre(data.genre);
|
|
1383
|
+
if (data.year !== void 0) tw.setYear(data.year);
|
|
1384
|
+
if (data.track !== void 0) tw.setTrack(data.track);
|
|
1385
|
+
},
|
|
1386
|
+
getAudioProperties() {
|
|
1387
|
+
const pw = raw.getAudioProperties();
|
|
1388
|
+
if (!pw) return null;
|
|
1389
|
+
const containerFormat = pw.containerFormat() || "unknown";
|
|
1390
|
+
const mpegVersion = pw.mpegVersion();
|
|
1391
|
+
const formatVersion = pw.formatVersion();
|
|
1392
|
+
return {
|
|
1393
|
+
duration: pw.lengthInSeconds(),
|
|
1394
|
+
durationMs: pw.lengthInMilliseconds(),
|
|
1395
|
+
bitrate: pw.bitrate(),
|
|
1396
|
+
sampleRate: pw.sampleRate(),
|
|
1397
|
+
channels: pw.channels(),
|
|
1398
|
+
bitsPerSample: pw.bitsPerSample(),
|
|
1399
|
+
codec: pw.codec() || "unknown",
|
|
1400
|
+
containerFormat,
|
|
1401
|
+
isLossless: pw.isLossless(),
|
|
1402
|
+
...mpegVersion > 0 ? { mpegVersion, mpegLayer: pw.mpegLayer() } : {},
|
|
1403
|
+
...containerFormat === "MP4" || containerFormat === "ASF" ? { isEncrypted: pw.isEncrypted() } : {},
|
|
1404
|
+
...formatVersion > 0 ? { formatVersion } : {}
|
|
1405
|
+
};
|
|
1406
|
+
}
|
|
1407
|
+
};
|
|
1408
|
+
return new Proxy(raw, {
|
|
1409
|
+
get(target, prop, receiver) {
|
|
1410
|
+
if (prop in overrides) return overrides[prop];
|
|
1411
|
+
const value = Reflect.get(target, prop, receiver);
|
|
1412
|
+
return typeof value === "function" ? value.bind(target) : value;
|
|
1413
|
+
}
|
|
1414
|
+
});
|
|
1415
|
+
}
|
|
1416
|
+
var init_embind_adapter = __esm({
|
|
1417
|
+
"src/taglib/embind-adapter.ts"() {
|
|
1418
|
+
"use strict";
|
|
1419
|
+
}
|
|
1420
|
+
});
|
|
1421
|
+
|
|
1378
1422
|
// src/taglib/audio-file-impl.ts
|
|
1379
1423
|
function readFileSync(path) {
|
|
1380
1424
|
if (typeof Deno !== "undefined") return Deno.readFileSync(path);
|
|
@@ -1397,6 +1441,7 @@ var init_audio_file_impl = __esm({
|
|
|
1397
1441
|
init_file();
|
|
1398
1442
|
init_write();
|
|
1399
1443
|
init_audio_file_base();
|
|
1444
|
+
init_embind_adapter();
|
|
1400
1445
|
AudioFileImpl = class extends BaseAudioFileImpl {
|
|
1401
1446
|
constructor(module, fileHandle, sourcePath, originalSource, isPartiallyLoaded = false, partialLoadOptions) {
|
|
1402
1447
|
super(
|
|
@@ -1442,7 +1487,8 @@ var init_audio_file_impl = __esm({
|
|
|
1442
1487
|
);
|
|
1443
1488
|
}
|
|
1444
1489
|
if (this.isPartiallyLoaded && this.originalSource) {
|
|
1445
|
-
const
|
|
1490
|
+
const rawFullHandle = this.module.createFileHandle();
|
|
1491
|
+
const fullFileHandle = this.module.isWasi ? rawFullHandle : wrapEmbindHandle(rawFullHandle);
|
|
1446
1492
|
try {
|
|
1447
1493
|
const success = await (async () => {
|
|
1448
1494
|
const data = await readFileData(this.originalSource);
|
|
@@ -1453,17 +1499,7 @@ var init_audio_file_impl = __esm({
|
|
|
1453
1499
|
"Failed to load full audio file for saving"
|
|
1454
1500
|
);
|
|
1455
1501
|
}
|
|
1456
|
-
|
|
1457
|
-
const fullTag = fullFileHandle.getTag();
|
|
1458
|
-
if (partialTag && fullTag) {
|
|
1459
|
-
fullTag.setTitle(partialTag.title());
|
|
1460
|
-
fullTag.setArtist(partialTag.artist());
|
|
1461
|
-
fullTag.setAlbum(partialTag.album());
|
|
1462
|
-
fullTag.setComment(partialTag.comment());
|
|
1463
|
-
fullTag.setGenre(partialTag.genre());
|
|
1464
|
-
fullTag.setYear(partialTag.year());
|
|
1465
|
-
fullTag.setTrack(partialTag.track());
|
|
1466
|
-
}
|
|
1502
|
+
fullFileHandle.setTagData(this.handle.getTagData());
|
|
1467
1503
|
fullFileHandle.setProperties(this.handle.getProperties());
|
|
1468
1504
|
fullFileHandle.setPictures(this.handle.getPictures());
|
|
1469
1505
|
if (!fullFileHandle.save()) {
|
|
@@ -1693,7 +1729,7 @@ var VERSION;
|
|
|
1693
1729
|
var init_version = __esm({
|
|
1694
1730
|
"src/version.ts"() {
|
|
1695
1731
|
"use strict";
|
|
1696
|
-
VERSION = "1.1.
|
|
1732
|
+
VERSION = "1.1.2";
|
|
1697
1733
|
}
|
|
1698
1734
|
});
|
|
1699
1735
|
|
|
@@ -1743,6 +1779,30 @@ var init_module_loader_browser = __esm({
|
|
|
1743
1779
|
});
|
|
1744
1780
|
|
|
1745
1781
|
// src/taglib/taglib-class.ts
|
|
1782
|
+
function toWasiPath(osPath) {
|
|
1783
|
+
if (osPath.startsWith("\\\\") || osPath.startsWith("//")) {
|
|
1784
|
+
throw new FileOperationError(
|
|
1785
|
+
"read",
|
|
1786
|
+
`UNC paths are not supported. Path: ${osPath}`
|
|
1787
|
+
);
|
|
1788
|
+
}
|
|
1789
|
+
let p = osPath;
|
|
1790
|
+
if (!p.startsWith("/") && !/^[A-Za-z]:/.test(p)) {
|
|
1791
|
+
const g = globalThis;
|
|
1792
|
+
const cwd = typeof Deno !== "undefined" ? Deno.cwd() : g.process?.cwd?.();
|
|
1793
|
+
if (cwd) {
|
|
1794
|
+
p = cwd.replace(/[/\\]+$/, "") + "/" + p;
|
|
1795
|
+
}
|
|
1796
|
+
}
|
|
1797
|
+
p = p.replaceAll("\\", "/");
|
|
1798
|
+
const driveMatch = p.match(/^([A-Za-z]):\//);
|
|
1799
|
+
if (driveMatch) {
|
|
1800
|
+
p = `/${driveMatch[1].toUpperCase()}${p.slice(2)}`;
|
|
1801
|
+
}
|
|
1802
|
+
p = p.replace(/\/\.\//g, "/").replace(/\/+/g, "/");
|
|
1803
|
+
if (!p.startsWith("/")) p = "/" + p;
|
|
1804
|
+
return p;
|
|
1805
|
+
}
|
|
1746
1806
|
async function createTagLib(module) {
|
|
1747
1807
|
return new TagLib(module);
|
|
1748
1808
|
}
|
|
@@ -1755,7 +1815,9 @@ var init_taglib_class = __esm({
|
|
|
1755
1815
|
init_audio_file_impl();
|
|
1756
1816
|
init_load_audio_data();
|
|
1757
1817
|
init_tag_mapping();
|
|
1818
|
+
init_errors2();
|
|
1758
1819
|
init_version();
|
|
1820
|
+
init_embind_adapter();
|
|
1759
1821
|
TagLib = class _TagLib {
|
|
1760
1822
|
constructor(module) {
|
|
1761
1823
|
__publicField(this, "module");
|
|
@@ -1793,7 +1855,8 @@ var init_taglib_class = __esm({
|
|
|
1793
1855
|
try {
|
|
1794
1856
|
const fh = fileHandle2;
|
|
1795
1857
|
if (fh.loadFromPath) {
|
|
1796
|
-
const
|
|
1858
|
+
const wasiPath = toWasiPath(actualInput);
|
|
1859
|
+
const success = fh.loadFromPath(wasiPath);
|
|
1797
1860
|
if (!success) {
|
|
1798
1861
|
throw new InvalidFormatError(
|
|
1799
1862
|
`Failed to load audio file. Path: ${actualInput}`
|
|
@@ -1830,7 +1893,8 @@ var init_taglib_class = __esm({
|
|
|
1830
1893
|
audioData.byteOffset + audioData.byteLength
|
|
1831
1894
|
)
|
|
1832
1895
|
) : audioData;
|
|
1833
|
-
const
|
|
1896
|
+
const rawHandle = this.module.createFileHandle();
|
|
1897
|
+
const fileHandle = this.module.isWasi ? rawHandle : wrapEmbindHandle(rawHandle);
|
|
1834
1898
|
try {
|
|
1835
1899
|
const success = fileHandle.loadFromBuffer(uint8Array);
|
|
1836
1900
|
if (!success) {
|
package/dist/simple.browser.js
CHANGED
|
@@ -1222,61 +1222,63 @@ var init_audio_file_base = __esm({
|
|
|
1222
1222
|
return this.getFormat() === format;
|
|
1223
1223
|
}
|
|
1224
1224
|
tag() {
|
|
1225
|
-
const
|
|
1226
|
-
|
|
1227
|
-
throw new MetadataError(
|
|
1228
|
-
"read",
|
|
1229
|
-
"Tag may be corrupted or format not fully supported"
|
|
1230
|
-
);
|
|
1231
|
-
}
|
|
1225
|
+
const handle = this.handle;
|
|
1226
|
+
let data = handle.getTagData();
|
|
1232
1227
|
const tag = {
|
|
1233
1228
|
get title() {
|
|
1234
|
-
return
|
|
1229
|
+
return data.title;
|
|
1235
1230
|
},
|
|
1236
1231
|
get artist() {
|
|
1237
|
-
return
|
|
1232
|
+
return data.artist;
|
|
1238
1233
|
},
|
|
1239
1234
|
get album() {
|
|
1240
|
-
return
|
|
1235
|
+
return data.album;
|
|
1241
1236
|
},
|
|
1242
1237
|
get comment() {
|
|
1243
|
-
return
|
|
1238
|
+
return data.comment;
|
|
1244
1239
|
},
|
|
1245
1240
|
get genre() {
|
|
1246
|
-
return
|
|
1241
|
+
return data.genre;
|
|
1247
1242
|
},
|
|
1248
1243
|
get year() {
|
|
1249
|
-
return
|
|
1244
|
+
return data.year;
|
|
1250
1245
|
},
|
|
1251
1246
|
get track() {
|
|
1252
|
-
return
|
|
1247
|
+
return data.track;
|
|
1253
1248
|
},
|
|
1254
1249
|
setTitle: (value) => {
|
|
1255
|
-
|
|
1250
|
+
handle.setTagData({ title: value });
|
|
1251
|
+
data = handle.getTagData();
|
|
1256
1252
|
return tag;
|
|
1257
1253
|
},
|
|
1258
1254
|
setArtist: (value) => {
|
|
1259
|
-
|
|
1255
|
+
handle.setTagData({ artist: value });
|
|
1256
|
+
data = handle.getTagData();
|
|
1260
1257
|
return tag;
|
|
1261
1258
|
},
|
|
1262
1259
|
setAlbum: (value) => {
|
|
1263
|
-
|
|
1260
|
+
handle.setTagData({ album: value });
|
|
1261
|
+
data = handle.getTagData();
|
|
1264
1262
|
return tag;
|
|
1265
1263
|
},
|
|
1266
1264
|
setComment: (value) => {
|
|
1267
|
-
|
|
1265
|
+
handle.setTagData({ comment: value });
|
|
1266
|
+
data = handle.getTagData();
|
|
1268
1267
|
return tag;
|
|
1269
1268
|
},
|
|
1270
1269
|
setGenre: (value) => {
|
|
1271
|
-
|
|
1270
|
+
handle.setTagData({ genre: value });
|
|
1271
|
+
data = handle.getTagData();
|
|
1272
1272
|
return tag;
|
|
1273
1273
|
},
|
|
1274
1274
|
setYear: (value) => {
|
|
1275
|
-
|
|
1275
|
+
handle.setTagData({ year: value });
|
|
1276
|
+
data = handle.getTagData();
|
|
1276
1277
|
return tag;
|
|
1277
1278
|
},
|
|
1278
1279
|
setTrack: (value) => {
|
|
1279
|
-
|
|
1280
|
+
handle.setTagData({ track: value });
|
|
1281
|
+
data = handle.getTagData();
|
|
1280
1282
|
return tag;
|
|
1281
1283
|
}
|
|
1282
1284
|
};
|
|
@@ -1284,28 +1286,9 @@ var init_audio_file_base = __esm({
|
|
|
1284
1286
|
}
|
|
1285
1287
|
audioProperties() {
|
|
1286
1288
|
if (!this.cachedAudioProperties) {
|
|
1287
|
-
|
|
1288
|
-
if (!propsWrapper) {
|
|
1289
|
-
return void 0;
|
|
1290
|
-
}
|
|
1291
|
-
const containerFormat = propsWrapper.containerFormat() || "unknown";
|
|
1292
|
-
const mpegVersion = propsWrapper.mpegVersion();
|
|
1293
|
-
const formatVersion = propsWrapper.formatVersion();
|
|
1294
|
-
this.cachedAudioProperties = {
|
|
1295
|
-
duration: propsWrapper.lengthInSeconds(),
|
|
1296
|
-
bitrate: propsWrapper.bitrate(),
|
|
1297
|
-
sampleRate: propsWrapper.sampleRate(),
|
|
1298
|
-
channels: propsWrapper.channels(),
|
|
1299
|
-
bitsPerSample: propsWrapper.bitsPerSample(),
|
|
1300
|
-
codec: propsWrapper.codec() || "unknown",
|
|
1301
|
-
containerFormat,
|
|
1302
|
-
isLossless: propsWrapper.isLossless(),
|
|
1303
|
-
...mpegVersion > 0 ? { mpegVersion, mpegLayer: propsWrapper.mpegLayer() } : {},
|
|
1304
|
-
...containerFormat === "MP4" || containerFormat === "ASF" ? { isEncrypted: propsWrapper.isEncrypted() } : {},
|
|
1305
|
-
...formatVersion > 0 ? { formatVersion } : {}
|
|
1306
|
-
};
|
|
1289
|
+
this.cachedAudioProperties = this.handle.getAudioProperties() ?? null;
|
|
1307
1290
|
}
|
|
1308
|
-
return this.cachedAudioProperties;
|
|
1291
|
+
return this.cachedAudioProperties ?? void 0;
|
|
1309
1292
|
}
|
|
1310
1293
|
properties() {
|
|
1311
1294
|
return remapKeysFromTagLib(this.handle.getProperties());
|
|
@@ -1363,6 +1346,67 @@ var init_audio_file_base = __esm({
|
|
|
1363
1346
|
}
|
|
1364
1347
|
});
|
|
1365
1348
|
|
|
1349
|
+
// src/taglib/embind-adapter.ts
|
|
1350
|
+
function wrapEmbindHandle(raw) {
|
|
1351
|
+
const overrides = {
|
|
1352
|
+
getTagData() {
|
|
1353
|
+
const tw = raw.getTag();
|
|
1354
|
+
return {
|
|
1355
|
+
title: tw.title(),
|
|
1356
|
+
artist: tw.artist(),
|
|
1357
|
+
album: tw.album(),
|
|
1358
|
+
comment: tw.comment(),
|
|
1359
|
+
genre: tw.genre(),
|
|
1360
|
+
year: tw.year(),
|
|
1361
|
+
track: tw.track()
|
|
1362
|
+
};
|
|
1363
|
+
},
|
|
1364
|
+
setTagData(data) {
|
|
1365
|
+
const tw = raw.getTag();
|
|
1366
|
+
if (data.title !== void 0) tw.setTitle(data.title);
|
|
1367
|
+
if (data.artist !== void 0) tw.setArtist(data.artist);
|
|
1368
|
+
if (data.album !== void 0) tw.setAlbum(data.album);
|
|
1369
|
+
if (data.comment !== void 0) tw.setComment(data.comment);
|
|
1370
|
+
if (data.genre !== void 0) tw.setGenre(data.genre);
|
|
1371
|
+
if (data.year !== void 0) tw.setYear(data.year);
|
|
1372
|
+
if (data.track !== void 0) tw.setTrack(data.track);
|
|
1373
|
+
},
|
|
1374
|
+
getAudioProperties() {
|
|
1375
|
+
const pw = raw.getAudioProperties();
|
|
1376
|
+
if (!pw) return null;
|
|
1377
|
+
const containerFormat = pw.containerFormat() || "unknown";
|
|
1378
|
+
const mpegVersion = pw.mpegVersion();
|
|
1379
|
+
const formatVersion = pw.formatVersion();
|
|
1380
|
+
return {
|
|
1381
|
+
duration: pw.lengthInSeconds(),
|
|
1382
|
+
durationMs: pw.lengthInMilliseconds(),
|
|
1383
|
+
bitrate: pw.bitrate(),
|
|
1384
|
+
sampleRate: pw.sampleRate(),
|
|
1385
|
+
channels: pw.channels(),
|
|
1386
|
+
bitsPerSample: pw.bitsPerSample(),
|
|
1387
|
+
codec: pw.codec() || "unknown",
|
|
1388
|
+
containerFormat,
|
|
1389
|
+
isLossless: pw.isLossless(),
|
|
1390
|
+
...mpegVersion > 0 ? { mpegVersion, mpegLayer: pw.mpegLayer() } : {},
|
|
1391
|
+
...containerFormat === "MP4" || containerFormat === "ASF" ? { isEncrypted: pw.isEncrypted() } : {},
|
|
1392
|
+
...formatVersion > 0 ? { formatVersion } : {}
|
|
1393
|
+
};
|
|
1394
|
+
}
|
|
1395
|
+
};
|
|
1396
|
+
return new Proxy(raw, {
|
|
1397
|
+
get(target, prop, receiver) {
|
|
1398
|
+
if (prop in overrides) return overrides[prop];
|
|
1399
|
+
const value = Reflect.get(target, prop, receiver);
|
|
1400
|
+
return typeof value === "function" ? value.bind(target) : value;
|
|
1401
|
+
}
|
|
1402
|
+
});
|
|
1403
|
+
}
|
|
1404
|
+
var init_embind_adapter = __esm({
|
|
1405
|
+
"src/taglib/embind-adapter.ts"() {
|
|
1406
|
+
"use strict";
|
|
1407
|
+
}
|
|
1408
|
+
});
|
|
1409
|
+
|
|
1366
1410
|
// src/taglib/audio-file-impl.ts
|
|
1367
1411
|
function readFileSync(path) {
|
|
1368
1412
|
if (typeof Deno !== "undefined") return Deno.readFileSync(path);
|
|
@@ -1385,6 +1429,7 @@ var init_audio_file_impl = __esm({
|
|
|
1385
1429
|
init_file();
|
|
1386
1430
|
init_write();
|
|
1387
1431
|
init_audio_file_base();
|
|
1432
|
+
init_embind_adapter();
|
|
1388
1433
|
AudioFileImpl = class extends BaseAudioFileImpl {
|
|
1389
1434
|
constructor(module, fileHandle, sourcePath, originalSource, isPartiallyLoaded = false, partialLoadOptions) {
|
|
1390
1435
|
super(
|
|
@@ -1430,7 +1475,8 @@ var init_audio_file_impl = __esm({
|
|
|
1430
1475
|
);
|
|
1431
1476
|
}
|
|
1432
1477
|
if (this.isPartiallyLoaded && this.originalSource) {
|
|
1433
|
-
const
|
|
1478
|
+
const rawFullHandle = this.module.createFileHandle();
|
|
1479
|
+
const fullFileHandle = this.module.isWasi ? rawFullHandle : wrapEmbindHandle(rawFullHandle);
|
|
1434
1480
|
try {
|
|
1435
1481
|
const success = await (async () => {
|
|
1436
1482
|
const data = await readFileData(this.originalSource);
|
|
@@ -1441,17 +1487,7 @@ var init_audio_file_impl = __esm({
|
|
|
1441
1487
|
"Failed to load full audio file for saving"
|
|
1442
1488
|
);
|
|
1443
1489
|
}
|
|
1444
|
-
|
|
1445
|
-
const fullTag = fullFileHandle.getTag();
|
|
1446
|
-
if (partialTag && fullTag) {
|
|
1447
|
-
fullTag.setTitle(partialTag.title());
|
|
1448
|
-
fullTag.setArtist(partialTag.artist());
|
|
1449
|
-
fullTag.setAlbum(partialTag.album());
|
|
1450
|
-
fullTag.setComment(partialTag.comment());
|
|
1451
|
-
fullTag.setGenre(partialTag.genre());
|
|
1452
|
-
fullTag.setYear(partialTag.year());
|
|
1453
|
-
fullTag.setTrack(partialTag.track());
|
|
1454
|
-
}
|
|
1490
|
+
fullFileHandle.setTagData(this.handle.getTagData());
|
|
1455
1491
|
fullFileHandle.setProperties(this.handle.getProperties());
|
|
1456
1492
|
fullFileHandle.setPictures(this.handle.getPictures());
|
|
1457
1493
|
if (!fullFileHandle.save()) {
|
|
@@ -1681,7 +1717,7 @@ var VERSION;
|
|
|
1681
1717
|
var init_version = __esm({
|
|
1682
1718
|
"src/version.ts"() {
|
|
1683
1719
|
"use strict";
|
|
1684
|
-
VERSION = "1.1.
|
|
1720
|
+
VERSION = "1.1.2";
|
|
1685
1721
|
}
|
|
1686
1722
|
});
|
|
1687
1723
|
|
|
@@ -1730,6 +1766,30 @@ var init_module_loader_browser = __esm({
|
|
|
1730
1766
|
});
|
|
1731
1767
|
|
|
1732
1768
|
// src/taglib/taglib-class.ts
|
|
1769
|
+
function toWasiPath(osPath) {
|
|
1770
|
+
if (osPath.startsWith("\\\\") || osPath.startsWith("//")) {
|
|
1771
|
+
throw new FileOperationError(
|
|
1772
|
+
"read",
|
|
1773
|
+
`UNC paths are not supported. Path: ${osPath}`
|
|
1774
|
+
);
|
|
1775
|
+
}
|
|
1776
|
+
let p = osPath;
|
|
1777
|
+
if (!p.startsWith("/") && !/^[A-Za-z]:/.test(p)) {
|
|
1778
|
+
const g = globalThis;
|
|
1779
|
+
const cwd = typeof Deno !== "undefined" ? Deno.cwd() : g.process?.cwd?.();
|
|
1780
|
+
if (cwd) {
|
|
1781
|
+
p = cwd.replace(/[/\\]+$/, "") + "/" + p;
|
|
1782
|
+
}
|
|
1783
|
+
}
|
|
1784
|
+
p = p.replaceAll("\\", "/");
|
|
1785
|
+
const driveMatch = p.match(/^([A-Za-z]):\//);
|
|
1786
|
+
if (driveMatch) {
|
|
1787
|
+
p = `/${driveMatch[1].toUpperCase()}${p.slice(2)}`;
|
|
1788
|
+
}
|
|
1789
|
+
p = p.replace(/\/\.\//g, "/").replace(/\/+/g, "/");
|
|
1790
|
+
if (!p.startsWith("/")) p = "/" + p;
|
|
1791
|
+
return p;
|
|
1792
|
+
}
|
|
1733
1793
|
async function createTagLib(module) {
|
|
1734
1794
|
return new TagLib(module);
|
|
1735
1795
|
}
|
|
@@ -1742,7 +1802,9 @@ var init_taglib_class = __esm({
|
|
|
1742
1802
|
init_audio_file_impl();
|
|
1743
1803
|
init_load_audio_data();
|
|
1744
1804
|
init_tag_mapping();
|
|
1805
|
+
init_errors2();
|
|
1745
1806
|
init_version();
|
|
1807
|
+
init_embind_adapter();
|
|
1746
1808
|
TagLib = class _TagLib {
|
|
1747
1809
|
constructor(module) {
|
|
1748
1810
|
__publicField(this, "module");
|
|
@@ -1780,7 +1842,8 @@ var init_taglib_class = __esm({
|
|
|
1780
1842
|
try {
|
|
1781
1843
|
const fh = fileHandle2;
|
|
1782
1844
|
if (fh.loadFromPath) {
|
|
1783
|
-
const
|
|
1845
|
+
const wasiPath = toWasiPath(actualInput);
|
|
1846
|
+
const success = fh.loadFromPath(wasiPath);
|
|
1784
1847
|
if (!success) {
|
|
1785
1848
|
throw new InvalidFormatError(
|
|
1786
1849
|
`Failed to load audio file. Path: ${actualInput}`
|
|
@@ -1817,7 +1880,8 @@ var init_taglib_class = __esm({
|
|
|
1817
1880
|
audioData.byteOffset + audioData.byteLength
|
|
1818
1881
|
)
|
|
1819
1882
|
) : audioData;
|
|
1820
|
-
const
|
|
1883
|
+
const rawHandle = this.module.createFileHandle();
|
|
1884
|
+
const fileHandle = this.module.isWasi ? rawHandle : wrapEmbindHandle(rawHandle);
|
|
1821
1885
|
try {
|
|
1822
1886
|
const success = fileHandle.loadFromBuffer(uint8Array);
|
|
1823
1887
|
if (!success) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module-loading.d.ts","sourceRoot":"","sources":["../../../../src/runtime/unified-loader/module-loading.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAG7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"module-loading.d.ts","sourceRoot":"","sources":["../../../../src/runtime/unified-loader/module-loading.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAG7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AA0CzE,wBAAsB,UAAU,CAC9B,QAAQ,EAAE,MAAM,GAAG,YAAY,EAC/B,OAAO,EAAE,sBAAsB,EAC/B,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,gBAAgB,CAAC,CAS3B"}
|
|
@@ -2,6 +2,27 @@ import { supportsExnref } from "../detector.js";
|
|
|
2
2
|
import { ModuleLoadError } from "./types.js";
|
|
3
3
|
import { errorMessage } from "../../errors/classes.js";
|
|
4
4
|
import { fileUrlToPath } from "../../utils/path.js";
|
|
5
|
+
function isWindows() {
|
|
6
|
+
return typeof Deno !== "undefined" ? Deno.build.os === "windows" : globalThis.process ? globalThis.process.platform === "win32" : false;
|
|
7
|
+
}
|
|
8
|
+
function getPreopens() {
|
|
9
|
+
if (!isWindows()) return { "/": "/" };
|
|
10
|
+
const preopens = {};
|
|
11
|
+
for (const letter of "CDEFGHIJKLMNOPQRSTUVWXYZAB") {
|
|
12
|
+
const root = `${letter}:\\`;
|
|
13
|
+
try {
|
|
14
|
+
if (typeof Deno !== "undefined") {
|
|
15
|
+
Deno.statSync(root);
|
|
16
|
+
} else {
|
|
17
|
+
const fs = new Function("return require('node:fs')")();
|
|
18
|
+
fs.statSync(root);
|
|
19
|
+
}
|
|
20
|
+
preopens[`/${letter}`] = root;
|
|
21
|
+
} catch {
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return Object.keys(preopens).length > 0 ? preopens : { "/C": "C:\\" };
|
|
25
|
+
}
|
|
5
26
|
function resolveWasmPath(relativePath) {
|
|
6
27
|
const url = new URL(relativePath, import.meta.url);
|
|
7
28
|
return url.protocol === "file:" ? fileUrlToPath(url) : url.href;
|
|
@@ -22,7 +43,7 @@ async function loadWasiModuleWithFallback(runtime, options) {
|
|
|
22
43
|
const { loadWasiHost } = await import("../wasi-host-loader.js");
|
|
23
44
|
const wasiModule = await loadWasiHost({
|
|
24
45
|
wasmPath: options.wasmUrl || defaultWasmPath,
|
|
25
|
-
preopens:
|
|
46
|
+
preopens: getPreopens()
|
|
26
47
|
});
|
|
27
48
|
return { module: wasiModule, actualWasmType: "wasi" };
|
|
28
49
|
} catch (hostError) {
|
|
@@ -11,8 +11,6 @@ export declare class WasiToTagLibAdapter implements TagLibModule {
|
|
|
11
11
|
private readonly heap;
|
|
12
12
|
constructor(wasiModule: WasiModule);
|
|
13
13
|
FileHandle: new () => FileHandle;
|
|
14
|
-
TagWrapper: new () => import("../../wasm.js").TagWrapper;
|
|
15
|
-
AudioPropertiesWrapper: new () => import("../../wasm.js").AudioPropertiesWrapper;
|
|
16
14
|
get ready(): Promise<this>;
|
|
17
15
|
get HEAP8(): Int8Array;
|
|
18
16
|
get HEAP16(): Int16Array;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../../src/runtime/wasi-adapter/adapter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAKhE,qBAAa,mBAAoB,YAAW,YAAY;IACtD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAa;IAClC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAa;gBAEtB,UAAU,EAAE,UAAU;IAKlC,UAAU,EAMM,UAAU,UAAU,CAAC;IAErC,
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../../src/runtime/wasi-adapter/adapter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAKhE,qBAAa,mBAAoB,YAAW,YAAY;IACtD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAa;IAClC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAa;gBAEtB,UAAU,EAAE,UAAU;IAKlC,UAAU,EAMM,UAAU,UAAU,CAAC;IAErC,IAAI,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAEzB;IAED,IAAI,KAAK,IAAI,SAAS,CAErB;IAED,IAAI,MAAM,IAAI,UAAU,CAEvB;IAED,IAAI,MAAM,IAAI,UAAU,CAEvB;IAED,IAAI,MAAM,IAAI,UAAU,CAEvB;IAED,IAAI,OAAO,IAAI,WAAW,CAEzB;IAED,IAAI,OAAO,IAAI,WAAW,CAEzB;IAED,IAAI,OAAO,IAAI,YAAY,CAE1B;IAED,IAAI,OAAO,IAAI,YAAY,CAE1B;IAED,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAI7B,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAIxB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM;IAe9C,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;IAOjC,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM;IAQhE,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;IAIpC,gBAAgB,IAAI,UAAU;IAI9B,OAAO,IAAI,MAAM;IAIjB,WAAW,CAAC,KAAK,EAAE,GAAG,GAAG,MAAM;IAM/B,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAMlC,KAAK,CACH,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,GAAG,IAAI,EAC1B,SAAS,EAAE,MAAM,EAAE,GAClB,GAAG;IAMN,KAAK,CACH,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,GAAG,IAAI,EAC1B,SAAS,EAAE,MAAM,EAAE,EACnB,KAAK,EAAE,GAAG,EAAE,GACX,GAAG;CAKP"}
|
|
@@ -15,18 +15,6 @@ class WasiToTagLibAdapter {
|
|
|
15
15
|
);
|
|
16
16
|
}
|
|
17
17
|
});
|
|
18
|
-
__publicField(this, "TagWrapper", class {
|
|
19
|
-
constructor() {
|
|
20
|
-
throw new WasmerExecutionError("TagWrapper not directly constructable");
|
|
21
|
-
}
|
|
22
|
-
});
|
|
23
|
-
__publicField(this, "AudioPropertiesWrapper", class {
|
|
24
|
-
constructor() {
|
|
25
|
-
throw new WasmerExecutionError(
|
|
26
|
-
"AudioPropertiesWrapper not directly constructable"
|
|
27
|
-
);
|
|
28
|
-
}
|
|
29
|
-
});
|
|
30
18
|
this.wasi = wasiModule;
|
|
31
19
|
this.heap = new Uint8Array(wasiModule.memory.buffer);
|
|
32
20
|
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @fileoverview WASI-based FileHandle implementation
|
|
3
3
|
*/
|
|
4
|
-
import type {
|
|
4
|
+
import type { FileHandle, RawPicture } from "../../wasm.js";
|
|
5
|
+
import type { BasicTagData } from "../../types/tags.js";
|
|
6
|
+
import type { AudioProperties } from "../../types.js";
|
|
5
7
|
import type { WasiModule } from "../wasmer-sdk-loader/types.js";
|
|
6
8
|
export declare class WasiFileHandle implements FileHandle {
|
|
7
9
|
private readonly wasi;
|
|
@@ -15,9 +17,9 @@ export declare class WasiFileHandle implements FileHandle {
|
|
|
15
17
|
loadFromPath(path: string): boolean;
|
|
16
18
|
isValid(): boolean;
|
|
17
19
|
save(): boolean;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
getAudioProperties():
|
|
20
|
+
getTagData(): BasicTagData;
|
|
21
|
+
setTagData(data: Partial<BasicTagData>): void;
|
|
22
|
+
getAudioProperties(): AudioProperties | null;
|
|
21
23
|
getFormat(): string;
|
|
22
24
|
private detectOggCodec;
|
|
23
25
|
getBuffer(): Uint8Array;
|