語音驅動網頁應用程式 - Web Speech API 簡介

新版 JavaScript Web Speech API 可讓您輕鬆在網頁中加入語音辨識功能。這個 API 可讓您靈活控管 Chrome 25 以上版本中的語音辨識功能,並提供相關彈性。在以下示例中,已辨識的文字幾乎會在說話時立即顯示。

Web Speech API 示範

示範 / 來源

一起來看看背後的運作原理。首先,我們會檢查 webkitSpeechRecognition 物件是否存在,確認瀏覽器是否支援 Web Speech API。如果沒有,我們建議使用者升級瀏覽器。(由於 API 仍在實驗階段,因此目前是由供應商加入)。最後,我們會建立 webkitSpeechRecognition 物件來提供語音介面,並設定部分屬性和事件處理常式。

if (!('webkitSpeechRecognition' in window)) {
    upgrade();
} else {
    var recognition = new webkitSpeechRecognition();
    recognition.continuous = true;
    recognition.interimResults = true;

    recognition.onstart = function() { ... }
    recognition.onresult = function(event) { ... }
    recognition.onerror = function(event) { ... }
    recognition.onend = function() { ... }
    ...

continuous 的預設值為 False,表示當使用者停止說話時,語音辨識功能就會結束。這個模式非常適合用於短輸入欄位等簡單的文字。在這個示範中,我們將值設為 true,這樣即便使用者在說話時暫停,仍可繼續辨識。

interimResults 的預設值是 false,表示辨識器傳回的結果是最終結果,不會變更。示範會將其設為 true,以便盡早取得可能改變的暫時性結果。請仔細觀看示範影片,灰色文字是暫時性文字,有時不會改變,黑色文字則是辨識工具發出的最終回應,且不會改變。

如要開始操作,使用者點選麥克風按鈕後會觸發以下程式碼:

function startButton(event) {
    ...
    final_transcript = '';
    recognition.lang = select_dialect.value;
    recognition.start();

我們將語音辨識器「lang」的口語設定為使用者透過選取下拉式清單選取的 BCP-47 值,例如「en-US」代表英文 (美國)。如未設定,則會預設為 HTML 文件根元素和階層的 lang。Chrome 語音辨識功能支援許多語言 (請參閱示範來源中的「langs」表格),以及這項示範未包含的幾種從右到左書寫的語言,例如「He-IL」和「ar-EG」。

設定語言後,我們會呼叫 recognition.start() 以啟用語音辨識器。它開始擷取音訊後會呼叫 onstart 事件處理常式,然後針對每一組新的結果呼叫 onresult 事件處理常式。

recognition.onresult = function(event) {
    var interim_transcript = '';

    for (var i = event.resultIndex; i < event.results.length; ++i) {
        if (event.results[i].isFinal) {
            final_transcript += event.results[i][0].transcript;
        } else {
            interim_transcript += event.results[i][0].transcript;
        }
    }
    final_transcript = capitalize(final_transcript);
    final_span.innerHTML = linebreak(final_transcript);
    interim_span.innerHTML = linebreak(interim_transcript);
    };
}

這個處理常式會將目前為止收到的所有結果串連為兩個字串:final_transcriptinterim_transcript。產生的字串可能會包含「\n」,例如使用者說出「new paragraph」(新段落) 時,我們會使用 linebreak 函式將這些字串轉換為 HTML 標記 <br><p>。最後,這些字串會將這些字串設為相應 <span> 元素的 innerHTML:final_span (樣式為黑色) 和 interim_span (樣式為灰色)。

interim_transcript 是本機變數,會在每次呼叫此事件時徹底重建,因為自上次 onresult 事件以來,所有暫時性結果都可能有所變化。我們可以用 0 為 0 開始迴圈,以對 final_transcript 進行相同操作。不過,由於最終文字不會變更,因此我們將 final_transcript 設為全域,會更有效率地在這裡編寫程式碼,讓這個事件可在 event.resultIndex 啟動 迴圈,並只附加任何新的最終文字。

這樣就大功告成了!程式碼的其餘部分只是讓所有內容看起來更美觀。應用程式會維持狀態、向使用者顯示一些資訊訊息,並在靜態麥克風、麥克風斜線圖片與麥克風動畫 (紅點閃爍) 之間切換麥克風按鈕上的 GIF 圖片。

呼叫 recognition.start() 時顯示麥克風斜線圖片,然後在 onstart 觸發時替換為麥克風動畫。一般情況下,延遲情形因此不明顯,但首次使用語音辨識功能時,Chrome 必須要求使用者授予麥克風使用權限;在這種情況下,只有在使用者授予權限時,onstart 才會觸發。透過 HTTPS 代管的網頁無需重複要求權限,HTTP 代管網頁則不需要重複要求權限。

因此,建議您不妨讓使用者傾聽他們的意見,讓網頁動起來!

歡迎提供意見...

請參閱 Chrome 隱私權白皮書,瞭解 Google 如何處理這個 API 的語音資料。