玩转百度语音识别,就是这么简单

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的微信公众号,我会将我的文章推送给您,并和您一起分享我日常阅读过的优质文章。

  
  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值