Fixed option ui binidngs.
This commit is contained in:
+79
-111
@@ -89,6 +89,12 @@ export class KokoroHandler extends TTSHandler {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Ensure we have at least default voices ready
|
||||
if (!this.voices || this.voices.length === 0) {
|
||||
console.log('Kokoro TTS: No voices set, initializing with defaults');
|
||||
this.voices = this.getDefaultVoices();
|
||||
}
|
||||
|
||||
// Set loading flag
|
||||
this.loading = true;
|
||||
this.isReady = false; // Explicitly set to false during initialization
|
||||
@@ -169,10 +175,11 @@ export class KokoroHandler extends TTSHandler {
|
||||
} else {
|
||||
console.warn('Kokoro TTS: No voices received during initialization or invalid voices data');
|
||||
if (data.success) {
|
||||
// If initialization was successful but no voices were received,
|
||||
// use default voices
|
||||
this.voices = this.getDefaultVoices();
|
||||
console.log('Kokoro TTS: Using default voices as fallback');
|
||||
// Even though we already set the default voices, check and update if needed
|
||||
if (!this.voices || this.voices.length === 0) {
|
||||
this.voices = this.getDefaultVoices();
|
||||
console.log('Kokoro TTS: Using default voices as fallback');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,7 +189,7 @@ export class KokoroHandler extends TTSHandler {
|
||||
console.log('Kokoro TTS: Voice set up from preferences during initialization');
|
||||
}).catch(error => {
|
||||
console.error('Kokoro TTS: Error setting up voice from preferences during initialization:',
|
||||
error ? (error.message || JSON.stringify(error)) : 'Unknown error');
|
||||
error ? (error.message || error) : 'Unknown error');
|
||||
});
|
||||
}
|
||||
|
||||
@@ -191,30 +198,17 @@ export class KokoroHandler extends TTSHandler {
|
||||
}
|
||||
};
|
||||
|
||||
// Add the message listener
|
||||
// Add the message handler
|
||||
window.addEventListener('message', messageHandler);
|
||||
|
||||
// Send initialization message to iframe
|
||||
if (this.iframe.contentWindow) {
|
||||
console.log('Kokoro TTS: Sending init message to iframe');
|
||||
setTimeout(() => {
|
||||
this.iframe.contentWindow.postMessage({
|
||||
type: 'kokoro-init'
|
||||
}, '*');
|
||||
}, 500); // Add a small delay to ensure iframe is ready
|
||||
} else {
|
||||
console.error('Kokoro TTS: Cannot access iframe content window');
|
||||
this.loading = false;
|
||||
this.isReady = false;
|
||||
this.available = false;
|
||||
resolve(false);
|
||||
}
|
||||
// Initial progress update
|
||||
handleProgress(0.1, 'Starting Kokoro initialization');
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Kokoro TTS: Error initializing:', error ? (error.message || JSON.stringify(error)) : 'Unknown error');
|
||||
console.error('Kokoro TTS: Error during initialization:', error);
|
||||
this.loading = false;
|
||||
this.available = false;
|
||||
this.isReady = false;
|
||||
this.available = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -224,91 +218,56 @@ export class KokoroHandler extends TTSHandler {
|
||||
* @param {MessageEvent} event - Message event
|
||||
*/
|
||||
handleIframeMessage(event) {
|
||||
// Ignore messages from other sources
|
||||
// Only process messages from our iframe
|
||||
if (!this.iframe || event.source !== this.iframe.contentWindow) {
|
||||
return;
|
||||
}
|
||||
|
||||
const data = event.data;
|
||||
console.log('Kokoro TTS: Received message from iframe:', JSON.stringify(data));
|
||||
console.log('Kokoro TTS: Received message from iframe:', data.type);
|
||||
|
||||
switch (data.type) {
|
||||
case 'kokoro-ready':
|
||||
console.log('Kokoro TTS: Received ready message with success =', data.success);
|
||||
case 'kokoro-log':
|
||||
console.log(`Kokoro Loader: ${data.message}`);
|
||||
break;
|
||||
|
||||
// Store voices if provided
|
||||
case 'kokoro-ready':
|
||||
console.log('Kokoro TTS: Received ready message from iframe. Success:', data.success, 'Voices:', data.voices ? data.voices.length : 0);
|
||||
|
||||
// Store availability
|
||||
this.loading = false;
|
||||
this.available = data.success;
|
||||
this.isReady = data.success; // Important to set this for the base handler
|
||||
|
||||
// Store voices
|
||||
if (data.success && data.voices && Array.isArray(data.voices)) {
|
||||
console.log(`Kokoro TTS: Received ${data.voices.length} voices from Kokoro iframe`);
|
||||
console.log(`Kokoro TTS: Storing ${data.voices.length} voices from iframe`);
|
||||
this.voices = data.voices;
|
||||
|
||||
// Set availability and ready flags
|
||||
this.available = true;
|
||||
this.loading = false;
|
||||
this.isReady = true;
|
||||
|
||||
// Set up voice from preferences after voices are loaded
|
||||
this.setupVoiceFromPreferences().then(() => {
|
||||
console.log('Kokoro TTS: Voice set up from preferences after receiving voices');
|
||||
|
||||
// Notify TTS Factory that we're ready now
|
||||
document.dispatchEvent(new CustomEvent('kokoro:ready', {
|
||||
detail: { success: true }
|
||||
}));
|
||||
}).catch(error => {
|
||||
console.error('Kokoro TTS: Error setting up voice from preferences after receiving voices:',
|
||||
error ? (error.message || JSON.stringify(error)) : 'Unknown error');
|
||||
|
||||
// Still notify as ready since we have voices, even if preference setup failed
|
||||
document.dispatchEvent(new CustomEvent('kokoro:ready', {
|
||||
detail: { success: true }
|
||||
}));
|
||||
});
|
||||
|
||||
// Notify about voices being updated
|
||||
document.dispatchEvent(new CustomEvent('kokoro:voices-updated', {
|
||||
detail: { voices: this.voices }
|
||||
}));
|
||||
} else {
|
||||
console.warn('Kokoro TTS: No voices received from iframe or invalid voices data');
|
||||
// Even with no voices, mark as ready if success is true
|
||||
if (data.success) {
|
||||
this.voices = this.getDefaultVoices();
|
||||
this.available = true;
|
||||
this.loading = false;
|
||||
this.isReady = true;
|
||||
console.log('Kokoro TTS: Using default voices as fallback');
|
||||
|
||||
// Notify TTS Factory that we're ready
|
||||
document.dispatchEvent(new CustomEvent('kokoro:ready', {
|
||||
detail: { success: true }
|
||||
}));
|
||||
|
||||
// Notify about voices being available
|
||||
document.dispatchEvent(new CustomEvent('kokoro:voices-updated', {
|
||||
detail: { voices: this.voices }
|
||||
}));
|
||||
} else {
|
||||
this.available = false;
|
||||
this.loading = false;
|
||||
this.isReady = false;
|
||||
console.error('Kokoro TTS: Initialization failed:', data.error || 'Unknown error');
|
||||
|
||||
// Notify TTS Factory about failure
|
||||
document.dispatchEvent(new CustomEvent('kokoro:ready', {
|
||||
detail: { success: false, error: data.error || 'Unknown error' }
|
||||
}));
|
||||
}
|
||||
} else if (data.success) {
|
||||
// If success but no voices, use defaults
|
||||
console.warn('Kokoro TTS: No voices received from iframe, using defaults');
|
||||
this.voices = this.getDefaultVoices();
|
||||
}
|
||||
|
||||
// Set up voice from preferences if ready
|
||||
if (this.available) {
|
||||
this.setupVoiceFromPreferences().then(() => {
|
||||
console.log('Kokoro TTS: Voice set up from preferences');
|
||||
});
|
||||
}
|
||||
|
||||
// Dispatch ready event
|
||||
this.dispatchEvent('tts:ready', { success: data.success });
|
||||
break;
|
||||
|
||||
case 'kokoro-generated':
|
||||
// Handle generated speech
|
||||
const pendingGeneration = this.pendingGenerations.get(data.id);
|
||||
if (pendingGeneration) {
|
||||
// Handle generated speech
|
||||
if (data.id && this.pendingGenerations.has(data.id)) {
|
||||
const { resolve, reject } = this.pendingGenerations.get(data.id);
|
||||
this.pendingGenerations.delete(data.id);
|
||||
|
||||
if (data.success) {
|
||||
// Create audio element from the result
|
||||
if (data.success && data.result) {
|
||||
// Create an audio element from the result
|
||||
try {
|
||||
// Create a blob from the buffer
|
||||
const blob = new Blob([data.result.buffer], { type: 'audio/wav' });
|
||||
@@ -323,26 +282,18 @@ export class KokoroHandler extends TTSHandler {
|
||||
});
|
||||
};
|
||||
|
||||
pendingGeneration.resolve({ audio, play, blob });
|
||||
resolve({ audio, play, blob });
|
||||
} catch (error) {
|
||||
console.error('Error processing Kokoro audio:', error);
|
||||
pendingGeneration.reject(error);
|
||||
reject(error);
|
||||
}
|
||||
} else {
|
||||
pendingGeneration.reject(new Error(data.error || 'Unknown error'));
|
||||
console.error('Kokoro TTS: Invalid speech generation result');
|
||||
reject(new Error(data.error || 'Unknown error generating speech'));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'kokoro-log':
|
||||
// Log messages from the iframe
|
||||
if (data.logType === 'error') {
|
||||
console.error(`Kokoro iframe: ${data.message}`);
|
||||
} else {
|
||||
console.log(`Kokoro iframe: ${data.message}`);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'kokoro-progress':
|
||||
// Progress updates are handled during initialization
|
||||
break;
|
||||
@@ -440,7 +391,7 @@ export class KokoroHandler extends TTSHandler {
|
||||
}
|
||||
} catch (error) {
|
||||
// Log detailed error information
|
||||
console.error('Kokoro TTS: Error setting up voice from preferences:', error ? error.message || JSON.stringify(error) : 'Unknown error');
|
||||
console.error('Kokoro TTS: Error setting up voice from preferences:', error ? error.message || error : 'Unknown error');
|
||||
|
||||
// Default to first voice if available
|
||||
if (this.voices && this.voices.length > 0) {
|
||||
@@ -505,9 +456,12 @@ export class KokoroHandler extends TTSHandler {
|
||||
|
||||
/**
|
||||
* Get available voices
|
||||
* @returns {Array} - Array of available voices
|
||||
* @returns {Array} - Array of voice objects
|
||||
*/
|
||||
getVoices() {
|
||||
if (!this.voices || this.voices.length === 0) {
|
||||
return this.getDefaultVoices();
|
||||
}
|
||||
return this.voices;
|
||||
}
|
||||
|
||||
@@ -710,11 +664,14 @@ export class KokoroHandler extends TTSHandler {
|
||||
if (this.currentVoice && this.currentVoice.id) {
|
||||
voiceId = this.currentVoice.id;
|
||||
} else if (this.voices && this.voices.length > 0) {
|
||||
// If currentVoice is not set but we have voices, use the first one
|
||||
voiceId = this.voices[0].id;
|
||||
// Default to first voice if none selected
|
||||
this.currentVoice = this.voices[0];
|
||||
voiceId = this.currentVoice.id;
|
||||
console.log(`Kokoro TTS: No voice set, defaulting to ${voiceId}`);
|
||||
}
|
||||
|
||||
console.log(`Kokoro TTS: Generating speech with voice ${voiceId}`);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
// Generate unique ID for this request
|
||||
const id = `gen-${++this.generationCounter}`;
|
||||
@@ -787,11 +744,22 @@ export class KokoroHandler extends TTSHandler {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default voices
|
||||
* @returns {Array} - Array of default voices
|
||||
* @private
|
||||
* Get default voices for current locale
|
||||
* @returns {Array} Default voices
|
||||
*/
|
||||
getDefaultVoices() {
|
||||
// Check if localization module is available
|
||||
const localization = this.getModule('localization');
|
||||
let locale = 'en-us'; // Default fallback
|
||||
|
||||
if (localization) {
|
||||
locale = localization.getLocale();
|
||||
console.log(`Kokoro TTS: Getting default voices for locale: ${locale}`);
|
||||
} else {
|
||||
console.log('Kokoro TTS: Localization module not available, using default locale: en-us');
|
||||
}
|
||||
|
||||
// Use the actual voices defined in the Kokoro loader
|
||||
return [
|
||||
// American Female voices
|
||||
{ id: 'af_heart', name: 'Heart', lang: 'en-US', gender: 'female' },
|
||||
|
||||
Reference in New Issue
Block a user