Webduino 學習手冊網站即將改版,提供您更好的閱讀體驗!

搶先試用

語音辨識

語音辨識的技術其實存在已久,而 Chrome 瀏覽器也早就將其納入預設的支援,由於是 Chrome 內建的功能,所以不需要額外載入其他資源就可以運行,但也很可惜的是現在就只有桌上版的 Chrome 才支援 ( Android 版本只部分支援,iOS 版本則是尚未支援 )

相關 Webduino 教學參考:LED ( 語音聲控 )

語音辨識初體驗

有興趣的人可以先到這個語音辨識 demo 網站看看:,下拉選單選擇自己要唸的語言,按一下右上的麥克風,就可以開始玩語音輸入了。

網站連結:https://www.google.com/intl/en/chrome/demos/speech.html

語音辨識 demo 網站

如果覺得直接寫程式碼太複雜,其實 Webduino Blockly 線上工具 ( https://blockly.webduino.io ) 也有提供語音辨識的功能,開啟下面的範例連結,點選右上角紅色的執行,就可以直接體驗。

範例連結:https://goo.gl/1BJ5eB

語音辨識積木

實作語音辨識

來看一下怎麼實作語音辨識,語音辨識一開始要判斷「webkitSpeechRecognition」有沒有存在瀏覽器裡,因為這是內建於瀏覽器的 API,從 webkit 的字樣可以知道,只有 Chrome 才支援,所以一開始的程式可以這樣寫:

if (!('webkitSpeechRecognition' in window)) {
  // do something...
} else {
  // do something...
}

if 裡面就可以放個 alert 或顯示文字作為警告,重點放在 else 裏頭,一開始要先建立 webkitSpeechRecognition 物件,接著才可以使用這個物件的屬性來做設定。

var recognition = new webkitSpeechRecognition();

再來瞭解一下有哪些屬性可以用:

recognition.onresult 是進行語音辨識最關鍵的動作,所以我們要來解構一下語音辨識時的結果,用下面的範例來看看 event 長怎樣,當我們講話進行辨識的時候,就會印出 event。

var recognition = new webkitSpeechRecognition();

recognition.continuous=true;
recognition.interimResults=true;
recognition.lang="cmn-Hant-TW";

recognition.onstart=function(){
  console.log('開始辨識...');
};
recognition.onend=function(){
  console.log('停止辨識!');
};

recognition.onresult=function(event){
  console.log(event);
};

recognition.start();     

語音辨識運作程式碼

從印出來的結果可以看到,每一段話之間其實都存在著一個「isFinal」的屬性,這個屬性如果是 true,表示這段話結束,就會把這段話存為一個 result,因此我們可以從這邊發現幾個比較重要的 event 屬性如下:

有了上面的屬性列表,我們就可以做一個即時辨識並把文字顯示在網頁上頭的範例:

var show = document.getElementById('show');
var recognition = new webkitSpeechRecognition();

recognition.continuous=true;
recognition.interimResults=true;
recognition.lang="cmn-Hant-TW";

recognition.onstart=function(){
  console.log('開始辨識...');
};
recognition.onend=function(){
  console.log('停止辨識!');
};

recognition.onresult=function(event){
  var i = event.resultIndex;
  var j = event.results[i].length-1;
  show.innerHTML = event.results[i][j].transcript;
};

recognition.start();

顯示語音辨識文字

語音辨識控制燈泡

了解語音辨識的用法之後,接著就來看一下怎麼把語音辨識和智慧插座結合,燈泡接線圖很簡單:

語音辨識和智慧插座結合

一如往常,HTML 的部分先在自己的網頁內引入「 webduino-min.js 」還有「 webduino-blockly.js 」這兩個 JavaScript,在 body 的區域放入一個 h2 來顯示辨識出來的文字,然後放入兩張燈泡一明一暗的圖片,讓接收到語音辨識的時候,網頁上的燈泡也會發生反應。

<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
  <title>Webduino</title>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
  <script src="https://webduino.io/components/webduino-js/dist/webduino-all.min.js"></script>
  <script src="https://blockly.webduino.io/webduino-blockly.js"></script>
</head>

<body>
  <h2 id="show"></h2>
  <img src="http://example.oxxostudio.tw/it2016/it2016-day05-on.jpg" id="on">
  <img src="http://example.oxxostudio.tw/it2016/it2016-day05-off.jpg" class="show" id="off">
</body>
</html>

CSS 的部分就只是寫個簡單的控制燈泡圖片有沒有出現而已。

img{
  display:none;
}
.show{
  display:block;
}

JavaScript 的部分一開始先設定一些變數,以及語音辨識的參數,比較特別的是我在這裡多設定一個非官方的屬性 recognition.status = true,因為語音辨識會在「切換分頁」或是「五分鐘內沒有接收到訊號」的情況下中斷,因此多加一個判斷,讓「非使用者自行中斷」的情形發生時,又會自動啟動語音辨識。

至於接下來的判斷,因為只有「開燈」與「關燈」的字詞而已,所以這邊就單純使用 indexOf 來判斷,當然如果邏輯寫得更複雜,應該就能做出更好的判斷囉!

$(function(){

  var led,
      $show=$('#show'),
      $on = $('#on'), 
      $off = $('#off'),
      a = 0,
      result;

  var recognition = new webkitSpeechRecognition(); //new 一個語音辨識物件

  //語音辨識參數設定
  recognition.continuous = true;
  recognition.interimResults = true;
  recognition.lang = "cmn-Hant-TW";
  recognition.status = true;  //手動添加判斷,避免如果五分鐘沒有語音,就會自動停止
  recognition.onstart=function(){
    $show.text('語音辨識中...');
  };
  recognition.onend=function(){
    if(recognition.status === true){
      recognition.start();
    }else{
      $show.text('停止辨識!');
    }
  };

  //裝置連線
  boardReady('你的裝置 ID', function (board) {
    board.systemReset();
    board.samplingInterval = 250;
    led = getLed(board, 10); //設定 LED 為 10 號腳
    recognition.onresult=function(event){
      var i = event.resultIndex;
      var j = event.results[i].length-1;
      result = event.results[i][j].transcript; //取出語音辨識結果
      $show.text(result); //顯示語音辨識結果
      if(result.indexOf('開燈')!== -1){
        led.on();
        $on.addClass('show');
        $off.removeClass('show');
      }else if(result.indexOf('關燈')!== -1){
        led.off();
        $on.removeClass('show');
        $off.addClass('show');
      }
    };
    recognition.start(); 
  });

});

用 Chrome 打開網頁,就可以用講話來控制燈泡的亮滅囉。

完整程式碼:http://bin.webduino.io/fayi/1/edit?html,js,output

利用語音辨識點亮智慧插座燈泡

如果是用 Webduino Blockly 來完成,積木的長相就會像這樣:

範例程式:https://goo.gl/rThnGD

Webduino Blockly 語音辨識設定積木

小結

其實語音辨識技術的難度並沒有很高,而且辨識度也滿好的,相信許多的應用都能夠使用到語音辨識的技術!

參考資料