UNPKG

taglib-wasm

Version:

TagLib-Wasm is the universal tagging library for TypeScript/JavaScript platforms: Browsers, Node.js, Deno, Bun, Cloudflare Workers, and Electron apps

122 lines (121 loc) 4.08 kB
function isValidBitrateMode(value) { return value === "CBR" || value === "VBR" || value === "ABR"; } function wrapEmbindHandle(raw) { const stagedId3v2Frames = {}; const overrides = { getTagData() { const tw = raw.getTag(); return { title: tw.title(), artist: tw.artist(), album: tw.album(), comment: tw.comment(), genre: tw.genre(), year: tw.year(), track: tw.track() }; }, setTagData(data) { const tw = raw.getTag(); if (data.title !== void 0) tw.setTitle(data.title); if (data.artist !== void 0) tw.setArtist(data.artist); if (data.album !== void 0) tw.setAlbum(data.album); if (data.comment !== void 0) tw.setComment(data.comment); if (data.genre !== void 0) tw.setGenre(data.genre); if (data.year !== void 0) tw.setYear(data.year); if (data.track !== void 0) tw.setTrack(data.track); }, getBextData() { const v = raw.getBextData(); if (v === void 0 || v === null) return void 0; const u8 = v instanceof Uint8Array ? v : new Uint8Array(v); return u8.length > 0 ? u8 : void 0; }, setBextData(data) { raw.setBextData(data ?? null); }, getIxml() { const v = raw.getIxml(); return typeof v === "string" && v.length > 0 ? v : void 0; }, setIxml(data) { raw.setIxml( data ?? null ); }, // Emscripten exposes USLT only through the PropertyMap "LYRICS" key (no // dedicated Embind binding), so bridge get/setLyrics to get/setProperties. // Text only — language/description are not surfaced by the PropertyMap. getLyrics() { const props = raw.getProperties(); return (props["LYRICS"] ?? []).map((text) => ({ text, description: "", language: "" })); }, setLyrics(lyrics) { const handle = raw; const props = handle.getProperties(); if (lyrics.length > 0) props["LYRICS"] = lyrics.map((l) => l.text); else delete props["LYRICS"]; handle.setProperties(props); }, setId3v2Frames(id, data) { stagedId3v2Frames[id] = data.map((d) => new Uint8Array(d)); raw.setId3v2Frames(id, data); }, removeId3v2Frames(id) { stagedId3v2Frames[id] = []; raw.removeId3v2Frames(id); }, getStagedId3v2Frames() { return Object.keys(stagedId3v2Frames).length > 0 ? { ...stagedId3v2Frames } : void 0; }, hasId3Tags() { const v = raw.hasId3Tags(); if (!v || typeof v !== "object") return { v1: false, v2: false }; const o = v; return { v1: o.v1 === true, v2: o.v2 === true }; }, stripId3Tags(opts) { raw.stripId3Tags(opts); }, getAudioProperties() { const pw = raw.getAudioProperties(); if (!pw) return null; const containerFormat = pw.containerFormat() || "unknown"; const codec = pw.codec() || "unknown"; const mpegVersion = pw.mpegVersion(); const formatVersion = pw.formatVersion(); const bitrateMode = pw.bitrateMode(); return { duration: pw.lengthInSeconds(), durationMs: pw.lengthInMilliseconds(), bitrate: pw.bitrate(), sampleRate: pw.sampleRate(), channels: pw.channels(), bitsPerSample: pw.bitsPerSample(), codec, containerFormat, isLossless: pw.isLossless(), ...mpegVersion > 0 ? { mpegVersion, mpegLayer: pw.mpegLayer() } : {}, ...containerFormat === "MP4" || containerFormat === "ASF" ? { isEncrypted: pw.isEncrypted() } : {}, ...formatVersion > 0 ? { formatVersion } : {}, ...isValidBitrateMode(bitrateMode) ? { bitrateMode } : {}, ...codec === "Opus" ? { outputGainDb: pw.outputGainDb() } : {} }; } }; return new Proxy(raw, { get(target, prop, receiver) { if (prop in overrides) return overrides[prop]; const value = Reflect.get(target, prop, receiver); return typeof value === "function" ? value.bind(target) : value; } }); } export { wrapEmbindHandle };