使用Google語音識別引擎(Google Speech API)

文章來源:http://blog.csdn.net/dlangu0393/article/details/7214728

最近在使用Qt編寫一個客戶端程序的時候需要增加語音識別輸入的功能。起初嘗試使用SAPI來完成這個任務,但是發現SAPI不僅使用起來超級複雜,而且識別效果也很慘烈。於是就需要尋找一個更加便捷優秀的方案。

    自從Chrome 11開始,Chrome開始支持HTML5的語音輸入API,QQ緊接着也推出了語音識別輸入(可以看做跟風麼:D)。顯然這些識別操作不可能在本地完成,那麼我們就有直接利用接口的可能。

 

    對Chromium的repo進行搜索之後,終於找到了Chromium對語音識別的實現代碼:

 

http://src.chromium.org/viewvc/chrome/trunk/src/content/browser/speech/

 

    分析過程就算了,直接上成果。

    Chromium先從mic獲取音頻,然後使用flac或者speex進行編碼,直接通過HTTPS POST到服務器。接口地址如下:

 

    https://www.google.com/speech-api/v1/recognize

 

    Chromium在請求時還會拼上很多參數:

 

    xjerr=1&client=chromium&lang=en-US&maxresults=1

 

    注:參數解釋

        xjerr=1    # 不詳,猜測爲錯誤的標準

        client=chromium    # 客戶端類型,這裏是Chromium,猜測Chrome也應該可行,估計是作爲統計用的。

        lang=en-US    # 語言類型,這裏是英文,中文爲zh-CN,其餘語言代碼參考:http://msdn.microsoft.com/en-us/library/ms533052(v=vs.85).aspx

        maxresults=1    # 最大返回結果數量,多個結果在hypotheses列表中保存。

 

    參數很明瞭,這給我們提供了很多便利。我們對參數進行調整,得到如下的接口地址:

 

    http://www.google.com/speech-api/v1/recognize?xjerr=1&client=chromium&lang=zh-CN&maxresults=1

 

    

    接下來祭出wget,對已經發現的接口進行測試:

 

  1. flac.exe -8 -f --sample-rate=16000 speechInput.wav  
  1. wget -O "GoogleSpeechAPI.txt" --user-agent="Mozilla/5.0" --post-file=test.flac --header="Content-Type: audio/x-flac; rate=16000" "http://www.google.com/speech-api/v1/recognize?xjerr=1&client=chromium&lang=zh-CN&maxresults=1"  

 

    結果如下:

 

[javascript] view plaincopyprint?
 
  1. {  
  2.     "status":0,    /* 結果代碼,詳細見本文結尾 */  
  3.     "id":"c421dee91abe31d9b8457f2a80ebca91-1",    /* 識別編號 */  
  4.     "hypotheses":    /* 假設,即結果 */  
  5.     [  
  6.         {  
  7.             "utterance":"下午好",    /* 話語 */  
  8.             "confidence":0.2507637    /* 信心,即準確度 */  
  9.         }  
  10.     ]  
  11. }  

 

    注:註釋後爲手工添加的結果解釋

 

    返回結果太明瞭了!直接就能拿來用了不是~ 返回的編碼是UTF-8

    對於編碼格式,在測試中使用了FLAC編碼,採樣率爲16kHz,經測試其他採樣率同樣可用,但一定要保證Header裏的rate與實際數據相符。(關於其他格式的實驗請看本文底部。)

 

 

 

    總結:

    1、基本流程:

 

一、從音頻輸入設備獲取原始數據。
二、對原始數據進行包裝、編碼。
三、將編碼後的音頻POST至接口地址。
四、分析處理接口返回的JSON並得出結果。

    2、請求接口

 

 

請求方式:HTTP POST
頭部信息:Content-Type: audio/x-flac; rate=16000   (注:Content-Type根據所使用的編碼格式不同而不同,詳見文章底部。rate爲音頻採樣率。)
請求數據:編碼後的音頻數據

 

    3、音頻編碼格式:

 

FLAC或WAV或SPEEX

 

 

    下面是我寫的Qt(C++)中的請求:

 

 

  1. void Protocol::Request_SPEECH(QByteArray & audioData)  
  2. {  
  3.     if (!Nt_SPEECH)  
  4.     {  
  5.         QNetworkRequest request;  
  6.         QString speechAPI = "http://www.google.com/speech-api/v1/recognize?xjerr=1&client=chromium&lang=zh-CN&maxresults=1";  
  7.         request.setUrl(speechAPI);  
  8.   
  9.         request.setRawHeader("User-Agent""Mozilla/5.0");  
  10.         request.setRawHeader("Content-Type""audio/x-flac; rate=16000");  
  11.   
  12.         Nt_SPEECH = NetworkMGR.post(request, audioData);  
  13.         connect(Nt_SPEECH, SIGNAL(readyRead()), this, SLOT(Read_SPEECH()));  
  14.     }  
  15. }  


    至於讀取函數,就不貼在這裏了,具體見:

 

Protocol: http://pastebin.com/6G6wggfF

AudioInput:

    speechInput.h: http://pastebin.com/qdMPeWZD

    speechInput.cpp: http://pastebin.com/567B47qF

main:

    mainwidget: http://pastebin.com/c8bk7zd2

 

    在翻閱Chromium源碼的過程之中,還發現了其他有用的東西:

Speech Input API Specification http://www.w3.org/2005/Incubator/htmlspeech/2010/10/google-api-draft.html

    到目前爲止,Google好像還沒有公開這個API,使用許可依舊不詳,請求也沒有用到任何認證。但它確實能用,而且十分方便,對於編寫非商業程序的人來說,這個東西真的是再好不過了(因爲它有着高的爆表的識別率)。

 

參考:

Chromium Repository    http://src.chromium.org/viewvc/chrome/trunk/src/content/browser/speech/

Accessing Google Speech API / Chrome 11    http://mikepultz.com/2011/03/accessing-google-speech-api-chrome-11/

 

 

附:

1、SpeechInputError interface 錯誤信息

 

  1. // This enumeration follows the values described here:  
  2. // http://www.w3.org/2005/Incubator/htmlspeech/2010/10/google-api-draft.html#speech-input-error  
  3. enum SpeechInputError {  
  4.   // There was no error.  
  5.   SPEECH_INPUT_ERROR_NONE = 0,  
  6.   // The user or a script aborted speech input.  
  7.   SPEECH_INPUT_ERROR_ABORTED,  
  8.   // There was an error with recording audio.  
  9.   SPEECH_INPUT_ERROR_AUDIO,  
  10.   // There was a network error.  
  11.   SPEECH_INPUT_ERROR_NETWORK,  
  12.   // No speech heard before timeout.  
  13.   SPEECH_INPUT_ERROR_NO_SPEECH,  
  14.   // Speech was heard, but could not be interpreted.  
  15.   SPEECH_INPUT_ERROR_NO_MATCH,  
  16.   // There was an error in the speech recognition grammar.  
  17.   SPEECH_INPUT_ERROR_BAD_GRAMMAR,  
  18. };  


2、多種音頻格式的測試

    收到朋友的郵件說使用flac實在是很不方便,問我有沒有更好的解決方法,於是我嘗試將其他編碼格式應用於Google Speech API。以下爲結果:

    1、WAV格式

    請求Header:Content-Type: audio/L16; rate=16000

    返回結果:識別成功

    2、MP3格式

    請求Header:Content-Type: audio/mpeg; rate=16000

    返回結果:無法識別的編碼

 

    請求Header:Content-Type: audio/mpeg3; rate=16000

    返回結果:無法識別的編碼

    請求Header:Content-Type: audio/x-mpeg; rate=16000

    返回結果:無法識別的編碼

 

    請求Header:Content-Type: audio/x-mpeg-3; rate=16000

    返回結果:無法識別的編碼

    請求Header:Content-Type: audio/mp3; rate=16000

    返回結果:無法識別的編碼

    3、PCM格式

 

    請求Header:Content-Type: audio/x-ogg-pcm; rate=16000

    返回結果:無法識別的編碼

    請求Header:Content-Type: audio/pcm; rate=16000

    返回結果:無法識別的編碼

    4、SPEEX格式

    請求Header:Content-Type: audio/x-speex-with-header-byte; rate=16000

    返回結果:識別成功

 

    請求Header:Content-Type: audio/speex; rate=16000

    返回結果:識別成功

 

    由於識別接口並不開放,所以無法得知具體的支持格式,如果哪位朋友發現了新的支持格式,請一定要留言哦!

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