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 } | ||||
|  | ||||
| /** | ||||
|  * 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 { | ||||
|     //########// | ||||
|     // Config // | ||||
| @@ -142,7 +211,12 @@ class SystemTtsProvider { | ||||
|             utterance.pitch = this.settings.pitch || 1; | ||||
|             utterance.onend = () => resolve(silence); | ||||
|             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