taglib-wasm 1.1.1 → 1.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/README.md +512 -38
- package/dist/index.browser.js +366 -56
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/simple.browser.js +366 -56
- package/dist/src/bwf/bext.d.ts +28 -0
- package/dist/src/bwf/bext.d.ts.map +1 -0
- package/dist/src/bwf/bext.js +126 -0
- package/dist/src/msgpack/encoder.d.ts.map +1 -1
- package/dist/src/msgpack/encoder.js +9 -1
- package/dist/src/runtime/unified-loader/module-loading.js +1 -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 +12 -4
- package/dist/src/runtime/wasi-adapter/file-handle.d.ts.map +1 -1
- package/dist/src/runtime/wasi-adapter/file-handle.js +73 -54
- package/dist/src/runtime/wasi-host-loader.d.ts +1 -1
- package/dist/src/runtime/wasi-host-loader.js +1 -1
- 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-bwf.d.ts +14 -0
- package/dist/src/taglib/audio-file-bwf.d.ts.map +1 -0
- package/dist/src/taglib/audio-file-bwf.js +41 -0
- package/dist/src/taglib/audio-file-impl.d.ts +10 -0
- package/dist/src/taglib/audio-file-impl.d.ts.map +1 -1
- package/dist/src/taglib/audio-file-impl.js +69 -13
- package/dist/src/taglib/audio-file-interface.d.ts +27 -0
- package/dist/src/taglib/audio-file-interface.d.ts.map +1 -1
- package/dist/src/taglib/embind-adapter.d.ts +53 -0
- package/dist/src/taglib/embind-adapter.d.ts.map +1 -0
- package/dist/src/taglib/embind-adapter.js +82 -0
- package/dist/src/taglib/taglib-class.d.ts.map +1 -1
- package/dist/src/taglib/taglib-class.js +3 -1
- package/dist/src/types/audio-formats.d.ts +20 -0
- package/dist/src/types/audio-formats.d.ts.map +1 -1
- package/dist/src/types/bwf.d.ts +43 -0
- package/dist/src/types/bwf.d.ts.map +1 -0
- package/dist/src/types/bwf.js +0 -0
- package/dist/src/types/chapters.d.ts +47 -0
- package/dist/src/types/chapters.d.ts.map +1 -0
- package/dist/src/types/chapters.js +0 -0
- package/dist/src/types/index.d.ts +2 -0
- package/dist/src/types/index.d.ts.map +1 -1
- package/dist/src/types/index.js +2 -0
- 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/tags.d.ts +25 -7
- 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 +17 -39
- package/dist/src/wasm.d.ts.map +1 -1
- package/dist/taglib-wasi.wasm +0 -0
- package/dist/taglib-web.wasm +0 -0
- package/dist/taglib-wrapper.d.ts +0 -2
- package/dist/taglib-wrapper.js +1 -1
- package/package.json +5 -5
- package/dist/taglib_wasi.wasm +0 -0
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
const FIXED_PREFIX_LEN = 602;
|
|
2
|
+
const VERSION_OFFSET = 346;
|
|
3
|
+
const UMID_OFFSET = 348;
|
|
4
|
+
const UMID_LEN = 64;
|
|
5
|
+
const LOUDNESS_OFFSET = 412;
|
|
6
|
+
const LOUDNESS_UNSET = 32767;
|
|
7
|
+
function readFixedString(bytes, offset, len) {
|
|
8
|
+
let end = offset;
|
|
9
|
+
const max = Math.min(offset + len, bytes.length);
|
|
10
|
+
while (end < max && bytes[end] !== 0) end++;
|
|
11
|
+
let s = "";
|
|
12
|
+
for (let i = offset; i < end; i++) s += String.fromCharCode(bytes[i]);
|
|
13
|
+
return s;
|
|
14
|
+
}
|
|
15
|
+
function writeFixedString(bytes, offset, len, value) {
|
|
16
|
+
for (let i = 0; i < len; i++) {
|
|
17
|
+
bytes[offset + i] = i < value.length ? value.charCodeAt(i) & 255 : 0;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function clampInt16(n) {
|
|
21
|
+
return Math.max(-32768, Math.min(32767, Math.round(n)));
|
|
22
|
+
}
|
|
23
|
+
function loudnessRaw(v) {
|
|
24
|
+
return v === void 0 ? LOUDNESS_UNSET : clampInt16(v * 100);
|
|
25
|
+
}
|
|
26
|
+
function loudnessFromRaw(raw) {
|
|
27
|
+
return raw === LOUDNESS_UNSET ? void 0 : raw / 100;
|
|
28
|
+
}
|
|
29
|
+
function bytesToHex(bytes) {
|
|
30
|
+
let s = "";
|
|
31
|
+
for (const b of bytes) s += b.toString(16).padStart(2, "0");
|
|
32
|
+
return s;
|
|
33
|
+
}
|
|
34
|
+
function hexToBytes(hex, outLen) {
|
|
35
|
+
const clean = hex.replace(/[^0-9a-fA-F]/g, "");
|
|
36
|
+
const out = new Uint8Array(outLen);
|
|
37
|
+
for (let i = 0; i + 1 < clean.length + 1 && i / 2 < outLen; i += 2) {
|
|
38
|
+
const pair = clean.slice(i, i + 2);
|
|
39
|
+
if (pair.length === 2) out[i / 2] = parseInt(pair, 16);
|
|
40
|
+
}
|
|
41
|
+
return out;
|
|
42
|
+
}
|
|
43
|
+
function decodeBext(bytes) {
|
|
44
|
+
if (bytes.length < VERSION_OFFSET + 2) return void 0;
|
|
45
|
+
const dv = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
46
|
+
const timeRefLow = dv.getUint32(338, true);
|
|
47
|
+
const timeRefHigh = dv.getUint32(342, true);
|
|
48
|
+
const version = dv.getUint16(VERSION_OFFSET, true);
|
|
49
|
+
const result = {
|
|
50
|
+
description: readFixedString(bytes, 0, 256),
|
|
51
|
+
originator: readFixedString(bytes, 256, 32),
|
|
52
|
+
originatorReference: readFixedString(bytes, 288, 32),
|
|
53
|
+
originationDate: readFixedString(bytes, 320, 10),
|
|
54
|
+
originationTime: readFixedString(bytes, 330, 8),
|
|
55
|
+
timeReferenceSamples: BigInt(timeRefHigh) << 32n | BigInt(timeRefLow),
|
|
56
|
+
version,
|
|
57
|
+
codingHistory: bytes.length > FIXED_PREFIX_LEN ? readFixedString(
|
|
58
|
+
bytes,
|
|
59
|
+
FIXED_PREFIX_LEN,
|
|
60
|
+
bytes.length - FIXED_PREFIX_LEN
|
|
61
|
+
) : ""
|
|
62
|
+
};
|
|
63
|
+
if (version >= 1 && bytes.length >= UMID_OFFSET + UMID_LEN) {
|
|
64
|
+
result.umid = bytesToHex(
|
|
65
|
+
bytes.subarray(UMID_OFFSET, UMID_OFFSET + UMID_LEN)
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
if (version >= 2 && bytes.length >= LOUDNESS_OFFSET + 10) {
|
|
69
|
+
const lv = loudnessFromRaw(dv.getInt16(LOUDNESS_OFFSET, true));
|
|
70
|
+
const lr = loudnessFromRaw(dv.getInt16(LOUDNESS_OFFSET + 2, true));
|
|
71
|
+
const mtp = loudnessFromRaw(dv.getInt16(LOUDNESS_OFFSET + 4, true));
|
|
72
|
+
const mml = loudnessFromRaw(dv.getInt16(LOUDNESS_OFFSET + 6, true));
|
|
73
|
+
const msl = loudnessFromRaw(dv.getInt16(LOUDNESS_OFFSET + 8, true));
|
|
74
|
+
if (lv !== void 0) result.loudnessValueDb = lv;
|
|
75
|
+
if (lr !== void 0) result.loudnessRangeDb = lr;
|
|
76
|
+
if (mtp !== void 0) result.maxTruePeakLevelDbtp = mtp;
|
|
77
|
+
if (mml !== void 0) result.maxMomentaryLoudnessDb = mml;
|
|
78
|
+
if (msl !== void 0) result.maxShortTermLoudnessDb = msl;
|
|
79
|
+
}
|
|
80
|
+
return result;
|
|
81
|
+
}
|
|
82
|
+
function encodeBext(b) {
|
|
83
|
+
const codingHistory = b.codingHistory ?? "";
|
|
84
|
+
const bytes = new Uint8Array(FIXED_PREFIX_LEN + codingHistory.length);
|
|
85
|
+
const dv = new DataView(bytes.buffer);
|
|
86
|
+
const hasLoudness = b.loudnessValueDb !== void 0 || b.loudnessRangeDb !== void 0 || b.maxTruePeakLevelDbtp !== void 0 || b.maxMomentaryLoudnessDb !== void 0 || b.maxShortTermLoudnessDb !== void 0;
|
|
87
|
+
const version = Number.isInteger(b.version) ? b.version : hasLoudness ? 2 : b.umid ? 1 : 0;
|
|
88
|
+
writeFixedString(bytes, 0, 256, b.description ?? "");
|
|
89
|
+
writeFixedString(bytes, 256, 32, b.originator ?? "");
|
|
90
|
+
writeFixedString(bytes, 288, 32, b.originatorReference ?? "");
|
|
91
|
+
writeFixedString(bytes, 320, 10, b.originationDate ?? "");
|
|
92
|
+
writeFixedString(bytes, 330, 8, b.originationTime ?? "");
|
|
93
|
+
const tr = b.timeReferenceSamples ?? 0n;
|
|
94
|
+
dv.setUint32(338, Number(tr & 0xffffffffn), true);
|
|
95
|
+
dv.setUint32(342, Number(tr >> 32n & 0xffffffffn), true);
|
|
96
|
+
dv.setUint16(VERSION_OFFSET, version, true);
|
|
97
|
+
if (version >= 1 && b.umid) {
|
|
98
|
+
bytes.set(hexToBytes(b.umid, UMID_LEN), UMID_OFFSET);
|
|
99
|
+
}
|
|
100
|
+
if (version >= 2) {
|
|
101
|
+
dv.setInt16(LOUDNESS_OFFSET, loudnessRaw(b.loudnessValueDb), true);
|
|
102
|
+
dv.setInt16(LOUDNESS_OFFSET + 2, loudnessRaw(b.loudnessRangeDb), true);
|
|
103
|
+
dv.setInt16(LOUDNESS_OFFSET + 4, loudnessRaw(b.maxTruePeakLevelDbtp), true);
|
|
104
|
+
dv.setInt16(
|
|
105
|
+
LOUDNESS_OFFSET + 6,
|
|
106
|
+
loudnessRaw(b.maxMomentaryLoudnessDb),
|
|
107
|
+
true
|
|
108
|
+
);
|
|
109
|
+
dv.setInt16(
|
|
110
|
+
LOUDNESS_OFFSET + 8,
|
|
111
|
+
loudnessRaw(b.maxShortTermLoudnessDb),
|
|
112
|
+
true
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
writeFixedString(
|
|
116
|
+
bytes,
|
|
117
|
+
FIXED_PREFIX_LEN,
|
|
118
|
+
codingHistory.length,
|
|
119
|
+
codingHistory
|
|
120
|
+
);
|
|
121
|
+
return bytes;
|
|
122
|
+
}
|
|
123
|
+
export {
|
|
124
|
+
decodeBext,
|
|
125
|
+
encodeBext
|
|
126
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"encoder.d.ts","sourceRoot":"","sources":["../../../src/msgpack/encoder.ts"],"names":[],"mappings":"AAAA,qFAAqF;AAErF,OAAO,EAAU,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAE/D,OAAO,KAAK,EACV,eAAe,EACf,WAAW,EACX,OAAO,EACP,WAAW,EACZ,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"encoder.d.ts","sourceRoot":"","sources":["../../../src/msgpack/encoder.ts"],"names":[],"mappings":"AAAA,qFAAqF;AAErF,OAAO,EAAU,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAE/D,OAAO,KAAK,EACV,eAAe,EACf,WAAW,EACX,OAAO,EACP,WAAW,EACZ,MAAM,aAAa,CAAC;AAsBrB,wBAAgB,aAAa,CAAC,OAAO,EAAE,WAAW,GAAG,UAAU,CAiB9D;AAED,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,eAAe,GAAG,UAAU,CAS7E;AAED,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,WAAW,GAAG,UAAU,CAStE;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,UAAU,CAe1D;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,UAAU,CAelE;AAED,wBAAgB,iBAAiB,CAAC,CAAC,EACjC,IAAI,EAAE,CAAC,EACP,OAAO,GAAE,OAAO,CAAC,cAAc,CAAM,GACpC,UAAU,CAUZ;AAED,wBAAgB,wBAAwB,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,UAAU,CAe/D;AAqBD,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,WAAW,EAAE,GAAG,UAAU,CAc1E;AAED,wBAAiB,uBAAuB,CAAC,CAAC,EACxC,YAAY,EAAE,QAAQ,CAAC,CAAC,CAAC,GACxB,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,OAAO,CAAC,CActC;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAS7D;AAED,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,IAAI,CAAC,WAAW,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC,GAC1E,UAAU,CAeZ;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAW7D;AAED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,OAAO,GAAG;IACxD,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;CAC1B,CAaA"}
|
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
import { encode } from "@msgpack/msgpack";
|
|
2
2
|
import { errorMessage, MetadataError } from "../errors/classes.js";
|
|
3
3
|
import { toTagLibKey } from "../constants/properties.js";
|
|
4
|
-
const PASSTHROUGH_KEYS = /* @__PURE__ */ new Set([
|
|
4
|
+
const PASSTHROUGH_KEYS = /* @__PURE__ */ new Set([
|
|
5
|
+
"pictures",
|
|
6
|
+
"ratings",
|
|
7
|
+
"lyrics",
|
|
8
|
+
"chapters",
|
|
9
|
+
"_mp4ChapterStyle",
|
|
10
|
+
"bextData",
|
|
11
|
+
"ixml"
|
|
12
|
+
]);
|
|
5
13
|
const MSGPACK_ENCODE_OPTIONS = {
|
|
6
14
|
sortKeys: false,
|
|
7
15
|
forceFloat32: false,
|
|
@@ -38,7 +38,7 @@ async function loadModule(wasmType, runtime, options) {
|
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
async function loadWasiModuleWithFallback(runtime, options) {
|
|
41
|
-
const defaultWasmPath = resolveWasmPath("../../../
|
|
41
|
+
const defaultWasmPath = resolveWasmPath("../../../taglib-wasi.wasm");
|
|
42
42
|
try {
|
|
43
43
|
const { loadWasiHost } = await import("../wasi-host-loader.js");
|
|
44
44
|
const wasiModule = await loadWasiHost({
|
|
@@ -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, RawChapter, 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;
|
|
@@ -33,6 +35,12 @@ export declare class WasiFileHandle implements FileHandle {
|
|
|
33
35
|
setPictures(pictures: RawPicture[]): void;
|
|
34
36
|
addPicture(picture: RawPicture): void;
|
|
35
37
|
removePictures(): void;
|
|
38
|
+
getChapters(): RawChapter[];
|
|
39
|
+
setChapters(chapters: RawChapter[], mp4ChapterStyle: string): void;
|
|
40
|
+
getBextData(): Uint8Array | undefined;
|
|
41
|
+
setBextData(data: Uint8Array | null): void;
|
|
42
|
+
getIxml(): string | undefined;
|
|
43
|
+
setIxml(data: string | null): void;
|
|
36
44
|
getRatings(): {
|
|
37
45
|
rating: number;
|
|
38
46
|
email: string;
|
|
@@ -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,
|
|
1
|
+
{"version":3,"file":"file-handle.d.ts","sourceRoot":"","sources":["../../../../src/runtime/wasi-adapter/file-handle.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AACxE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAEV,eAAe,EAEhB,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AA8DhE,qBAAa,cAAe,YAAW,UAAU;IAC/C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAa;IAClC,OAAO,CAAC,QAAQ,CAA2B;IAC3C,OAAO,CAAC,QAAQ,CAAuB;IACvC,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,IAAI,EAAE,MAAM,GAAG,OAAO;IAWnC,OAAO,IAAI,OAAO;IAMlB,IAAI,IAAI,OAAO;IAqBf,UAAU,IAAI,YAAY;IAc1B,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,IAAI;IAK7C,kBAAkB,IAAI,eAAe,GAAG,IAAI;IA+B5C,SAAS,IAAI,MAAM;IA2DnB,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;IAehB,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,WAAW,IAAI,UAAU,EAAE;IAK3B,WAAW,CAAC,QAAQ,EAAE,UAAU,EAAE,EAAE,eAAe,EAAE,MAAM,GAAG,IAAI;IASlE,WAAW,IAAI,UAAU,GAAG,SAAS;IAKrC,WAAW,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,GAAG,IAAI;IAS1C,OAAO,IAAI,MAAM,GAAG,SAAS;IAM7B,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAKlC,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"}
|
|
@@ -24,9 +24,18 @@ const AUDIO_KEYS = /* @__PURE__ */ new Set([
|
|
|
24
24
|
"lengthMs",
|
|
25
25
|
"mpegLayer",
|
|
26
26
|
"mpegVersion",
|
|
27
|
+
"outputGainDb",
|
|
27
28
|
"sampleRate"
|
|
28
29
|
]);
|
|
29
|
-
const INTERNAL_KEYS = /* @__PURE__ */ new Set([
|
|
30
|
+
const INTERNAL_KEYS = /* @__PURE__ */ new Set([
|
|
31
|
+
"pictures",
|
|
32
|
+
"ratings",
|
|
33
|
+
"lyrics",
|
|
34
|
+
"chapters",
|
|
35
|
+
"_mp4ChapterStyle",
|
|
36
|
+
"bextData",
|
|
37
|
+
"ixml"
|
|
38
|
+
]);
|
|
30
39
|
const CONTAINER_TO_FORMAT = {
|
|
31
40
|
MP3: "MP3",
|
|
32
41
|
MP4: "MP4",
|
|
@@ -43,6 +52,10 @@ const NUMERIC_FIELD_ALIASES = {
|
|
|
43
52
|
date: "year",
|
|
44
53
|
trackNumber: "track"
|
|
45
54
|
};
|
|
55
|
+
function firstString(v) {
|
|
56
|
+
if (Array.isArray(v)) return v[0] ?? "";
|
|
57
|
+
return v || "";
|
|
58
|
+
}
|
|
46
59
|
class WasiFileHandle {
|
|
47
60
|
constructor(wasiModule) {
|
|
48
61
|
__publicField(this, "wasi");
|
|
@@ -95,67 +108,44 @@ class WasiFileHandle {
|
|
|
95
108
|
}
|
|
96
109
|
return false;
|
|
97
110
|
}
|
|
98
|
-
|
|
111
|
+
getTagData() {
|
|
99
112
|
this.checkNotDestroyed();
|
|
100
|
-
|
|
101
|
-
return this.createTagWrapper({});
|
|
102
|
-
}
|
|
103
|
-
return this.createTagWrapper(this.tagData);
|
|
104
|
-
}
|
|
105
|
-
createTagWrapper(data) {
|
|
106
|
-
const firstString = (v) => {
|
|
107
|
-
if (Array.isArray(v)) return v[0] ?? "";
|
|
108
|
-
return v || "";
|
|
109
|
-
};
|
|
113
|
+
const d = this.tagData ?? {};
|
|
110
114
|
return {
|
|
111
|
-
title:
|
|
112
|
-
artist:
|
|
113
|
-
album:
|
|
114
|
-
comment:
|
|
115
|
-
genre:
|
|
116
|
-
year:
|
|
117
|
-
track:
|
|
118
|
-
setTitle: (value) => {
|
|
119
|
-
this.tagData = { ...this.tagData, title: value };
|
|
120
|
-
},
|
|
121
|
-
setArtist: (value) => {
|
|
122
|
-
this.tagData = { ...this.tagData, artist: value };
|
|
123
|
-
},
|
|
124
|
-
setAlbum: (value) => {
|
|
125
|
-
this.tagData = { ...this.tagData, album: value };
|
|
126
|
-
},
|
|
127
|
-
setComment: (value) => {
|
|
128
|
-
this.tagData = { ...this.tagData, comment: value };
|
|
129
|
-
},
|
|
130
|
-
setGenre: (value) => {
|
|
131
|
-
this.tagData = { ...this.tagData, genre: value };
|
|
132
|
-
},
|
|
133
|
-
setYear: (value) => {
|
|
134
|
-
this.tagData = { ...this.tagData, year: value };
|
|
135
|
-
},
|
|
136
|
-
setTrack: (value) => {
|
|
137
|
-
this.tagData = { ...this.tagData, track: value };
|
|
138
|
-
}
|
|
115
|
+
title: firstString(d.title),
|
|
116
|
+
artist: firstString(d.artist),
|
|
117
|
+
album: firstString(d.album),
|
|
118
|
+
comment: firstString(d.comment),
|
|
119
|
+
genre: firstString(d.genre),
|
|
120
|
+
year: d.year || 0,
|
|
121
|
+
track: d.track || 0
|
|
139
122
|
};
|
|
140
123
|
}
|
|
124
|
+
setTagData(data) {
|
|
125
|
+
this.checkNotDestroyed();
|
|
126
|
+
this.tagData = { ...this.tagData, ...data };
|
|
127
|
+
}
|
|
141
128
|
getAudioProperties() {
|
|
142
129
|
this.checkNotDestroyed();
|
|
143
130
|
if (!this.tagData || !("sampleRate" in this.tagData)) return null;
|
|
144
|
-
const
|
|
131
|
+
const d = this.tagData;
|
|
132
|
+
const containerFormat = d.containerFormat || "unknown";
|
|
133
|
+
const mpegVersion = d.mpegVersion ?? 0;
|
|
134
|
+
const formatVersion = d.formatVersion ?? 0;
|
|
145
135
|
return {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
bitrate:
|
|
149
|
-
sampleRate:
|
|
150
|
-
channels:
|
|
151
|
-
bitsPerSample:
|
|
152
|
-
codec:
|
|
153
|
-
containerFormat
|
|
154
|
-
isLossless:
|
|
155
|
-
mpegVersion
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
136
|
+
duration: d.length ?? 0,
|
|
137
|
+
durationMs: d.lengthMs ?? 0,
|
|
138
|
+
bitrate: d.bitrate ?? 0,
|
|
139
|
+
sampleRate: d.sampleRate ?? 0,
|
|
140
|
+
channels: d.channels ?? 0,
|
|
141
|
+
bitsPerSample: d.bitsPerSample ?? 0,
|
|
142
|
+
codec: d.codec || "unknown",
|
|
143
|
+
containerFormat,
|
|
144
|
+
isLossless: d.isLossless ?? false,
|
|
145
|
+
...mpegVersion > 0 ? { mpegVersion, mpegLayer: d.mpegLayer ?? 0 } : {},
|
|
146
|
+
...containerFormat === "MP4" || containerFormat === "ASF" ? { isEncrypted: d.isEncrypted ?? false } : {},
|
|
147
|
+
...formatVersion > 0 ? { formatVersion } : {},
|
|
148
|
+
...d.outputGainDb !== void 0 ? { outputGainDb: d.outputGainDb } : {}
|
|
159
149
|
};
|
|
160
150
|
}
|
|
161
151
|
getFormat() {
|
|
@@ -295,6 +285,35 @@ class WasiFileHandle {
|
|
|
295
285
|
this.checkNotDestroyed();
|
|
296
286
|
this.tagData = { ...this.tagData, pictures: [] };
|
|
297
287
|
}
|
|
288
|
+
getChapters() {
|
|
289
|
+
this.checkNotDestroyed();
|
|
290
|
+
return this.tagData?.chapters ?? [];
|
|
291
|
+
}
|
|
292
|
+
setChapters(chapters, mp4ChapterStyle) {
|
|
293
|
+
this.checkNotDestroyed();
|
|
294
|
+
this.tagData = {
|
|
295
|
+
...this.tagData,
|
|
296
|
+
_mp4ChapterStyle: mp4ChapterStyle,
|
|
297
|
+
chapters
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
getBextData() {
|
|
301
|
+
this.checkNotDestroyed();
|
|
302
|
+
return this.tagData?.bextData ?? void 0;
|
|
303
|
+
}
|
|
304
|
+
setBextData(data) {
|
|
305
|
+
this.checkNotDestroyed();
|
|
306
|
+
this.tagData = { ...this.tagData, bextData: data };
|
|
307
|
+
}
|
|
308
|
+
getIxml() {
|
|
309
|
+
this.checkNotDestroyed();
|
|
310
|
+
const v = this.tagData?.ixml;
|
|
311
|
+
return typeof v === "string" && v.length > 0 ? v : void 0;
|
|
312
|
+
}
|
|
313
|
+
setIxml(data) {
|
|
314
|
+
this.checkNotDestroyed();
|
|
315
|
+
this.tagData = { ...this.tagData, ixml: data };
|
|
316
|
+
}
|
|
298
317
|
getRatings() {
|
|
299
318
|
this.checkNotDestroyed();
|
|
300
319
|
return this.tagData?.ratings ?? [];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @fileoverview WASI host loader for in-process filesystem access
|
|
3
3
|
*
|
|
4
|
-
* Loads the
|
|
4
|
+
* Loads the taglib-wasi.wasm binary with real WASI filesystem
|
|
5
5
|
* implementations, enabling efficient seek-based file I/O.
|
|
6
6
|
*/
|
|
7
7
|
import type { FileSystemProvider } from "./wasi-fs-provider.js";
|
|
@@ -22,7 +22,7 @@ async function resolveFs(provided) {
|
|
|
22
22
|
}
|
|
23
23
|
async function loadWasiHost(config) {
|
|
24
24
|
const defaultPath = (() => {
|
|
25
|
-
const url = new URL("../../
|
|
25
|
+
const url = new URL("../../taglib-wasi.wasm", import.meta.url);
|
|
26
26
|
return url.protocol === "file:" ? fileUrlToPath(url) : url.href;
|
|
27
27
|
})();
|
|
28
28
|
const wasmPath = config.wasmPath ?? defaultPath;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audio-file-base.d.ts","sourceRoot":"","sources":["../../../src/taglib/audio-file-base.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC3D,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"audio-file-base.d.ts","sourceRoot":"","sources":["../../../src/taglib/audio-file-base.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC3D,OAAO,KAAK,EACV,eAAe,EACf,QAAQ,EACR,WAAW,EACX,WAAW,EACZ,MAAM,aAAa,CAAC;AAGrB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAEhE;;;;;GAKG;AACH,8BAAsB,iBAAiB;IASnC,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,YAAY;IARzC,SAAS,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;IACxC,SAAS,CAAC,qBAAqB,EAAE,eAAe,GAAG,IAAI,CAAQ;IAC/D,SAAS,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IACvC,SAAS,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,UAAU,GAAG,WAAW,GAAG,IAAI,CAAC;IACpE,SAAS,CAAC,iBAAiB,EAAE,OAAO,CAAS;IAC7C,SAAS,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,WAAW,CAAC;gBAG/B,MAAM,EAAE,YAAY,EACvC,UAAU,EAAE,UAAU,EACtB,UAAU,CAAC,EAAE,MAAM,EACnB,cAAc,CAAC,EAAE,MAAM,GAAG,UAAU,GAAG,WAAW,GAAG,IAAI,EACzD,iBAAiB,GAAE,OAAe,EAClC,kBAAkB,CAAC,EAAE,WAAW;IASlC,SAAS,KAAK,MAAM,IAAI,UAAU,CAKjC;IAED,SAAS,IAAI,QAAQ;IAIrB,QAAQ,CAAC,CAAC,SAAS,QAAQ,EAAE,MAAM,EAAE,CAAC,GAAG,IAAI,IAAI,cAAc,CAAC,CAAC,CAAC;IAIlE,GAAG,IAAI,UAAU;IAgEjB,eAAe,IAAI,eAAe,GAAG,SAAS;IAO9C,UAAU,IAAI,WAAW;IAIzB,aAAa,CAAC,UAAU,EAAE,WAAW,GAAG,IAAI;IAQ5C,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAK5C,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAI7C,KAAK,IAAI,OAAO;IAIhB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAQ3C,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAO5C,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAOhC,OAAO,IAAI,OAAO;IAIlB,OAAO,IAAI,IAAI;IAQf,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI;CAGzB"}
|
|
@@ -31,61 +31,63 @@ class BaseAudioFileImpl {
|
|
|
31
31
|
return this.getFormat() === format;
|
|
32
32
|
}
|
|
33
33
|
tag() {
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
throw new MetadataError(
|
|
37
|
-
"read",
|
|
38
|
-
"Tag may be corrupted or format not fully supported"
|
|
39
|
-
);
|
|
40
|
-
}
|
|
34
|
+
const handle = this.handle;
|
|
35
|
+
let data = handle.getTagData();
|
|
41
36
|
const tag = {
|
|
42
37
|
get title() {
|
|
43
|
-
return
|
|
38
|
+
return data.title;
|
|
44
39
|
},
|
|
45
40
|
get artist() {
|
|
46
|
-
return
|
|
41
|
+
return data.artist;
|
|
47
42
|
},
|
|
48
43
|
get album() {
|
|
49
|
-
return
|
|
44
|
+
return data.album;
|
|
50
45
|
},
|
|
51
46
|
get comment() {
|
|
52
|
-
return
|
|
47
|
+
return data.comment;
|
|
53
48
|
},
|
|
54
49
|
get genre() {
|
|
55
|
-
return
|
|
50
|
+
return data.genre;
|
|
56
51
|
},
|
|
57
52
|
get year() {
|
|
58
|
-
return
|
|
53
|
+
return data.year;
|
|
59
54
|
},
|
|
60
55
|
get track() {
|
|
61
|
-
return
|
|
56
|
+
return data.track;
|
|
62
57
|
},
|
|
63
58
|
setTitle: (value) => {
|
|
64
|
-
|
|
59
|
+
handle.setTagData({ title: value });
|
|
60
|
+
data = handle.getTagData();
|
|
65
61
|
return tag;
|
|
66
62
|
},
|
|
67
63
|
setArtist: (value) => {
|
|
68
|
-
|
|
64
|
+
handle.setTagData({ artist: value });
|
|
65
|
+
data = handle.getTagData();
|
|
69
66
|
return tag;
|
|
70
67
|
},
|
|
71
68
|
setAlbum: (value) => {
|
|
72
|
-
|
|
69
|
+
handle.setTagData({ album: value });
|
|
70
|
+
data = handle.getTagData();
|
|
73
71
|
return tag;
|
|
74
72
|
},
|
|
75
73
|
setComment: (value) => {
|
|
76
|
-
|
|
74
|
+
handle.setTagData({ comment: value });
|
|
75
|
+
data = handle.getTagData();
|
|
77
76
|
return tag;
|
|
78
77
|
},
|
|
79
78
|
setGenre: (value) => {
|
|
80
|
-
|
|
79
|
+
handle.setTagData({ genre: value });
|
|
80
|
+
data = handle.getTagData();
|
|
81
81
|
return tag;
|
|
82
82
|
},
|
|
83
83
|
setYear: (value) => {
|
|
84
|
-
|
|
84
|
+
handle.setTagData({ year: value });
|
|
85
|
+
data = handle.getTagData();
|
|
85
86
|
return tag;
|
|
86
87
|
},
|
|
87
88
|
setTrack: (value) => {
|
|
88
|
-
|
|
89
|
+
handle.setTagData({ track: value });
|
|
90
|
+
data = handle.getTagData();
|
|
89
91
|
return tag;
|
|
90
92
|
}
|
|
91
93
|
};
|
|
@@ -93,28 +95,9 @@ class BaseAudioFileImpl {
|
|
|
93
95
|
}
|
|
94
96
|
audioProperties() {
|
|
95
97
|
if (!this.cachedAudioProperties) {
|
|
96
|
-
|
|
97
|
-
if (!propsWrapper) {
|
|
98
|
-
return void 0;
|
|
99
|
-
}
|
|
100
|
-
const containerFormat = propsWrapper.containerFormat() || "unknown";
|
|
101
|
-
const mpegVersion = propsWrapper.mpegVersion();
|
|
102
|
-
const formatVersion = propsWrapper.formatVersion();
|
|
103
|
-
this.cachedAudioProperties = {
|
|
104
|
-
duration: propsWrapper.lengthInSeconds(),
|
|
105
|
-
bitrate: propsWrapper.bitrate(),
|
|
106
|
-
sampleRate: propsWrapper.sampleRate(),
|
|
107
|
-
channels: propsWrapper.channels(),
|
|
108
|
-
bitsPerSample: propsWrapper.bitsPerSample(),
|
|
109
|
-
codec: propsWrapper.codec() || "unknown",
|
|
110
|
-
containerFormat,
|
|
111
|
-
isLossless: propsWrapper.isLossless(),
|
|
112
|
-
...mpegVersion > 0 ? { mpegVersion, mpegLayer: propsWrapper.mpegLayer() } : {},
|
|
113
|
-
...containerFormat === "MP4" || containerFormat === "ASF" ? { isEncrypted: propsWrapper.isEncrypted() } : {},
|
|
114
|
-
...formatVersion > 0 ? { formatVersion } : {}
|
|
115
|
-
};
|
|
98
|
+
this.cachedAudioProperties = this.handle.getAudioProperties() ?? null;
|
|
116
99
|
}
|
|
117
|
-
return this.cachedAudioProperties;
|
|
100
|
+
return this.cachedAudioProperties ?? void 0;
|
|
118
101
|
}
|
|
119
102
|
properties() {
|
|
120
103
|
return remapKeysFromTagLib(this.handle.getProperties());
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview BWF (`bext` + iXML) operations, factored out of AudioFileImpl
|
|
3
|
+
* to keep that file under the size limit. Each function takes the raw FileHandle
|
|
4
|
+
* plus the already-resolved format string (for the unsupported-format guard).
|
|
5
|
+
*/
|
|
6
|
+
import type { FileHandle } from "../wasm.js";
|
|
7
|
+
import type { BroadcastAudioExtension } from "../types/bwf.js";
|
|
8
|
+
export declare function getBextData(handle: FileHandle): Uint8Array | undefined;
|
|
9
|
+
export declare function setBextData(handle: FileHandle, format: string, data: Uint8Array | null): void;
|
|
10
|
+
export declare function getBext(handle: FileHandle): BroadcastAudioExtension | undefined;
|
|
11
|
+
export declare function setBext(handle: FileHandle, format: string, bext: BroadcastAudioExtension): void;
|
|
12
|
+
export declare function getIxml(handle: FileHandle): string | undefined;
|
|
13
|
+
export declare function setIxml(handle: FileHandle, format: string, data: string | null): void;
|
|
14
|
+
//# sourceMappingURL=audio-file-bwf.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audio-file-bwf.d.ts","sourceRoot":"","sources":["../../../src/taglib/audio-file-bwf.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAc/D,wBAAgB,WAAW,CAAC,MAAM,EAAE,UAAU,GAAG,UAAU,GAAG,SAAS,CAGtE;AAED,wBAAgB,WAAW,CACzB,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,UAAU,GAAG,IAAI,GACtB,IAAI,CAGN;AAED,wBAAgB,OAAO,CACrB,MAAM,EAAE,UAAU,GACjB,uBAAuB,GAAG,SAAS,CAGrC;AAED,wBAAgB,OAAO,CACrB,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,uBAAuB,GAC5B,IAAI,CAGN;AAED,wBAAgB,OAAO,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,GAAG,SAAS,CAE9D;AAED,wBAAgB,OAAO,CACrB,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,GAAG,IAAI,GAClB,IAAI,CAGN"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { decodeBext, encodeBext } from "../bwf/bext.js";
|
|
2
|
+
import { UnsupportedFormatError } from "../errors.js";
|
|
3
|
+
const BWF_FORMATS = /* @__PURE__ */ new Set(["WAV", "FLAC"]);
|
|
4
|
+
function requireBwf(format) {
|
|
5
|
+
if (!BWF_FORMATS.has(format)) {
|
|
6
|
+
throw new UnsupportedFormatError(format, ["WAV", "FLAC"], {
|
|
7
|
+
operation: "BWF metadata"
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
function getBextData(handle) {
|
|
12
|
+
const raw = handle.getBextData();
|
|
13
|
+
return raw && raw.length > 0 ? raw : void 0;
|
|
14
|
+
}
|
|
15
|
+
function setBextData(handle, format, data) {
|
|
16
|
+
requireBwf(format);
|
|
17
|
+
handle.setBextData(data);
|
|
18
|
+
}
|
|
19
|
+
function getBext(handle) {
|
|
20
|
+
const raw = handle.getBextData();
|
|
21
|
+
return raw && raw.length > 0 ? decodeBext(raw) : void 0;
|
|
22
|
+
}
|
|
23
|
+
function setBext(handle, format, bext) {
|
|
24
|
+
requireBwf(format);
|
|
25
|
+
handle.setBextData(encodeBext(bext));
|
|
26
|
+
}
|
|
27
|
+
function getIxml(handle) {
|
|
28
|
+
return handle.getIxml();
|
|
29
|
+
}
|
|
30
|
+
function setIxml(handle, format, data) {
|
|
31
|
+
requireBwf(format);
|
|
32
|
+
handle.setIxml(data);
|
|
33
|
+
}
|
|
34
|
+
export {
|
|
35
|
+
getBext,
|
|
36
|
+
getBextData,
|
|
37
|
+
getIxml,
|
|
38
|
+
setBext,
|
|
39
|
+
setBextData,
|
|
40
|
+
setIxml
|
|
41
|
+
};
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { FileHandle, TagLibModule } from "../wasm.js";
|
|
2
2
|
import type { OpenOptions, Picture } from "../types.js";
|
|
3
|
+
import type { Chapter, SetChaptersOptions } from "../types/chapters.js";
|
|
4
|
+
import type { BroadcastAudioExtension } from "../types/bwf.js";
|
|
3
5
|
import type { Rating } from "../constants/complex-properties.js";
|
|
4
6
|
import type { AudioFile } from "./audio-file-interface.js";
|
|
5
7
|
import { BaseAudioFileImpl } from "./audio-file-base.js";
|
|
@@ -19,6 +21,14 @@ export declare class AudioFileImpl extends BaseAudioFileImpl implements AudioFil
|
|
|
19
21
|
setPictures(pictures: Picture[]): void;
|
|
20
22
|
addPicture(picture: Picture): void;
|
|
21
23
|
removePictures(): void;
|
|
24
|
+
getChapters(): Chapter[];
|
|
25
|
+
setChapters(chapters: Chapter[], options?: SetChaptersOptions): void;
|
|
26
|
+
getBext(): BroadcastAudioExtension | undefined;
|
|
27
|
+
setBext(bext: BroadcastAudioExtension): void;
|
|
28
|
+
getBextData(): Uint8Array | undefined;
|
|
29
|
+
setBextData(data: Uint8Array | null): void;
|
|
30
|
+
getIxml(): string | undefined;
|
|
31
|
+
setIxml(data: string | null): void;
|
|
22
32
|
getRatings(): Rating[];
|
|
23
33
|
setRatings(ratings: Rating[]): void;
|
|
24
34
|
getRating(): number | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audio-file-impl.d.ts","sourceRoot":"","sources":["../../../src/taglib/audio-file-impl.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,
|
|
1
|
+
{"version":3,"file":"audio-file-impl.d.ts","sourceRoot":"","sources":["../../../src/taglib/audio-file-impl.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAc,YAAY,EAAE,MAAM,YAAY,CAAC;AACvE,OAAO,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAExD,OAAO,KAAK,EAAE,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AACxE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAE/D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oCAAoC,CAAC;AAQjE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAqCzD;;;;;GAKG;AACH,qBAAa,aAAc,SAAQ,iBAAkB,YAAW,SAAS;IACvE,OAAO,CAAC,cAAc,CAA2B;gBAG/C,MAAM,EAAE,YAAY,EACpB,UAAU,EAAE,UAAU,EACtB,UAAU,CAAC,EAAE,MAAM,EACnB,cAAc,CAAC,EAAE,MAAM,GAAG,UAAU,GAAG,WAAW,GAAG,IAAI,EACzD,iBAAiB,GAAE,OAAe,EAClC,kBAAkB,CAAC,EAAE,WAAW;IAYlC,IAAI,IAAI,OAAO;IAYf,aAAa,IAAI,UAAU;IAgBrB,UAAU,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAmE9C,WAAW,IAAI,OAAO,EAAE;IAUxB,WAAW,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,IAAI;IAStC,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IASlC,cAAc,IAAI,IAAI;IAItB,WAAW,IAAI,OAAO,EAAE;IAYxB,WAAW,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,IAAI;IAkBpE,OAAO,IAAI,uBAAuB,GAAG,SAAS;IAI9C,OAAO,CAAC,IAAI,EAAE,uBAAuB,GAAG,IAAI;IAI5C,WAAW,IAAI,UAAU,GAAG,SAAS;IAIrC,WAAW,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,GAAG,IAAI;IAI1C,OAAO,IAAI,MAAM,GAAG,SAAS;IAI7B,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAIlC,UAAU,IAAI,MAAM,EAAE;IAUtB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI;IAQnC,SAAS,IAAI,MAAM,GAAG,SAAS;IAK/B,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI;CAGhD"}
|