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

新的 JavaScript Web Speech API 可讓您輕鬆在網頁中加入語音辨識功能。這個 API 可讓您在 Chrome 25 以上版本中,靈活控管語音辨識功能。以下範例顯示,在您說話時,系統幾乎立即顯示辨識結果。

Web Speech API 示範

DEMO / SOURCE

我們來看看內部運作情形。首先,我們會檢查瀏覽器是否支援 Web Speech API,方法是檢查 webkitSpeechRecognition 物件是否存在。如果不是,建議使用者升級瀏覽器。(由於 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 事件以來,所有中間結果都可能已變更。我們可以對 final_transcript 執行相同的操作,只要將 for 迴圈從 0 開始即可。不過,由於最終文字永遠不會變更,我們將 final_transcript 設為全域變數,讓這段程式碼更有效率,這樣這項事件就能在 event.resultIndex 開始 for 迴圈,並只附加任何新的最終文字。

這樣就大功告成了!程式碼的其餘部分只是為了讓一切看起來更美觀。它會維持狀態、向使用者顯示一些資訊性訊息,並在麥克風按鈕上交替顯示靜態麥克風、麥克風加刪號圖示,以及麥克風動畫與閃爍紅點。

呼叫 recognition.start() 時會顯示麥克風斜線圖示,然後在 onstart 觸發時替換為麥克風動畫圖示。通常這會發生得非常迅速,因此使用者不會注意到斜線,但第一次使用語音辨識時,Chrome 需要向使用者要求使用麥克風的權限,在這種情況下,onstart 只會在使用者允許權限時觸發。託管在 HTTPS 上的網頁不需要重複要求權限,但 HTTP 託管的網頁則需要。

因此,請讓網頁能聆聽使用者的聲音,讓網頁更生動有趣!

歡迎提供寶貴意見...

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