Android TTS的暂停与恢复功能

        最近有同事做项目遇到这样一个需求,就是通过原生TTS播报文本希望能有暂停的功能,目前原生TTS接口TextToSpeech没有提供相应的接口,所以只能通过其他途径进行解决,目前初步的解决思路是:

  • (1)通过TextToSpeech保存文本为本地wav文件
  • (2)通过MediaPlayer播放本地的wav文件
  • (3)通过MediaPlayer的接口实现播放的暂停,回复和重置等功能

思路很简单,网上也有相应的说法,但是没有落实的方案,今天特意测试了一下,先给出主要的代码逻辑,在总结一下主要的问提。

(1)通过TextToSpeech保存文本为本地wav文件

  HashMap<String, String> myHashRender.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, content);
  mSpeech.synthesizeToFile(content, myHashRender, wavPath);
//或者
//mSpeech.synthesizeToFile(content, null, wavPath,TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID);

(2)通过MediaPlayer播放本地的wav文件

MediaPlayer本身也是一块较多较复杂的内容,我们这里只是最基本的用法:

player.setDataSource(wavPath);
player.prepare();

(3)通过MediaPlayer的接口实现播放的暂停,回复和重置等功能

//播放
player.start();
//暂停
player.pause();
//恢复
player.resume();
//重置
player.reset();

完整的逻辑代码如下:

package aoto.com.ttstest;

import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.media.MediaPlayer;
import android.os.Build;
import android.os.Environment;
import android.speech.tts.TextToSpeech;
import android.support.annotation.RequiresApi;
import android.util.Log;

import java.io.IOException;
import java.util.HashMap;
import java.util.Locale;
import java.util.Set;

/**
 * author:why
 * created on: 2019/7/10 9:57
 * description:
 */
public class TTSManager {

    private static final String TAG = "TTSManagerWhy";
    private static volatile TTSManager manager = null;
    private static TextToSpeech mSpeech = null;
    private Context mContext;
    private String wavPath;
    private MediaPlayer player;
    private HashMap<String, String> myHashRender = new HashMap();

    @RequiresApi(api = Build.VERSION_CODES.M)
    private TTSManager(Context context) {
        this.mContext = context;
        wavPath = Environment.getExternalStorageDirectory() + "/temp.wav";
        player = new MediaPlayer();

          //6.0以上可以设置语速
//        Log.e(TAG, "TTSManager: "+ player.getPlaybackParams().getSpeed());
//        player.setPlaybackParams(player.getPlaybackParams().setSpeed(??));
         initSpeech();
    }

    /**
     * Init TTS and set params
     */
    private void initSpeech() {
        mSpeech = new TextToSpeech(mContext, new TextToSpeech.OnInitListener() {
            @Override
            public void onInit(int status) {
                mSpeech.setLanguage(Locale.ENGLISH);
            }
        });
}

    @RequiresApi(api = Build.VERSION_CODES.M)
    public static TTSManager getInstance(Context context) {
        if (manager == null) {
            synchronized (TTSManager.class) {
                if (manager == null) {
                    manager = new TTSManager(context);
                }
            }
        }
        return manager;
    }


    public void speak(String content) {
        Log.e(TAG, "speak content: " + content);
        myHashRender.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, content);
        int r = mSpeech.synthesizeToFile(content, myHashRender, wavPath);
        if (r == TextToSpeech.SUCCESS) {
            Log.e(TAG, "save success" + wavPath);
        } else {
            Log.e(TAG, "save fail");
        }
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        try {
            player.reset();
            player.setDataSource(wavPath);
            player.prepare();
        } catch (IOException e) {
            e.printStackTrace();
        }
        player.start();
    }


    /**
     * pause the TTS
     */
    public void pause() {
        if (player.isPlaying()) {
            player.pause();
        }
    }

    /**
     * reset the TTS
     */
    public void resume() {
        player.start();
    }

    /**
     * stop the TTS
     */
    public void stop() {
        player.stop();
        player.release();
        mSpeech.shutdown();
        mSpeech.stop();
    }
}

下面总结几个重要的点:

(1)这里面我的语言设置的是英语,因为原生的不支持中文,而且在设置TextToSpeech参数的时候,需要在初始化工作完成之后进行,否则容易出现设置无效的情况;关于如何实现中文的暂停播报,主要问题就是需要解决中文文本转为音频文件的工作

(2)这里的播放速度控制不能通过TextToSpeech来设置了,需要通过MediaPlayer来设置实现,有一点需要注意的是,这个功能只有在6.0以上的系统才有,可以通过如下方式设置:

player.setPlaybackParams(player.getPlaybackParams().setSpeed(??));

(3)在测试中发现,我们通过TextToSpeech保存wav文件时,log显示成功了之后我直接调用播放代码是播放不了的,需要休眠一段时间之后才行,这一点也需要注意一下,我这里休眠了500ms,估计这个和文本长度还有关系,具体可以多测试一下

(4)注意各种权限的申请

后续要做的工作就是实现中文的暂停播报。

注:如果喜欢,可以扫码关注

Android TTS的暂停与恢复功能

 

上一篇:自动化监控软件之zabbix安装及使用


下一篇:【TTS】AIX->Linux--基于RMAN(真实环境)