> 文章列表 > 讯飞语音合成andriod版本

讯飞语音合成andriod版本

讯飞语音合成andriod版本

目录直达

      • 1、成员变量声明
      • 2、参数设置
      • 3、获取离线资源
      • 4、语音合成监听
      • 5、调用方法合成语音
      • 6、在onCreate中初始化合成对象
      • 7、添加一个按钮
      • 8、按钮按下监听

在离线命令的基础上,我们可以添加语音合成功能,因为讯飞语音合成于离线命令识别有相同的地方,所以在这来主要就讲语音合成不同的地方,详细资料可以查看文末博客和仓库源码。

1、成员变量声明

SpeechSynthesizer 就是语音合成的对象,主要去调用它的startSpeaking(text, SynthesizerListener)方法来实现发声操作。

    /*  语音合成*/// 语音合成对象private SpeechSynthesizer mTts;public static String voicerCloud = "xiaoyan";// 默认本地发音public static String voicerLocal = "xiaoyan";public static String voicerXtts = "xiaoyan";//缓冲进度private int mPercentForBuffering = 0;//播放进度private int mPercentForPlaying = 0;

2、参数设置

离线命令识别和语音合成都有各自的参数设置,可以在代码中固定,也可以做成界面来动态调节。

    // 语音合成参数设置private void setParam_to_compound() {// 清空参数mTts.setParameter(SpeechConstant.PARAMS, null);//设置合成if (mEngineType.equals(SpeechConstant.TYPE_CLOUD)) {//设置使用云端引擎mTts.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD);//设置发音人mTts.setParameter(SpeechConstant.VOICE_NAME, voicerCloud);} else if (mEngineType.equals(SpeechConstant.TYPE_LOCAL)) {//设置使用本地引擎mTts.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_LOCAL);//设置发音人资源路径mTts.setParameter(ResourceUtil.TTS_RES_PATH, getResourcePath());//设置发音人mTts.setParameter(SpeechConstant.VOICE_NAME, voicerLocal);} else {mTts.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_XTTS);//设置发音人资源路径mTts.setParameter(ResourceUtil.TTS_RES_PATH, getResourcePath());//设置发音人mTts.setParameter(SpeechConstant.VOICE_NAME, voicerXtts);}//mTts.setParameter(SpeechConstant.TTS_DATA_NOTIFY,"1");//支持实时音频流抛出,仅在synthesizeToUri条件下支持//设置合成语速mTts.setParameter(SpeechConstant.SPEED, mSharedPreferences.getString("speed_preference", "50"));//设置合成音调mTts.setParameter(SpeechConstant.PITCH, mSharedPreferences.getString("pitch_preference", "50"));//设置合成音量mTts.setParameter(SpeechConstant.VOLUME, mSharedPreferences.getString("volume_preference", "50"));//设置播放器音频流类型mTts.setParameter(SpeechConstant.STREAM_TYPE, mSharedPreferences.getString("stream_preference", "3"));//	mTts.setParameter(SpeechConstant.STREAM_TYPE, AudioManager.STREAM_MUSIC+"");// 设置播放合成音频打断音乐播放,默认为truemTts.setParameter(SpeechConstant.KEY_REQUEST_FOCUS, "true");// 设置音频保存路径,保存音频格式支持pcm、wav,设置路径为sd卡请注意WRITE_EXTERNAL_STORAGE权限mTts.setParameter(SpeechConstant.AUDIO_FORMAT, "wav");mTts.setParameter(SpeechConstant.TTS_AUDIO_PATH,getExternalFilesDir("msc").getAbsolutePath() + "/tts.pcm");}

3、获取离线资源

在这里获取的离线资源其实就是获取发音人文件(.jet文件),这个是官方提供的有免费的,也有付费的(比较贵),详情就需要去讯飞官网查看了。

 /*获取文件下的离线资源* @return*/private String getResourcePath() {String type = "tts";StringBuffer tempBuffer = new StringBuffer();//离线命令识别通用资源tempBuffer.append(ResourceUtil.generateResourcePath(this, ResourceUtil.RESOURCE_TYPE.assets, "iat/common.jet"));tempBuffer.append(";");tempBuffer.append(ResourceUtil.generateResourcePath(this, ResourceUtil.RESOURCE_TYPE.assets, "iat/sms_16k.jet"));//语音合成通用资源tempBuffer.append(ResourceUtil.generateResourcePath(this, ResourceUtil.RESOURCE_TYPE.assets, type + "/common.jet"));tempBuffer.append(";");//发音人资源if (mEngineType.equals(SpeechConstant.TYPE_XTTS)) {tempBuffer.append(ResourceUtil.generateResourcePath(this, ResourceUtil.RESOURCE_TYPE.assets, type + "/" + IatActivity.voicerXtts + ".jet"));} else {tempBuffer.append(ResourceUtil.generateResourcePath(this, ResourceUtil.RESOURCE_TYPE.assets, type + "/" + IatActivity.voicerLocal + ".jet"));}return tempBuffer.toString();}

4、语音合成监听

在语音合成这个过程有很多操作,类使用方法的生命周期,可以在这个过程中做一些操作。

    /* 合成回调监听 合成过程中状态监听*/private SynthesizerListener mTtsListener = new SynthesizerListener() {@Overridepublic void onSpeakBegin() {//showTip("开始播放");Log.d(MainActivity.TAG, "开始播放:" + System.currentTimeMillis());}@Overridepublic void onSpeakPaused() {showTip("暂停播放");}@Overridepublic void onSpeakResumed() {showTip("继续播放");}@Overridepublic void onBufferProgress(int percent, int beginPos, int endPos,String info) {// 合成进度mPercentForBuffering = percent;showTip(String.format(getString(R.string.tts_toast_format),mPercentForBuffering, mPercentForPlaying));}@Overridepublic void onSpeakProgress(int percent, int beginPos, int endPos) {// 播放进度mPercentForPlaying = percent;showTip(String.format(getString(R.string.tts_toast_format),mPercentForBuffering, mPercentForPlaying));}@Overridepublic void onCompleted(SpeechError error) {if (error == null) {showTip("播放完成");} else {showTip(error.getPlainDescription(true));}}@Overridepublic void onEvent(int eventType, int arg1, int arg2, Bundle obj) {// 以下代码用于获取与云端的会话id,当业务出错时将会话id提供给技术支持人员,可用于查询会话日志,定位出错原因// 若使用本地能力,会话id为nullif (SpeechEvent.EVENT_SESSION_ID == eventType) {String sid = obj.getString(SpeechEvent.KEY_EVENT_AUDIO_URL);Log.d(TAG, "session id =" + sid);}//实时音频流输出参考/*if (SpeechEvent.EVENT_TTS_BUFFER == eventType) {byte[] buf = obj.getByteArray(SpeechEvent.KEY_EVENT_TTS_BUFFER);Log.e("MscSpeechLog", "buf is =" + buf);}*/}};

5、调用方法合成语音

  /* 语音合成方法* @param text 需要合成的内容*/private void anwerRobot(String text){// 语音合成参数设置setParam_to_compound();Log.d(TAG, "准备点击: " + System.currentTimeMillis());int code = mTts.startSpeaking(text, mTtsListener);if (code != ErrorCode.SUCCESS) {showTip("语音合成失败,错误码: " + code + ",请点击网址https://www.xfyun.cn/document/error-code查询解决方案");}}

6、在onCreate中初始化合成对象

 // 初始化合成对象mTts = SpeechSynthesizer.createSynthesizer(this, mInitListener);Button_Compound()

7、添加一个按钮

<Buttonandroid:id="@+id/button_compound"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginBottom="396dp"android:text="语音合成"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toBottomOf="@+id/tv_result" />

8、按钮按下监听

private void Button_Compound(){Button button = findViewById(R.id.button_compound);button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {if (null == mIat) {// 创建单例失败,与 21001 错误为同样原因,参考 http://bbs.xfyun.cn/forum.php?mod=viewthread&tid=9688showTip("创建对象失败,请确认 libmsc.so 放置正确,\\n 且有调用 createUtility 进行初始化");return;}if(edit_result !=null){try {Thread.sleep(1000);anwerRobot("好的主人");} catch (InterruptedException e) {throw new RuntimeException(e);}}}});}

本文的功能是基于上一篇博客的基础上整合的,代码不是完整的,但是这是语音合成的核心部分代码。想要实现完整功能可以查看以下博客或去源码仓库拉取代码查看。

离线语音识别

源码仓库