android|Android开发之科大讯飞语音合成与播报


Android开发之科大讯飞语音合成与播报

  • 一、效果图
  • 二、打开[讯飞开放平台](https://www.xfyun.cn/),注册登录后,找到我的应用,点击创建新应用。
  • 三、填写相关信息,然后点击提交。
  • 四、点击创建好的应用。
  • 五、可以看到APPID信息。
  • 六、往下滑可以下载SDK。
  • 七、下载到本地后,解压。
  • 八、把刚才解压后的libs中的文件复制到项目中的libs下。
    • **1.此时这个Msc.jar还是不可用的,下面鼠标右键点击它。**
    • 2.点击Add As Library…
    • 3.点击OK,此时你可以看到它可以展开了,就说明你的app模块中已经添加了这个jar的依赖了。
  • 九、复制assets文件夹到项目中。
  • 十、粘贴到main下面,如下图所示。
  • 十一、配置项目,打开build.gradle。
  • 十二、AndroidManifest.xml中配置权限。
  • 十三、新建一个MyApplication类。
    • 1.然后在AndroidManifest.xml中配置
  • 十四、主布局文件(activity_yy)
  • 十五、主java文件(YybbActivity)

今天做一个稍微复杂点的,Android集成科大讯飞实现语音合成与播报功能。
老规矩,直接进入正题。
一、效果图 android|Android开发之科大讯飞语音合成与播报
文章图片

二、打开讯飞开放平台,注册登录后,找到我的应用,点击创建新应用。 android|Android开发之科大讯飞语音合成与播报
文章图片

三、填写相关信息,然后点击提交。 android|Android开发之科大讯飞语音合成与播报
文章图片

四、点击创建好的应用。 android|Android开发之科大讯飞语音合成与播报
文章图片

五、可以看到APPID信息。 android|Android开发之科大讯飞语音合成与播报
文章图片

六、往下滑可以下载SDK。 android|Android开发之科大讯飞语音合成与播报
文章图片

七、下载到本地后,解压。 android|Android开发之科大讯飞语音合成与播报
文章图片

这里重点就是这个libs文件夹中的内容了。
八、把刚才解压后的libs中的文件复制到项目中的libs下。 android|Android开发之科大讯飞语音合成与播报
文章图片

1.此时这个Msc.jar还是不可用的,下面鼠标右键点击它。 android|Android开发之科大讯飞语音合成与播报
文章图片

2.点击Add As Library… android|Android开发之科大讯飞语音合成与播报
文章图片

3.点击OK,此时你可以看到它可以展开了,就说明你的app模块中已经添加了这个jar的依赖了。 android|Android开发之科大讯飞语音合成与播报
文章图片

九、复制assets文件夹到项目中。 android|Android开发之科大讯飞语音合成与播报
文章图片

十、粘贴到main下面,如下图所示。 android|Android开发之科大讯飞语音合成与播报
文章图片

十一、配置项目,打开build.gradle。
//资源设置 sourceSets { main { jniLibs.srcDirs = ['libs'] } }

十二、AndroidManifest.xml中配置权限。

十三、新建一个MyApplication类。 android|Android开发之科大讯飞语音合成与播报
文章图片

package com.example; import android.app.Application; import com.iflytek.cloud.SpeechConstant; import com.iflytek.cloud.SpeechUtility; import org.xutils.x; public class MyApplication extends Application {@Override public void onCreate() { SpeechUtility.createUtility(MyApplication.this, SpeechConstant.APPID +"=\n" + "7b6e5ba7"); super.onCreate(); x.Ext.init(this); x.Ext.setDebug(BuildConfig.DEBUG); //这个会影响性能 } }

1.然后在AndroidManifest.xml中配置 android|Android开发之科大讯飞语音合成与播报
文章图片

十四、主布局文件(activity_yy) android|Android开发之科大讯飞语音合成与播报
文章图片


十五、主java文件(YybbActivity)
package com.example.activity; import static com.iflytek.cloud.VerifierResult.TAG; import android.Manifest; import android.content.pm.PackageManager; import android.graphics.Color; import android.os.Build; import android.os.Bundle; import android.os.MemoryFile; import android.text.Spannable; import android.text.SpannableStringBuilder; import android.text.style.BackgroundColorSpan; import android.util.Log; import android.view.View; import android.widget.EditText; import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; import com.example.R; import com.iflytek.cloud.ErrorCode; import com.iflytek.cloud.InitListener; import com.iflytek.cloud.SpeechConstant; import com.iflytek.cloud.SpeechError; import com.iflytek.cloud.SpeechEvent; import com.iflytek.cloud.SpeechSynthesizer; import com.iflytek.cloud.SynthesizerListener; import com.iflytek.cloud.msc.util.FileUtil; import com.iflytek.cloud.msc.util.log.DebugLog; import java.util.Vector; public class YybbActivity extends AppCompatActivity implements View.OnClickListener,AdapterView.OnItemSelectedListener { //语速 private String speedValue = "https://www.it610.com/article/50"; //音调 private String pitchValue = "https://www.it610.com/article/50"; //音量 private String volumeValue = "https://www.it610.com/article/50"; //输入框 private EditText etText; // 语音合成对象 private SpeechSynthesizer mTts; // 默认发音人 private String voicer = "xiaoyan"; //发音人名称 private static final String[] arrayName = {"讯飞小燕", "讯飞许久", "讯飞小萍", "讯飞小婧", "讯飞许小宝"}; //发音人值 private static final String[] arrayValue = https://www.it610.com/article/{"xiaoyan", "aisjiuxu", "aisxping", "aisjinger", "aisbabyxu"}; //数组适配器 private ArrayAdapter arrayAdapter; // 引擎类型 private String mEngineType = SpeechConstant.TYPE_CLOUD; //播放的文字 String text = " 属性:昔刘涓子晋末于丹阳郊外照射,忽见一物,高二丈许,射而中之,如雷电声若风雨。其夜不敢前追,诘旦率门徒子弟数人,寻纵至山下,见一小儿提罐,问何往为。"; private Vector container = new Vector<>(); //内存文件 MemoryFile memoryFile; //总大小 public volatile long mTotalSize = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_yy); //请求权限 requestPermissions(); initView(); // 初始化合成对象 mTts = SpeechSynthesizer.createSynthesizer(this, mTtsInitListener); } /** * 初始化页面 */ private void initView() { etText = findViewById(R.id.et_text); findViewById(R.id.btn_play).setOnClickListener(this); findViewById(R.id.btn_cancel).setOnClickListener(this); findViewById(R.id.btn_pause).setOnClickListener(this); findViewById(R.id.btn_resume).setOnClickListener(this); SeekBar sbSpeed = findViewById(R.id.sb_speed); SeekBar sbPitch = findViewById(R.id.sb_pitch); SeekBar sbVolume = findViewById(R.id.sb_volume); Spinner spinner = findViewById(R.id.spinner); //将可选内容与ArrayAdapter连接起来 arrayAdapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, arrayName); //设置下拉列表的风格 arrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); //将adapter 添加到spinner中 spinner.setAdapter(arrayAdapter); //添加事件Spinner事件监听 spinner.setOnItemSelectedListener(this); setSeekBar(sbSpeed, 1); setSeekBar(sbPitch, 2); setSeekBar(sbVolume, 3); }/** * 请求权限 */ private void requestPermissions() { try { //Android6.0及以上版本 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { int permission = ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE); if (permission != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.WRITE_SETTINGS, Manifest.permission.READ_EXTERNAL_STORAGE}, 0x0010); } } } catch (Exception e) { e.printStackTrace(); } } /** * 权限请求返回结果 */ @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); } /** * 页面点击事件 * @param v 控件 */ @Override public void onClick(View v) { if (mTts == null) { this.showTip("创建对象失败,请确认 libmsc.so 放置正确,且有调用 createUtility 进行初始化"); return; } switch (v.getId()) { case R.id.btn_play://开始合成 //输入文本 String etStr = etText.getText().toString().trim(); if (!etStr.isEmpty()) { text = etStr; } //设置参数 setParam(); //开始合成播放 int code = mTts.startSpeaking(text, mTtsListener); if (code != ErrorCode.SUCCESS) { showTip("语音合成失败,错误码: " + code); } break; case R.id.btn_cancel://取消合成 mTts.stopSpeaking(); break; case R.id.btn_pause://暂停播放 mTts.pauseSpeaking(); break; case R.id.btn_resume://继续播放 mTts.resumeSpeaking(); break; default: break; } } /** * 初始化监听。 */ private InitListener mTtsInitListener = new InitListener() { @Override public void onInit(int code) { Log.i(TAG, "InitListener init() code = " + code); if (code != ErrorCode.SUCCESS) { showTip("初始化失败,错误码:" + code); } else { showTip("初始化成功"); } } }; /** * Toast提示 * @param msg */ private void showTip(String msg) { Toast.makeText(this, msg, Toast.LENGTH_SHORT).show(); } /** * 参数设置 * * @return */ private void setParam() { // 清空参数 mTts.setParameter(SpeechConstant.PARAMS, null); // 根据合成引擎设置相应参数 if (mEngineType.equals(SpeechConstant.TYPE_CLOUD)) { mTts.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD); //支持实时音频返回,仅在synthesizeToUri条件下支持 mTts.setParameter(SpeechConstant.TTS_DATA_NOTIFY, "1"); // 设置在线合成发音人 mTts.setParameter(SpeechConstant.VOICE_NAME, voicer); //设置语速 mTts.setParameter(SpeechConstant.VOICE_NAME, voicer); //设置音调 mTts.setParameter(SpeechConstant.PITCH, pitchValue); //设置音量 mTts.setParameter(SpeechConstant.VOLUME, volumeValue); } else { mTts.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_LOCAL); mTts.setParameter(SpeechConstant.VOICE_NAME, ""); } // 设置播放合成音频打断音乐播放,默认为true mTts.setParameter(SpeechConstant.KEY_REQUEST_FOCUS, "false"); // 设置音频保存路径,保存音频格式支持pcm、wav mTts.setParameter(SpeechConstant.AUDIO_FORMAT, "pcm"); mTts.setParameter(SpeechConstant.TTS_AUDIO_PATH, getExternalFilesDir(null) + "/msc/tts.pcm"); } /** * 合成回调监听。 */ private SynthesizerListener mTtsListener = new SynthesizerListener() { //开始播放 @Override public void onSpeakBegin() { Log.i(TAG, "开始播放"); }//暂停播放 @Override public void onSpeakPaused() { Log.i(TAG, "暂停播放"); }//继续播放 @Override public void onSpeakResumed() { Log.i(TAG, "继续播放"); }//合成进度 @Override public void onBufferProgress(int percent, int beginPos, int endPos, String info) { Log.i(TAG, "合成进度:" + percent + "%"); }//播放进度 @Override public void onSpeakProgress(int percent, int beginPos, int endPos) { // 播放进度 Log.i(TAG, "播放进度:" + percent + "%"); SpannableStringBuilder style = new SpannableStringBuilder(text); style.setSpan(new BackgroundColorSpan(Color.RED), beginPos, endPos, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); etText.setText(style); }//播放完成 @Override public void onCompleted(SpeechError error) { if (error == null) { Log.i(TAG, "播放完成," + container.size()); DebugLog.LogD("播放完成," + container.size()); for (int i = 0; i < container.size(); i++) { //写入文件 writeToFile(container.get(i)); } //保存文件 FileUtil.saveFile(memoryFile, mTotalSize, getExternalFilesDir(null) + "/1.pcm"); } else { //异常信息 showTip(error.getPlainDescription(true)); } } /** * 写入文件 */ private void writeToFile(byte[] data) { if (data =https://www.it610.com/article/= null || data.length == 0) { return; } try { if (memoryFile == null) { Log.i(TAG,"memoryFile is null"); String mFilepath = getExternalFilesDir(null) + "/1.pcm"; memoryFile = new MemoryFile(mFilepath, 1920000); memoryFile.allowPurging(false); } memoryFile.writeBytes(data, 0, (int) mTotalSize, data.length); mTotalSize += data.length; } catch (Exception e) { e.printStackTrace(); } }//事件 @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.i(TAG, "session id =" + sid); }//当设置SpeechConstant.TTS_DATA_NOTIFY为1时,抛出buf数据 if (SpeechEvent.EVENT_TTS_BUFFER == eventType) { byte[] buf = obj.getByteArray(SpeechEvent.KEY_EVENT_TTS_BUFFER); Log.i(TAG, "bufis =" + buf.length); container.add(buf); } }}; /** * 选中 */ @Override public void onItemSelected(AdapterView parent, View view, int position, long id) { voicer = arrayValue[position]; } @Override public void onNothingSelected(AdapterView parent) { } //设置SeekBar private void setSeekBar(SeekBar seekBar, final int type) {seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { switch (type) { case 1://设置语速 范围 1~100 speedValue = https://www.it610.com/article/Integer.toString(progress); break; case 2://设置音调范围 1~100 pitchValue = Integer.toString(progress); break; case 3://设置音量范围 1~100 volumeValue = Integer.toString(progress); break; default: break; } }@Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onStopTrackingTouch(SeekBar seekBar) { } }); }}

【android|Android开发之科大讯飞语音合成与播报】到这里就结束了,你可以试试哦

    推荐阅读