你所不知道的HTML5——語音合成

你所不知道的HTML5——語音合成

前端能力的增強很大程度上依賴於 HTML5 的新 API,從這篇文章開始我也會對平時做不常用的一些 API 做一下學習總結
今天的文章就從語音合成開始

爲什麼想到這個 API 呢?

在寫報告查資料的時候在 “人人都是產品經理”http://www.woshipm.com/ 上發現了一個有趣的功能(打了醜醜的馬賽克)

聽一下就會發現,播放出來的聲音並不是預先錄製好的音頻資料,而是通過文字識別後合成的語音

那麼我們如何在前端實現這樣的功能呢?主角登場!

⚠️注意,這個 API 尚在草案階段,並且在寫 demo 的時候瀏覽器提示部分 API 可能將不被支持,所以本文中提到的解決方案不要用於產品中

語音合成超簡單例子

請先戴上耳機,然後將下面的代碼複製到chrome控制檯中體驗~

let msg = new SpeechSynthesisUtterance("歡迎你閱讀我的博客");
window.speechSynthesis.speak(msg);

看,前端實現語音合成並不難

今天的主角 Speech Synthesis API

通過上面的例子我們可以猜測到上面調用的兩個方法的功能

  • SpeechSyntehesisUtteranc 用來構造一個可以被讀出的“東西”
  • window.speechSynthesis.speak 將構造好的“東西”讀出來

當然了,語音合成不僅僅包含這兩個API,but我們先從這兩點入手

SpeechSyntehesisUtteranc

參考:https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesisUtterance
SpeechSyntehesisUtteranc對象包含了語音服務要讀取的內容和一些參數,比如語言,音高和音量

  • 首先我們可以通過 SpeechSyntehesisUtteranc() 構造函數構造一個對象
  • SpeechSynthesisUtterance.lang 語言
  • SpeechSynthesisUtterance.pitch 音調
  • SpeechSynthesisUtterance.rate 語速
  • SpeechSynthesisUtterance.voice 語音
  • SpeechSynthesisUtterance.volume 音量

注意: 以上屬性都是 可讀寫 的!
可以把下面這段代碼copy下來嘗試一下,註釋中會有說明

let msg = new SpeechSynthesisUtterance();
msg.text = "how are you" // 要合成的文本
msg.lang = "en-US" // 美式英語發音(默認自動選擇)
msg.rate = 2  // 二倍速(默認爲 1,範圍 0.1~10)
msg.pitch = 2 // 高音調(數字越大越尖銳,默認爲 1,範圍 0~2 )
msg.volume = 0.5 // 音量 0.5 倍(默認爲1,範圍 0~1)
window.speechSynthesis.speak(msg);

同時這個對象還可以響應一系列事件,可能會用到的:

  • start 開始閱讀
  • end 閱讀結束
  • boundary 到達單詞或句子邊界
  • pause 暫停
  • resume 從暫停中恢復

藉助這些事件我們可以完成一些簡單的功能,比如英文句子的單詞數量統計:

let count = 0; // 詞語數量
let msg = new SpeechSynthesisUtterance();
let synth = window.speechSynthesis;
msg.addEventListener('start',()=>{
    // 開始閱讀
    console.log(`文本內容: ${msg.text}`);
    console.log("start");
});
msg.addEventListener('end',()=>{
    // 閱讀結束
    console.log("end");
    console.log(`文本單詞(詞語)數量:${count}`);
    count = 0;
});
msg.addEventListener('boundary',()=>{
    // 統計單詞
    count++;
});

經過嘗試,由於中文沒有用空格將每個詞語分開,所以會進行自動的識別,比如 歡迎讀者 會被識別爲 歡迎讀者 兩個詞語

SpeechSynthesis

參考:https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesis

說完了 SpeechSyntehesisUtteranc 我們再來看看 SpeechSynthesis

SpeechSynthesis 的主要作用是對語音進行一系列的控制,比如開始或者暫停

它有三個只讀屬性,表明了語音的狀態:

  • SpeechSynthesis.paused(boolean 是否處於暫停)
  • SpeechSynthesis.pending(boolean 是否處於還有未讀語句)
  • SpeechSynthesis.speaking` (boolean 是否處於閱讀中)

同時還有一系列方法用來操作語音:

  • SpeechSynthesis.speak() 開始讀語音,同時觸發 start 事件
  • SpeechSynthesis.pause() 暫停,同時觸發 pause 事件
  • SpeechSynthesis.resume() 繼續,同時觸發 resume 事件
  • SpeechSynthesis.cancel() 取消閱讀,同時觸發 end 事件

基於這些操作方法,我們可以進一步增強我們的文字閱讀器:

回到最初的起點

讓我們回到最初的起點,我們可以基於上面的內容猜測一下有些網站中,文章的自動閱讀是怎麼實現的

如果這個網站前端採用了 MVVM 框架(以 Vue 爲例),那麼文章內容是也許存儲在 data 中,可以用來構造我們需要的語音合成

當然,也有可能文章是通過 ajax 請求得到的,解析請求的數據,構造語音合成對象

如果文章是直接在 html 中寫死的,這個時候就需要對 DOM 進行解析,經過測試,即便是下面這樣的混亂的結構

<div id="test">
    <p>1</p>
    <p>2</p>
    <ul>
        <li>3</li>
        <li>4</li>
    </ul>
    <table>
        <tr>
            <td>5</td>
            <td>6</td>
        </tr>
        <tr>
            <td>7</td>
            <td>8</td>
        </tr>
    </table>
    <img src="https://www.baidu.com/img/bd_logo1.png" alt="">
    9
</div>

直接通過 innerText 讀取其中的文本,然後構造語音合成對象,也能按照期望順序閱讀(圖片會被忽略)

當然如果我們想要忽略一些特殊的結構,比如表格,我們可以花一些精力在解析上,把我們不想要的數據或者 DOM 元素篩掉

不管怎樣,我們都能找到合適的解決方案~

閒話

這個特性,是一個還在草案中的特性,沒有被廣泛支持

再次強調,這個 API 暫時還不能應用到生產環境中

目前比較通用的做法是在後端構造將文本合成成語音文件的 API(也許是第三方 API),然後在前端作爲媒體播放

曾經在我迷茫的時候,我去閱讀一些大牛的文章,讀到一些前輩對前端開發的思考。其中有一點令我印象深刻:

前端是最貼近用戶的,一切要從用戶的的角度考慮,無障礙使用也是一個很重要的課題。雖然做這樣的功能帶來的收益遠遠小於其他業務,但是爲了讓產品更好的服務用戶,多付出一些勞動也是值得的,這也是前端開發的一種精神

本文同步發佈於我的個人博客CSDN掘金

如果有什麼問題,意見,建議歡迎評論;如果覺得我寫的不錯,那就點個贊吧~
完整demo

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章