科大讯飞的集成,含详细的步骤和注意细节
最近,想用一下科大讯飞的语音,查看了使用文档,有点笨,还是没有学会,后来参考了其他人写的一些博客,终于搞清楚怎么搞的了.
申请使用
去到科大讯飞的开放平台http://www.xfyun.cn/,注册自己的账户.去到自己的控制台
点击左侧的创建新应用,按要求填写即可Appid
代码中要使用的Appid要按要求提交各种信息,然后提交审核,大概过个一两天会通过,有问题的话科大那边也会通过QQ联系你
下载SDK
解压后:
集成到Android studio
将libs下的两个jar包(Msc.jar和Sunflower.jar)添加到libs目录下(别忘了jar包要add), 将同路径下的其它 .so文件(与c进行交互)复制到main路径下新建的 jniLibs(L要大写)目录下 , 将assert目录拷贝到main目录下
注意 : 这些都是自己创建的应用生成的, 在申请appid时就与自己的应用绑定了, 拷贝别人的是没有用的
添加权限,注意安卓6.0后有些权限需要动态添加
代码
在中initSpeech//将“12345678”替换成您申请的APPID,请勿在“ =”与appid之间添加任务空字符或者转义符
packagecom.example.dominic.xunfeidemo_z;
importandroid.Manifest;
importandroid.content.pm.PackageManager;
importandroid.os.Bundle;
importandroid.support.annotation.NonNull;
importandroid.support.v4.app.ActivityCompat;
importandroid.support.v7.app.AppCompatActivity;
importandroid.util.Log;
importandroid.view.View;
importandroid.widget.Button;
importandroid.widget.EditText;
importandroid.widget.Toast;
importcom.iflytek.cloud.ErrorCode;
importcom.iflytek.cloud.InitListener;
importcom.iflytek.cloud.RecognizerListener;
importcom.iflytek.cloud.RecognizerResult;
importcom.iflytek.cloud.SpeechConstant;
importcom.iflytek.cloud.SpeechError;
importcom.iflytek.cloud.SpeechRecognizer;
importcom.iflytek.cloud.SpeechSynthesizer;
importcom.iflytek.cloud.SpeechUtility;
importcom.iflytek.cloud.SynthesizerListener;
importcom.iflytek.cloud.ui.RecognizerDialog;
importcom.iflytek.cloud.ui.RecognizerDialogListener;
importorg.json.JSONException;
importorg.json.JSONObject;
importjava.util.HashMap;
importjava.util.LinkedHashMap;
public classMainActivityextendsAppCompatActivityimplementsView.OnClickListener{
private static finalStringTAG=MainActivity.class.getSimpleName();
privateEditTextet_input;
privateButtonbtn_startspeech,btn_startspeektext;
//用HashMap存储听写结果
privateHashMapmIatResults=newLinkedHashMap();
@Override
protected voidonCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState) ;
checkRecordPermission();
initView() ;
initSpeech() ;
}
private voidcheckRecordPermission() {
intresult =ActivityCompat.checkSelfPermission(getApplicationContext(),Manifest.permission.RECORD_AUDIO);
if(result ==PackageManager.PERMISSION_DENIED){
ActivityCompat.requestPermissions(this,newString[]{Manifest.permission.RECORD_AUDIO},0);
}
}
@Override
public voidonRequestPermissionsResult(intrequestCode,@NonNullString[]permissions,@NonNullint[]grantResults) {
if(requestCode==0){
if(grantResults[0] ==PackageManager.PERMISSION_GRANTED){
}{
Toast.makeText(getApplicationContext(),"权限未同意,无法下载",Toast.LENGTH_SHORT).show();
}
}
super.onRequestPermissionsResult(requestCode,permissions,grantResults);
}
private voidinitView() {
setContentView(R.layout.activity_main) ;
et_input= (EditText)findViewById(R.id.et_input);
btn_startspeech= (Button)findViewById(R.id.btn_startspeech);
btn_startspeektext= (Button)findViewById(R.id.btn_startspeektext);
btn_startspeech.setOnClickListener(this) ;
btn_startspeektext.setOnClickListener(this) ;
}
private voidinitSpeech() {
//将“12345678”替换成您申请的APPID,申请地址:http://www.xfyun.cn
//请勿在“ =”与appid之间添加任务空字符或者转义符
SpeechUtility.createUtility(this,SpeechConstant.APPID+"=58a6bd74");
}
@Override
public voidonClick(Viewv) {
switch(v.getId()) {
caseR.id.btn_startspeech://语音识别(把声音转文字)
startSpeechDialog();
break;
caseR.id.btn_startspeektext://语音合成(把文字转声音)
speekText();
break;
}
}
private voidspeekText() {
//1.创建SpeechSynthesizer对象,第二个参数: 本地合成时传InitListener
SpeechSynthesizermTts =SpeechSynthesizer.createSynthesizer(this,null);
//2.合成参数设置,详见《MSC Reference Manual》SpeechSynthesizer类
//设置发音人(更多在线发音人,用户可参见 附录13.2
mTts.setParameter(SpeechConstant.VOICE_NAME,"vixyun");//设置发音人
mTts.setParameter(SpeechConstant.SPEED,"50");//设置语速
mTts.setParameter(SpeechConstant.VOLUME,"80");//设置音量,范围0~100
mTts.setParameter(SpeechConstant.ENGINE_TYPE,SpeechConstant.TYPE_CLOUD);//设置云端
//设置合成音频保存位置(可自定义保存位置),保存在“./sdcard/iflytek.pcm”
//保存在SD卡需要在AndroidManifest.xml添加写SD卡权限
//仅支持保存为pcm和wav格式, 如果不需要保存合成音频,注释该行代码
mTts.setParameter(SpeechConstant.TTS_AUDIO_PATH,"./sdcard/iflytek.pcm");
//3.开始合成
mTts.startSpeaking("科大讯飞,有东北音?",newMySynthesizerListener()) ;
}
classMySynthesizerListenerimplementsSynthesizerListener{
@Override
public voidonSpeakBegin() {
showTip("开始播放");
}
@Override
public voidonSpeakPaused() {
showTip("暂停播放");
}
@Override
public voidonSpeakResumed() {
showTip("继续播放");
}
@Override
public voidonBufferProgress(intpercent,intbeginPos,intendPos,
Stringinfo) {
//合成进度
}
@Override
public voidonSpeakProgress(intpercent,intbeginPos,intendPos) {
//播放进度
}
@Override
public voidonCompleted(SpeechErrorerror) {
if(error==null) {
showTip("播放完成");
}else if(error!=null) {
showTip(error.getPlainDescription(true));
}
}
@Override
public voidonEvent(inteventType,intarg1,intarg2,Bundleobj) {
//以下代码用于获取与云端的会话id,当业务出错时将会话id提供给技术支持人员,可用于查询会话日志,定位出错原因
//若使用本地能力,会话id为null
//if (SpeechEvent.EVENT_SESSION_ID == eventType) {
// String sid = obj.getString(SpeechEvent.KEY_EVENT_SESSION_ID);
// Log.d(TAG, "session id =" + sid);
//}
}
}
private voidstartSpeechDialog() {
//1.创建RecognizerDialog对象
RecognizerDialogmDialog =newRecognizerDialog(this,newMyInitListener()) ;
//2.设置accent、language等参数
mDialog.setParameter(SpeechConstant.LANGUAGE,"zh_cn");//设置中文
mDialog.setParameter(SpeechConstant.ACCENT,"mandarin");
//若要将UI控件用于语义理解,必须添加以下参数设置,设置之后onResult回调返回将是语义理解
//结果
// mDialog.setParameter("asr_sch", "1");
// mDialog.setParameter("nlp_version", "2.0");
//3.设置回调接口
mDialog.setListener(newMyRecognizerDialogListener()) ;
//4.显示dialog,接收语音输入
mDialog.show() ;
}
classMyRecognizerDialogListenerimplementsRecognizerDialogListener{
/**
*@param results
*@param isLast是否说完了
*/
@Override
public voidonResult(RecognizerResultresults,booleanisLast) {
Stringresult =results.getResultString();//为解析的
showTip(result) ;
System.out.println("没有解析的:"+ result);
Stringtext =JsonParser.parseIatResult(result) ;//解析过后的
System.out.println("解析后的:"+ text);
Stringsn =null;
//读取json结果中的sn字段
try{
JSONObjectresultJson =newJSONObject(results.getResultString()) ;
sn = resultJson.optString("sn");
}catch(JSONExceptione) {
e.printStackTrace();
}
mIatResults.put(sn, text) ;//没有得到一句,添加到
StringBufferresultBuffer =newStringBuffer();
for(Stringkey :mIatResults.keySet()) {
resultBuffer.append(mIatResults.get(key));
}
et_input.setText(resultBuffer.toString());//设置输入框的文本
et_input.setSelection(et_input.length()) ;//把光标定位末尾
}
@Override
public voidonError(SpeechErrorspeechError) {
}
}
classMyInitListenerimplementsInitListener{
@Override
public voidonInit(intcode) {
if(code!=ErrorCode.SUCCESS) {
showTip("初始化失败");
}
}
}
/**
*语音识别
*/
private voidstartSpeech() {
//1.创建SpeechRecognizer对象,第二个参数: 本地识别时传InitListener
SpeechRecognizermIat =SpeechRecognizer.createRecognizer(this,null);//语音识别器
//2.设置听写参数,详见《MSC Reference Manual》SpeechConstant类
mIat.setParameter(SpeechConstant.DOMAIN,"iat");//短信和日常用语:iat (默认)
mIat.setParameter(SpeechConstant.LANGUAGE,"zh_cn");//设置中文
mIat.setParameter(SpeechConstant.ACCENT,"mandarin");//设置普通话
//3.开始听写
mIat.startListening(mRecoListener);
}
//听写监听器
privateRecognizerListenermRecoListener=newRecognizerListener() {
//听写结果回调接口(返回Json格式结果,用户可参见附录13.1);
//一般情况下会通过onResults接口多次返回结果,完整的识别内容是多次结果的累加;
//关于解析Json的代码可参见Demo中JsonParser类;
//isLast等于true时会话结束。
public voidonResult(RecognizerResultresults,booleanisLast) {
Log.e(TAG,results.getResultString());
System.out.println(results.getResultString()) ;
showTip(results.getResultString()) ;
}
//会话发生错误回调接口
public voidonError(SpeechErrorerror) {
showTip(error.getPlainDescription(true)) ;
//获取错误码描述
Log.e(TAG,"error.getPlainDescription(true)=="+error.getPlainDescription(true));
}
//开始录音
public voidonBeginOfSpeech() {
showTip("开始录音");
}
//volume音量值0~30,data音频数据
public voidonVolumeChanged(intvolume,byte[]data) {
showTip("声音改变了");
}
//结束录音
public voidonEndOfSpeech() {
showTip("结束录音");
}
//扩展用接口
public voidonEvent(inteventType,intarg1,intarg2,Bundleobj) {
}
};
private voidshowTip(Stringdata) {
// Toast.makeText( this, data, Toast.LENGTH_SHORT).show() ;
}
}
json解析类
packagecom.example.dominic.xunfeidemo_z;
importorg.json.JSONArray;
importorg.json.JSONObject;
importorg.json.JSONTokener;
/**
* Created by Dominic on 2017/2/23.
*/
public classJsonParser{
public staticStringparseIatResult(Stringjson) {
StringBufferret =newStringBuffer() ;
try{
JSONTokenertokener =newJSONTokener(json) ;
JSONObjectjoResult =newJSONObject(tokener) ;
JSONArraywords = joResult.getJSONArray("ws");
for(inti =0; i < words.length(); i++) {
//转写结果词,默认使用第一个结果
JSONArrayitems = words.getJSONObject(i).getJSONArray("cw");
JSONObjectobj = items.getJSONObject(0);
ret.append(obj.getString("w"));
//如果需要多候选结果,解析数组其他字段
// for(int j = 0; j < items.length(); j++)
// {
// JSONObject obj = items.getJSONObject(j);
// ret.append(obj.getString("w"));
// }
}
}catch(Exceptione) {
e.printStackTrace();
}
returnret.toString();
}
public staticStringparseGrammarResult(Stringjson) {
StringBufferret =newStringBuffer() ;
try{
JSONTokenertokener =newJSONTokener(json) ;
JSONObjectjoResult =newJSONObject(tokener) ;
JSONArraywords = joResult.getJSONArray("ws");
for(inti =0; i < words.length(); i++) {
JSONArrayitems = words.getJSONObject(i).getJSONArray("cw");
for(intj =0; j < items.length() ; j++)
{
JSONObjectobj = items.getJSONObject(j);
if(obj.getString("w").contains("nomatch"))
{
ret.append("没有匹配结果.") ;
returnret.toString();
}
ret.append("【结果】"+ obj.getString("w"));
ret.append("【置信度】"+ obj.getInt("sc"));
ret.append("\n");
}
}
}catch(Exceptione) {
e.printStackTrace();
ret.append("没有匹配结果.");
}
returnret.toString();
}
public staticStringparseLocalGrammarResult(Stringjson) {
StringBufferret =newStringBuffer() ;
try{
JSONTokenertokener =newJSONTokener(json) ;
JSONObjectjoResult =newJSONObject(tokener) ;
JSONArraywords = joResult.getJSONArray("ws");
for(inti =0; i < words.length(); i++) {
JSONArrayitems = words.getJSONObject(i).getJSONArray("cw");
for(intj =0; j < items.length() ; j++)
{
JSONObjectobj = items.getJSONObject(j);
if(obj.getString("w").contains("nomatch"))
{
ret.append("没有匹配结果.") ;
returnret.toString();
}
ret.append("【结果】"+ obj.getString("w"));
ret.append("\n");
}
}
ret.append("【置信度】"+ joResult.optInt("sc"));
}catch(Exceptione) {
e.printStackTrace();
ret.append("没有匹配结果.");
}
returnret.toString();
}
}
布局
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
android:id="@+id/et_input"
android:layout_margin="10dp"
android:layout_width="match_parent"
android:layout_height="80dp"
android:hint="请输入文本信息..."/>
android:id="@+id/btn_startspeech"
android:text="点击按钮语音输入"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
android:id="@+id/btn_startspeektext"
android:text="语音合成(把文字转声音)"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>