Android 语音播报 , 百度在线语音合成封装;

本文详细介绍了如何使用百度在线语音合成API进行语音播报的实现,包括SDK的下载、配置及初始化过程,同时还提供了队列播放消息的封装示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Android自带的语音播报不支持中文;

科大讯飞开始收费了;

百度离线语音合成也收费,但是! 在线语音合成不收费,需要在百度开放平台申请AppId;

文档:https://cloud.baidu.com/doc/SPEECH/index.html

SDK下载:https://ai.baidu.com/sdk#tts 

百度在线语音合成:

没有找到百度在线语音合成的文档,自己参考百度语音SDK抽取了一下;

1、下载百度的SDK https://cloud.baidu.com/doc/SPEECH/s/Ck4nlz4cx , 把jar包之类的拷贝一下;

2、初始化,在线语音合成很简单(获取实例,给上下文、设置appid等、然后调用初始化就行了),百度建议放在子线程中:

protected SpeechSynthesizer mSpeechSynthesizer;                
                mSpeechSynthesizer = SpeechSynthesizer.getInstance();
                mSpeechSynthesizer.setContext(context);
                // 2. 设置listener
                mSpeechSynthesizer.setSpeechSynthesizerListener(null);
                // 3. 设置appId,appKey.secretKey
                mSpeechSynthesizer.setAppId(AppConfig.BaiduTTSAppId);
                mSpeechSynthesizer.setApiKey(AppConfig.BaiduTTSAppKey, AppConfig.BaiduTTSSecretKey);

                // 5. 以下setParam 参数选填。不填写则默认值生效
                // 设置在线发声音人: 0 普通女声(默认) 1 普通男声 2 特别男声 3 情感男声<度逍遥> 4 情感儿童声<度丫丫>
                mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_SPEAKER, "0");
                // 设置合成的音量,0-15 ,默认 5
                mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_VOLUME, "15");
                // 设置合成的语速,0-15 ,默认 5
                mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_SPEED, "5");
                // 设置合成的语调,0-15 ,默认 5
                mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_PITCH, "5");
                mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_MIX_MODE, SpeechSynthesizer.MIX_MODE_DEFAULT);
                // 该参数设置为TtsMode.MIX生效。即纯在线模式不生效。
                // 6. 初始化
                int result = mSpeechSynthesizer.initTts(TtsMode.ONLINE);

3、播放、暂停、恢复播放、停止播放:

mSpeechSynthesizer.speak(text); //开始播放
mSpeechSynthesizer.pause(); //暂停
mSpeechSynthesizer.resume(); //恢复
mSpeechSynthesizer.stop(); //停止

百度在线语音合成封装:


/**
 * 百度语音合成 在线TTS
 *
 * 播放 :立即播报
 *       排在正在播放的下一个
 *       排在播放列表的最后
 *
 * 暂停 : 立即暂停
 *        播报完成当前语音再暂停
 *
 * 停止 : 立即停止
 *        播报完成当前语音再停止
 *
 * 恢复播放 : 若当前播报未完成,继续播报当前语音 否则播报队列中的;
 *
 * 可以获取当前播报状态
 *
 */
public class TtsSyntherizer {

    public TtsSyntherizer(Context context) {
        this.context = context;
        initTTs();
    }

    private Context context;
    protected SpeechSynthesizer mSpeechSynthesizer;
    private volatile boolean isInitTts = false;
    /**
     * 初始化语音播报
     */
    protected void initTTs() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                if (AppConfig.IS_DEV) LoggerProxy.printable(true); // 日志打印在logcat中
                // 1. 获取实例
                mSpeechSynthesizer = SpeechSynthesizer.getInstance();
                mSpeechSynthesizer.setContext(context);
                // 2. 设置listener
                mSpeechSynthesizer.setSpeechSynthesizerListener(new MessageListener(){
                    @Override
                    public void onSpeechStart(String utteranceId) {
                        super.onSpeechStart(utteranceId);
                        L.cc("播放开始");
                        ttsState = TtsStateEnum.PLAY;
                    }

                    @Override
                    public void onSpeechFinish(String utteranceId) {
                        super.onSpeechFinish(utteranceId);
                        if (!ListUtils.isEmpty(ttsPlayDatas) && ttsState == TtsStateEnum.PLAY){
                            //如果当前播放列表中有数据,并且不是暂停状态或停止状态
                            ttsSpeak(ttsPlayDatas.get(0));
                            ttsPlayDatas.remove(0);
                        }
                        L.cc("播放结束");
                        ttsState = TtsStateEnum.LDLE;
                    }
                });

                // 3. 设置appId,appKey.secretKey
                mSpeechSynthesizer.setAppId(AppConfig.BaiduTTSAppId);
                mSpeechSynthesizer.setApiKey(AppConfig.BaiduTTSAppKey, AppConfig.BaiduTTSSecretKey);

                // 5. 以下setParam 参数选填。不填写则默认值生效
                // 设置在线发声音人: 0 普通女声(默认) 1 普通男声 2 特别男声 3 情感男声<度逍遥> 4 情感儿童声<度丫丫>
                mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_SPEAKER, "0");
                // 设置合成的音量,0-15 ,默认 5
                mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_VOLUME, "15");
                // 设置合成的语速,0-15 ,默认 5
                mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_SPEED, "5");
                // 设置合成的语调,0-15 ,默认 5
                mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_PITCH, "5");
                mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_MIX_MODE, SpeechSynthesizer.MIX_MODE_DEFAULT);
                // 该参数设置为TtsMode.MIX生效。即纯在线模式不生效。
                // 6. 初始化
                int result = mSpeechSynthesizer.initTts(TtsMode.ONLINE);
                if (result == 0) {
                    isInitTts = true;
                } else {
                    isInitTts = false;
                }
            }
        }).start();
    }


    private TtsStateEnum ttsState = TtsStateEnum.LDLE; //默认是空闲状态
    private List<String> ttsPlayDatas; //语音播报列表

    /**
     * 开始语音播报
     * @param text 播报内容
     * @param code 1 代表立即播报
     *             2 排在正在播放的下一个
     *             3 排在最后
     * @param isClearQueue 是否播放完本条内容后清空队列停止播报
     * @return
     */
    public int ttsSpeak(String text , int code , boolean isClearQueue) {
        if (mSpeechSynthesizer != null && isInitTts){
                 int result = 0;
                 if (ttsPlayDatas == null)ttsPlayDatas = new ArrayList<>();
                switch (code){
                    case 1: //立即播报
                        if (ttsState != TtsStateEnum.LDLE)ttsStop(true);
                        ttsSpeak(text);
                        break;
                    case 2: //排在正在播放的下一个
                        if (ttsState != TtsStateEnum.LDLE) {
                            ttsPlayDatas.add(0, text);
                        }else {
                            ttsSpeak(text);
                        }
                        break;
                    case 3:
                        if (ttsState != TtsStateEnum.LDLE) {
                            ttsPlayDatas.add(text);
                        }else {
                            ttsSpeak(text);
                        }
                        break;
                }
                if (isClearQueue) ttsPlayDatas.clear();
                return result;

        }else {
            return 1;
        }
    }

    /**
     * 默认开始播放
     * @param text
     * @return
     */
    public int ttsSpeak(String text) {
        if (AppConfig.IS_OFF_TTS_PLAY){
            return 2; //已经关闭语音播报开关
        }
        if (mSpeechSynthesizer != null && isInitTts){
            int result = mSpeechSynthesizer.speak(text);
            return result;
        }else {
            return 1;
        }
    }

    /**
     * 暂停语音播报
     *  @parem afterCurrent 是否立即暂停
     * @return 0 是成功
     */
    public int ttsPause(boolean afterCurrent) {
        if (mSpeechSynthesizer != null && isInitTts){
            if (afterCurrent){ //立即暂停
                int result = mSpeechSynthesizer.pause();
                ttsState = TtsStateEnum.PAUSE;
                return result;
            }else { //播放完当前语音再暂停
                ttsState = TtsStateEnum.PAUSE;
                return 0;
            }

        }else {
            return 1;
        }
    }

    /**
     * 恢复语音播报
     * @return 0 是成功
     */
    public int ttsResume() {
        if (mSpeechSynthesizer != null && isInitTts){
            if (ttsState == TtsStateEnum.PAUSE){ //如果是暂停状态,就恢复播放
                int result = mSpeechSynthesizer.resume();
                ttsState = TtsStateEnum.PLAY;
                return result;
            }else { //如果不是暂停状态
                if (!ListUtils.isEmpty(ttsPlayDatas) && ttsState == TtsStateEnum.LDLE){
                  ttsSpeak(ttsPlayDatas.get(0));
                }
                return 0;
            }
        }else {
            return -1;
        }
    }

    /**
     *  停止语音播报
     *  @parem afterCurrent 是否立即暂停
     * @return 0是成功
     */
    public int ttsStop(boolean afterCurrent) {
        if (mSpeechSynthesizer != null && isInitTts){
            if (ttsPlayDatas != null) ttsPlayDatas.clear();
            if (afterCurrent){ //立即停止播报
                int result = mSpeechSynthesizer.stop();
                ttsState = TtsStateEnum.LDLE;
                return result;
            }else { //当前播报完成再停止
                ttsState = TtsStateEnum.LDLE;
                return 0;
            }
        }else {
            return 1;
        }
    }


    /**
     *  获取TTS状态
     * @return 0是成功
     */
    public TtsStateEnum getTtsState() {
        if (mSpeechSynthesizer != null && isInitTts){
            return ttsState;
        }else {
            return TtsStateEnum.LDLE;
        }
    }

    /**
     * 释放TTS资源
     */
    public void release() {
        if (mSpeechSynthesizer != null){
            mSpeechSynthesizer.stop();
            mSpeechSynthesizer.release();
            isInitTts = false;
            ttsState = TtsStateEnum.LDLE;
            ttsPlayDatas = null;
            mSpeechSynthesizer = null;
        }
    }
}
public enum TtsStateEnum {
    PLAY(0)
    ,PAUSE(1)
    ,LDLE(2);

    private int state;

    TtsStateEnum(int state){
        this.state = state;
    }

    public int getState(){
        return state;
    }
}

代码其实很简单,自己又封装了一下队列播放消息;

最后,如果你打开了混淆,别忘记添加混淆配置:

# TTS
-keep class com.baidu.tts.**{*;}
-keep class com.baidu.speechsynthesizer.**{*;}

 

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值