明后兩天就是公司一年一度的Fedex Day了。我的理解就是技術界的頭腦風暴,idea噴如泉涌的盛大節日。
對於這次活動每個人或者兩三個人一組需要有個idea,針對當前的產品現狀,提出自己的改進或者豐富產品的想法,我拿出自己的手機並登了經常去的網站,語音識別這個名詞脫穎而出,擊中我的腦海。相比較以前手指時代的手工輸入,各種在中英文乃至數字之間進行切換,往往還會因為走神或者手抖導致輸入出錯,然后又是一通狂按刪除鍵,一遍一遍的輸入,面對偌大的屏幕,有種使不上勁的感覺。語音輸入就可以告別這一煩惱,如今的語音識別准確率高,使用簡單易操作,更是為解放雙手鋪平了道路。你可以對着siri說幫我查看最近的天氣或者定個鬧鈴,你可以使用訊飛語音輸入法,說到哪就輸入到哪,你可以讓各種品牌的手機自帶的語音助手給你講個笑話……
今天閑來想先動動手,了解下這個語音識別技術,有什么好用的api可以調用。因為用的是度娘,所以映入眼簾的就是百度語音,"永久免費智能語音開放平台"的旗號還是深深的把我打動了。
摸索下來,看了兩種方式,一是基於REST API的方式完成語音識別,另一個是基於移動端Android平台的app語音識別。
一 、獲得入場券
1.注冊成為開發者
點擊進入http://yuyin.baidu.com/,用你的百度賬號完成登錄,如果在點擊“應用管理”選項卡后發現如下圖所示
說明你需要完成注冊驗證,提交完畢后,你就是一名百度開發者用戶了。
2.創建應用
完成上面操作后,點擊“應用管理”,如果頁面中沒有任何應用列表,說明你還需要添加一個應用,點擊頁面右上角“創建新應用”,填好應用類別並給他個名字,這樣就完成了應用創建。創建成功后就會看到類似下面這樣的效果。
在“查看Key”中,我們可以看到后面我們需要用到的App ID, API Key和Secret Key
3.開通服務
創建了應用后,我們需要開通語音識別的服務之后才能使用語音識別。點擊應用卡片上的“開通服務”,選擇語音識別即可。
至此,您已經獲得了入場券資格。
二、 基於REST API 的語音識別
百度語音支持android、ios和REST API三種平台。這里先介紹REST API,相對來說不用搭建android或者ios開發環境。
進入http://yuyin.baidu.com/asr/download下載REST API的示例和文檔。
示例分別有java、linux c和php版本,還附帶了一個test.pcm的音頻文件。
選擇java版本,導入eclipse中,代碼很簡單就一個測試類。
package com.baidu.speech.serviceapi; import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import javax.xml.bind.DatatypeConverter; import org.json.JSONObject; public class Sample { private static final String serverURL = "http://vop.baidu.com/server_api"; private static String token = ""; private static final String testFileName = "C:\\Users\\Administrator\\workspace\\speechrecognition\\src\\test.pcm"; //put your own params here private static final String apiKey = "***";//這里的apiKey就是前面申請在應用卡片中的apiKey private static final String secretKey = "***";//這里的secretKey就是前面申請在應用卡片中的secretKey private static final String cuid = "***";//cuid是設備的唯一標示,因為我用的是PC,所以這里用的是網卡Mac地址 public static void main(String[] args) throws Exception { getToken(); method1(); method2(); } private static void getToken() throws Exception { String getTokenURL = "https://openapi.baidu.com/oauth/2.0/token?grant_type=client_credentials" + "&client_id=" + apiKey + "&client_secret=" + secretKey; HttpURLConnection conn = (HttpURLConnection) new URL(getTokenURL).openConnection(); token = new JSONObject(printResponse(conn)).getString("access_token"); } private static void method1() throws Exception { File pcmFile = new File(testFileName); HttpURLConnection conn = (HttpURLConnection) new URL(serverURL).openConnection(); // construct params JSONObject params = new JSONObject(); params.put("format", "pcm"); params.put("rate", 8000); params.put("channel", "1"); params.put("token", token); params.put("cuid", cuid); params.put("len", pcmFile.length()); params.put("speech", DatatypeConverter.printBase64Binary(loadFile(pcmFile))); // add request header conn.setRequestMethod("POST"); conn.setRequestProperty("Content-Type", "application/json; charset=utf-8"); conn.setDoInput(true); conn.setDoOutput(true); // send request DataOutputStream wr = new DataOutputStream(conn.getOutputStream()); wr.writeBytes(params.toString()); wr.flush(); wr.close(); printResponse(conn); } private static void method2() throws Exception { File pcmFile = new File(testFileName); HttpURLConnection conn = (HttpURLConnection) new URL(serverURL + "?cuid=" + cuid + "&token=" + token).openConnection(); // add request header conn.setRequestMethod("POST"); conn.setRequestProperty("Content-Type", "audio/pcm; rate=8000"); conn.setDoInput(true); conn.setDoOutput(true); // send request DataOutputStream wr = new DataOutputStream(conn.getOutputStream()); wr.write(loadFile(pcmFile)); wr.flush(); wr.close(); printResponse(conn); } private static String printResponse(HttpURLConnection conn) throws Exception { if (conn.getResponseCode() != 200) { // request error return ""; } InputStream is = conn.getInputStream(); BufferedReader rd = new BufferedReader(new InputStreamReader(is)); String line; StringBuffer response = new StringBuffer(); while ((line = rd.readLine()) != null) { response.append(line); response.append('\r'); } rd.close(); System.out.println(new JSONObject(response.toString()).toString(4)); return response.toString(); } private static byte[] loadFile(File file) throws IOException { InputStream is = new FileInputStream(file); long length = file.length(); byte[] bytes = new byte[(int) length]; int offset = 0; int numRead = 0; while (offset < bytes.length && (numRead = is.read(bytes, offset, bytes.length - offset)) >= 0) { offset += numRead; } if (offset < bytes.length) { is.close(); throw new IOException("Could not completely read file " + file.getName()); } is.close(); return bytes; } }
整個類運行和普通的類運行完全沒兩樣,得到的控制台的信息如下:
{ "access_token": "***66a6adc3bb14***99.2592000.1462845194.282335-7***", "refresh_token": "25.344b6***6a9748d8b25a***360000.1775613194.282335-7***", "scope": "public audio_voice_assistant_get wise_adapt lebo_resource_base lightservice_public hetu_basic lightcms_map_poi kaidian_kaidian", "session_key": "9mzdC***7BvKTa4HuiEVYXrXOUPY***RSS8h4936rRxxd***V4PMq1Y+6OVKac+18rRxRtsT", "session_secret": "*352***e9a7a664ef***775e", "expires_in": 2592000 } { "result": ["百度語音提供技術支持,"], "err_msg": "success.", "sn": "160625465371460253194", "corpus_no": "6271739712934435529", "err_no": 0 } { "result": ["百度語音提供技術支持,"], "err_msg": "success.", "sn": "613862746801460253195", "corpus_no": "6271739717258680030", "err_no": 0 }
從結果看出,裝在test.pcm的那段語音內容就是“百度語音提供技術支持”。於是,我也利用windows自帶的錄音機功能,錄制了一段wav格式的語音,一開始報錯3301,查看文檔說是識別錯誤,打開音頻文件,發現沒有錄入任何東西,於是重新錄入進行識別,雖然沒有報錯,但是識別的並非語音內容,估計是噪音太大。
三、基於Android平台的語音識別
顯然,光是REST API模式還是玩的不過癮,想着在來試試移動端的效果如何,移動平台有android和ios,考慮到自己本子的情況,還是選擇了android,當然,這兩者都不熟悉。
網上找了一個可以直接使用的android環境http://blog.sina.com.cn/s/blog_6de000c20101rpva.html#cmt_2623882,下載了一通eclipse、sdk和adt等等,憑着之前搭建過一次android平台的記憶,勉強把環境弄好了。
於是還是如REST API中一樣需要下載android的sdk和文檔。SDK目錄包含以下內容:
各個模塊的功能如下:
導入demo項目到eclipse中,配置好virtual device,就可以啟動虛擬機(我在實際操作過程中,發現將libbdEASRAndroid.so和libBDVoiceRecognitionClient_MFE_V1.so導入classpath時會報錯,於是我刪除了這兩個包),運行起來的效果如下:
點擊下面工具欄的中間按鈕,進入全部應用,可以找到應用“Speech Recorder”:
點擊進入應用:
目前在點擊“Record”,應用會閃退,還沒摸清是什么原因,后面在研究下(有遇到過的歡迎留言指教)~~~
總得來說,百度語音還是蠻好上手的,文檔也比較詳細,但是就個人錄制的音頻識別來說,效果還有待提高(可能是音頻文件噪音過大)。
先混個臉熟,了解下支持的平台,api的調用方式,后面兩天趁Fedex Day好好看看這塊。
如果您覺得閱讀本文對您有幫助,請點一下“推薦”按鈕,您的“推薦”將是我最大的寫作動力!如果您想持續關注我的文章,請掃描二維碼,關注JackieZheng的微信公眾號,我會將我的文章推送給您,並和您一起分享我日常閱讀過的優質文章。