科大讯飞开放平台:https://www.xfyun.cn/
SDK下载:https://www.xfyun.cn/sdk/dispatcher
创建应用
添加AI能力(主要应该就是语音听写)
生成相关SDK,下载解压
开发文档:https://doc.xfyun.cn/msc_android/index.html
可以参考:https://doc.xfyun.cn/msc_android/%E9%A2%84%E5%A4%87%E5%B7%A5%E4%BD%9C.html
和以前一样,在src/main下创建jniLibs,并把下载解压后得到的相关so文件复制进去
还有一个jar包,也需要导入libs目录,并add
也和之前一样,专门建一个application,并在配置清单中注册
package com.example.a5_23speech_recognition;
import android.app.Application;
import com.iflytek.cloud.SpeechConstant;
import com.iflytek.cloud.SpeechUtility;
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
// 将“12345678”替换成您申请的APPID,申请地址:http://www.xfyun.cn
// 请勿在“=”与appid之间添加任何空字符或者转义符
//我这里已经换了...
SpeechUtility.createUtility(this, SpeechConstant.APPID +"=5ce61df0");
}
}
代码参考:https://doc.xfyun.cn/msc_android/%E8%AF%AD%E9%9F%B3%E5%90%AC%E5%86%99.html
需要配置NDK
public class MainActivity extends AppCompatActivity {
private TextView tv_content;
private HashMap nIatResults = new LinkedHashMap<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_content = findViewById(R.id.textView_content);
}
public void startSpeechClick(View v) {
//初始化识别无UI识别对象
//使用SpeechRecognizer对象,可根据回调消息自定义界面;
SpeechRecognizer mIat = SpeechRecognizer.createRecognizer(this, null);
//设置语法ID和 SUBJECT 为空,以免因之前有语法调用而设置了此参数;或直接清空所有参数,具体可参考 DEMO 的示例。
mIat.setParameter(SpeechConstant.DOMAIN, "iat");//应用领域
//设置语音输入语言,zh_cn为简体中文
mIat.setParameter(SpeechConstant.LANGUAGE, "zh_cn");
//设置结果返回语言,普通话
mIat.setParameter(SpeechConstant.ACCENT, "mandarin");
mIat.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD);
//设置返回结果格式
mIat.setParameter(SpeechConstant.RESULT_TYPE, "json");
//设置语音前端点:静音超时时间,单位ms,即用户多长时间不说话则当做超时处理
//取值范围{1000~10000}
mIat.setParameter(SpeechConstant.VAD_BOS, "4000");
//设置语音后端点:后端点静音检测时间,单位ms,即用户停止说话多长时间内即认为不再输入,
//自动停止录音,范围{0~10000}
mIat.setParameter(SpeechConstant.VAD_EOS, "1000");
//设置标点符号,设置为"0"返回结果无标点,设置为"1"返回结果有标点
mIat.setParameter(SpeechConstant.ASR_PTT, "1");
//设置听写的动态修正
mIat.setParameter(SpeechConstant.ASR_DWA, "0");
//开始识别,并设置监听器
mIat.startListening(mRecoListener);
}
//听写监听器
private RecognizerListener mRecoListener = new RecognizerListener() {
//音量值0-30
@Override
public void onVolumeChanged(int i, byte[] bytes) {
}
//开始录音
@Override
public void onBeginOfSpeech() {
}
//结束录音
@Override
public void onEndOfSpeech() {
}
//返回结果
@Override
public void onResult(RecognizerResult recognizerResult, boolean b) {
System.out.println(recognizerResult.getResultString());
}
@Override
public void onError(SpeechError speechError) {
}
@Override
public void onEvent(int i, int i1, int i2, Bundle bundle) {
}
};
如上代码基本上可以运行了,效果会在控制台输出对应识别的内容
注意,似乎SDK提供的so文件并不全,可能并不支持大部分模拟器,如出现安装失败,建议换真机进行调试
完整实现需要将识别的文本进行解析并显示在textView
需要一个解析器类,可以在Demo里找到
package com.example.a5_23speech_recognition;
import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONTokener;
import android.util.Log;
/**
* Json结果解析类
*/
public class JsonParser {
public static String parseIatResult(String json) {
StringBuffer ret = new StringBuffer();
try {
JSONTokener tokener = new JSONTokener(json);
JSONObject joResult = new JSONObject(tokener);
JSONArray words = joResult.getJSONArray("ws");
for (int i = 0; i < words.length(); i++) {
// 转写结果词,默认使用第一个结果
JSONArray items = words.getJSONObject(i).getJSONArray("cw");
JSONObject obj = 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 (Exception e) {
e.printStackTrace();
}
return ret.toString();
}
public static String parseGrammarResult(String json) {
StringBuffer ret = new StringBuffer();
try {
JSONTokener tokener = new JSONTokener(json);
JSONObject joResult = new JSONObject(tokener);
JSONArray words = joResult.getJSONArray("ws");
for (int i = 0; i < words.length(); i++) {
JSONArray items = words.getJSONObject(i).getJSONArray("cw");
for(int j = 0; j < items.length(); j++)
{
JSONObject obj = items.getJSONObject(j);
if(obj.getString("w").contains("nomatch"))
{
ret.append("没有匹配结果.");
return ret.toString();
}
ret.append("【结果】" + obj.getString("w"));
ret.append("【置信度】" + obj.getInt("sc"));
ret.append("\n");
}
}
} catch (Exception e) {
e.printStackTrace();
ret.append("没有匹配结果.");
}
return ret.toString();
}
public static String parseLocalGrammarResult(String json) {
StringBuffer ret = new StringBuffer();
try {
JSONTokener tokener = new JSONTokener(json);
JSONObject joResult = new JSONObject(tokener);
JSONArray words = joResult.getJSONArray("ws");
for (int i = 0; i < words.length(); i++) {
JSONArray items = words.getJSONObject(i).getJSONArray("cw");
for(int j = 0; j < items.length(); j++)
{
JSONObject obj = items.getJSONObject(j);
if(obj.getString("w").contains("nomatch"))
{
ret.append("没有匹配结果.");
return ret.toString();
}
ret.append("【结果】" + obj.getString("w"));
ret.append("\n");
}
}
ret.append("【置信度】" + joResult.optInt("sc"));
} catch (Exception e) {
e.printStackTrace();
ret.append("没有匹配结果.");
}
return ret.toString();
}
public static String parseTransResult(String json,String key) {
StringBuffer ret = new StringBuffer();
try {
JSONTokener tokener = new JSONTokener(json);
JSONObject joResult = new JSONObject(tokener);
String errorCode = joResult.optString("ret");
if(!errorCode.equals("0")) {
return joResult.optString("errmsg");
}
JSONObject transResult = joResult.optJSONObject("trans_result");
ret.append(transResult.optString(key));
/*JSONArray words = joResult.getJSONArray("results");
for (int i = 0; i < words.length(); i++) {
JSONObject obj = words.getJSONObject(i);
ret.append(obj.getString(key));
}*/
} catch (Exception e) {
e.printStackTrace();
}
return ret.toString();
}
}
并修改代码
package com.example.a5_23speech_recognition;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import com.iflytek.cloud.RecognizerListener;
import com.iflytek.cloud.RecognizerResult;
import com.iflytek.cloud.SpeechConstant;
import com.iflytek.cloud.SpeechError;
import com.iflytek.cloud.SpeechRecognizer;
import com.iflytek.cloud.SpeechUtility;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.HashMap;
import java.util.LinkedHashMap;
public class MainActivity extends AppCompatActivity {
private TextView tv_content;
private HashMap nIatResults = new LinkedHashMap<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_content = findViewById(R.id.textView_content);
}
public void startSpeechClick(View v) {
//初始化识别无UI识别对象
//使用SpeechRecognizer对象,可根据回调消息自定义界面;
SpeechRecognizer mIat = SpeechRecognizer.createRecognizer(this, null);
//设置语法ID和 SUBJECT 为空,以免因之前有语法调用而设置了此参数;或直接清空所有参数,具体可参考 DEMO 的示例。
mIat.setParameter(SpeechConstant.DOMAIN, "iat");//应用领域
//设置语音输入语言,zh_cn为简体中文
mIat.setParameter(SpeechConstant.LANGUAGE, "zh_cn");
//设置结果返回语言,普通话
mIat.setParameter(SpeechConstant.ACCENT, "mandarin");
mIat.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD);
//设置返回结果格式
mIat.setParameter(SpeechConstant.RESULT_TYPE, "json");
//设置语音前端点:静音超时时间,单位ms,即用户多长时间不说话则当做超时处理
//取值范围{1000~10000}
mIat.setParameter(SpeechConstant.VAD_BOS, "4000");
//设置语音后端点:后端点静音检测时间,单位ms,即用户停止说话多长时间内即认为不再输入,
//自动停止录音,范围{0~10000}
mIat.setParameter(SpeechConstant.VAD_EOS, "1000");
//设置标点符号,设置为"0"返回结果无标点,设置为"1"返回结果有标点
mIat.setParameter(SpeechConstant.ASR_PTT, "1");
//设置听写的动态修正
mIat.setParameter(SpeechConstant.ASR_DWA, "0");
//开始识别,并设置监听器
mIat.startListening(mRecoListener);
}
//听写监听器
private RecognizerListener mRecoListener = new RecognizerListener() {
//音量值0-30
@Override
public void onVolumeChanged(int i, byte[] bytes) {
}
//开始录音
@Override
public void onBeginOfSpeech() {
}
//结束录音
@Override
public void onEndOfSpeech() {
}
//返回结果
@Override
public void onResult(RecognizerResult recognizerResult, boolean b) {
System.out.println(recognizerResult.getResultString());
printResult(recognizerResult);
}
@Override
public void onError(SpeechError speechError) {
}
@Override
public void onEvent(int i, int i1, int i2, Bundle bundle) {
}
};
//输出结果
private void printResult(RecognizerResult results) {
String text = JsonParser.parseGrammarResult(results.getResultString());
String sn = null;
//读取json结果中的sn字段
try {
JSONObject resultJson = new JSONObject(results.getResultString());
sn = resultJson.optString("sn");
} catch (JSONException e) {
e.printStackTrace();
}
nIatResults.put(sn, text);
StringBuffer resultBuffer = new StringBuffer();
for (String key : nIatResults.keySet()) {
resultBuffer.append(nIatResults.get(key));
}
tv_content.setText(resultBuffer.toString());
}
}
如果觉得太丑了...或者某些东西没必要
可以对参数进行修改,比如把标点设置不显示,修改解析器,把置信度之类的去掉..
大概这样 语音合成等下补..