您的位置:首页 > 其它

百度语音合成Demo(纯在线模式)

2018-02-02 00:09 176 查看
环境:Android Studio , Mac


第一步:

开通百度语音服务按提示操作即可


第二步

环境配置 
下载SDK和NDK库 

1.com.baidu.tts_x.x.x.xxxxx_xxxxx.jar 位于 app/libs 目录下。(引入jar包)





2.armeabi,armeabi-v7a,arm64-v8a,x86,x86_64 5个架构目录位于app\src\main\jniLibs 目录下,如果为了节省安装包体积,可以只使用armeabi目录,性能损失微小。(我只保留了armeabi目录)。


第三步:

实现监听器SpeechSynthesizerListener
package com.demo.tts.listener;

import android.util.Log;

import com.baidu.tts.client.SpeechError;
import com.baidu.tts.client.SpeechSynthesizerListener;
/**
* SpeechSynthesizerListener 简单地实现,仅仅记录日志
* Created by xiaowen on 2017/5/19.
*/

public class MessageListener implements SpeechSynthesizerListener{
private static final String TAG = "MessageListener";

/**
* 播放开始,每句播放开始都会回调
*
* @param utteranceId
*/
@Override
public void onSynthesizeStart(String utteranceId) {
sendMessage("准备开始合成,序列号:" + utteranceId);
}

/**
* 语音流 16K采样率 16bits编码 单声道 。
*
* @param utteranceId
* @param bytes       二进制语音 ,注意可能有空data的情况,可以忽略
* @param progress    如合成“百度语音问题”这6个字, progress肯定是从0开始,到6结束。 但progress无法和合成到第几个字对应。
*/
@Override
public void onSynthesizeDataArrived(String utteranceId, byte[] bytes, int progress) {
//  Log.i(TAG, "合成进度回调, progress:" + progress + ";序列号:" + utteranceId );
}

/**
* 合成正常结束,每句合成正常结束都会回调,如果过程中出错,则回调onError,不再回调此接口
*
* @param utteranceId
*/
@Override
public void onSynthesizeFinish(String utteranceId) {
sendMessage("合成结束回调, 序列号:" + utteranceId);
}

@Override
public void onSpeechStart(String utteranceId) {
sendMessage("播放开始回调, 序列号:" + utteranceId);
}

/**
* 播放进度回调接口,分多次回调
*
* @param utteranceId
* @param progress    如合成“百度语音问题”这6个字, progress肯定是从0开始,到6结束。 但progress无法保证和合成到第几个字对应。
*/
@Override
public void onSpeechProgressChanged(String utteranceId, int progress) {
//  Log.i(TAG, "播放进度回调, progress:" + progress + ";序列号:" + utteranceId );
}

/**
* 播放正常结束,每句播放正常结束都会回调,如果过程中出错,则回调onError,不再回调此接口
*
* @param utteranceId
*/
@Override
public void onSpeechFinish(String utteranceId) {
sendMessage("播放结束回调, 序列号:" + utteranceId);
}

/**
* 当合成或者播放过程中出错时回调此接口
*
* @param utteranceId
* @param speechError 包含错误码和错误信息
*/
@Override
public void onError(String utteranceId, SpeechError speechError) {
sendErrorMessage("错误发生:" + speechError.description + ",错误编码:"
+ speechError.code + ",序列号:" + utteranceId);
}

private void sendMessage(String message) {
sendMessage(message, false);
}

private void sendErrorMessage(String message) {
sendMessage(message, true);
}

protected void sendMessage(String message, boolean isError) {
if (isError) {
Log.e(TAG, message);
} else {
Log.i(TAG, message);
}

}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102


第四步:

封装SpeechSynthesizer的操作
package com.demo.tts;

import android.Manifest;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.media.AudioManager;
import android.os.Build;
import android.util.Log;

import com.baidu.tts.client.SpeechSynthesizer;
import com.baidu.tts.client.SpeechSynthesizerListener;
import com.baidu.tts.client.TtsMode;
import com.demo.tts.listener.MessageListener;

import java.util.ArrayList;

/**
* Created by xiaowen on 2017/11/3.
*/

public class Speek {

// ================== 初始化参数设置开始 ==========================
/**
* 发布时请替换成自己申请的appId appKey 和 secretKey。注意如果需要离线合成功能,请在您申请的应用中填写包名。
*/
private String appId = "10318618";

private String appKey = "cOvGbUOyDr0gVyML07543vnY";

private String secretKey = "5280e6434339c695eee267ff373567a4";

// TtsMode.MIX; 离在线融合,在线优先; TtsMode.ONLINE 纯在线; 没有纯离线
private TtsMode ttsMode = TtsMode.ONLINE;

protected SpeechSynthesizer mSpeechSynthesizer;

private static final String TAG = "Speek";

private Activity activity;

private static boolean isPermissionRequested = false;

public Speek(Activity activity){
this.activity=activity;
Permission();
initTTs();
}

public void Speeking(String text){
int result = mSpeechSynthesizer.speak(text);
checkResult(result, "speak");
}

/**
* 初始化TTS
*/
private void initTTs() {
SpeechSynthesizerListener listener=new MessageListener();
//获取 SpeechSynthesizer 实例
mSpeechSynthesizer = SpeechSynthesizer.getInstance();
//设置使用环境
mSpeechSynthesizer.setContext(activity);
//注册监听其
mSpeechSynthesizer.setSpeechSynthesizerListener(listener);
/**
* 授权检验接口
* 测试AppId,AppKey AppSecret填写正确,语音合成服务是否开通。
* 在线合成模式下,验证权限。首次验证时比较耗时,第一次调用成功,之后可以不必调用。
*/
mSpeechSynthesizer.auth(TtsMode.ONLINE);  // 纯在线
/**
* 设置 App Id和 App Key 及 App Secret
* 用户在语音官网或者百度云网站上申请语音合成的应用后,会有appId appKey及appSecret
*/
int result =  mSpeechSynthesizer.setAppId(appId);
checkResult(result, "setAppId");
result = mSpeechSynthesizer.setApiKey(appKey, secretKey);
checkResult(result, "setApiKey");

//设置合成参数
// 以下setParam 参数选填。不填写则默认值生效
mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_SPEAKER, "0"); // 设置在线发声音人: 0 普通女声(默认) 1 普通男声 2 特别男声 3 情感男声<度逍遥> 4 情感儿童声<度丫丫>
mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_VOLUME, "9"); // 设置合成的音量,0-9 ,默认 5
mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_SPEED, "5");// 设置合成的语速,0-9 ,默认 5
mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_PITCH, "5");// 设置合成的语调,0-9 ,默认 5

//mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_MIX_MODE, SpeechSynthesizer.MIX_MODE_DEFAULT);
// 该参数设置为TtsMode.MIX生效。即纯在线模式不生效。
// MIX_MODE_DEFAULT 默认 ,wifi状态下使用在线,非wifi离线。在线状态下,请求超时6s自动转离线
// MIX_MODE_HIGH_SPEED_SYNTHESIZE_WIFI wifi状态下使用在线,非wifi离线。在线状态下, 请求超时1.2s自动转离线
// MIX_MODE_HIGH_SPEED_NETWORK , 3G 4G wifi状态下使用在线,其它状态离线。在线状态下,请求超时1.2s自动转离线
// MIX_MODE_HIGH_SPEED_SYNTHESIZE, 2G 3G 4G wifi状态下使用在线,其它状态离线。在线状态下,请求超时1.2s自动转离线

/**
* 初始化合成引擎
* 设置合成的参数后,需要调用此方法初始化
*/
result = mSpeechSynthesizer.initTts(ttsMode);
checkResult(result, "initTts");

//设置音频流类型
mSpeechSynthesizer.setAudioStreamType(AudioManager.MODE_IN_CALL);

}

/**
* 获取权限(Android6.0 以上需要动态获取权限)
*/
private void Permission() {
if (Build.VERSION.SDK_INT >= 23 && !isPermissionRequested) {

String permissions[] = {
Manifest.permission.INTERNET,
Manifest.permission.ACCESS_NETWORK_STATE,
Manifest.permission.MODIFY_AUDIO_SETTINGS,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.WRITE_SETTINGS,
Manifest.permission.READ_PHONE_STATE,
Manifest.permission.ACCESS_WIFI_STATE,
Manifest.permission.CHANGE_WIFI_STATE
};

ArrayList<String> toApplyList = new ArrayList<String>();

for (String perm : permissions) {
if (PackageManager.PERMISSION_GRANTED != activity.checkSelfPermission(perm)) {
toApplyList.add(perm);
//进入到这里代表没有权限.
}
}
if(toApplyList.size()==0)
{
return;
}
else
{
activity.requestPermissions(toApplyList.toArray(new String[toApplyList.size()]), 0);
}
}
}

private void print(String message) {
Log.i(TAG, message);
}
private void checkResult(int result, String method) {
if (result != 0) {
print("error code :" + result + " method:" + method + ", 错误码文档:http://yuyin.baidu.com/docs/tts/122 ");
}
}
public void Destory(){
if (mSpeechSynthesizer != null){
mSpeechSynthesizer.stop();
mSpeechSynthesizer.release();
mSpeechSynthesizer = null;
print("释放资源成功");
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161


测试
a44b
Activity

package com.demo.map;

import android.app.Activity;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import com.demo.tts.Speek;

/**
* Created by xiaowen on 2017/11/5.
*/

public class TTsActivity extends Activity {

private Button mBtnPlay;
private EditText mEdtWords;
private Speek speek;
private String words;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tts);
speek=new Speek(this);
initView();
}
private void initView(){
mBtnPlay= (Button) findViewById(R.id.play);
mEdtWords= (EditText) findViewById(R.id.words);

mBtnPlay.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
words=mEdtWords.getText().toString();
if(!words.equals(""))
{
speek.Speeking(words);
}
else
{
speek.Speeking("请告诉我,您需要我说些什么");
}
}
});
}

@Override
protected void onDestroy() {
super.onDestroy();
//释放资源
speek.Destory();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: