前提说明:讯飞SDK与appID(后台申请)是一一对应的、否则就会导致初始化不成功!
1、创建appID并下载SDK(没有账号的先行注册)
https://console.xfyun.cn/app/myapp
创建完成后、如图
下载解压包
simple就是官方demo、默认会填写你已经申请好的appid、你可以比这官方Demo写
2、自己再封装lib、仅保留语音转文字功能、
语音转换核心控制类:
/**
* 音频读写转换
*/
public class RecognizeSpeechManager implements RecognizerListener, InitListener {
private static final String TAG = "RecognizeSpeechManager";
private RecognizeListener recognizeListener;
// 语音听写对象
private SpeechRecognizer iat;
private StringBuffer charBufffer = new StringBuffer();
private WeakReference<Context> bindContext;
private static RecognizeSpeechManager instance;
private RecognizeSpeechManager() {
}
public static RecognizeSpeechManager instance() {
if (instance == null) {
instance = new RecognizeSpeechManager();
}
return instance;
}
public void setRecognizeListener(RecognizeListener recognizeListener) {
this.recognizeListener = recognizeListener;
}
public void init(Context context) {
if (bindContext == null) {
bindContext = new WeakReference<Context>(context);
}
if (iat == null) {
iat = SpeechRecognizer.createRecognizer(bindContext.get(), this);
}
}
@Override
public void onInit(int code) {
if (code != ErrorCode.SUCCESS) {
Log.d(TAG, "init error code " + code);
}
}
/**
* 开始监听
* ErrorCode.SUCCESS 监听成功状态码
*/
public int startRecognize() {
setParam();
return iat.startListening(this);
}
/**
* 取消听写
*/
public void cancelRecognize() {
iat.cancel();
}
/**
* 停止听写
*/
public void stopRecognize() {
iat.stopListening();
}
public void release() {
iat.cancel();
iat.destroy();
iat = null;
bindContext.clear();
bindContext = null;
charBufffer.delete(0, charBufffer.length());
}
@Override
public void onVolumeChanged(int i, byte[] bytes) {
}
@Override
public void onBeginOfSpeech() {
Log.d(TAG, "onBeginOfSpeech");
}
@Override
public void onEndOfSpeech() {
Log.d(TAG, "onEndOfSpeech isListening " + iat.isListening());
}
@Override
public void onResult(RecognizerResult results, boolean b) {
if (recognizeListener != null) {
recognizeListener.onNewResult(printResult(results));
recognizeListener.onTotalResult(charBufffer.toString(), iat.isListening());
}
}
@Override
public void onError(SpeechError speechError) {
if (recognizeListener != null) {
recognizeListener.onError(speechError);
}
}
@Override
public void onEvent(int i, int i1, int i2, Bundle bundle) {
Log.d(TAG, "onEvent type " + i);
}
private String printResult(RecognizerResult results) {
String text = JsonParser.parseIatResult(results.getResultString());
Log.d(TAG, "printResult " + text + " isListening " + iat.isListening());
String sn = null;
// 读取json结果中的sn字段
try {
JSONObject resultJson = new JSONObject(results.getResultString());
sn = resultJson.optString("sn");
} catch (JSONException e) {
e.printStackTrace();
}
if (!TextUtils.isEmpty(text)) {
charBufffer.append(text);
}
return text;
}
/**
* 参数设置
*
* @return
*/
private void setParam() {
// 清空参数
iat.setParameter(SpeechConstant.PARAMS, null);
// 设置听写引擎
iat.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD);
// 设置返回结果格式
iat.setParameter(SpeechConstant.RESULT_TYPE, "json");
iat.setParameter(SpeechConstant.LANGUAGE, "zh_cn");
iat.setParameter(SpeechConstant.ACCENT, "mandarin");
//此处用于设置dialog中不显示错误码信息
//iat.setParameter("view_tips_plain","false");
// 设置语音前端点:静音超时时间,即用户多长时间不说话则当做超时处理
iat.setParameter(SpeechConstant.VAD_BOS, "10000");
// 设置语音后端点:后端点静音检测时间,即用户停止说话多长时间内即认为不再输入, 自动停止录音
iat.setParameter(SpeechConstant.VAD_EOS, "10000");
// 设置标点符号,设置为"0"返回结果无标点,设置为"1"返回结果有标点
iat.setParameter(SpeechConstant.ASR_PTT, "1");
// 设置音频保存路径,保存音频格式支持pcm、wav,设置路径为sd卡请注意WRITE_EXTERNAL_STORAGE权限
/* iat.setParameter(SpeechConstant.AUDIO_FORMAT, "wav");
iat.setParameter(SpeechConstant.ASR_AUDIO_PATH, Environment.getExternalStorageDirectory() + "/msc/iat.wav");*/
}
}
RecognizeListener 接口、用于语音转换成功后、文本回调
/**
* 听写回调
*/
public interface RecognizeListener {
void onNewResult(String result);
void onTotalResult(String result,boolean isLast);
void onError(SpeechError speechError);
}
解析工具类、来自官方Demo
/**
* 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();
}
}
权限配置
<!--连接网络权限,用于执行云端语音能力 -->
<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.WRITE_EXTERNAL_STORAGE"/>
<!--外存储读权限,构建语法需要用到此权限 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<!--配置权限,用来记录应用配置信息 -->
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
<!--手机定位信息,用来为语义等功能提供定位,提供更精准的服务-->
<!--定位信息是敏感信息,可通过Setting.setLocationEnable(false)关闭定位请求 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
3、主工程Application中初始化 、并依赖recognizespeech lib库
//注意、appid=xxxx 不能省略(xxxx 写上自己的appid)
SpeechUtility.createUtility(
this,
"appid=xxxxx"
)
如图:
测试类代码
class MainActivity : AppCompatActivity(),RecognizeListener {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
RecognizeSpeechManager.instance().init(this)
RecognizeSpeechManager.instance().setRecognizeListener(this)
btStart.setOnClickListener {
RecognizeSpeechManager.instance().startRecognize()
}
btCancel.setOnClickListener {
RecognizeSpeechManager.instance().cancelRecognize()
}
btStop.setOnClickListener {
RecognizeSpeechManager.instance().stopRecognize()
}
}
override fun onDestroy() {
super.onDestroy()
RecognizeSpeechManager.instance().release()
}
@SuppressLint("SetTextI18n")
override fun onNewResult(result: String?) {
tvContent.append("最新翻译:$result \n")
}
@SuppressLint("SetTextI18n")
override fun onTotalResult(result: String, isLast: Boolean) {
tvContent.append("所有翻译:$result \n")
}
override fun onError(speechError: SpeechError?) {
Toast.makeText(this,"出错了 $speechError",Toast.LENGTH_SHORT).show()
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
tools:context=".MainActivity">
<TextView
android:id="@+id/tvContent"
android:padding="20dp"
android:layout_gravity="top"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
android:layout_marginTop="50dp"
android:id="@+id/btStart"
android:text="开始识别"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/btCancel"
android:layout_marginTop="20dp"
android:text="取消"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/btStop"
android:text="停止"
android:layout_marginTop="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
至此OVer、Demo https://download.csdn.net/download/BirdEatBug/19714846?spm=1001.2014.3001.5501