项目开发中,当今流行的机器人,教育类英语学习类,有模块需要用到语音功能,文字语音之间互相转换等需求,当然如果只是固定的几个静态语音需要播放,可以直接用软件把文字转成语音生成MP3,之后在项目中直接播放音频即可,这里推荐朗读女
讯飞开发平台注册应用
下载相应的包
配置相应文件
选择文字片段进行语音播放,结合科大讯飞及系统语音播放实现
- 科大讯飞在android 8.0系统及以上版本兼容性不好 会出现问题
- 采用android 8.0系统版本及以上版本使用系统语音播放器播放
- 选中全篇文章带有段落及缩进的 Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1 监听不到系统播放完成跳转到下一段落
系统语音播放
import android.content.Context;
import android.os.Build;
import android.speech.tts.TextToSpeech;
import android.speech.tts.UtteranceProgressListener;
import com.iflytek.cloud.SpeechError;
import com.iflytek.cloud.SynthesizerListener;
import java.util.Locale;
/**
* 系统语音朗读服务
*
* @author
* @time 19-3-7 下午5:37
*/
public class TTSManager {
private static final String TAG = TTSManager.class.getSimpleName();
private Context context;
/**
* 系统语音识别
*/
private TextToSpeech mSpeech;
/**
* TTS监听
*/
private TTSListener ttsListener;
/**
* 朗读进度监听
*/
private SynthesizerListener soundSynthesizerListener;
public TTSManager(Context context) {
this.context = context;
// 初始化语音朗读
speechInit();
}
private final class TTSListener implements TextToSpeech.OnInitListener {
@Override
public void onInit(int status) {
Logger.e(TAG, "TextToSpeech onInit result :" + (status == TextToSpeech.SUCCESS));
int result = mSpeech.setLanguage(Locale.CHINESE);
if (result == TextToSpeech.LANG_NOT_SUPPORTED || result == TextToSpeech.LANG_MISSING_DATA) {
MyToast.show(context, context.getApplicationContext().getString(R.string.tts_not_support_chinese));
}
// 如果返回值为-2,说明不支持这种语言
Logger.e(TAG, "isSupportLanguage :" + (result != TextToSpeech.LANG_NOT_SUPPORTED));
}
}
/**
* 初始化TextToSpeech,在onCreate中调用
*
* @author lzy
* @time 18-12-21 下午1:46
*/
private void speechInit() {
if (mSpeech != null) {
mSpeech.stop();
mSpeech.shutdown();
mSpeech = null;
}
// 创建TTS对象
mSpeech = new TextToSpeech(context, new TTSListener());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
mSpeech.setOnUtteranceProgressListener(new UtteranceProgressListener() {
@Override
public void onStart(String str) {
// 朗读开始
if (null != soundSynthesizerListener) {
soundSynthesizerListener.onSpeakBegin();
}
}
@Override
public void onDone(String str) {
// 朗读完成
stopSpeaking();
if (null != soundSynthesizerListener) {
soundSynthesizerListener.onCompleted(null);
}
}
@Override
public void onError(String str) {
// 朗读失败
if (null != soundSynthesizerListener) {
soundSynthesizerListener.onCompleted(new SpeechError(100, str));
}
}
});
} else {
// 监听语音朗读
mSpeech.setOnUtteranceCompletedListener(new TextToSpeech.OnUtteranceCompletedListener() {
@Override
public void onUtteranceCompleted(String s) {
// 朗读完成
stopSpeaking();
if (null != soundSynthesizerListener) {
soundSynthesizerListener.onCompleted(null);
}
}
});
}
}
/**
* 释放系统语音朗读
*
* @author
* @time 19-3-7 下午5:54
*/
public void release() {
// 系统语音朗读注销处理
if (ttsListener != null) {
ttsListener = null;
}
if (mSpeech != null) {
mSpeech.stop();
mSpeech.shutdown();
mSpeech = null;
}
}
/**
* 停止朗读
*
* @author lzy
* @time 19-3-7 下午7:18
*/
public void stopSpeaking() {
if (!mSpeech.isSpeaking()) {
mSpeech.stop();
}
}
/**
* 将文本用TTS播放
*
* @param str 播放的文本内容
* @author lzy
* @time 18-12-21 下午1:45
*/
public void playTTS(String str) {
if (mSpeech == null) {
mSpeech = new TextToSpeech(context, ttsListener);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mSpeech.speak(str, TextToSpeech.QUEUE_FLUSH, null, TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID);
} else {
mSpeech.speak(str, TextToSpeech.QUEUE_FLUSH, null);
}
Logger.i(TAG, "playTTS :" + str);
}
public SynthesizerListener getSoundSynthesizerListener() {
return soundSynthesizerListener;
}
public void setSoundSynthesizerListener(SynthesizerListener soundSynthesizerListener) {
this.soundSynthesizerListener = soundSynthesizerListener;
}
}
页面调用方法
/**
* 朗读文章段内容
*
* @param str : 段落内容
* @author lzy
* @time 19-3-7 下午7:12
*/
private void readParagraph(String str) {
if (TextUtils.isEmpty(str)) {
return;
}
try {
// 判断系统版本
if (Build.VERSION.SDK_INT >= 26) {
// 采用系统语音朗读
if (null == ttsManager.getSoundSynthesizerListener()) {
ttsManager.setSoundSynthesizerListener(soundSynthesizerListener);
}
ttsManager.playTTS(str);
} else {
SpeechUtil.getInstance(mContext).startSpeaking(str, soundSynthesizerListener);
}
} catch (Exception e) {
e.printStackTrace();
}
}
科大讯飞语音朗读服务
import android.content.Context;
import android.os.Bundle;
import com.iflytek.cloud.SpeechConstant;
import com.iflytek.cloud.SpeechError;
import com.iflytek.cloud.SpeechSynthesizer;
import com.iflytek.cloud.SynthesizerListener;
public class SpeechUtil {
private static SpeechUtil instance = null;
private SpeechSynthesizer mTts;
private SpeechUtil(Context context) {
//1.创建SpeechSynthesizer对象, 第二个参数:本地合成时传InitListener
mTts = SpeechSynthesizer.createSynthesizer(context, null);
//2.合成参数设置,详见《科大讯飞MSC API手册(Android)》SpeechSynthesizer 类
mTts.setParameter(SpeechConstant.VOICE_NAME, "xiaoyan");//设置发音人
mTts.setParameter(SpeechConstant.SPEED, "50");//设置语速
mTts.setParameter(SpeechConstant.VOLUME, "80");//设置音量,范围0~100
mTts.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD); //设置云端
}
public static synchronized SpeechUtil getInstance(Context context) {
if (instance == null) {
instance = new SpeechUtil(context);
}
return instance;
}
public static void recovery() {
if (instance != null) {
instance.stopSpeaking();
}
}
/**
* @param str
* @param mSynListener 回调接口,如果不需要创null
*/
public void startSpeaking(String str, SynthesizerListener mSynListener) {
if (StringUtil.isNotNull(str)) {
Logger.i("soundplay", getClass().getSimpleName() + ":" + str);
if (mTts.isSpeaking()) {
mTts.stopSpeaking();
}
mTts.startSpeaking(str, mSynListener);
}
}
public void pauseSpeaking() {
if (mTts.isSpeaking()) {
mTts.pauseSpeaking();
}
}
public void resumeSpeaking() {
mTts.resumeSpeaking();
}
/**
* 停止播放
*/
public void stopSpeaking() {
if (mTts.isSpeaking()) {
mTts.stopSpeaking();
}
}
public static class SynthesizerListenerAdpter implements SynthesizerListener {
@Override
public void onSpeakBegin() {
}
@Override
public void onBufferProgress(int i, int i1, int i2, String s) {
}
@Override
public void onSpeakPaused() {
}
@Override
public void onSpeakResumed() {
}
@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) {
}
}
}