網頁載入時自動朗讀內容 - 使用 SpeechSynthesisUtterance
前言
最近有接到一個 CASE 需求是在網頁載入後,網頁能自動朗讀內文的內容,最後使用 JS 內建的 SpeechSynthesisUtterance 來達成這個需求。順便記錄一下遇到的問題。
SpeechSynthesisUtterance
原本以為要自動朗讀得透過什麼第三方套件或 API 來達成,結果搜尋了一下原來瀏覽器就內建有這個功能可以使用。
它是一個蠻老牌的功能,但因為太少需求使用以及瀏覽器本身都有提供朗讀的功能,所以完全不曉得。
相容性
透過 MDN 的資料 MDN - SpeechSynthesisUtterance 來看
除了 IE
還有在 Android 上的 webview 及 Opera
不相容外,主流瀏覽器都可以正常使用。
使用
SpeechSynthesisUtterance 是 window 的一個物件,可以直接使用 window.SpeechSynthesisUtterance
,屬性有以下幾種
- lang : 語言,如果未設定將會抓 html 上設定的
lang
屬性。 - pitch : 音調,值為 0 ~ 2,預設為 1。
- rate : 速度,值為 0.5 ~ 2,預設為 1。
- volume : 音量,值為 0 ~ 1,預設為 1。
- text : 要朗讀的內容
- voice : 聲音,預設為瀏覽器的預設聲音,可以透過
speechSynthesis.getVoices()
來取得所有可用的聲音。
const voices = window.speechSynthesis.getVoices();
這邊得到的 voices 是一個陣列,裡面包含了所有可用的聲音,內容會依照瀏覽器不同有所差異
相關的配置可以透過 August 大寫的網頁來交叉測試
相關的事件
- onstart : 開始朗讀時觸發
- onend : 朗讀結束時觸發
- onerror : 朗讀錯誤時觸發
- onpause : 朗讀暫停時觸發
- onresume : 朗讀繼續時觸發
相關的方法
- speak() : 開始朗讀
- pause() : 暫停朗讀
- resume() : 繼續朗讀
- cancel() : 取消朗讀
- getVoices() : 取得所有可用的聲音
專案的需求
這邊專案的需求是在網頁載入後,自動朗讀內文的內容。 所以是透過 window.onload
來達成
function speak(content) {
const utterance = new SpeechSynthesisUtterance();
// 配置可以寫在這
// utterance.lang = 'zh-TW';
// utterance.pitch = 1;
// utterance.rate = 1;
// utterance.volume = 1;
utterance.text = content;
window.speechSynthesis.speak(utterance);
}
window.onload = function () {
speak("這是要朗讀的內容");
};
到這邊儲存後重新整理進入網頁時,就會自動朗讀內容,也因為沒有指定 voice 所以會用預設的聲音朗讀
原本以為這樣就完成了,但後來發現會有一堆問題:
1. 切換網頁時,還在繼續朗讀
更詳細的查資料才發現,原來 speechSynthesis
是可以放入多個 SpeechSynthesisUtterance
,進行佇列,也不受網頁切換的影響會將原本的內容朗讀完。
因此需要在切換網頁時,透過 onbeforeunload
事件手動清除佇列中的內容。
window.onbeforeunload = function () {
window.speechSynthesis.cancel();
};
2. 手機上不能自動朗讀
這邊是因為手機上的瀏覽器都會有一個 user gesture
的機制,也就是說必須要有使用者的行為才能觸發,所以在手機上是無法自動朗讀的。
和影片自動播放的原理相同,如果要自動播放就只能使用靜音的方式,但這樣就無法達到需求了。
也想過寫一個隱藏的 button 在載入時自動觸發 click,但後來發現也是無法自動朗讀,於是在手機上就只能提供一個朗讀的按鈕讓使用者自行觸發。