http://www.cnblogs.com/bigdataZJ/p/SpeechRecognition.html
明后两天就是公司一年一度的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中,代码很简单就一个测试类。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | 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; } } |
整个类运行和普通的类运行完全没两样,得到的控制台的信息如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | { "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的微信公众号,我会将我的文章推送给您,并和您一起分享我日常阅读过的优质文章。