使用语音识别服务
近期因为项目需要,探索了两家提供语音识别服务的效果,分别是Google(参考文档)和国内的科大讯飞,探索的维度主要包括服务的使用方法以及识别的准确性。
Google很早就有自己的语音识别技术了,只不过没有开放出服务,有技术大拿通过挖掘Chrome中H5语音输入API相关的源码,找到了语音识别服务的接口,地址如下:
https://www.google.com/speech-api/v1/recognize
通过将编码的语音文件POST到这个API,带上相关参数,API就会返回识别结果。
使用API示例:
wget -O "GoogleSpeechAPI.txt" --user-agent="Mozilla/5.0" --post-file=record_0001.wav --header="Content-Type: audio/L16; rate=16000" "http://www.google.com/speech-api/v1/recognize?xjerr=1&client=chromium&lang=zh-CN&maxresults=1"
参数说明:
# HTTP头:
Content-Type: audio/L16; rate=16000 # 指定音频编码方式和采样频率
# 请求参数:
xjerr=1 # 不详,猜测为错误的标准
client=chromium # 客户端类型,这里是Chromium,Chrome也可行
lang=zh-CN # 语言类型,其余参考:http://msdn.microsoft.com/en-us/library/ms533052.aspx
maxresults=1 # 最大返回结果数量,多个结果在hypotheses列表中保存。
返回的结果:
{
"status":0, /* 结果代码,详细见本文结尾 */
"id":"c421dee91abe31d9b8457f2a80ebca91-1", /* 识别编号 */
"hypotheses": /* 结果 */
[
{
"utterance":"这是语音识别测试", /* 话语 */
"confidence":0.91828251 /* 信心,即准确度 */
}
]
}
测试的时候之前可能是因为音频实际采样频率不正确,识别的结果完全不搭嘎,后来找了一款android的录音软件,设置音频了采样频率,结果开始靠谱。既然有HTTP API,要在Java中实现调用不会困难。至于识别的准确率,参考后面的比较。
总结:
- API可用,对于简短的语句,识别的效果还算不错
- 支持多种语言(测试了中英文都可以),但需要我们告诉她是什么语言
- 支持WAV、Flac、SPEEX等多种音频格式
- 返回结果中给出了准确度信息,这样我们可以根据这个消息做差异化处理
- 存在一些可能的风险:
- 这个服务没有开放使用,法务上是否有问题
- 没有测试过是否有使用次数限制
- GFW
科大讯飞语音云
科大讯飞在国内做语音识别、语音合成等方面算得上领先的公司(上市公司),讯飞语音云(http://open.voicecloud.cn/)是其为开发者提供的语音识别/合成开放平台。
讯飞语音云提供了包括Android/iOS/Windows/Linux/Java等多个平台的SDK,SDK主要起到访问server端相应服务的客户端的作用,我们这次使用的是Java SDK。
使用SDK前需要先在web端申请注册应用并提交审核,审核通过前有500次/天的调用限制,通过后无次数限制。
Java SDK使用方法:
- 访问科大讯飞语音云主页,注册账号并申请一个appid
- 下载Java SDK,将提供的jar引入到项目classpath中,运行时将提供的dll/so文件引入到JVM本地库目录(可以通过java.library.path添加)
- 编写代码,调用SDK中相应接口发送音频流,并注册Listener接受识别结果,接口对音频流有限制,要求是
采样率16KHZ或者8KHZ,单声道,采样精度16bit的PCM或者WAV格式的音频
识别语音Java代码:
private void execute() throws Exception {
SpeechRecognizer speechRecognizer = SpeechRecognizer.createRecognizer("appid=xxx");
FileInputStream inputStream = new FileInputStream(new File("Record.wav"));
byte[] bytes = IOUtils.toByteArray(inputStream);
speechRecognizer.recognizeAudio(new MyListener(), bytes, "sms", null, null);
Thread.sleep(20*1000);
}
private class MyListener implements RecognizerListener {
@Override
public void onVolumeChanged(int i) {
}
@Override
public void onBeginOfSpeech() {
}
@Override
public void onEndOfSpeech() {
}
@Override
public void onResults(ArrayList results, boolean b) {
String text = "";
for(int i = 0; i < results.size(); i++)
{
RecognizerResult result = (RecognizerResult)results.get(i);
text += result.text;
}
System.out.println("result:" + text);
}
@Override
public void onEnd(SpeechError speechError) {
}
@Override
public void onCancel() {
}
}
总结:
- 提供了跨平台的SDK,Java SDK使用起来还算方便(除了要在运行时引入本地库)
- 同Google一样,在识别简短语句时准确率还不错,当语音较长或者说话者说话断断续续时(停下来思考如何点评),识别率降低很多
- 仅支持中文,对输入的音频编码格式要求较严格
- 稳定性没做过验证
- 技术支持很到位,在群里问的问题基本都有人会回答
语音识别测试效果对比
原文 | 科大讯飞 | |
---|---|---|
这是语音识别测试 | 这是语音识别测试 | 这是语音识别测试 |
blog comments powered by Disqus