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