Blame Raw
Cohee · e3f41666 · · 113 lines (3.1 KB)
1 contributor
1// kokoro-worker.js
2/** @type {import('./lib/kokoro.web.js').KokoroTTS} */
3let tts = null;
4/** @type {boolean} */
5let ready = false;
6/** @type {string[]} */
7let voices = [];
8
9// Handle messages from the main thread
10self.onmessage = async function (e) {
11 const { action, data } = e.data;
12
13 switch (action) {
14 case 'initialize':
15 try {
16 const result = await initializeTts(data);
17 self.postMessage({
18 action: 'initialized',
19 success: result,
20 voices,
21 });
22 } catch (error) {
23 self.postMessage({
24 action: 'initialized',
25 success: false,
26 error: error.message,
27 });
28 }
29 break;
30
31 case 'generateTts':
32 try {
33 const audioBlob = await generateTts(data.text, data.voice, data.speakingRate);
34 const blobUrl = URL.createObjectURL(audioBlob);
35 self.postMessage({
36 action: 'generatedTts',
37 success: true,
38 blobUrl,
39 requestId: data.requestId,
40 });
41 } catch (error) {
42 self.postMessage({
43 action: 'generatedTts',
44 success: false,
45 error: error.message,
46 requestId: data.requestId,
47 });
48 }
49 break;
50
51 case 'checkReady':
52 self.postMessage({ action: 'readyStatus', ready });
53 break;
54 }
55};
56
57// Initialize the TTS engine
58async function initializeTts(settings) {
59 try {
60 const { KokoroTTS } = await import('./lib/kokoro.web.js');
61
62 console.log('Worker: Initializing Kokoro TTS with settings:', {
63 modelId: settings.modelId,
64 dtype: settings.dtype,
65 device: settings.device,
66 });
67
68 // Create TTS instance
69 tts = await KokoroTTS.from_pretrained(settings.modelId, {
70 dtype: settings.dtype,
71 device: settings.device,
72 });
73
74 // Get available voices
75 voices = Object.keys(tts.voices);
76
77 // Check if generate method exists
78 if (typeof tts.generate !== 'function') {
79 throw new Error('TTS instance does not have generate method');
80 }
81
82 console.log('Worker: TTS initialized successfully');
83 ready = true;
84 return true;
85 } catch (error) {
86 console.error('Worker: Kokoro TTS initialization failed:', error);
87 ready = false;
88 throw error;
89 }
90}
91
92// Generate TTS audio
93async function generateTts(text, voiceId, speakingRate) {
94 if (!ready || !tts) {
95 throw new Error('TTS engine not initialized');
96 }
97
98 if (text.trim().length === 0) {
99 throw new Error('Empty text');
100 }
101
102 try {
103 const audio = await tts.generate(text, {
104 voice: voiceId,
105 speed: speakingRate || 1.0,
106 });
107
108 return audio.toBlob();
109 } catch (error) {
110 console.error('Worker: TTS generation failed:', error);
111 throw error;
112 }
113}