Android 离线文字转语音功能-TTS(Text To Speech)

简介: Android 离线文字转语音功能-TTS(Text To Speech)

前言


    在 Android 中,TTS全称叫做 Text to Speech,从字面就能理解它解决的问题是什么,把文本转为语音服务,意思就是你输入一段文本信息,然后Android 系统可以把这段文字播报出来。这种应用场景目前比较多是在各种语音助手APP上,很多手机系统集成商内部都有内置文本转语音服务,可以读当前页面上的文本信息。同样,在一些阅读类APP上我们也能看到相关服务,打开微信读书,里面就直接可以把当前页面直接用语音方式播放出来,特别适合哪种不方便拿着手机屏幕阅读的场景。


    Android系统从1.6版本开始就支持TTS, 不过遗憾的是系统默认的TTS引擎:Pico TTS,并不支持中文。


    在查找了许相关资料后, 发现很多的资源都已经失效, APK找不到, 对应的页面404. 更多的厂商则转成了开放平台甚至不再提供离线/免费服务.


目前找到的离线TTS


注:下面的链接可能需要科学上网才可以访问

image.png


使用


首先, 安装对应的TTS应用, 再在设置中设置对应的语音输出服务

一般设置的步骤为: 设置>无障碍>文字转语音(TTS)输出

image.png

程序调用只需使用SDK标准的TTS接口即可.

在介绍TTS使用的文章中, 下面这一段的代码, 对于前面的科大讯飞或ITRI TTS并没什么效果, 只是多了一个弹窗, 当然, 也可以理解为, 这两个APP并没有按标准接口开发.


//显示应用选择窗.
Intent checkIntent = new Intent();
checkIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
startActivityForResult(checkIntent, MY_DATA_CHECK_CODE);
private TextToSpeech mTts;
protected void onActivityResult(
        int requestCode, int resultCode, Intent data) {
    if (requestCode == MY_DATA_CHECK_CODE) {
        if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) {
            // success, create the TTS instance
            mTts = new TextToSpeech(this, this);
        } else {
            // missing data, install it
            Intent installIntent = new Intent();
            installIntent.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
            startActivity(installIntent);
        }
    }
}

image.png


在程序中打印TTS所支持的语言及声音getAvailableLanguages和getVoices:


if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
            Set<Locale> ava = mTts.getAvailableLanguages();
            if (ava != null) {
                for (Locale l : ava) {
                    Logger.v(TAG, "supported " + l.toString());
                }
            } else {
                Logger.d(TAG, "no supported language");
            }
            Set<Voice> voices = mTts.getVoices();
            if(voices != null){
                for(Voice v : voices){
                    Logger.d(TAG, "TTS Voice: " + v.toString());
                }
            }
        }
        String engine = mTts.getDefaultEngine();
        Logger.d(TAG, "TTS Engine = " + engine);


2022-10-18 15:21:22.577 25266-25266 TextToSpeech       com.tts.test         I  Connected to ComponentInfo{tw.pu.tts/tw.pu.tts.UttsService}
2022-10-18 15:21:22.582 25266-26006 TextToSpeech       com.tts.test         I  Set up connection to ComponentInfo{tw.pu.tts/tw.pu.tts.UttsService}
2022-10-18 15:21:22.594 25266-25266 TTS                com.tts.test         D   onInit 0
2022-10-18 15:21:22.650 25266-25266 TTS                com.tts.test         V   supported zh
2022-10-18 15:21:22.650 25266-25266 TTS                com.tts.test         V   supported en
2022-10-18 15:21:22.650 25266-25266 TTS                com.tts.test         V   supported zh__#Hans
2022-10-18 15:21:22.650 25266-25266 TTS                com.tts.test         V   supported zh__#Hant
2022-10-18 15:21:22.690 25266-25266 TTS                com.tts.test         D   TTS Voice: Voice[Name: zh, locale: zh__#Hans, quality: 300, latency: 300, requiresNetwork: false, features: []]
2022-10-18 15:21:22.691 25266-25266 TTS                com.tts.test         D   TTS Voice: Voice[Name: en, locale: en, quality: 300, latency: 300, requiresNetwork: false, features: []]
2022-10-18 15:21:22.691 25266-25266 TTS                com.tts.test         D   TTS Voice: Voice[Name: zh, locale: zh, quality: 300, latency: 300, requiresNetwork: false, features: []]
2022-10-18 15:21:22.691 25266-25266 TTS                com.tts.test         D   TTS Voice: Voice[Name: zh, locale: zh__#Hant, quality: 300, latency: 300, requiresNetwork: false, features: []]
2022-10-18 15:21:22.698 25266-25266 TTS                com.tts.test         D   TTS Engine = tw.pu.tts


注: TTS的功能需要在TextToSpeech.OnInitListener回调, 并确认状态正常后才可以开始正常工作


完整代码TTS.java


import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.media.AudioAttributes;
import android.media.AudioManager;
import android.speech.tts.TextToSpeech;
import android.speech.tts.Voice;
import java.util.Locale;
import java.util.Set;
public class TTS implements TextToSpeech.OnInitListener {
    final String TAG = "TTS";
    TextToSpeech mTts;
    public TTS(Context context){
        mTts = new TextToSpeech(context, this);
    }
    public TTS(Context context, TextToSpeech.OnInitListener lis){
        mTts = new TextToSpeech(context, this);
        setOnInitListener(lis);
    }
    final int DATA_CHECK_CODE = 0x774;
    @Deprecated
    public TTS(Activity activity){
        Intent checkIntent = new Intent(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
        activity.startActivityForResult(checkIntent, 0x774);
    }
    @Deprecated
    public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {
        if (requestCode == DATA_CHECK_CODE) {
            if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) {
                // success, create the TTS instance
                mTts = new TextToSpeech(activity, this);
            } else {
                // missing data, install it
                Intent installIntent = new Intent(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
                activity.startActivity(installIntent);
            }
        }
    }
    public TextToSpeech getTts(){return mTts;}
    private void dump(){
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
            Set<Locale> ava = mTts.getAvailableLanguages();
            if (ava != null) {
                for (Locale l : ava) {
                    Logger.v(TAG, "supported " + l.toString());
                }
                //mTts.setLanguage(Locale.US);
            } else {
                Logger.d(TAG, "no supported language");
            }
            Set<Voice> voices = mTts.getVoices();
            if(voices != null){
                for(Voice v : voices){
                    Logger.d(TAG, "TTS Voice: " + v.toString());
                }
            }
        }
        String engine = mTts.getDefaultEngine();
        Logger.d(TAG, "TTS Engine = " + engine);
    }
    public void setSpeechSpeed(float speed){
        mTts.setSpeechRate(speed);
    }
    public void setVoiceFreq(float freq){
        mTts.setPitch(freq);
    }
    public void speak(String s){
        if(mTts == null){
            Logger.e(TAG, "speak failed: TTS not ready");
            return;
        }
        int res = mTts.speak(s, TextToSpeech.QUEUE_ADD, null);
        if(res != 0){
            Logger.w(TAG, "speak failed: " + res);
        }else{
            Logger.d(TAG, "speak " + s + " done");
        }
    }
    public void stop(){
        mTts.stop();
    }
    @Override
    public void onInit(int status) {
        Logger.d(TAG, "onInit " + status);
        if(status == 0) {
            dump();
            mTts.setPitch(1f);
            mTts.setSpeechRate(1f);
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
                AudioAttributes attr = new AudioAttributes.Builder().setLegacyStreamType(AudioManager.STREAM_MUSIC).build();
                mTts.setAudioAttributes(attr);
            }
        }
        if(initLis != null)initLis.onInit(status);
    }
    TextToSpeech.OnInitListener initLis;
    public void setOnInitListener(TextToSpeech.OnInitListener initLis){
        this.initLis = initLis;
    }
}


参考


Android 中文語音引擎資源

Android中使用自带TextToSpeech实现离线语音合成功能

The 7 Best Text-to-Speech Apps for Android

Android中提供的免费文字转语音功能TextToSpeech之快速入门用法(Android TTS 语音合成播报)

An introduction to Text-To-Speech in Android


附:

文字转语音(TTS) 应用 (APK)


相关文章
|
1月前
|
XML 缓存 Android开发
Android开发,使用kotlin学习多媒体功能(详细)
Android开发,使用kotlin学习多媒体功能(详细)
103 0
|
3月前
|
安全 Linux Android开发
Android 安全功能
Android 安全功能
37 0
|
6月前
|
安全 Android开发 开发者
Android 原生 Picture in Picture 画中画功能避坑指南(下)
Android 原生 Picture in Picture 画中画功能避坑指南(下)
104 0
|
4天前
|
Java Android开发
Android Mediatek 应用层重置USB设备功能
Android Mediatek 应用层重置USB设备功能
11 0
|
4月前
|
JSON 自然语言处理 Java
Android App开发语音处理之系统自带的语音引擎、文字转语音、语音识别的讲解及实战(超详细 附源码)
Android App开发语音处理之系统自带的语音引擎、文字转语音、语音识别的讲解及实战(超详细 附源码)
122 0
|
4月前
|
XML 前端开发 Java
Android App实战项目之实现手写签名APP功能(附源码,简单易懂 可直接实用)
Android App实战项目之实现手写签名APP功能(附源码,简单易懂 可直接实用)
50 0
|
1月前
|
运维 监控 Android开发
应用研发平台EMAS常见问题之安卓push的离线转通知目前无法收到如何解决
应用研发平台EMAS(Enterprise Mobile Application Service)是阿里云提供的一个全栈移动应用开发平台,集成了应用开发、测试、部署、监控和运营服务;本合集旨在总结EMAS产品在应用开发和运维过程中的常见问题及解决方案,助力开发者和企业高效解决技术难题,加速移动应用的上线和稳定运行。
25 1
|
4月前
|
传感器 物联网 Android开发
【Android App】物联网中查看手机支持的传感器及实现摇一摇功能-加速度传感器(附源码和演示 超详细)
【Android App】物联网中查看手机支持的传感器及实现摇一摇功能-加速度传感器(附源码和演示 超详细)
69 1
|
4月前
|
XML Java 定位技术
【Android App】定位导航GPS中开启手机定位功能讲解及实战(附源码和演示 超详细)
【Android App】定位导航GPS中开启手机定位功能讲解及实战(附源码和演示 超详细)
118 0
|
4月前
|
XML 前端开发 Java
【Android App】三维处理中三维投影OpenGL功能的讲解及实战(附源码和演示 超详细必看)
【Android App】三维处理中三维投影OpenGL功能的讲解及实战(附源码和演示 超详细必看)
34 1