feature: 'kokoro-js' supports TTS #3412 (#3656)

* feature: 'kokoro-js' supports TTS #3412

* Linting, add credits for kokoro library

* Fix voice preview

* Fix display languages on previews

* Fix settings restoration. Debounce model init on settings change

* Fix engine sorting

* Move TTS processing to a web worker. Remove unused gain setting

* Speaking rate fix

* Update status when recreating a worker

* Pass voices list from TTS engine

* Call dispose function on provider change

* Extend worker init timeout to 10 minutes

---------

Co-authored-by: ryan <1014670860@qq.com>
Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
This commit is contained in:
felger
2025-03-11 04:54:54 +08:00
committed by GitHub
parent 13a3f4772e
commit e23f3a6314
11 changed files with 491 additions and 27 deletions

View File

@ -9,6 +9,8 @@ import { QuickReplySettings } from './src/QuickReplySettings.js';
import { SlashCommandHandler } from './src/SlashCommandHandler.js';
import { ButtonUi } from './src/ui/ButtonUi.js';
import { SettingsUi } from './src/ui/SettingsUi.js';
import { debounceAsync } from '../../utils.js';
export { debounceAsync };
@ -17,32 +19,6 @@ const _VERBOSE = true;
export const debug = (...msg) => _VERBOSE ? console.debug('[QR2]', ...msg) : null;
export const log = (...msg) => _VERBOSE ? console.log('[QR2]', ...msg) : null;
export const warn = (...msg) => _VERBOSE ? console.warn('[QR2]', ...msg) : null;
/**
* Creates a debounced function that delays invoking func until after wait milliseconds have elapsed since the last time the debounced function was invoked.
* @param {Function} func The function to debounce.
* @param {Number} [timeout=300] The timeout in milliseconds.
* @returns {Function} The debounced function.
*/
export function debounceAsync(func, timeout = 300) {
let timer;
/**@type {Promise}*/
let debouncePromise;
/**@type {Function}*/
let debounceResolver;
return (...args) => {
clearTimeout(timer);
if (!debouncePromise) {
debouncePromise = new Promise(resolve => {
debounceResolver = resolve;
});
}
timer = setTimeout(() => {
debounceResolver(func.apply(this, args));
debouncePromise = null;
}, timeout);
return debouncePromise;
};
}
const defaultConfig = {