# Web Speech Synthesis (TTS) ###### tags: `JavaScript` `TTS` ## TTS(text-to-speech) console上面輸入 ``` speechSynthesis.speak(new SpeechSynthesisUtterance('Hey')) ``` ## 實作 先實例出一個SpeechSynthesisUtterance ``` var utterance = new SpeechSynthesisUtterance(); ``` 可以設定一些properties ``` utterance.pitch = 1.5 utterance.volume = 0.5 utterance.rate = 8 ``` 最後 ``` speechSynthesis.speak(utterance) ``` 如果設定voices: speechSynthesis.getVoices選出裡面的object,帶入utterance.voice = speechSynthesis.getVoices()[i] ## Promise用法: ``` const getVoices = () => { return new Promise(resolve => { let voices = speechSynthesis.getVoices() if (voices.length) { resolve(voices) return } speechSynthesis.onvoiceschanged = () => { voices = speechSynthesis.getVoices() resolve(voices) } }) } const printVoicesList = async () => { (await getVoices()).forEach(voice => { console.log(voice.name, voice.lang) }) } printVoicesList() ``` ``` const lang = 'it-IT' const voiceIndex = 1 const speak = async text => { if (!speechSynthesis) { return } const message = new SpeechSynthesisUtterance(text) message.voice = await chooseVoice() speechSynthesis.speak(message) } const getVoices = () => { return new Promise(resolve => { let voices = speechSynthesis.getVoices() if (voices.length) { resolve(voices) return } speechSynthesis.onvoiceschanged = () => { voices = speechSynthesis.getVoices() resolve(voices) } }) } const chooseVoice = async () => { const voices = (await getVoices()).filter(voice => voice.lang == lang) return new Promise(resolve => { resolve(voices[voiceIndex]) }) } speak('Ciao') ``` ## 遇到的坑: google chrome的speechsynthesis.getVoices是以callback的方式回傳資料,使用Promise await方式等待他回傳成功後接收資料,或是官方提供的範例 onvoiceschanged ``` window.speechSynthesis.onvoiceschanged = function() { window.speechSynthesis.getVoices(); ... }; ``` 但是很怪異的有時候第一次會回傳空的empty,第二次才會有資料,可能是第一次getVoices會需要比較久的時間,所以可以設定一個interval每隔多少秒就執行一次,直到取得資料為止會比較保險 ``` var timer = setInterval(function() { var voices = speechSynthesis.getVoices(); console.log(voices); if (voices.length !== 0) { var msg = new SpeechSynthesisUtterance(/*some string here*/); msg.voice = voices[/*some number here to choose from array*/]; speechSynthesis.speak(msg); clearInterval(timer); } }, 200); $("#test").on('click', timer); ``` ## 參考文章: API https://developer.mozilla.org/en-US/docs/Web/API/Web_Speech_API/Using_the_Web_Speech_API#Speech_synthesis 英文 https://flaviocopes.com/speech-synthesis-api/ 中文 https://www.jianshu.com/p/92dec635f6c5