科大讯飞的集成,含详细的步骤和注意细节

      最近,想用一下科大讯飞的语音,查看了使用文档,有点笨,还是没有学会,后来参考了其他人写的一些博客,终于搞清楚怎么搞的了.

本demo github下载地址

申请使用

去到科大讯飞的开放平台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"/>

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,902评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,037评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,978评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,867评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,763评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,104评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,565评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,236评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,379评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,313评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,363评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,034评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,637评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,719评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,952评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,371评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,948评论 2 341

推荐阅读更多精彩内容