android 语音转换文字(科大讯飞SDK简易封装)
2016-10-31 17:56
447 查看
简介:本地讲解的是 科大讯飞开发平台的语音转换功能的集成方法和封装
准备工作:
1、首先申请平台账号,创建我的应用,新增语音服务,获取Appid
2、下载创建的应用的对应SDK,这条很重要,每一个应用会对应一个SDK,用于做区分。
构建项目:
1、首先将需要的组件.jar包和.so文件引入工程,(注:由于CPU型号限制,speechDemo下的libs下的 arm64-v8a文件夹不要粘贴到我的工程,否则会报CPU型号异常而打不开APP,记得将你的其他组件的.so文件分别复制粘贴到 armeabi和armeabi-v7a文件下,否则会报错)
2、其次将下载的SDK的speechDemo中的 assets目录下的所有文件拷贝到我的项目中。注:必须是对应的SDK下的SpeechDemo中的assets文件夹,这个文件夹的内部文件其实也可以说是,区别于其他APP的SDK,内部包括录音Dialog的图片素材等文件
3、复制speechDemo中的相关Util组件到我的项目
下面贴几张图:("设置"界面我将它放在外部了,因为是SDK中提供好的Activity我就不贴代码了)
![](https://img-blog.csdn.net/20161101155455879?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](https://img-blog.csdn.net/20161101155523454?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](https://img-blog.csdn.net/20161101155546641?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](https://img-blog.csdn.net/20161101155605006?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
下面是我封装的speechDemo的方法:
以下是Activity的调用:
准备工作:
1、首先申请平台账号,创建我的应用,新增语音服务,获取Appid
2、下载创建的应用的对应SDK,这条很重要,每一个应用会对应一个SDK,用于做区分。
构建项目:
1、首先将需要的组件.jar包和.so文件引入工程,(注:由于CPU型号限制,speechDemo下的libs下的 arm64-v8a文件夹不要粘贴到我的工程,否则会报CPU型号异常而打不开APP,记得将你的其他组件的.so文件分别复制粘贴到 armeabi和armeabi-v7a文件下,否则会报错)
2、其次将下载的SDK的speechDemo中的 assets目录下的所有文件拷贝到我的项目中。注:必须是对应的SDK下的SpeechDemo中的assets文件夹,这个文件夹的内部文件其实也可以说是,区别于其他APP的SDK,内部包括录音Dialog的图片素材等文件
3、复制speechDemo中的相关Util组件到我的项目
下面贴几张图:("设置"界面我将它放在外部了,因为是SDK中提供好的Activity我就不贴代码了)
下面是我封装的speechDemo的方法:
package com.android.action.app.iflytek.util; /** * 录音转译功能封装类,用于语音识别和转换文字 * * @version 1 * @param 2016.10.31 由Sherdon构建 * */ public class SpeechService { private Context context; private SpeechRecognizer speechRecognizer;// private String mEngineType;// 转译类型 private static String TAG = "SpeechService_"; public SpeechService() { }; /** * 录音转译功能封装类 * * @param mEngineType * 转译模式类型((云端)在线,本地,混合) * */ public SpeechService(Context context, String mEngineType) { this.context = context; this.mEngineType = mEngineType; }; private RecognizerDialog speechRecognizerDialog; private SharedPreferences mSharedPreferences; /** * 返回语音转换对象, * @return SpeechRecognizer * 返回语音识别器对象,在当前Activity的生命周期中需要用到,进行销毁暂停等操作 * */ public SpeechRecognizer initIflytek() { // 注册 // SpeechUtility.createUtility(context,SpeechConstant.APPID + // "=ab123456");这里替换为你自己的Appid SpeechUtility.createUtility(context, SpeechConstant.APPID + StringConstants.VoiceAppid); // 使用SpeechRecognizer对象,可根据回调消息自定义界面; speechRecognizer = SpeechRecognizer.createRecognizer(context, mInitListener); // 初始化听写Dialog,如果只使用有UI听写功能,无需创建SpeechRecognizer // 使用UI听写功能,请根据sdk文件目录下的notice.txt,放置布局文件和图片资源 speechRecognizerDialog = new RecognizerDialog(context, mInitListener); mSharedPreferences = context.getSharedPreferences( IatSettings.PREFER_NAME, Activity.MODE_PRIVATE); // mToast = Toast.makeText(this, "", Toast.LENGTH_SHORT); // et_remark = ((EditText) findViewById(R.id.iat_text)); // mInstaller = new ApkInstaller(context); // Activity activity = (Activity) context; return speechRecognizer; } /** * 初始化监听器。 */ private InitListener mInitListener = new InitListener() { @Override public void onInit(int code) { Log.d(TAG + "初始化监听器", "SpeechRecognizer init() code = " + code); if (code != ErrorCode.SUCCESS) { Toast.makeText(context, "初始化失败,错误码:" + code, Toast.LENGTH_SHORT) .show(); } } }; // 用HashMap存储听写结果 private HashMap<String, String> speechRecognizerResults = new LinkedHashMap<String, String>(); 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(); } speechRecognizerResults.put(sn, text); StringBuffer resultBuffer = new StringBuffer(); for (String key : speechRecognizerResults.keySet()) { resultBuffer.append(speechRecognizerResults.get(key)); } currentEditText.setText(resultBuffer.toString()); currentEditText.setSelection(currentEditText.length()); // switch (voiceType) { // case 1:// 今日小结 // mEdResult.setText(resultBuffer.toString()); // mEdResult.setSelection(mEdResult.length()); // break; // case 2:// 补充说明 // mEdSuppleExplan.setText(resultBuffer.toString()); // mEdSuppleExplan.setSelection(mEdSuppleExplan.length()); // break; // } } private EditText currentEditText;// 当前需要赋值的EditText /** * 返回录音文件的路径用于播放 * * @param mEngineType * 语音识别模式 云端(在线)、本地、混合,此处传该参数是用于,刷新可能被修改的语音识别模式 * @param editText 目标输入框,语音转译后生成文本的目标控件 * @return mAudioPath 返回录音文件路径,用于录音文件处理 * */ public String doIflytek(EditText editText, String mEngineType) { this.mEngineType = mEngineType; this.currentEditText = editText; // 移动数据分析,收集开始听写事件 FlowerCollector.onEvent(context, "iat_recognize"); editText.setText(null);// 清空显示内容 speechRecognizerResults.clear(); // 设置参数 setParam(); boolean isShowDialog = mSharedPreferences.getBoolean( context.getString(R.string.pref_key_iat_show), true); if (isShowDialog) { // 显示听写对话框 speechRecognizerDialog.setListener(mRecognizerDialogListener); speechRecognizerDialog.show(); // showMessage(context.getString(R.string.text_begin)); Toast.makeText(context, context.getString(R.string.text_begin), Toast.LENGTH_SHORT).show(); } else { // 不显示听写对话框 int ret = speechRecognizer.startListening(mRecognizerListener); if (ret != ErrorCode.SUCCESS) { Toast.makeText(context, "听写失败,错误码:" + ret, Toast.LENGTH_SHORT) .show(); } else { Toast.makeText(context, context.getString(R.string.text_begin), Toast.LENGTH_SHORT).show(); } } return mAudioPath; } private String mAudioPath; // 录音 public void setParam() { // 清空参数 speechRecognizer.setParameter(SpeechConstant.PARAMS, null); // 设置听写引擎 speechRecognizer.setParameter(SpeechConstant.ENGINE_TYPE, mEngineType); // 设置返回结果格式 speechRecognizer.setParameter(SpeechConstant.RESULT_TYPE, "json"); String lag = mSharedPreferences.getString("iat_language_preference", "mandarin"); if (lag.equals("en_us")) { // 设置语言 speechRecognizer.setParameter(SpeechConstant.LANGUAGE, "en_us"); } else { // 设置语言 speechRecognizer.setParameter(SpeechConstant.LANGUAGE, "zh_cn"); // 设置语言区域 speechRecognizer.setParameter(SpeechConstant.ACCENT, lag); } // 设置语音前端点:静音超时时间,即用户多长时间不说话则当做超时处理 speechRecognizer.setParameter(SpeechConstant.VAD_BOS, mSharedPreferences.getString 4000 ("iat_vadbos_preference", "4000")); // 设置语音后端点:后端点静音检测时间,即用户停止说话多长时间内即认为不再输入, 自动停止录音 speechRecognizer.setParameter(SpeechConstant.VAD_EOS, mSharedPreferences.getString("iat_vadeos_preference", "1800")); // 设置标点符号,设置为"0"返回结果无标点,设置为"1"返回结果有标点 speechRecognizer.setParameter(SpeechConstant.ASR_PTT, mSharedPreferences.getString("iat_punc_preference", "1")); // 设置音频保存路径,保存音频格式支持pcm、wav,设置路径为sd卡请注意WRITE_EXTERNAL_STORAGE权限 // 注:AUDIO_FORMAT参数语记需要更新版本才能生效 speechRecognizer.setParameter(SpeechConstant.AUDIO_FORMAT, "wav"); // mAudioPath = Environment.getExternalStorageDirectory() // + "/ydsanbu/msc/" + DateUtil.getCurrentTime() + ".wav"; mAudioPath = context.getExternalFilesDir(null) + File.separator + "logReport.wav"; speechRecognizer .setParameter(SpeechConstant.ASR_AUDIO_PATH, mAudioPath); } /** * 听写监听器。 */ private RecognizerListener mRecognizerListener = new RecognizerListener() { @Override public void onBeginOfSpeech() { // 此回调表示:sdk内部录音机已经准备好了,用户可以开始语音输入 Toast.makeText(context, "开始说话", Toast.LENGTH_SHORT).show(); } @Override public void onError(SpeechError error) { // Tips: // 错误码:10118(您没有说话),可能是录音机权限被禁,需要提示用户打开应用的录音权限。 // 如果使用本地功能(语记)需要提示用户开启语记的录音权限。 Toast.makeText(context, error.getPlainDescription(true), Toast.LENGTH_SHORT).show(); } @Override public void onEndOfSpeech() { // 此回调表示:检测到了语音的尾端点,已经进入识别过程,不再接受语音输入 Toast.makeText(context, "结束说话", Toast.LENGTH_SHORT).show(); } @Override public void onResult(RecognizerResult results, boolean isLast) { Log.d(TAG + "onResult", results.getResultString()); printResult(results); if (isLast) { // TODO 最后的结果 // File file=new File(mAudioPath); // if(file!=null){ // // mAudioPath = pVisitVO.getOpinionAudio(); // int time = Util.getSeconds(mAudioPath); // rl_audio.setVisibility(View.VISIBLE); // tv_audio.setCompoundDrawablesWithIntrinsicBounds( // R.drawable.chatto_voice_playing, 0, 0, 0); // tv_audio.setCompoundDrawablePadding(5); // tv_audio.setText(String.valueOf(time)); // tv_audio.setGravity(Gravity.CENTER_VERTICAL); // } } } @Override public void onVolumeChanged(int volume, byte[] data) { // showMessage("当前正在说话,音量大小:" + volume); Log.d(TAG + "onVolumeChanged", "返回音频数据:" + data.length); } @Override public void onEvent(int eventType, int arg1, int arg2, Bundle obj) { // 以下代码用于获取与云端的会话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); // } } }; /** * 听写UI监听器 */ private RecognizerDialogListener mRecognizerDialogListener = new RecognizerDialogListener() { public void onResult(RecognizerResult results, boolean isLast) { printResult(results); if (isLast) { // TODO 最后的结果 // File file=new File(mAudioPath); // if(file!=null){ // // mAudioPath = pVisitVO.getOpinionAudio(); // int time = Util.getSeconds(mAudioPath); // rl_audio.setVisibility(View.VISIBLE); // tv_audio.setCompoundDrawablesWithIntrinsicBounds( // R.drawable.chatto_voice_playing, 0, 0, 0); // tv_audio.setCompoundDrawablePadding(5); // tv_audio.setText(String.valueOf(time)); // tv_audio.setGravity(Gravity.CENTER_VERTICAL); // } } } /** * 识别回调错误. */ public void onError(SpeechError error) { Toast.makeText(context, error.getPlainDescription(true), Toast.LENGTH_SHORT).show(); } }; }
以下是Activity的调用:
package com.android.action.app.activity.page.vspharmacy; @SuppressLint("NewApi") public class SalesActiveActivity extends BaseActivity implements OnLongClickListener { private final String TAG = "SalesActiveActivity"; /** private String mAbnormalAudio; // 录音 private EditText et_remark; private TextView m_tv_word; // 剩余字数
private TextView title; // private int m_total_count = 200; // 默认最长输入200个字符 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.abnormal_layout); // 获取上个界面传递过来的数据 parseIntent(); initViews(); initListeners(); initData(); initIflytek(); } private String mEngineType = SpeechConstant.TYPE_CLOUD; private SpeechRecognizer sRecognizer; // 语记安装助手类,用于语音模式切换,切换本地或者混合模式时,提示安装语记,来部署本地环境 ApkInstaller mInstaller; private void initIflytek() { // TODO Auto-generated method stub mInstaller = new ApkInstaller(SalesActiveActivity.this); speechService = new SpeechService(SalesActiveActivity.this, mEngineType);//这就是我的语音转换初始化和事件的封装类 sRecognizer = speechService.initIflytek();//语音识别器,OnDestroy(),和OnResume()事件中需要用到 } // private String SignType;// 签到类型 private void parseIntent() { } private RelativeLayout rl_audio_layout; private void initViews() { title = (TextView) findViewById(R.id.title); title.setText("促销活动"); rl_audio_layout = (RelativeLayout) findViewById(R.id.rl_audio_layout); // rl_audio_layout.setVisibility(View.GONE);//影藏布局 mBtnBack = (ImageView) findViewById(R.id.iv_back); btn_submit = (Button) findViewById(R.id.btn_submit); et_remark = (EditText) findViewById(R.id.etxt_abnormal_remark); btn_audio = (Button) findViewById(R.id.btn_abnormal_audio); rl_audio = (RelativeLayout) findViewById(R.id.rl_abnormal_audio_del); m_tv_word = (TextView) findViewById(R.id.tv_rest_word); } private void initListeners() { mBtnBack.setOnClickListener(listener); btn_audio.setOnClickListener(listener); btn_audio.setOnLongClickListener(this);//长按按钮进入语音模式选择界面 btn_submit.setOnClickListener(listener); et_remark.addTextChangedListener(new TextWatcher() { @Override public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) { } @Override public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) { } @Override public void afterTextChanged(Editable editable) { m_tv_word.setText(String.valueOf(m_total_count - editable.toString().length())); } }); } private SpeechService speechService; private void initData() { } private OnClickListener listener = new OnClickListener() { @Override public void onClick(View v) { Intent intent; switch (v.getId()) { case R.id.btn_abnormal_audio: speechService.doIflytek(et_remark, mEngineType);//这里来触发语音识别事件 break;//此方法我返回了录音文件路径,可作为扩展的语音播放功能的文件来源 case R.id.iv_back: SalesActiveActivity.this.finish(); break; } } }; @SuppressLint("NewApi") @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { // TODO Auto-generated method stub super.onActivityResult(requestCode, resultCode, data); if (resultCode == RESULT_OK) { switch (requestCode) { case REQUEST_CODE_VOICE_MODE: int datas = data.getIntExtra("VoiceMode", -1); switch (datas) { case 0: mEngineType = SpeechConstant.TYPE_CLOUD;//在线模式 break; case 1: mEngineType = SpeechConstant.TYPE_LOCAL;//本地模式 if (!SpeechUtility.getUtility().checkServiceInstalled()) { mInstaller.install(); } else { String result = FucUtil.checkLocalResource(); if (!TextUtils.isEmpty(result)) { showMessage(result); } } break; case 2: mEngineType = SpeechConstant.TYPE_MIX;//混合模式 if (!SpeechUtility.getUtility().checkServiceInstalled()) { mInstaller.install(); } else { String result = FucUtil.checkLocalResource(); if (!TextUtils.isEmpty(result)) { showMessage(result); } } break; } break; } } } @Override public void finish() { // TODO Auto-generated method stub super.finishWithAnimation(R.anim.start_activity_out2, R.anim.finish_activity_out2); } @Override protected void onDestroy() { super.onDestroy(); // 退出时释放连接 sRecognizer.cancel(); sRecognizer.destroy(); } @Override protected void onResume() { // 开放统计 移动数据统计分析 FlowerCollector.onResume(SalesActiveActivity.this); FlowerCollector.onPageStart(TAG); super.onResume(); } @Override protected void onPause() { // 开放统计 移动数据统计分析 FlowerCollector.onPageEnd(TAG); FlowerCollector.onPause(SalesActiveActivity.this); super.onPause(); } @Override public boolean onLongClick(View v) {//我把设置语音识别模式放到外部,做了一个单独的activity // TODO Auto-generated method stub Intent intent = new Intent(SalesActiveActivity.this, VoiceModeActivity.class); int mode = -1; if (mEngineType.equals(SpeechConstant.TYPE_CLOUD)) { mode = 0; } if (mEngineType.equals(SpeechConstant.TYPE_LOCAL)) { mode = 1; } if (mEngineType.equals(SpeechConstant.TYPE_MIX)) { mode = 2; } intent.putExtra("VoiceMode", mode); startActivityForResult(intent, REQUEST_CODE_VOICE_MODE); return false; } private final int REQUEST_CODE_VOICE_MODE = 10; }再把语音模式设置activity代码贴上:
package com.android.action.app.iflytek.setting; import android.content.Intent; import android.content.pm.PackageInfo; import android.os.Build; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.RadioButton; import android.widget.RadioGroup; import android.widget.RadioGroup.OnCheckedChangeListener; import android.widget.RelativeLayout; import android.widget.TextView; import com.android.ydsanbu.app.R; import com.android.ydsanbu.app.activity.BaseActivity; import com.android.ydsanbu.app.iflytek.setting.IatSettings; public class VoiceModeActivity extends BaseActivity implements OnClickListener, OnCheckedChangeListener { @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setView(); initView(); initData(); initListener(); } private LinearLayout lltt; private ImageView iv_back; private TextView tv_tt; private void setView() { // TODO Auto-generated method stub setContentView(R.layout.activity_voice_mode); lltt = (LinearLayout) findViewById(R.id.ll_tittle); iv_back = (ImageView) lltt.findViewById(R.id.iv_tittle_back); tv_tt = (TextView) lltt.findViewById(R.id.tv_title_text); tv_tt.setText("语音模式选择"); } private RadioGroup rd_group; private void initView() { // TODO Auto-generated method stub rd_group = (RadioGroup) findViewById(R.id.radioGroup); rd_cloud = (RadioButton) findViewById(R.id.iatRadioCloud); rd_local = (RadioButton) findViewById(R.id.iatRadioLocal); rd_mix = (RadioButton) findViewById(R.id.iatRadioMix); } private int mode; private RadioButton rd_cloud; private RadioButton rd_local; private RadioButton rd_mix; private void initData() { mode = getIntent().getIntExtra("VoiceMode", 0); switch (mode) { case 0: rd_cloud.setChecked(true); break; case 1: rd_local.setChecked(true); break; case 2: rd_mix.setChecked(true); break; default: break; } } private void initListener() { // TODO Auto-generated method stub iv_back.setOnClickListener(this); rd_group.setOnCheckedChangeListener(this); } @Override public void onClick(View v) { // TODO Auto-generated method stub switch (v.getId()) { case R.id.iv_tittle_back: Intent intent = new Intent(); intent.putExtra("VoiceMode", checkedId); setResult(RESULT_OK, intent); onBackPressed(); break; default: break; } } private int checkedId;// 语音模式 @Override public void onCheckedChanged(RadioGroup group, int checkedId) { // TODO Auto-generated method stub switch (checkedId) { case R.id.iatRadioCloud://在线模式 this.checkedId = 0; break; case R.id.iatRadioLocal://本地模式 this.checkedId = 1; break; case R.id.iatRadioMix://混合模式 this.checkedId = 2; break; } Intent intent = new Intent(); intent.putExtra("VoiceMode", this.checkedId); setResult(RESULT_OK, intent); onBackPressed(); } }
相关文章推荐
- android 融云 + 科大讯飞 实现仿微信语音消息转换为文字
- android自学之TextToSpeech实现文字向语音的转换
- UE4+科大讯飞SDK 语音转文字之字符串转码问题
- Android实战——科大讯飞语音听写SDK的使用,实现语音识别功能
- 使用科大讯飞语音SDK实现文字在线合成语音
- Android实战——科大讯飞语音听写SDK的使用,实现语音识别功能
- Android 科大讯飞语音集成,文字转语音
- android 轻松实现在线即时聊天【图片、语音、表情、文字】等!含源码!
- android语音识别之科大讯飞语音API的使用
- android语音识别之科大讯飞语音API的使用
- Android 语音合成(使用科大讯飞sdk)
- android语音识别之科大讯飞语音API的使用
- Android开发 语音识别技术之科大讯飞语音识别(一) — 语音听写
- android 轻松实现在线即时聊天【图片、语音、表情、文字】等!含源码!
- Android开发 语音识别技术之科大讯飞语音识别(二) — 语音合成
- 如何让Win7发声“讲述”将文字转换为语音
- 转:android语音识别之科大讯飞语音API的使用
- android语音识别之科大讯飞语音API的使用
- .android 语音(声音)转文字