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

article/2025/10/5 1:34:01

前言

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

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

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

目前找到的离线TTS

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

应用名称支持离线备注下载地址
ITRI TTS下载
讯飞语记需打开一次, 但不需要登陆下载
科大讯飞语音引擎3.0推荐下载
Speech Services by Google需要科学上网, 离线需要先下载语音包下载

使用

首先, 安装对应的TTS应用, 再在设置中设置对应的语音输出服务
一般设置的步骤为: 设置>无障碍>文字转语音(TTS)输出
在这里插入图片描述
程序调用只需使用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 instancemTts = new TextToSpeech(this, this);} else {// missing data, install itIntent installIntent = new Intent();installIntent.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);startActivity(installIntent);}}
}

在这里插入图片描述

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

        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;@Deprecatedpublic TTS(Activity activity){Intent checkIntent = new Intent(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);activity.startActivityForResult(checkIntent, 0x774);}@Deprecatedpublic 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 instancemTts = new TextToSpeech(activity, this);} else {// missing data, install itIntent 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();}@Overridepublic 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)


http://chatgpt.dhexx.cn/article/7InGKP6R.shtml

相关文章

使用TextToSpeech朗读文字

1.使用TextToSpeech将一段文字转换为语音 android也可以实现把输入的文字朗读出来&#xff0c;使用到的是TextToSpeech&#xff0c;将一段文字转换为成语音&#xff0c;可根据需要合成出不同音色、语速和语调的声音&#xff0c;让机器像人一样开口说话。 不过目前只支持5种语言…

Android通过TextToSpeech实现文字转语音

一、直接上代码&#xff1a; import android.app.Activity; import android.os.Bundle; import android.speech.tts.TextToSpeech; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widge…

Android中TextToSpeech的使用

系列文章目录 Android中TextToSpeech的使用 文章目录 系列文章目录前言实现1.初始化语音。这是一个异步操作。初始化完成后调用oninitListener(第二个参数)。2.实现TextToSpeech.OnInitListener3.写一个朗读方法&#xff0c;在需要的时候触发&#xff08;如&#xff1a;点击事…

微软文本转语音小工具(Text to speech)

软件下载地址失效了&#xff0c;推荐使用网页版。 网站地址&#xff1a;Text To Speech - 在线文本转语音 话说一直在用最新的基于Chromium的微软Edge浏览器&#xff0c;绝对是我认为的最好的替代谷歌浏览器的软件了&#xff0c;拓展商店、账号书签插件同步、各种人性化功能应有…

TextToSpeech文本转语音

目录 一、TextToSpeech类中的常用方法 二、使用例子 MainActivity: activity_main: 效果图&#xff1a; 一、TextToSpeech类中的常用方法 TextToSpeech是一个Android平台提供的文本转语音功能&#xff0c;可以将文字快速地转换为语音播放。 方法名称功能setLanguage(Loc…

wereew

rtyhtyhj u y uikuiok,

werwerttwt

8987878898998 fgdfgd dfgdfgd dfgddg 欢迎使用Markdown编辑器 你好&#xff01; 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章&#xff0c;了解一下Markdown的基本语法知识。 新的改变 我们对Markdown编…

wewqe

前言 又是一年一度的“剁手节”&#xff0c;在女生购物车里装满了化妆品、包包、衣服、鞋子等等东西时&#xff0c;有类人的购物车里的东西画风十分清奇&#xff0c;不落俗套。 这类人穿着统一、爱好相似、有明显的群体特征&#xff0c;这就是程序员们。 通常双十一&#xff0c…

Weave

weave网络通信模型 weave通过在docker集群的每个主机上启动虚拟的路由器&#xff0c;将主机作为路由器&#xff0c;形成互联互通的网络拓扑&#xff0c;在此基础上&#xff0c;实现容器的跨主机通信。其主机网络拓扑参见下图&#xff1a;如上图所示&#xff0c;在每一个部署Do…

Web Worker

Web Worker Web Worker?Web Worker 基本使用主线程Worker线程 Web Worker的优势在哪? Web Worker? 我们都知道JavaScript是单线程的&#xff0c;至于为什么是单线程的&#xff0c;以下内容来源阮一峰前辈的文章 作为浏览器脚本语言&#xff0c;JavaScript的主要用途是与用户…

werw er

TOCerwr wer wer wer 欢迎使用Markdown编辑器 你好&#xff01; 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章&#xff0c;了解一下Markdown的基本语法知识。 新的改变 我们对Markdown编辑器进行了一些功能…

whisper

Robust Speech Recognition via Large-Scale Weak Supervision 介绍 大规模弱监督的训练。先前的方法都是通过大量的无监督学习训练&#xff08;无监督的数据容易收集&#xff0c;所以通过大量无监督的学习可以训练出一个质量较好的encoder&#xff09;。但是用的时候还需要找…

2015WPE封包刷Q币图文教程

首先进入魔域小组官网 www.myxzg.pw 然后观看免费的视频教程 土豆网观看地址:http://www.tudou.com/listplay/2tXberN2LlM/-6FhCm1CMv0.html

WPE详细教程一

这里讲的WPEPRO的使用方法 一、打开WPE&#xff0c;选择进程client.exe&#xff0c;切换到游戏打一段话(如9个1)&#xff0c;然后切出去按开始截取&#xff0c;切换到游戏反复粘贴刚才那复制好的9个1。 然后切出游戏按停止,就会出来一堆数字.其中找S包最简单的方法就是找位数相…

WPE详细教程

这里讲的WPEPRO的使用方法 一、打开WPE&#xff0c;选择进程client.exe&#xff0c;切换到游戏打一段话(如9个1)&#xff0c;然后切出去按开始截取&#xff0c;切换到游戏反复粘贴刚才那复制好的9个1。 然后切出游戏按停止,就会出来一堆数字.其中找S包最简单的方法就是找位数相…

Wpe工作原理和教程-以传奇为列

wpe所要改的&#xff0c;不是[游戏里面的数值]&#xff0c;而是[伪造信息封包]。 什么意思咧??就是我们用wpe所要改的&#xff0c;并不是"生命力由100变成10000"之类的东西&#xff0c; 这种东西无法用wpe改&#xff0c; 我们要改的可能是把"我卖了一个500元的…

WPE详细教程二

本教程的内容安排 本教程的安排如下:首先是讲为什么会有封包,封包的结构是怎样的。  然后介绍TCP/IP技术的相关内容,定位封包在网络传输中的层!  然后介绍WPE的工作界面,以及各功能按扭的作用!  前面的内容属于了解阶段的内容,帮助您了解相关内容,对下面的学习会…

WPE 过滤器 滤镜 用法

过滤所有数值匹配的数据包&#xff0c;并修改指定的bit位 打开游戏 打开WPE 附加游戏进程 选项配置 用来配置抓取发送和接收包类型 先抓取发送包&#xff0c;也就是游戏中主动发给服务器的包 点击开始抓包 输入喊话内容 分别输入1和2进行抓包 结束抓包 显示…

WPE详细教程三

关于滤镜 经过前面的讲解,大家该知道封包制作外挂的原理了,这里再深入讲解一点,作为封包,按道理只能修改封包,达到修改游戏的目的,其实,如果我们能更广泛地想一想,如果我们能分析封包,其实是可以制作出很强大的功能的,当然,如果让WPE分析封包,能达到的功能是有限的…