TTS与MediaPlayer混合使用


package com.xxx.xxx.Util;

import android.content.Context;
import android.media.MediaPlayer;
import android.speech.tts.TextToSpeech;
import android.util.Log;

import java.io.File;
import java.util.HashMap;
import java.util.Locale;
import java.util.concurrent.ConcurrentLinkedQueue;

public class TTSUtil implements TextToSpeech.OnInitListener {
    private MediaPlayer mediaPlayer = new MediaPlayer();
    private final TextToSpeech mTextToSpeech;//TTS对象
    private final ConcurrentLinkedQueue mBufferedMessages;//消息队列
    private Context mContext;
    private boolean mIsReady;//标识符


    public TTSUtil(Context context){
        this.mContext=context;//获取上下文
        this.mBufferedMessages=new ConcurrentLinkedQueue();//实例化队列
        this.mTextToSpeech=new TextToSpeech(this.mContext,this);//实例化TTS
    }

    //初始化TTS引擎
    @Override
    public void onInit(int status) {
        Log.i("TextToSpeechDemo",String.valueOf(status));
        if(status==TextToSpeech.SUCCESS){
            int result = this.mTextToSpeech.setLanguage(Locale.CHINA);//设置识别语音为英文或者中文

            synchronized (this){
                this.mIsReady=true;//设置标识符为true
                for(Object bufferedMessage : this.mBufferedMessages){
                    String s = String.valueOf(bufferedMessage);
                    speakText(s);//读语音
                }
                this.mBufferedMessages.clear();//读完后清空队列
            }
        }
    }
    //释放资源
    public void release(){
        synchronized (this){
            this.mTextToSpeech.shutdown();
            this.mIsReady=false;
        }
    }

    //更新消息队列,或者读语音
    public void notifyNewMessage(String text){
        //如果已经有音频文件,使用MediaPlayer播放
        try {
            File file = new File(mContext.getCacheDir().getAbsolutePath()+"//", text+".wav");
            if(file.exists()) {
mediaPlayer.reset();
           mediaPlayer.setDataSource(file.getPath()); // 指定音频文件的路径
                mediaPlayer.prepare(); // 让MediaPlayer进入到准备状态
                mediaPlayer.start();
                return;
            }

        } catch (Exception e) {

            e.printStackTrace();

        }


        String message=text;
        synchronized (this){
            if(this.mIsReady){
                speakText(message);
            }else{
                this.mBufferedMessages.add(message);
            }
        }
    }
    //把TTS朗读结果保存
    public void sayTofile(String text)
    {
        HashMap<String,
                String> ttsRender = new HashMap<String,
                String>();
        String destFileName =  mContext.getCacheDir().getAbsolutePath()+"//"+text+".wav";
            ttsRender.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID,
                    text);
            this.mTextToSpeech.synthesizeToFile(text,
                    ttsRender, destFileName);

    }
    //自定义文字播放
    public void sayFromFile(String text)
    {
        String destFileName = mContext.getCacheDir().getAbsolutePath()+"//"+text+".wav";
        this.mTextToSpeech.addSpeech(text,destFileName);
        this.mTextToSpeech.speak(text,TextToSpeech.QUEUE_FLUSH, null);
    }
    //读语音处理
    private void speakText(String message){
        HashMap params=new HashMap();
        params.put(TextToSpeech.Engine.KEY_PARAM_STREAM,"STREAM_NOTIFICATION");//设置播放类型(音频流类型)
        this.mTextToSpeech.speak(message, TextToSpeech.QUEUE_ADD, params);//将这个发音任务添加当前任务之后
        this.mTextToSpeech.playSilence(100,TextToSpeech.QUEUE_ADD,params);//间隔多长时间
    }
}

有些平板上tts有bug,比如华为某64G存储 平板,有时启动不起来,需要点击一下收听示例才行,通过以上程序,第一次使用时可以实现把需要的几个语音文件生成出来,会自动保存语音到文件,之后就可以直接mediaplayer播放语音文件。

ttsUtil.sayTofile("测试语音");
ttsUtil.notifyNewMessage("测试语音");
比如上面第一句话执行后,第二句话直接调用wav文件。
注:程序中代码片段来自网友分享。

有的时候播放tts还是会无声情况,直接把wav文件放入程序资源中调用方法:https://www.cnblogs.com/zhaogaojian/p/10128827.html