文字转语音功能小结

项目开发中,当今流行的机器人,教育类英语学习类,有模块需要用到语音功能,文字语音之间互相转换等需求,当然如果只是固定的几个静态语音需要播放,可以直接用软件把文字转成语音生成MP3,之后在项目中直接播放音频即可,这里推荐朗读女

讯飞开发平台注册应用

image.png

下载相应的包

image.png

配置相应文件

选择文字片段进行语音播放,结合科大讯飞及系统语音播放实现

  • 科大讯飞在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) {

        }
    }
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,029评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,238评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,576评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,214评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,324评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,392评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,416评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,196评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,631评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,919评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,090评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,767评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,410评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,090评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,328评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,952评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,979评论 2 351

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,943评论 25 707
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,079评论 4 62
  • 今天是怎么过的我完全不知道,只觉得时间过得真快,一下子就到了晚上。午6点起床,6点半叫子栩起床。7点送孩子...
    晨曦晓林阅读 149评论 0 0
  • 按:2016年2月10日,皮尤慈善基金会发布了一项关于美国公众刑事司法改革认知的报告,该报告内容虽然不多,但对美国...
    1cb755b2b45f阅读 567评论 0 0
  • 就让这时光别停留 就让这姑娘别回头 就让这昨夜醉酒的人呐 不再流泪 就让这昨夜流泪的人呐 不再难受 by 大冰...
    幸运的福豆豆阅读 601评论 0 0