300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > 语音听写与合成--(讯飞语音识别与合成百度语音识别)

语音听写与合成--(讯飞语音识别与合成百度语音识别)

时间:2023-09-12 04:58:02

相关推荐

语音听写与合成--(讯飞语音识别与合成百度语音识别)

目前比较厉害的国内免费开源的语音识别库主要就是:讯飞和百度,本篇博客也是关于这两家SDK的使用。

讯飞语音开放平台:/msc_android/299547

讯飞平台下载的sdk有doc文件夹,其中有html结尾的API文件,需要的去官网可以下载

本篇博客Demo地址:/download/g_ying_jie/9895905

讯飞语音听写功能:

第一步、集成SDK,配置权限文档已经介绍的很清楚了,Demo也可以下下来直接运行。类似于以下目录结构

第二步、实例化语音听写对象和UI。该dialog资源需要用到assets的资源

// 语音听写对象private SpeechRecognizer mIat = SpeechRecognizer.createRecognizer(VoiToTxtActivity.this, mInitListener);// 语音听写UIprivate RecognizerDialog mIatDialog = new RecognizerDialog(VoiToTxtActivity.this, mInitListener);

/*** 初始化监听器。*/private InitListener mInitListener = new InitListener() {@Overridepublic void onInit(int code) {Log.d(TAG, "SpeechRecognizer init() code = " + code);if (code != ErrorCode.SUCCESS) {showTip("初始化失败,错误码:" + code);}}};

第三步、设置参数

/*** 参数设置*/public void setParam() {// 清空参数mIat.setParameter(SpeechConstant.PARAMS, null);// 设置听写引擎mIat.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD);// 设置返回结果格式mIat.setParameter(SpeechConstant.RESULT_TYPE, "json");// 设置语言mIat.setParameter(SpeechConstant.LANGUAGE, "zh_cn");// 设置语言区域mIat.setParameter(SpeechConstant.ACCENT, "mandarin");// 设置语音前端点:静音超时时间,即用户多长时间不说话则当做超时处理mIat.setParameter(SpeechConstant.VAD_BOS, "5000");// 设置语音后端点:后端点静音检测时间,即用户停止说话多长时间内即认为不再输入, 自动停止录音mIat.setParameter(SpeechConstant.VAD_EOS, "1800");// 设置标点符号,设置为"0"返回结果无标点,设置为"1"返回结果有标点mIat.setParameter(SpeechConstant.ASR_PTT, "1");// 设置音频保存路径,保存音频格式支持pcm、wav,设置路径为sd卡请注意WRITE_EXTERNAL_STORAGE权限//mIat.setParameter(SpeechConstant.AUDIO_FORMAT, "wav");//mIat.setParameter(SpeechConstant.ASR_AUDIO_PATH, Environment.getExternalStorageDirectory() + "/msc/iat.wav");}

第四步、开始听写识别

// 显示听写对话框mIatDialog.setListener(mRecognizerDialogListener);mIatDialog.show();

/*** 听写UI监听器*/private RecognizerDialogListener mRecognizerDialogListener = new RecognizerDialogListener() {public void onResult(RecognizerResult results, boolean isLast) {printResult(results);}/*** 识别回调错误.*/public void onError(SpeechError error) {showTip(error.getPlainDescription(true));}};

//解析返回的识别结果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();}mIatResults.put(sn, text);StringBuffer resultBuffer = new StringBuffer();for (String key : mIatResults.keySet()) {resultBuffer.append(mIatResults.get(key));}mResultText.setText(resultBuffer.toString());mResultText.setSelection(mResultText.length());}

注意:这里用HashMap来存储听写结果

// 用HashMap存储听写结果private HashMap<String, String> mIatResults = new LinkedHashMap<String, String>();

最后、在onDestroy中做好回收工作

@Overrideprotected void onDestroy() {super.onDestroy();if (null != mIat) {// 退出时释放连接mIat.cancel();mIat.destroy();}}

讯飞针对词组优化提供了上传联系人和词表的方法

①上传联系人并使用mResultText展示给用户

ContactManager mgr = ContactManager.createManager(VoiToTxtActivity.this, mContactListener);mgr.asyncQueryAllContactsName();/*** 获取联系人监听器。*/private ContactListener mContactListener = new ContactListener() {@Overridepublic void onContactQueryFinish(final String contactInfos, boolean changeFlag) {// 注:实际应用中除第一次上传之外,之后应该通过changeFlag判断是否需要上传,否则会造成不必要的流量.// 每当联系人发生变化,该接口都将会被回调,可通过ContactManager.destroy()销毁对象,解除回调。// if(changeFlag) {// 指定引擎类型runOnUiThread(new Runnable() {public void run() {mResultText.setText(contactInfos);}});mIat.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD);mIat.setParameter(SpeechConstant.TEXT_ENCODING, "utf-8");ret = mIat.updateLexicon("contact", contactInfos, mLexiconListener);if (ret != ErrorCode.SUCCESS) {showTip("上传联系人失败:" + ret);}}};

②上传用户词组

String contents = FucUtil.readFile(VoiToTxtActivity.this, "userwords","utf-8");mResultText.setText(contents);// 指定引擎类型mIat.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD);mIat.setParameter(SpeechConstant.TEXT_ENCODING, "utf-8");ret = mIat.updateLexicon("userword", contents, mLexiconListener);if (ret != ErrorCode.SUCCESS)showTip("上传热词失败,错误码:" + ret);

/*** 上传联系人/词表监听器。*/private LexiconListener mLexiconListener = new LexiconListener() {@Overridepublic void onLexiconUpdated(String lexiconId, SpeechError error) {if (error != null) {showTip(error.toString());} else {showTip("上传成功");}}};

讯飞语音合成:

第一步,实例化语音合成对象和云端发音人列表

// 语音合成对象private SpeechSynthesizer mTts = SpeechSynthesizer.createSynthesizer(TxtToVoiActivity.this, mTtsInitListener);// 默认发音人private String voicer = "xiaoyan";private String[] mCloudVoicersEntries = getResources().getStringArray(R.array.voicer_cloud_entries);private String[] mCloudVoicersValue = getResources().getStringArray(R.array.voicer_cloud_values);

/*** 初始化监听。*/private InitListener mTtsInitListener = new InitListener() {@Overridepublic void onInit(int code) {if (code != ErrorCode.SUCCESS) {showTip("初始化失败,错误码:" + code);} else {// 初始化成功,之后可以调用startSpeaking方法// 注:有的开发者在onCreate方法中创建完合成对象之后马上就调用startSpeaking进行合成,// 正确的做法是将onCreate中的startSpeaking调用移至这里}}};

res文件夹下的Strings配置如下

<string-array name="voicer_cloud_entries"><item>小燕—女青、中英、普通话</item><item>小宇—男青、中英、普通话</item><item>小研—女青、中英、普通话</item><item>小琪—女青、中英、普通话</item><item>小峰—男青、中英、普通话</item><item>小梅—女青、中英、粤语</item><item>小莉—女青、中英、台湾普通话</item></string-array><string-array name="voicer_cloud_values"><item>xiaoyan</item><item>xiaoyu</item><item>vixy</item><item>xiaoqi</item><item>vixf</item><item>vixm</item><item>vixl</item></string-array>

第二步,设置识别参数

private int selectedNum = 0;/*** 发音人选择。*/private void showPersonSelectDialog() {new AlertDialog.Builder(this).setTitle("在线合成发音人选项")/** CharSequence[] 单选框有几项,各是什么名字* checkedItem 默认的选项* listener 点击单选框后的回调* */.setSingleChoiceItems(mCloudVoicersEntries, selectedNum, new DialogInterface.OnClickListener() {public void onClick(DialogInterface dialog, int which) {// 点击了哪一项voicer = mCloudVoicersValue[which];selectedNum = which;dialog.dismiss();}}).show();}

/*** 参数设置*/private void setParam() {// 清空参数mTts.setParameter(SpeechConstant.PARAMS, null);// 根据合成引擎设置相应参数mTts.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD);// 设置在线合成发音人mTts.setParameter(SpeechConstant.VOICE_NAME, voicer);//设置合成语速mTts.setParameter(SpeechConstant.SPEED, "50");//设置合成音调mTts.setParameter(SpeechConstant.PITCH, "50");//设置合成音量mTts.setParameter(SpeechConstant.VOLUME, "50");//设置播放器音频流类型 值范围:android.media.AudioManager支持的流类型值mTts.setParameter(SpeechConstant.STREAM_TYPE, "3");// 设置播放合成音频打断音乐播放,默认为truemTts.setParameter(SpeechConstant.KEY_REQUEST_FOCUS, "true");// 设置音频保存路径,保存音频格式支持pcm、wav,设置路径为sd卡请注意WRITE_EXTERNAL_STORAGE权限// 注:AUDIO_FORMAT参数语记需要更新版本才能生效mTts.setParameter(SpeechConstant.AUDIO_FORMAT, "wav");mTts.setParameter(SpeechConstant.TTS_AUDIO_PATH, Environment.getExternalStorageDirectory() + "/msc/tts.wav");}

第三步,获取待合成的文字内容,开始合成语音

String text = ((EditText) findViewById(R.id.tts_text)).getText().toString();/** 只保存音频不调用播放接口时请注释startSpeaking接口* text:要合成的文本* listener:回调接口* uri:需要保存的音频全路径*///String path = Environment.getExternalStorageDirectory()+"/tts.pcm";//int code = mTts.synthesizeToUri(text, path, mTtsListener);int code = mTts.startSpeaking(text, mTtsListener);if (code != ErrorCode.SUCCESS) {showTip("语音合成失败,错误码: " + code);}

/*** 合成回调监听。*/private SynthesizerListener mTtsListener = new SynthesizerListener() {@Overridepublic void onSpeakBegin() {showTip("开始播放");}@Overridepublic void onSpeakPaused() {showTip("暂停播放");}@Overridepublic void onSpeakResumed() {showTip("继续播放");}@Overridepublic void onBufferProgress(int percent, int beginPos, int endPos, String info) {// 合成进度mPercentForBuffering = percent;showTip(String.format("缓冲进度为%d%%,播放进度为%d%%", mPercentForBuffering, mPercentForPlaying));}@Overridepublic void onSpeakProgress(int percent, int beginPos, int endPos) {// 播放进度mPercentForPlaying = percent;showTip(String.format("缓冲进度为%d%%,播放进度为%d%%", mPercentForBuffering, mPercentForPlaying));}@Overridepublic void onCompleted(SpeechError error) {if (error == null) {showTip("播放完成");} else if (error != null) {showTip(error.getPlainDescription(true));}}@Overridepublic 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);//}}};

其他的比较有用的方法:

// 取消合成mTts.stopSpeaking();// 暂停播放mTts.pauseSpeaking();// 继续播放mTts.resumeSpeaking();

好了到此讯飞在线语音就介绍完了,详细的使用可以下载我上传的Demo。这里为什么强调在线呢?因为讯飞的离线语音识别服务需要下载语记APP以及对应的离线数据包,而且离线识别只能适用于安卓平台,因此只是尝试了没有深入研究就不贴出来了。

百度语音篇

百度语音基础视频介绍:/v7867982-208144-1278714.html

百度语音识别API对接视频:/v7867982-209753-1294636.html

百度语音文档中心:/docs#/ASR-Android-SDK/top

本篇博客Demo:/detail/g_ying_jie/9890613

百度的SDK是离在线融合的(可是没研究出来离线识别,需要开通离线授权,巴拉巴拉。。。。如果有哪位大神弄出来了,希望也能够共享出来)

百度自定义了一个语音识别组件,所以基本一句话就可以实现语音识别的流程

第一步、开始识别

private void start() {Intent recognizerIntent = new Intent(MainActivity.this, BaiduASRDigitalDialog.class);//采样率recognizerIntent.putExtra(Constant.EXTRA_SAMPLE, 16000);//识别语种recognizerIntent.putExtra(Constant.EXTRA_LANGUAGE, "cmn-Hans-CN");//设置语言活动模式 input输入模式search搜索模式recognizerIntent.putExtra(Constant.EXTRA_VAD, "input");/*//说话开始的提示音recognizerIntent.putExtra(Constant.EXTRA_SOUND_START, R.raw.bdspeech_recognition_start);//说话结束的提示音recognizerIntent.putExtra(Constant.EXTRA_SOUND_END, R.raw.bdspeech_speech_end);//识别成功的提示音recognizerIntent.putExtra(Constant.EXTRA_SOUND_SUCCESS, R.raw.bdspeech_recognition_success);//识别出错的提示音recognizerIntent.putExtra(Constant.EXTRA_SOUND_ERROR, R.raw.bdspeech_recognition_error);//识别取消的提示音recognizerIntent.putExtra(Constant.EXTRA_SOUND_CANCEL, R.raw.bdspeech_recognition_cancel);//语义识别recognizerIntent.putExtra(Constant.EXTRA_NLU, "enable");*/startActivityForResult(recognizerIntent, 1);}

第二步、处理识别结果

@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult(requestCode, resultCode, data);if (resultCode == RESULT_OK) {textView.setText(data.getExtras().getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION).get(0));}}

注意:BaiduASRDigitalDialog需要与之配套的res资源,而且该资源都是放于drawable文件夹下,不能粗暴的将图片资源复制到mipmap中,使用Android studio的开发者一定要注意(楼主已经入坑)

Demo都上传到了csdn上面,有需要的可以下载运行,不需要积分。有问题或者建议欢迎在评论区留言

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。