在開發業務系統時,有時候可能需要使用語音播報一段文字,比如下面的場景:
當顧客付款成功後,需要系統自動播報收款的金額,其中付款金額是不固定的,比如1元、2元、3.2元等等
如果是相對固定的場景,並且語音有限的情況下,可以採用錄製的方式,即先錄製好所有的音訊資源,然後根據業務場景播放相應的音訊即可;但是如果場景不固定,需要的語音也不一樣時,採用錄製的方式的話,音訊資源將會非常多,而且還可能會出現不全的問題,那麼這個時候利用語音合成技術是一個較好的辦法,即實時將文字轉換成語音。
目前文字轉語音即語音合成技術現在已經很成熟了,像百度、訊飛等都提供了相關的服務,支援將文字轉換成各種形式的語音,通常這些服務都需要付費使用,如果對語音要求不高,並且又想節約成本,那麼可以直接使用瀏覽器的語音合成功能。
有些瀏覽器已經支援將文字轉換為語音的功能,下面來看看官方的介紹:
語音合成是通過 SpeechSynthesis 介面進行訪問,它提供了文字到語音(TTS)的能力,這使得程式能夠讀出它們的文字內容(通常使用裝置預設的語音合成器)。不同的聲音類型別通過 SpeechSynthesisVoice 物件進行表示,不同部分的文字則由 SpeechSynthesisUtterance 物件來表示,最後可以通過 SpeechSynthesis.speak() 方法來產生語音。
語音合成主要涉及到上面的三個物件:SpeechSynthesis 、SpeechSynthesisVoice 和 SpeechSynthesisUtterance 。
1、SpeechSynthesis
SpeechSynthesis 是語音合成服務的控制器介面,可用於獲取裝置上可用的合成語音,開始、暫停以及其它相關命令的資訊,可以使用 window.speechSynthesis 屬性來訪問 SpeechSynthesis 控制器,從而獲取語音合成功能的入口。
或者省略 window,直接使用 speechSynthesis 也是可以的
它有 paused、pending、speaking 三個屬性,都是隻讀屬性,不可修改。
它擁有的方法如下:
- SpeechSynthesis.cancel():取消語音播放
- SpeechSynthesis.getVoices():獲取當前裝置所有可用聲音的 SpeechSynthesisVoice 列表。
- SpeechSynthesis.pause() :暫停語音播放
- SpeechSynthesis.resume() :恢復播放
- SpeechSynthesis.speak() :新增語音到播放列隊,將會在其他語音播放完後自動播放
2、SpeechSynthesisVoice
SpeechSynthesisVoice 表示當前系統支援的語音資源,每一個 SpeechSynthesisVoice 都對應相關的語音服務,可以通過 SpeechSynthesis.getVoices()
獲取語音列表,如下:
它有5個只讀的屬性,分別為 default、lang、name、localService、voiceURI.
3、SpeechSynthesisUtterance
SpeechSynthesisUtterance 表示一次發音請求,其中包含了將由語音服務朗讀的內容,以及如何朗讀它(例如:語種、音高、音量)。
它有6個屬性,分別如下:
- lang:讀取時的語言
- pitch:聲音的音高,取值0~2 ,正常音高為1
- rate:讀取的語速,取值0.1~10 ,正常語速值為1
- text:要合成語音的文字內容
- voice:讀取文字的語音服務,預設為 SpeechSynthesisVoice 的屬性值為 default 的那個
- volume:讀取時聲音的音量,取值0~1,正常音量為1
除了上面的屬性外,還有7個事件方法,分別如下:
- onboundary:當播放至一個詞或句子結尾時觸發
- onend:語音播放結束時觸發
- onerror:語音播放錯誤時觸發
- onmark:當語音播放至 mark 標記時觸發
- onpause:暫停語音播放時觸發
- onresume:恢復語音播放時觸發
- onstart:開始語音播放時觸發
關於SpeechSynthesisVoice 的屬性和方法,可以直接在 console 中檢視,如下:
4、語音合成程式碼
在瞭解了語音合成的相關物件後,下面來簡單測試一下
let synth = window.speechSynthesis;
let utterThis = new SpeechSynthesisUtterance('支付寶到賬7.5元');
synth.speak(utterThis);
執行後,就可以聽到語音了,這裡使用 Chrome 瀏覽器測試的,語音聽起來還可以。
下面給出一個比較通用的方法,具體實現的程式碼:
/**
* @description 文字轉語音方法
* @public
* @param { text, rate, lang, volume, pitch } object
* @param text 要合成的文字內容,字串
* @param rate 讀取文字的語速 0.1~10 正常1
* @param lang 讀取文字時的語言
* @param volume 讀取時聲音的音量 0~1 正常1
* @param pitch 讀取時聲音的音高 0~2 正常1
* @returns SpeechSynthesisUtterance
*/
function speak({ text, speechRate, lang, volume, pitch }, endEvent, startEvent) {
if (!window.SpeechSynthesisUtterance) {
console.warn('當前瀏覽器不支援文字轉語音服務')
return;
}
if (!text) {
return;
}
const speechUtterance = new SpeechSynthesisUtterance();
speechUtterance.text = text;
speechUtterance.rate = speechRate || 1;
speechUtterance.lang = lang || 'zh-CN';
speechUtterance.volume = volume || 1;
speechUtterance.pitch = pitch || 1;
speechUtterance.onend = function() {
endEvent && endEvent();
};
speechUtterance.onstart = function() {
startEvent && startEvent();
};
speechSynthesis.speak(speechUtterance);
return speechUtterance;
}
測試一下
speak({
text: '微信到賬100元'
}, function() {
console.log('語音播放結束');
}, function() {
console.log('語音開始播放');
});
執行後,可以看到此時的 speechUtterance 例項如下:
同時控制檯會依次輸出下面的資訊
語音開始播放
語音播放結束
參考資料