项目集成语音识别(科大讯飞)
1.首先你要做的事情,打开讯飞开放平台,下载SDK(地址:http://www.xfyun.cn/sdk/dispatcher),平台上面的服务有很多种,根据项目的需求下载,下载前会让你先 创建一个应用,完后会生成一个唯一的appid。
2.这里以语音听写为例。(虽然是免费的,但是有次数限制,开发使用测试还可以,但是用户量多的还是建议购买服务)。
SDK下载完成之后解压出来,我们需要用到的有三样东西armeab文件夹里的libmsc.so库Msc.jar和Sunflower.jar,这三个放进去就OK了。
3.讯飞还为我们提供了一套语音听写的UI,如果选择使用的话,需要将刚才解压的SDK资源包assets路径下的资源文件拷贝到项目的asstes下(没有的话自己建一个)。
4.接下来看代码怎么实现,开放平台上面有开发文档,但是其实我不建议参考那个,因为SDK里面有demo,你只需要找到入口就可以,根据线索看下去,不一会儿就搞定了。
第一步:权限(只管拷贝进去就好了)
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<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.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
第二步:调用SpeechUtility.createUtility(this, "appid=" + getString(R.string.app_id)); 初始化创建对象,可以放在项目的application里面初始化,也可以在使用的时候初始化。
不然会报错:"创建对象失败,请确认 libmsc.so 放置正确,且有调用 createUtility 进行初始化"
接下来就把代码贴上去,带注释应该就能看懂了 。
在oncreat中的代码
mIat = SpeechRecognizer.createRecognizer(this, mInitListener);//这个是没有UI功能的,但是有Toast提示
mIatDialog = new RecognizerDialog(this, mInitListener);// 初始化听写Dialog,如果只使用有UI听写功能,无需创建SpeechRecognizer,这里我两个都做了,选择性使用
recognizerDialog = new RecognizerDialog(this, mInitListener);
sharedPreferences = getSharedPreferences(PREFER_NAME, Activity.MODE_PRIVATE);
spedit = sharedPreferences.edit();
btStart = (Button) findViewById(R.id.btStart);
btStart.setOnClickListener(this);
editText = (EditText) findViewById(R.id.editText);
toggleButton1 = (ToggleButton) findViewById(R.id.toggleButton1);
toggleButton1.setChecked(isShowDialog);
上面这一堆代码没有什么可读性,UI开关按钮还有显示控件等。
@Override
public void onClick(View v) {
if( null == mIat )
{
// 创建单例失败,与 21001 错误为同样原因,参考 http://bbs.xfyun.cn/forum.php?mod=viewthread&tid=9688
Toast.makeText(getApplicationContext(), "创建对象失败,请确认 libmsc.so 放置正确,且有调用 createUtility 进行初始化", Toast.LENGTH_LONG).show();
return;
}
switch (v.getId()) {
case R.id.btStart:
editText.setText(null);
mIatResults.clear();
// 设置参数
setParam();
if (toggleButton1.isChecked()) {
// 显示听写对话框
mIatDialog.setListener(mRecognizerDialogListener);
mIatDialog.show();
Toast.makeText(this, "请开始说话", Toast.LENGTH_LONG).show();
} else {
ret = mIat.startListening(mRecognizerListener);
if (ret != ErrorCode.SUCCESS) {
Toast.makeText(this, "听写失败,错误码:" + ret, Toast.LENGTH_LONG).show();
} else {
Toast.makeText(this, "请开始说话", Toast.LENGTH_LONG).show();
}
}
break;
default:
break;
}
}
/**
* 听写UI监听器
*/
private RecognizerDialogListener mRecognizerDialogListener = new RecognizerDialogListener() {
public void onResult(RecognizerResult results, boolean isLast) {
printResult(results);
}
/**
* 识别回调错误.
*/
public void onError(SpeechError error) {
if(mTranslateEnable && error.getErrorCode() == 14002) {
Toast.makeText(getApplicationContext(), error.getPlainDescription(true)+"\n请确认是否已开通翻译功能", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(),
error.getPlainDescription(true), Toast.LENGTH_LONG).show();
}
}
};
//设置参数
public void setParam()
{
// 清空参数
mIat.setParameter(SpeechConstant.PARAMS, null);
// 设置听写引擎
mIat.setParameter(SpeechConstant.ENGINE_TYPE, mEngineType);
// 设置返回结果格式
mIat.setParameter(SpeechConstant.RESULT_TYPE, "json");
String lag = sharedPreferences.getString("iat_language_preference",
"mandarin");
if (lag.equals("en_us")) {
// 设置语言
mIat.setParameter(SpeechConstant.LANGUAGE, "en_us");
} else {
// 设置语言
mIat.setParameter(SpeechConstant.LANGUAGE, "zh_cn");
// 设置语言区域
mIat.setParameter(SpeechConstant.ACCENT, lag);
}
// 设置语音前端点:静音超时时间,即用户多长时间不说话则当做超时处理
mIat.setParameter(SpeechConstant.VAD_BOS, sharedPreferences.getString("iat_vadbos_preference", "4000"));
// 设置语音后端点:后端点静音检测时间,即用户停止说话多长时间内即认为不再输入, 自动停止录音
mIat.setParameter(SpeechConstant.VAD_EOS, sharedPreferences.getString("iat_vadeos_preference", "1000"));
// 设置标点符号,设置为"0"返回结果无标点,设置为"1"返回结果有标点
mIat.setParameter(SpeechConstant.ASR_PTT, sharedPreferences.getString("iat_punc_preference", "1"));
// 设置音频保存路径,保存音频格式支持pcm、wav,设置路径为sd卡请注意WRITE_EXTERNAL_STORAGE权限
// 注:AUDIO_FORMAT参数语记需要更新版本才能生效
mIat.setParameter(SpeechConstant.AUDIO_FORMAT,"wav");
mIat.setParameter(SpeechConstant.ASR_AUDIO_PATH, Environment.getExternalStorageDirectory()+"/msc/iat.wav");
}
//这个是没有UI界面的听写监听器
/**
* 听写监听器。
*/
private RecognizerListener mRecognizerListener = new RecognizerListener() {
@Override
public void onBeginOfSpeech() {
// 此回调表示:sdk内部录音机已经准备好了,用户可以开始语音输入
Toast.makeText(getApplicationContext(), "开始说话", Toast.LENGTH_LONG).show();
}
@Override
public void onError(SpeechError error) {
// Tips:
// 错误码:10118(您没有说话),可能是录音机权限被禁,需要提示用户打开应用的录音权限。
// 如果使用本地功能(语记)需要提示用户开启语记的录音权限。
if(mTranslateEnable && error.getErrorCode() == 14002) {
Toast.makeText(getApplicationContext(), error.getPlainDescription(true)+"\n请确认是否已开通翻译功能", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(), error.getPlainDescription(true), Toast.LENGTH_LONG).show();
}
}
@Override
public void onEndOfSpeech() {
// 此回调表示:检测到了语音的尾端点,已经进入识别过程,不再接受语音输入
Toast.makeText(getApplicationContext(), "结束说话", Toast.LENGTH_SHORT).show();
Log.e("TAG", "结束说话");
}
@Override
public void onResult(RecognizerResult results, boolean isLast) {
printResult(results);
if (isLast) {
// TODO 最后的结果
}
}
@Override
public void onVolumeChanged(int volume, byte[] data) {
// Toast.makeText(getApplicationContext(), "当前正在说话,音量大小:" + volume, Toast.LENGTH_LONG).show();
Log.e("TAG", "当前正在说话,音量大小:" + volume);
}
@Override
public void onEvent(int eventType, int arg1, int arg2, Bundle obj) {
}
};
//最终结果
private void printResult(RecognizerResult results) {
String text = JsonParser.parseIatResult(results.getResultString());
String sn = null;
// 读取json结果中的sn字段
try {
JSONObject resultJson = new JSONObject(results.getResultString());
sn = resultJson.optString("sn");
} catch (JSONException e) {
e.printStackTrace();
}
mIatResults.put(sn, text);
StringBuffer resultBuffer = new StringBuffer();
for (String key : mIatResults.keySet()) {
resultBuffer.append(mIatResults.get(key));
}
editText.setText(resultBuffer.toString());//这儿是最终识别到的文字,显示在textview上面
editText.setSelection(editText.length());
}