今日任務: 語音合成 (Speech synthesis),將文字轉成語音,
可以選擇播放的語言、控制講話速度和音頻高低
Web Speech API 提供了兩個不同的功能領域:
瀏覽器支援:
對 Web Speech API 語音識別的支援目前只有於桌面版和 Android 版 Chrome
D20的時候我們介紹過語音辨識,今天要來介紹語音合成。
new SpeechSynthesisUtterance()
:創一個新的SpeechSynthesisUtterance物件來使用,
說話的語言、講話速度和音頻高低、內容都放進這個裡面。
const msg = new SpeechSynthesisUtterance();
let voices = [];
const voicesDropdown = document.querySelector('[name="voice"]');
const options = document.querySelectorAll('[type="range"], [name="text"]');
const speakBtn = document.querySelector('#speak');
const stopBtn = document.querySelector('#stop');
msg.text = document.querySelector('[name="text"]').value;
console.log(msg);
SpeechSynthesis: voiceschanged event
: 當SpeechSynthesis物件裡的SpeechSynthesisVoice清單被改變時觸發。
SpeechSynthesis.speak()
:加一段語音到列隊,前面的說完後就播放此語音。SpeechSynthesis.cancel()
:清空語音,如果當前正在講話,講話將立即停止。SpeechSynthesisVoice
: 語音物件。SpeechSynthesis.getVoices()
: 會回傳一個使用者設備上所有可用的SpeechSynthesisVoice清單陣列。
*注意*
:getVoices()
需搭配監聽voiceschanged
事件,否則會回傳空陣列。
SpeechSynthesisVoice清單
與頁面異步加載,所以當SpeechSynthesisVoice
被加載的時候voiceschanged事件
會被觸發一次,之後會因為getVoices()
觸發。
stackoverflow:Getting the list of voices in speechSynthesis
speechSynthesis.addEventListener('voiceschanged', populateVoices);
function populateVoices() {
voices= this.getVoices();
console.log(voices);
}
function populateVoices() {
voices = this.getVoices();
console.log(voices);
voicesDropdown.innerHTML = voices
.map((voice) =>
`<option value="${voice.name}">${voice.name}(${voice.lang})</option>`)
.join('');
}
console.log(msg)會看到voice,還是null
聲音有載入但還沒設定
當選項選擇後觸發,在voices中尋找符合使用者選擇的選項的值(this.value)
voicesDropdown.addEventListener('change', setVoice);
function setVoice() {
msg.voice = voices.find(voice=>voice.name===this.value)
}
選擇選項,並在console裡面輸入speechSynthesis.speak(msg)
,就會發出聲音
function setVoice() {
msg.voice = voices.find((voice) => voice.name === this.value);
toggle();
}
function toggle() {
speechSynthesis.cancel();
speechSynthesis.speak(msg);
}
有時候可能不想要直接播放新語音,可以傳一個參數來決定要不要直接播放新語音
function toggle(playOver = true) {
speechSynthesis.cancel();
if(playOver){
speechSynthesis.speak(msg);
}
}
options.forEach((option) => option.addEventListener('change', setOptions));
function setOptions(){
console.log(this);
msg[this.name] = this.value;
toggle();
}
不能這樣寫
這樣寫又太冗長
有兩種方法:
1.使用bind()
speakBtn.addEventListener('click', toggle);
stopBtn.addEventListener('click', toggle.bind(null,false));
2.箭頭函式
speakBtn.addEventListener('click', toggle);
stopBtn.addEventListener('click', () => toggle(false));
作者示範篩選語言為英文,這邊篩選中文:
function populateVoices() {
voices = this.getVoices();
voicesDropdown.innerHTML = voices
.filter((voice) =>voice.lang.includes('zh'))
.map((voice) => `<option value="${voice.name}">${voice.name}(${voice.lang})</option>`)
.join('');
}
今日學習到的:
new SpeechSynthesisUtterance()
:創一個新的SpeechSynthesisUtterance物件
來使用,SpeechSynthesisUtterance物件
屬性
lang
:語音的語言。pitch
:語音的音高。rate
:語音的說話的速度。text
:要合成語音的文字。voice
:語音的聲音。SpeechSynthesis
SpeechSynthesis: voiceschanged event
: 當SpeechSynthesis物件裡的SpeechSynthesisVoice清單被改變時觸發。SpeechSynthesis.speak()
:加一段語音到列隊,前面的說完後就播放此語音。SpeechSynthesis.cancel()
:清空語音,如果當前正在講話,講話將立即停止。SpeechSynthesisVoice
: 語音物件。SpeechSynthesis.getVoices()
: 會回傳一個使用者設備上所有可用的SpeechSynthesisVoice清單陣列。*注意:*
:getVoices()
需搭配監聽voiceschanged事件
,否則會回傳空陣列。效果連結:連結
參考連結:
MDN: SpeechSynthesisUtterance
MDN: SpeechSynthesis