随着智能家居概念的火热,语音交互这一新时代的人机交互方式再度掀起了热潮。移动互联网应用在设计开发时也纷纷考虑加入语音识别功能,带给用户除传统键盘或触控交互方式外的更便捷交互体验。中国移动近日推出的“灵犀云”,作为新一代的智能语音云平台,正致力于为应用提供全方位的智能语音能力服务,带给用户高效、准确、智能的交互体验。
基于中移动与语音行业领军者科大讯飞的深度战略合作背景,灵犀云的核心技术源自科大讯飞。凭借电信级网络及4G服务的优势,灵犀云在语音服务质量上具备领先优势。这也是继双方此前面向广大用户推出灵犀语音助手APP后,中移动向广大应用开发者们呈献的一大利器,助力应用进入智能交互时代。
这篇文章主要介绍利用灵犀云SDK实现语音识别(包括语音转换为文字的“语音听写”,及语音”命令词识别“)的方法:
1、注册并登录中国移动开发者社区 http://dev.10086.cn(建议使用IE或IE内核浏览器)
2、登录成功后,点击下图红框指示的“申请能力应用”
3、点击“申请能力应用”按钮
4、填写您应用的基本信息
5、语音服务AppID申请成功,之后点击下方按钮下载SDK。
6、让你下载的SDK用起来:
Step 1 导入SDK
[1]在Eclipse中建立你的Android工程。
[2] 将开发工具包中libs目录下的Msc.jar复制到新建工程的libs目录中(如下图所示)。
[3]将开发工具包中armeabi(armeabi-v7a,mips,x86)目录下的libmsc.so复制到新建工程的armeabi目录中(如下图所示)。
[4]在你需要使用MSC服务的文件中导入相应的类。
例如 添加听写功能:importcom.iflytek.cloud.SpeechRecognizer;
Step 2 添加用户权限
在工程AndroidManifest.xml文件中添加如下权限
<!--连接网络权限,用于执行云端语音能力 -->
<uses-permission android:name="android.permission.INTERNET"/>
<!--获取手机录音机使用权限,听写、识别、语义理解需要用到此权限 -->
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<!--读取网络信息状态 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<!--获取当前wifi状态 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<!--允许程序改变网络连接状态 -->
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<!--读取手机信息权限 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<!--读取联系人权限,上传联系人需要用到此权限 -->
<uses-permission android:name="android.permission.READ_CONTACTS"/>
注:如需打包或者生成APK的时候进行混淆,在proguard.cfg中添加如下代码
-keep class com.iflytek.**{*;}
Step 3 功能添加
[1] 初始化
创建用户语音配置对象后才可以使用语音服务,建议在程序入口处调用。
// 将“12345678”替换成您申请的APPID,申请地址:http://dev.10086.cn/
SpeechUtility.createUtility(context, SpeechConstant.APPID +"=12345678");
[2] 语音听写
主要指将连续语音快速识别为文字的过程,能识别通用常见的语句、词汇,不限制说法。
1.语音听写
//1.创建SpeechRecognizer对象
SpeechRecognizer mIat= SpeechRecognizer.createRecognizer(context, null);
//2.设置听写参数,详见《CMCC MSC Reference Manual》SpeechConstant类
mIat.setParameter(SpeechConstant.DOMAIN, "iat");
mIat.setParameter(SpeechConstant.LANGUAGE, "zh_cn");
mIat.setParameter(SpeechConstant.ACCENT, "mandarin ");
//3.开始听写
mIat.startListening(mRecoListener);
//听写监听器
private RecognizerListener mRecoListener = new RecognizerListener(){
//听写结果回调接口(返回Json格式结果,用户可参见文档末尾的附录表);
//一般情况下会通过onResults接口多次返回结果,完整的识别内容是多次结果的累加;
//关于解析Json的代码可参见MscDemo中JsonParser类;
//isLast等于true时会话结束。
public void onResult(RecognizerResult results, boolean isLast) {
Log.d("Result:",results.getResultString ());
}
//会话发生错误回调接口
public void onError(SpeechError error) {error.getPlainDescription(true) //获取错误码描述}
//开始录音
public void onBeginOfSpeech() {}
//音量值0~30
public void onVolumeChanged(int volume){}
//结束录音
public void onEndOfSpeech() {}
//扩展用接口
public void onEvent(int eventType,int arg1,int arg2,String msg) {}
};
2.上传联系人
上传联系人可以提高联系人名称识别率,也可以提高语义的效果,每个用户终端设备对应一个联系人列表,联系人格式详见 《CMCC MSC Reference Manual》ContactManager类。
//获取ContactManager实例化对象
ContactManager mgr = ContactManager.createManager(context, mContactListener);
//异步查询联系人接口,通过onContactQueryFinish接口回调
mgr.asyncQueryAllContactsName();
//获取联系人监听器。
private ContactListener mContactListener = new ContactListener() {
@Override
public void onContactQueryFinish(String contactInfos, boolean changeFlag) {
//指定引擎类型
mIat.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD);
mIat.setParameter(SpeechConstant.TEXT_ENCODING,"utf-8");
ret = mIat.updateLexicon("contact", contactInfos, lexiconListener);
if(ret != ErrorCode.SUCCESS){
Log.d(TAG,"上传联系人失败:" + ret);
}
}
};
//上传联系人监听器。
private LexiconListener lexiconListener = new LexiconListener() {
@Override
public void onLexiconUpdated(String lexiconId, SpeechError error) {
if(error != null){
Log.d(TAG,error.toString());
}else{
Log.d(TAG,"上传成功!");
}
}
};
3.上传用户词表
上传用户词表可以提高词表内词汇的识别率,也可以提高语义的效果,每个用户终端设备对应一个词表,用户词表的格式及构造方法详见 《CMCC MSC Reference Manual》UserWords类。
//上传用户词表,userwords为用户词表文件。
String contents = "您所定义的用户词表内容";
mIat.setParameter(SpeechConstant.TEXT_ENCODING,"utf-8");
//指定引擎类型
mIat.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD);
ret = mIat.updateLexicon("userword", contents, lexiconListener);
if(ret != ErrorCode.SUCCESS){
Log.d(TAG,"上传用户词表失败:" + ret);
}
//上传用户词表监听器。
private LexiconListener lexiconListener = new LexiconListener() {
@Override
public void onLexiconUpdated(String lexiconId, SpeechError error) {
if(error != null){
Log.d(TAG,error.toString());
}else{
Log.d(TAG,"上传成功!");
}
}
};
//下载用户词表
DataDownloader dataDownloader = new DataDownloader(context);
dataDownloader.setParameter(SpeechConstant.SUBJECT, "spp");
dataDownloader.setParameter(SpeechConstant.DATA_TYPE, "userword");
dataDownloader.downloadData(downloadlistener);
//用户词表下载监听器。
private SpeechListener downloadlistener = new SpeechListener(){
//用户词表结果回调
public void onData(byte[] data) {}
//用户词表完成回调
public void onCompleted(SpeechError error) {}
//用户词表事件回调
[3] 语法识别
主要指基于命令词的识别,识别指定关键词组合的词汇,或者固定说法的短句。语法识别采用ABNF语法格式进行识别。
//1.创建SpeechRecognizer对象
SpeechRecognizer mAsr = SpeechRecognizer.createRecognizer(context, null);
// ABNF语法示例,可以说”北京到上海”
String mCloudGrammar = "#ABNF 1.0 UTF-8;
languagezh-CN;
mode voice;
root $main;
$main = $place1 到$place2 ;
$place1 = 北京 | 武汉 | 南京 | 天津 | 天京 | 东京;
$place2 = 上海 | 合肥; ";
//2.构建语法文件
mAsr.setParameter(SpeechConstant.TEXT_ENCODING, "utf-8");
ret = mAsr.buildGrammar("abnf", mCloudGrammar , grammarListener);
if (ret != ErrorCode.SUCCESS){
Log.d(TAG,"语法构建失败,错误码:" + ret);
}else{
Log.d(TAG,"语法构建成功");
}
//3.开始识别,设置引擎类型为云端
mAsr.setParameter(SpeechConstant.ENGINE_TYPE, "cloud");
//设置grammarId
mAsr.setParameter(SpeechConstant.CLOUD_GRAMMAR, grammarId);
ret = mAsr.startListening(mRecognizerListener);
if (ret != ErrorCode.SUCCESS) {
Log.d(TAG,"识别失败,错误码: " + ret);
}
//构建语法监听器
private GrammarListener grammarListener = new GrammarListener() {
@Override
public void onBuildFinish(String grammarId, SpeechError error) {
if(error == null){
if(!TextUtils.isEmpty(grammarId)){
//构建语法成功,请保存grammarId用于识别
}else{
Log.d(TAG,"语法构建失败,错误码:" + error.getErrorCode());
}
}};