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)


相关文章
|
2月前
|
人工智能 Android开发 iOS开发
安卓版快捷指令,加了AI语音可以一句话操作v0.2.7
Shortcuts for Android(SFA)是一款安卓自动化工具,支持语音创建快捷指令,实现听歌、导航、发消息等操作。操作简单,提升效率,快来体验语音控制的便捷!
221 0
安卓版快捷指令,加了AI语音可以一句话操作v0.2.7
|
3月前
|
机器学习/深度学习 人工智能 搜索推荐
安卓声音克隆:让你的声音独一无二,探索个性化语音新世界!
在这个数字化飞速发展的时代,个性化已成为我们追求的重要目标之一。从独特的手机铃声到定制化的社交媒体内容,我们总希望能展现出与众不同的自我。那么,你是否想过在安卓设备上也能找到声音克隆的神奇功能,让你的
|
5月前
|
NoSQL 应用服务中间件 PHP
布谷一对一直播源码android版环境配置流程及功能明细
部署需基于 CentOS 7.9 系统,硬盘不低于 40G,使用宝塔面板安装环境,包括 PHP 7.3(含 Redis、Fileinfo 扩展)、Nginx、MySQL 5.6、Redis 和最新 Composer。Swoole 扩展需按步骤配置。2021.08.05 后部署需将站点目录设为 public 并用 ThinkPHP 伪静态。开发环境建议 Windows 操作系统与最新 Android Studio,基础配置涉及 APP 名称修改、接口域名更换、包名调整及第三方登录分享(如 QQ、微信)的配置,同时需完成阿里云与腾讯云相关设置。
|
11月前
|
Android开发
Android开发表情emoji功能开发
本文介绍了一种在Android应用中实现emoji表情功能的方法,通过将图片与表情字符对应,实现在`TextView`中的正常显示。示例代码展示了如何使用自定义适配器加载emoji表情,并在编辑框中输入或删除表情。项目包含完整的源码结构,可作为开发参考。视频演示和源码详情见文章内链接。
249 4
Android开发表情emoji功能开发
|
10月前
|
Android开发
布谷语音软件开发:android端语音软件搭建开发教程
语音软件搭建android端语音软件开发教程!
|
11月前
|
安全 Android开发 iOS开发
Android vs iOS:探索移动操作系统的设计与功能差异###
【10月更文挑战第20天】 本文深入分析了Android和iOS两个主流移动操作系统在设计哲学、用户体验、技术架构等方面的显著差异。通过对比,揭示了这两种系统各自的独特优势与局限性,并探讨了它们如何塑造了我们的数字生活方式。无论你是开发者还是普通用户,理解这些差异都有助于更好地选择和使用你的移动设备。 ###
346 3
|
编解码 测试技术 Android开发
Android经典实战之用 CameraX 库实现高质量的照片和视频拍摄功能
本文详细介绍了如何利用CameraX库实现高质量的照片及视频拍摄功能,包括添加依赖、初始化、权限请求、配置预览与捕获等关键步骤。此外,还特别针对不同分辨率和帧率的视频拍摄提供了性能优化策略,确保应用既高效又稳定。
1325 1
Android经典实战之用 CameraX 库实现高质量的照片和视频拍摄功能
|
JavaScript 前端开发 Android开发
让Vite+Vue3项目在Android端离线打开(不需要起服务)
让Vite+Vue3项目在Android端离线打开(不需要起服务)
517 10
|
Android开发
Android经典实战之Textview文字设置不同颜色、下划线、加粗、超链接等效果
本文介绍了 `SpannableString` 在 Android 开发中的强大功能,包括如何在单个字符串中应用多种样式,如颜色、字体大小、风格等,并提供了详细代码示例,展示如何设置文本颜色、添加点击事件等,助你实现丰富文本效果。
872 4
|
数据处理 开发工具 数据安全/隐私保护
Android平台RTMP推送|轻量级RTSP服务|GB28181接入之文字、png图片水印的精进之路
本文探讨了Android平台上推流模块中添加文字与PNG水印的技术演进。自2015年起,为了满足应急指挥及安防领域的需求,逐步发展出三代水印技术:第一代为静态文字与图像水印;第二代实现了动态更新水印内容的能力,例如实时位置与时间信息;至第三代,则优化了数据传输效率,直接使用Bitmap对象传递水印数据至JNI层,减少了内存拷贝次数。这些迭代不仅提升了用户体验和技术效率,也体现了开发者追求极致与不断创新的精神。
146 7