43 lines
1.4 KiB
JavaScript
43 lines
1.4 KiB
JavaScript
const version = document.querySelector('#frontend-version')?.textContent || 'dev';
|
|
const workerUrl = `/tts/piper-wasm-v1/piper-worker.js?v=${encodeURIComponent(version)}`;
|
|
let worker;
|
|
let requestId = 0;
|
|
const pending = new Map();
|
|
|
|
function getWorker() {
|
|
if (worker) return worker;
|
|
worker = new Worker(workerUrl);
|
|
worker.onmessage = event => {
|
|
const message = event.data || {};
|
|
const request = pending.get(message.id);
|
|
if (!request) return;
|
|
if (message.type === 'progress') {
|
|
request.onProgress?.(message.progress);
|
|
} else {
|
|
pending.delete(message.id);
|
|
if (message.type === 'audio') request.resolve(new Blob([message.audio], {type: 'audio/x-wav'}));
|
|
else request.reject(new Error(message.error || 'Piper-arbetaren misslyckades.'));
|
|
}
|
|
};
|
|
worker.onerror = event => {
|
|
const error = new Error(event.message || 'Piper-arbetaren kunde inte startas.');
|
|
for (const request of pending.values()) request.reject(error);
|
|
pending.clear();
|
|
worker?.terminate();
|
|
worker = null;
|
|
};
|
|
return worker;
|
|
}
|
|
|
|
window.GamePiper = {
|
|
voiceId: 'sv_SE-nst-medium',
|
|
synthesize(text, onProgress) {
|
|
return new Promise((resolve, reject) => {
|
|
const id = ++requestId;
|
|
pending.set(id, {resolve, reject, onProgress});
|
|
try { getWorker().postMessage({id, text: String(text)}); }
|
|
catch (error) { pending.delete(id); reject(error); }
|
|
});
|
|
},
|
|
};
|