讯飞离线语音合成接入:
文字转语音的方法
1.Google TextToSpeech + 中文语音引擎
Google提供了原生的方法TextToSpeech,但是不支持中文,sad…
不过可以用第三方的语音引擎,eg,讯飞,百度…
详情参考:
Android 文字转语音(中文) TextToSpeech+科大讯飞语音引擎3.0
个人项目可以尝试用,如果上线项目总不能让用户去下载语音引擎吧
2.第三方语音服务商(讯飞,百度)
接入的是讯飞离线语音SDK
- 注册讯飞开放平台账号
创建新应用-SDK下载-选择你需要的功能/服务
- SDK下载/导入
有readme文件,这个必须要读,
sample文件夹里,就是Demo代码,主要包含以下功能
因为他的demo缺少了很多配置文件,并不能跑起来,所以不仅要配置app目录,project的build.gradle等,还要按照readme提示,添加文件
从讯飞下载的Demo中,是自带APPID的,没有的话需要自己添加
讯飞初始化的地方放在了应用的Application的onCreate中
StringBuffer param = new StringBuffer();
param.append("appid="+getString(R.string.app_id));
param.append(",");
// 设置使用v5+
param.append(SpeechConstant.ENGINE_MODE+"="+SpeechConstant.MODE_MSC);
SpeechUtility.createUtility(SpeechApp.this, param.toString());
我们需要的功能是离线语音合成,点击体验语音合成进入页面
就可以操作了
封装了一个类处理SpeechSynthesizer
public class TtsManager {
private SpeechSynthesizer mTts;
private static final String TAG = TtsManager.class.getSimpleName();
// 默认云端发音人
public static String voicerCloud="xiaoyan";
// 默认本地发音人
public static String voicerLocal="xiaoyan";
private Context mContext;
public TtsManager(Context context) {
mContext = context;
Log.d(TAG,mTtsInitListener+"");
mTts = SpeechSynthesizer.createSynthesizer(mContext, mTtsInitListener);
Log.d(TAG,"SUCCESS");
}
// 初始化成功,之后可以调用startSpeaking方法
// 注:有的开发者在onCreate方法中创建完合成对象之后马上就调用startSpeaking进行合成,
// 正确的做法是将onCreate中的startSpeaking调用移至这里
InitListener mTtsInitListener = new InitListener() {
@Override
public void onInit(int code) {
Log.d(TAG, "InitListener init() code = " + code);
if (code != ErrorCode.SUCCESS) {
if (onTtsInitListener != null) {
onTtsInitListener.initError();
}
Log.d(TAG, "初始化失败,错误码:" + code + ",请点击网址https://www.xfyun.cn/document/error-code查询解决方案");
} else {
// 初始化成功,之后可以调用startSpeaking方法
// 注:有的开发者在onCreate方法中创建完合成对象之后马上就调用startSpeaking进行合成,
// 正确的做法是将onCreate中的startSpeaking调用移至这里
if (onTtsInitListener != null) {
Log.d(TAG, "开始播放");
onTtsInitListener.initSpeak();
}
Log.d(TAG, "初始化成功,开始播放");
}
}
};
private OnTtsInitListener onTtsInitListener;
public void setOnTtsInitListener(OnTtsInitListener ttsInitListener){
this.onTtsInitListener = ttsInitListener;
}
public interface OnTtsInitListener{
void initError();
void initSpeak();
}
private SynthesizerListener mTtsListener = new SynthesizerListener() {
@Override
public void onSpeakBegin() { //开始播放
}
@Override
public void onSpeakPaused() { //暂停播放
}
@Override
public void onSpeakResumed() { //继续播放
}
@Override
public void onBufferProgress(int i, int i1, int i2, String s) {
//合成进度
}
@Override
public void onSpeakProgress(int i, int i1, int i2) {
//播放进度
}
@Override
public void onCompleted(SpeechError speechError) {
//播放完成
}
@Override
public void onEvent(int i, int i1, int i2, Bundle bundle) {
// 以下代码用于获取与云端的会话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);
// }
//实时音频流输出参考
/*if (SpeechEvent.EVENT_TTS_BUFFER == eventType) {
byte[] buf = obj.getByteArray(SpeechEvent.KEY_EVENT_TTS_BUFFER);
Log.e("MscSpeechLog", "buf is =" + buf);
}*/
}
};
/**
* 默认本地
* @param text
* @return
*/
public int startLocalSpeaking(String text){
setParam(SpeechConstant.TYPE_LOCAL,voicerLocal);
return mTts.startSpeaking(text,mTtsListener);
}
//开始合成/播放
public int startSpeaking(String text,String type,String voicer){
setParam(type,voicer);
return mTts.startSpeaking(text,mTtsListener);
}
//停止播放
public void stopSpeaking(){
if( null != mTts ) {
mTts.stopSpeaking();
}
}
//暂停播放
public void pauseSpeaking(){
mTts.pauseSpeaking();
}
public void destroySpeaking(){
if( null != mTts ){
mTts.stopSpeaking();
// 退出时释放连接
mTts.destroy();
}
}
//继续播放
private void resumeSpeaking(){
mTts.resumeSpeaking();
}
private HashMap<String,String> getTtsParam(){
HashMap<String,String> hashMap = new HashMap();
hashMap.put(SpeechConstant.SPEED,"50");////设置合成语速
hashMap.put(SpeechConstant.PITCH,"50");// //设置合成音调
hashMap.put(SpeechConstant.VOLUME,"50");// //设置合成音量
hashMap.put(SpeechConstant.STREAM_TYPE,"3");// // //设置播放器音频流类型
hashMap.put(SpeechConstant.KEY_REQUEST_FOCUS,"50");// 设置播放合成音频打断音乐播放,默认为true
hashMap.put(SpeechConstant.AUDIO_FORMAT,"wav");// 设置音频保存路径,保存音频格式支持pcm、wav,设置路径为sd卡请注意WRITE_EXTERNAL_STORAGE权限
hashMap.put(SpeechConstant.TTS_AUDIO_PATH,Environment.getExternalStorageDirectory()+"/msc/tts.wav");
return hashMap;
/* //设置合成音调
mTts.setParameter(SpeechConstant.PITCH, TtsSpUtils.getInstance().getString("pitch_preference", "50"));
//设置合成音量
mTts.setParameter(SpeechConstant.VOLUME, TtsSpUtils.getInstance().getString("volume_preference", "50"));
//设置播放器音频流类型
mTts.setParameter(SpeechConstant.STREAM_TYPE, TtsSpUtils.getInstance().getString("stream_preference", "3"));
// 设置播放合成音频打断音乐播放,默认为true
mTts.setParameter(SpeechConstant.KEY_REQUEST_FOCUS, "true");
// 设置音频保存路径,保存音频格式支持pcm、wav,设置路径为sd卡请注意WRITE_EXTERNAL_STORAGE权限
mTts.setParameter(SpeechConstant.AUDIO_FORMAT, "wav");
mTts.setParameter(SpeechConstant.TTS_AUDIO_PATH, Environment.getExternalStorageDirectory()+"/msc/tts.wav");*/
}
private void setTtsParam(String key,String value){
HashMap<String,String> hashMap = getTtsParam();
if (key!= null) {
hashMap.put(key, value);
}
for (String mkey:hashMap.keySet()) {
mTts.setParameter(mkey,hashMap.get(mkey));
}
}
private void setLocalParam(){
// 清空参数
mTts.setParameter(SpeechConstant.PARAMS, null);
//设置使用本地引擎
mTts.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_LOCAL);
//设置发音人资源路径
mTts.setParameter(ResourceUtil.TTS_RES_PATH,getResourcePath());
//设置发音人
mTts.setParameter(SpeechConstant.VOICE_NAME,voicerLocal);
//mTts.setParameter(SpeechConstant.TTS_DATA_NOTIFY,"1");//支持实时音频流抛出,仅在synthesizeToUri条件下支持
//设置合成语速
mTts.setParameter(SpeechConstant.SPEED, TtsSpUtils.getInstance().getString("speed_preference", "50"));
}
private void setParam(String mEngineType,String voicer){
// 清空参数
mTts.setParameter(SpeechConstant.PARAMS, null);
//设置合成
if(mEngineType.equals(SpeechConstant.TYPE_CLOUD))
{
//设置使用云端引擎
mTts.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD);
//设置发音人
mTts.setParameter(SpeechConstant.VOICE_NAME, voicer == null?voicerCloud:voicer);
}else {
//设置使用本地引擎
mTts.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_LOCAL);
//设置发音人资源路径
mTts.setParameter(ResourceUtil.TTS_RES_PATH,getResourcePath());
//设置发音人
mTts.setParameter(SpeechConstant.VOICE_NAME,voicer == null?voicerLocal:voicer);
}
//mTts.setParameter(SpeechConstant.TTS_DATA_NOTIFY,"1");//支持实时音频流抛出,仅在synthesizeToUri条件下支持
//设置合成语速
mTts.setParameter(SpeechConstant.SPEED, TtsSpUtils.getInstance().getString("speed_preference", "50"));
//设置合成音调
mTts.setParameter(SpeechConstant.PITCH, TtsSpUtils.getInstance().getString("pitch_preference", "50"));
//设置合成音量
mTts.setParameter(SpeechConstant.VOLUME, TtsSpUtils.getInstance().getString("volume_preference", "50"));
//设置播放器音频流类型
mTts.setParameter(SpeechConstant.STREAM_TYPE, TtsSpUtils.getInstance().getString("stream_preference", "3"));
// 设置播放合成音频打断音乐播放,默认为true
mTts.setParameter(SpeechConstant.KEY_REQUEST_FOCUS, "true");
// 设置音频保存路径,保存音频格式支持pcm、wav,设置路径为sd卡请注意WRITE_EXTERNAL_STORAGE权限
mTts.setParameter(SpeechConstant.AUDIO_FORMAT, "wav");
mTts.setParameter(SpeechConstant.TTS_AUDIO_PATH, Environment.getExternalStorageDirectory()+"/msc/tts.wav");
}
//获取发音人资源路径
private String getResourcePath(){
StringBuffer tempBuffer = new StringBuffer();
//合成通用资源
tempBuffer.append(ResourceUtil.generateResourcePath(mContext, ResourceUtil.RESOURCE_TYPE.assets, "tts/common.jet"));
tempBuffer.append(";");
//发音人资源
tempBuffer.append(ResourceUtil.generateResourcePath(mContext, ResourceUtil.RESOURCE_TYPE.assets, "tts/"+voicerLocal+".jet"));
return tempBuffer.toString();
}
}
还有一个SharedPreferences工具类:
public class TtsSpUtils {
private static final String NAME = "Tts";
private static TtsSpUtils instance = null;
private SharedPreferences sp;
public static TtsSpUtils getInstance() {
synchronized (TtsSpUtils.class) {
if (null == instance)