mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
Fix System TTS ending abruptly in Chrome on Windows
This commit is contained in:
@ -1,5 +1,74 @@
|
|||||||
export { SystemTtsProvider }
|
export { SystemTtsProvider }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Chunkify
|
||||||
|
* Google Chrome Speech Synthesis Chunking Pattern
|
||||||
|
* Fixes inconsistencies with speaking long texts in speechUtterance objects
|
||||||
|
* Licensed under the MIT License
|
||||||
|
*
|
||||||
|
* Peter Woolley and Brett Zamir
|
||||||
|
* Modified by Haaris for bug fixes
|
||||||
|
*/
|
||||||
|
|
||||||
|
var speechUtteranceChunker = function (utt, settings, callback) {
|
||||||
|
settings = settings || {};
|
||||||
|
var newUtt;
|
||||||
|
var txt = (settings && settings.offset !== undefined ? utt.text.substring(settings.offset) : utt.text);
|
||||||
|
if (utt.voice && utt.voice.voiceURI === 'native') { // Not part of the spec
|
||||||
|
newUtt = utt;
|
||||||
|
newUtt.text = txt;
|
||||||
|
newUtt.addEventListener('end', function () {
|
||||||
|
if (speechUtteranceChunker.cancel) {
|
||||||
|
speechUtteranceChunker.cancel = false;
|
||||||
|
}
|
||||||
|
if (callback !== undefined) {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var chunkLength = (settings && settings.chunkLength) || 160;
|
||||||
|
var pattRegex = new RegExp('^[\\s\\S]{' + Math.floor(chunkLength / 2) + ',' + chunkLength + '}[.!?,]{1}|^[\\s\\S]{1,' + chunkLength + '}$|^[\\s\\S]{1,' + chunkLength + '} ');
|
||||||
|
var chunkArr = txt.match(pattRegex);
|
||||||
|
|
||||||
|
if (chunkArr == null || chunkArr[0] === undefined || chunkArr[0].length <= 2) {
|
||||||
|
//call once all text has been spoken...
|
||||||
|
if (callback !== undefined) {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var chunk = chunkArr[0];
|
||||||
|
newUtt = new SpeechSynthesisUtterance(chunk);
|
||||||
|
var x;
|
||||||
|
for (x in utt) {
|
||||||
|
if (utt.hasOwnProperty(x) && x !== 'text') {
|
||||||
|
newUtt[x] = utt[x];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
newUtt.lang = utt.lang;
|
||||||
|
newUtt.voice = utt.voice;
|
||||||
|
newUtt.addEventListener('end', function () {
|
||||||
|
if (speechUtteranceChunker.cancel) {
|
||||||
|
speechUtteranceChunker.cancel = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
settings.offset = settings.offset || 0;
|
||||||
|
settings.offset += chunk.length;
|
||||||
|
speechUtteranceChunker(utt, settings, callback);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings.modifier) {
|
||||||
|
settings.modifier(newUtt);
|
||||||
|
}
|
||||||
|
console.log(newUtt); //IMPORTANT!! Do not remove: Logging the object out fixes some onend firing issues.
|
||||||
|
//placing the speak invocation inside a callback fixes ordering and onend issues.
|
||||||
|
setTimeout(function () {
|
||||||
|
speechSynthesis.speak(newUtt);
|
||||||
|
}, 0);
|
||||||
|
};
|
||||||
|
|
||||||
class SystemTtsProvider {
|
class SystemTtsProvider {
|
||||||
//########//
|
//########//
|
||||||
// Config //
|
// Config //
|
||||||
@ -142,7 +211,12 @@ class SystemTtsProvider {
|
|||||||
utterance.pitch = this.settings.pitch || 1;
|
utterance.pitch = this.settings.pitch || 1;
|
||||||
utterance.onend = () => resolve(silence);
|
utterance.onend = () => resolve(silence);
|
||||||
utterance.onerror = () => reject();
|
utterance.onerror = () => reject();
|
||||||
speechSynthesis.speak(utterance);
|
speechUtteranceChunker(utterance, {
|
||||||
|
chunkLength: 200,
|
||||||
|
}, function () {
|
||||||
|
//some code to execute when done
|
||||||
|
console.log('System TTS done');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user