ttsreader
Version:
Text to Speech wrapper, player and helpers for the web-speech-api speech synthesis
2 lines (1 loc) • 6.22 kB
JavaScript
!function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,(function(r){return o(e[i][1][r]||r)}),p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}({1:[function(require,module,exports){window.wsGlobals=window.wsGlobals||{},window.wsGlobals.TtsEngine=require("./index").TtsEngine},{"./index":3}],2:[function(require,module,exports){function codeToLanguageCodeOnly(code){return null==code||code.length<2?"":code.toLowerCase().split("-")[0].split("_")[0]}function doCodesShareLanguage(a,b){return codeToLanguageCodeOnly(a)==codeToLanguageCodeOnly(b)}exports.TtsEngine={DEFAULT_LANG:"en",voice:{},voices:[],rate:1,utteranceId:0,startedAndNotTerminatedCounter:0,listener:null,utterance:{},_googleBugTimeout:null,_speakTimeout:null,_canceledAtMs:0,init:function(listener){listener&&(this.listener=listener),this._populateVoices(),speechSynthesis.onvoiceschanged=()=>{this._populateVoices()}},setListener:function(listener){this.listener=listener},setBestMatchingVoice:function(voice,voiceURI,lang){if(null==this.voices||0==this.voices.length)return"";if(voice&&voice.voiceURI||voiceURI||lang||(this.voice&&this.voice.voiceURI?voiceURI=this.voice.voiceURI:lang=this.DEFAULT_LANG),voice&&(voiceURI=voice.voiceURI||voiceURI),voiceURI)for(const iVoice of this.voices)if(iVoice.voiceURI==voiceURI)return this.voice=iVoice,iVoice.voiceURI;if(lang){if(this.voice&&doCodesShareLanguage(this.voice.lang,lang))return this.voice.voiceURI;let filteredVoices=this.voices.filter((iVoice=>doCodesShareLanguage(iVoice.lang,lang)));if(filteredVoices&&filteredVoices.length>0){if(1==filteredVoices.length)return this.voice=filteredVoices[0],this.voice.voiceURI;if(!lang.startsWith("en")&&!lang.startsWith("es"))return this.voice=filteredVoices[0],this.voice.voiceURI;{let selectedVoice,selectedVoiceScore=-1;for(const iVoice of filteredVoices){let score=0;iVoice.localService&&(score+=1.5),2==iVoice.lang.length?score+=3:-1!=["en-us","en-uk","en-gb","es-es"].indexOf(iVoice.lang.toLowerCase().replace("_","-"))?score+=4:-1==["en-in"].indexOf(iVoice.lang.toLowerCase().replace("_","-"))&&(score+=2),score>selectedVoiceScore&&(selectedVoiceScore=score,selectedVoice=iVoice)}if(selectedVoice)return this.voice=selectedVoice,this.voice.voiceURI}}}for(const iVoice of this.voices)if(this.voice=iVoice,iVoice.localService)return iVoice.voiceURI;return this.voice.voiceURI},_populateVoices:function(){let voices=window.speechSynthesis.getVoices();voices&&voices.length>0&&(this.voices=voices.filter((voice=>{if(!voice.voiceURI.includes("com.apple.eloquence")&&!voice.voiceURI.includes("com.apple.speech.synthesis"))return voice})),this.setBestMatchingVoice(this.voice,null,null),this.listener&&this.listener.onInit&&this.listener.onInit(this.voices))},setVoiceByUri:function(voiceURI){this.setBestMatchingVoice(null,voiceURI,null)},getVoiceURI:function(){return this.voice||this.setBestMatchingVoice(),this.voice?this.voice.voiceURI:""},setRate:function(rate){"string"==typeof rate&&(rate=Number(rate)),isNaN(rate)||(rate<.1&&(rate=.1),rate>4&&(rate=4),this.rate=rate)},isInitiated:function(){return null!=this.voices},_defaultOnStart:function(ev){this.startedAndNotTerminatedCounter++,this._solveChromeBug()},_defaultOnEnd:function(ev){this.startedAndNotTerminatedCounter>0&&this.startedAndNotTerminatedCounter--,this._clearUtteranceTimeouts()},_defaultOnError:function(ev){this.startedAndNotTerminatedCounter>0&&this.startedAndNotTerminatedCounter--,this._clearUtteranceTimeouts()},_clearUtteranceTimeouts:function(){null!=this._googleBugTimeout&&(window.clearTimeout(this._googleBugTimeout),this._googleBugTimeout=null)},_solveChromeBug:function(){if(!this.voice)return;if(-1===this.voice.voiceURI.toLowerCase().indexOf("google"))return;this._clearUtteranceTimeouts();let self=this;this._googleBugTimeout=window.setTimeout((function(){window.speechSynthesis.pause(),window.speechSynthesis.resume(),self._solveChromeBug()}),1e4)},_prepareTextForSynthesis:function(text){let decodedText=text;return decodedText=decodedText.replace("·",", "),decodedText=decodedText.replace("- ",", "),decodedText.trim(),decodedText},speakOut:function(text){let instance=this;if(this.startedAndNotTerminatedCounter>0||window.speechSynthesis.paused||window.speechSynthesis.pending||window.speechSynthesis.speaking)return this.stop(),void(this._speakTimeout=window.setTimeout((function(){instance.speakOut(text)}),200));if(!text)return void(this.utterance&&this.utterance.onend());if(text=this._prepareTextForSynthesis(text),!this.isInitiated())return!1;this.utteranceId++;let utterance=new SpeechSynthesisUtterance;this.utterance=utterance,utterance.text=text,null==this.voice&&this.setBestMatchingVoice(null,null,null),this.voice&&(utterance.lang=this.voice.lang,utterance.voiceURI=this.voice.voiceURI,utterance.voice=this.voice),utterance.rate=this.rate;let self=this;utterance.onmark=function(ev){},utterance.onstart=function(ev){self._defaultOnStart(ev),self.listener&&self.listener.onStart&&self.listener.onStart()},utterance.onboundary=function(event){},utterance.onend=function(ev){self._defaultOnEnd(ev),self.listener&&self.listener.onDone&&self.listener.onDone(),utterance=null},utterance.onerror=function(ev){self._defaultOnError(ev),utterance=null},this._speakUtterance(utterance)},stop(){null!=this._speakTimeout&&(window.clearTimeout(this._speakTimeout),this._speakTimeout=null),window.speechSynthesis.cancel(),this.startedAndNotTerminatedCounter=0,this._canceledAtMs=Date.now()},_speakUtterance(utterance){null!=this._speakTimeout&&(window.clearTimeout(this._speakTimeout),this._speakTimeout=null),window.speechSynthesis.paused&&window.speechSynthesis.resume(),Date.now()-this._canceledAtMs>100?window.speechSynthesis.speak(utterance):this._speakTimeout=window.setTimeout((function(){window.speechSynthesis.speak(utterance)}),200)}}},{}],3:[function(require,module,exports){exports.TtsEngine=require("./helpers/ttsEngine").TtsEngine},{"./helpers/ttsEngine":2}]},{},[1]);