集成Android免费语音合成功能(在线、离线、离在线融合),有这一篇文章就够了(离线)
集成Android免费语音合成功能(在线、离线、离在线融合),有这一篇文章就够了(离在线融合)

转眼间,大半年没写文章了,没什么理由,就是人变懒了。囧~
看标题,其实大家都被骗了,有这一篇文章还不够,我其实是打算分3篇文章来写的,如果合在一章里面就太长了,不过现在这个标题党横行的网络世界,我也被污染了,哈。
那么为什么要分3篇文章来讲呢?看标题也能猜到了,就是在线、离线、离在线融合这3种语音合成方式,我将分别使用科大讯飞、云知声、百度语音来实现Android的语音合成。至于有什么优缺点,大家可以自行百度,这里就不再赘言了,好吧,不说废话了,我怕有人会打我,哈哈~
首先,这一篇先写用科大讯飞实现的在线语音合成吧,是免费的,它的离线是要钱的,有需求的可以自己到它们官网去看看。
打开讯飞开放平台

注册、登录开发者账号

进入控制台,创建新应用

开通在线语音合成服务

下载SDK

下载完SDK后,解压压缩包sample-->SpeechDemo

打开SpeechDemo-->libs文件夹,复制jar包和.so文件到你的项目里面,然后sync一下

做完以上准备工作,就可以开始撸代码了
首先,AndroidManifest.xml申请权限(6.0需要动态申请权限,碍于篇幅,请自行百度)

[html] view plain copy
<uses-permission android:name="android.permission.RECORD_AUDIO" /> 
<uses-permission android:name="android.permission.INTERNET" /> 
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 
<uses-permission android:name="android. www.chuangyed.com permission.ACCESS_WIFI_STATE" /> 
<uses-permission android:name="android www.wmyl15.com/ permission.CHANGE_NETWORK_STATE" /> 
<uses-permission android:name="android. www.senta77.com /permission.READ_PHONE_STATE" /> 
<uses-permission android:name="android. www.xucaizxyl.com/ permission.ACCESS_FINE_LOCATION" /> 
<uses-permission android:name="android. www.lieqibiji.com/ permission.READ_CONTACTS" /> 
<uses-permission android:name="android. www.dejiaylsmile.cn permission.WRITE_EXTERNAL_STORAGE" /> 
<uses-permission android:name="android. www.6788878.cn/ permission.WRITE_SETTINGS" /> 
<uses-permission android:name="android. www.caihonyule.com permission.READ_EXTERNAL_STORAGE" /> 
 然后,新建MyApplication.Java文件,初始化语音合成SDK,APPID可在讯飞平台-->我的应用查看,也可查看下载的SDK压缩包名字后缀[java] view plain copy
package com.cyf.ttsdemo; 

import android.app.Application; 

import com.iflytek.cloud.SpeechUtility; 

/** 
 * Created by As on 2017/8/7. 
 */ 

public class MyApplication extends Application{ 

 @Override 
 public void onCreate() { 
 super.onCreate(); 
 SpeechUtility.createUtility(this, "appid=5987d170"); 
 } 
} 
 最后记得在AndroidManifest.xml注册该Application 为了可以全局调用语音合成功能,我封装成了一个工具类,大家可以直接复制过去用
[java] view plain copy
package com.cyf.ttsdemo.utils; 

import android.os.Bundle; 
import android.os.Environment; 
import android.util.Log; 

import com.cyf.ttsdemo.MyApplication; 
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; 

/** 
 * Created by As on 2017/8/7. 
 */ 

public class TTSUtils implements InitListener, SynthesizerListener { 

 private static final String TAG = "TTSUtils"; 
 private static volatile TTSUtils instance = null; 
 private boolean isInitSuccess = false; 
 private SpeechSynthesizer mTts; 

 private TTSUtils() { 
 } 

 public static TTSUtils getInstance() { 
 if (instance == null) { 
 synchronized (TTSUtils.class) { 
 if (instance == null) { 
 instance = new TTSUtils(); 
 } 
 } 
 } 
 return instance; 
 } 

 public void init() { 
 // 初始化合成对象 
 mTts = SpeechSynthesizer.createSynthesizer(www.qinlinyule.cn/ MyApplication.getContext(), this); 
 // 清空参数 
 mTts.setParameter(SpeechConstant.PARAMS, null); 
 // 设置在线合成引擎 
 mTts.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD); 
 // 设置在线合成发音人 
 mTts.setParameter(SpeechConstant.VOICE_NAME, "xiaoyan"); 
 // 设置合成语速 
 mTts.setParameter(SpeechConstant.SPEED, "50"); 
 // 设置合成音调 
 mTts.setParameter(SpeechConstant.PITCH, "50"); 
 // 设置合成音量 
 mTts.setParameter(SpeechConstant.VOLUME, "50"); 
 // 设置播放器音频流类型 
 mTts.setParameter(SpeechConstant.STREAM_TYPE, "3"); 
 // 设置播放合成音频打断音乐播放,默认为true 
 mTts.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"); 
 } 

 public void speak(String msg) { 
 if (isInitSuccess){ 
 if (mTts.isSpeaking()) { 
 stop(); 
 } 
 mTts.startSpeaking(msg, this); 
 }else { 
 init(); 
 } 
 } 

 public void pause() { 
 mTts.pauseSpeaking(); 
 } 

 public void resume() { 
 mTts.resumeSpeaking(); 
 } 

 public void stop() { 
 mTts.stopSpeaking(); 
 } 

 public void release() { 
 if (null != mTts) { 
 mTts.stopSpeaking(); 
 // 退出时释放连接 
 mTts.destroy(); 
 } 
 } 

 @Override 
 public void onInit(int code) { 
 Log.d(TAG, "InitListener init() code = " + code); 
 if (code == ErrorCode.SUCCESS) { 
 isInitSuccess = true; 
 } 
 } 

 @Override 
 public void onSpeakBegin() { 
 // 开始播放 
 } 

 @Override 
 public void onBufferProgress(int percent, int beginPos, int endPos, 
 String info) { 
 // 合成进度 
 } 

 @Override 
 public void onSpeakPaused() { 
 // 暂停播放 
 } 

 @Override 
 public void onSpeakResumed() { 
 // 继续播放 
 } 

 @Override 
 public void onSpeakProgress(int percent, int beginPos, int endPos) { 
 // 播放进度 
 } 

 @Override 
 public void onCompleted(SpeechError speechError) { 
 if (speechError != null) { 
 Log.d(TAG, "onCompleted: " + speechError.getPlainDescription(true)); 
 } 
 } 

 @Override 
 public void onEvent(int eventType, int i1, int i2, Bundle bundle) { 
 //以下代码用于获取与云端的会话id,当业务出错时将会话id提供给技术支持人员,可用于查询会话日志,定位出错原因 
 if (SpeechEvent.EVENT_SESSION_ID == eventType) { 
 String sid = bundle.getString(SpeechEvent.KEY_EVENT_SESSION_ID); 
 Log.d(TAG, "session id =" + sid); 
 } 
 } 
}<strong> 
</strong> 
 要使用这个工具类,那么就要改造一下前面的MyApplication.java文件了
[java] view plain copy
package com.cyf.ttsdemo; 

import android.app.Application; 
import android.content.Context; 

import com.cyf.ttsdemo.utils.TTSUtils; 
import com.iflytek.cloud.Setting; 
import com.iflytek.cloud.SpeechUtility; 

/** 
 * Created by As on 2017/8/7. 
 */ 

public class MyApplication extends Application { 

 private static Context context; 

 @Override 
 public void onCreate() { 
 super.onCreate(); 
 context = getApplicationContext(); 
 SpeechUtility.createUtility(this, "appid=5987d170"); 
 // 以下语句用于设置日志开关(默认开启),设置成false时关闭语音云SDK日志打印 
 Setting.setShowLog(false); 
 TTSUtils.getInstance().init(); 
 } 

 public static Context getContext() { 
 return context; 
 } 
}


好的,这样就大功告成了,在需要进行语音合成的地方调用TTSUtils.getInstance().speak("xxx")即可

最后,我们需要到讯飞开放平台进行上传应用审核,不然使用的语音合成功能每天是有次数限制的。

当应用审核通过之后,就可以免费无限制的使用在线语音合成功能啦。