明后两天就是公司一年一度的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(' '); } 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的微信公众号,我会将我的文章推送给您,并和您一起分享我日常阅读过的优质文章。