Text-To-Speech(TTS)语音朗读

2023-11-02

Text-To-Speech(TTS)语音朗读

更新: 2010-04-08 来源: 互联网 字体:【大 中 小 】
-

TextToSpeech简称 TTS,是Android 1.6版本中比较重要的新功能。将所指定的文本转成不同语言音频输出。它可以方便的嵌入到游戏或者应用程序中,增强用户体验。
在讲解TTS API和将这项功能应用到你的实际项目中的方法之前,先对这套TTS引擎有个初步的了解。

对TTS资源的大体了解:

TTS engine依托于当前Android Platform所支持的几种主要的语言:English、French、German、Italian和Spanish五大语言(暂时没有我们伟大的中 文,至少Google的科学家们还没有把中文玩到炉火纯青的地步,先易后难也是理所当然。)TTS可以将文本随意的转换成以上任意五种语言的语音输出。与 此同时,对于个别的语言版本将取决于不同的时区,例如:对于English,在TTS中可以分别输出美式和英式两种不同的版本(由此看出Google的做 事风格真够细致,而正因为如此估计Google不加入中文的另外一种理由是中文的方言太多了)。

能支持如此庞大的数据量,TTS 引擎对于资源的优化采取预加载的方法。根据一系列的参数信息(参数的用法将在后边有详细的介绍)从库中提取相应的资源,并加载到当前系统中。

尽管当前大部分加载有Android操作系统的设备都通过这套引擎来提供TTS功能,但由于一些设备的存储空间非常有限而影响到TTS无法最大限度的发挥 功能,算是当前的一个瓶颈。为此,开发小组引入了检测模块,让利用这项技术的应用程序或者游戏针对于不同的设备可以有相应的优化调整,从而避免由于此项功 能的限制,影响到整个应用程序的使用。比较稳妥的做法是让用户自行选择是否有足够的空间或者需求来加载此项资源,下边给出一个标准的检测方法:

Intent checkIntent = new Intent();
checkIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
startActivityForResult(checkIntent, MY_DATA_CHECK_CODE); 
如果当前系统允许创建一个 “android.speech.tts.TextToSpeech” 的Object, 说明已经提供TTS功能的支持,将检测返回结果中给出“ CHECK_VOICE_DATA_PASS ” 的标记。如果系统不支持这项功能,那么用户可以选择是否加载这项功能,从而让设备支持输出多国语言的语音功能“Multi-lingual Talking”。“ACTION_INSTALL_TTS_DATA” intent将用户引入Android market中的TTS下载界面。下载完成后将自动完成安装,下边是实现这一过程的完整代码 (androidres.com) :

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); } TextToSpeech实体和OnInitListener都需要引用当前Activity的Context作为构造参数。OnInitListener()的用处是通知系统当前TTS Engine已经加载完成,并处于可用状态。

根据需求设置语言参数:

早在Google I/O大会上,官方给出了一段关于应用这项功能的鲜活体验,将翻译结果直接通过五种不同国家语言的语音输出。加载语言的方法非常简单:

mTts.setLanguage(Locale.US); 
上边代码表示当前TTS实体加载美式英语。其参数并没有指示某种语言的名称,而是利用国家代码来表示,这样做的好处是不但可以确定语言的选择,而且可以根 据地区的不同而有所区别。例如:英语作为最广泛被应用的语种,在多个不同的地区都有一定的差别。判断当前系统是否支持某个地区的语言资源,可以通过调用 isLanguageAvailable()方法的返回值,根据返回值的描述来选择正确的处理方式。让应用某些绚丽功能的应用程序更加健壮,这个是贯穿整 个开发过程都要考虑的技术环节。下边是一些应用实例 (androidres.com) :

mTts.isLanguageAvailable(Locale.UK))
mTts.isLanguageAvailable(Locale.FRANCE))
mTts.isLanguageAvailable(new Locale("spa", "ESP"))) 
如果返回值是 “ TextToSpeech.LANG_COUNTRY_AVAILABLE ” 说明所选择的地区被包含在当前TTS系统中。如果系统中已经创建了TTS实体,那么可以利用isLanguageAvailable()方法来替代 Start “ACTION_CHECK_TTS_DATA ” intent 检测。当无法找到任何可用资源匹配所指定的参数时,将会返回 “ TextToSpeech.LANG_MISSING_DATA ”的结果。下边给出另外两个返回其它不同状态信息的例子:

mTts.isLanguageAvailable(Locale.CANADA_FRENCH))
mTts.isLanguageAvailable(new Locale("spa")) 
两个语句的返回值均为 “ TextToSpeech.LANG_AVAILABLE ” 。第一个是检测当前系统是否支持加拿*****语,由于系统在资源库中无法找到这个地区的法语分支,其含义是仅支持这项语言(法语),而不支持当前地区的语言分支。

另外,相比于上面强制用户应用预定的语音设置,更加提倡利用Locale.getDefault()方法根据用户默认的地区设置来选择合适的语言库。

执行Speak的具体方法:

根据上边的介绍,基本实现了TextToSpeech的初始化和参数配置。下面是一个有关闹钟的应用实例,利用Speak()方法可以直接在应用程序中发挥强大的语音功能。没错,用起来就是这么简单:

String myText1 = "This Translation is from androidRes.com";
String myText2 = "I hope so, because it's time to wake up.";
mTts.speak(myText1, TextToSpeech.QUEUE_FLUSH, null);
mTts.speak(myText2, TextToSpeech.QUEUE_ADD, null); 
TTS Engine的工作原理:

每个独立的应用程序都可以单独创建一个TTS实体,而他们需要执行的语音消息列队(Queue)都统一由TTS Engine管理和语音合成。

名词解释:

synthesize [ˈsɪnθəsaɪz] DJ ['sɪnθəˈsaɪz] KK:to produce sounds, music or speech using electronic equipment (音响)合成

utterances [ˈʌtərəns] DJ [ˈʌtərəns] KK :说话方式,语音/语调。

每个独立的TTS实例管理语音消息列队请求的优先级和顺序等。当引用 “TextToSpeech.QUEUE_FLUSH” 调用Speak()方法时,会中断当前实例正在运行的任务(也可以理解为清除当前语音任务,转而执行新的列队任务)。引用 “TextToSpeech.QUEUE_ADD”标签的发音任务将被添加到当前任务列队之后。

为语音任务关联Stream Type:

在Android操作系统中所有的Audio Stream任务都是通过AudioManager类来实现,而它会针对不同的Stream Type来改 变语音的播放模式。StreamType可以理解为语音的播放属性,这个属性是用户根据自己的需要在系统中配置的应用方案。如果将语音任务都清楚的分门别 类,可以方便的统一管理相同类别任务的属性。基于上一个Alarm Clock例子的基础上,将Speak()方法的最后一个Null参数替换成具有实际含义的数值。这个参数的类型是HashMap,如果希望将当前的 Stream Type设置为系统中Alarm类型,对上一个例子稍作改动:

HashMap myHashAlarm = new HashMap();
myHashAlarm.put(TextToSpeech.Engine.KEY_PARAM_STREAM,
String.valueOf(AudioManager.STREAM_ALARM));
mTts.speak(myText1, TextToSpeech.QUEUE_FLUSH, myHashAlarm);
mTts.speak(myText2, TextToSpeech.QUEUE_ADD, myHashAlarm); 
应用语音功能的Completion Callback:

TTS中的Speak()的是异步调用,无论应用QUEUE_FLUSH 或者QUEUE_ADD作为参数都可以通过定义Listener监听当前任务的完成状态。可以利用这个方法追加Speak()执行之后的一些额外操作。下 接下来的例子中,当完成第二次Speak()方法调用之后,利用OnUtteranceCompletedListener接口来调用其它方法:

mTts.setOnUtteranceCompletedListener(this);
myHashAlarm.put(TextToSpeech.Engine.KEY_PARAM_STREAM,
String.valueOf(AudioManager.STREAM_ALARM));
mTts.speak(myText1, TextToSpeech.QUEUE_FLUSH, myHashAlarm);
myHashAlarm.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID,
"end of wakeup message ID");
// myHashAlarm now contains two optional parameters
mTts.speak(myText2, TextToSpeech.QUEUE_ADD, myHashAlarm); 
下边是定义Listener的代码,类似与监听按钮或者其它View Events的方法。在这里将会把Speak()中HashMap参数传进Listener中,作为条件的判断依据:

public void onUtteranceCompleted(String uttId) {
if (uttId == "end of wakeup message ID") {
playAnnoyingMusic(); } 
“烘焙”当前实时的语音数据:

看到烘焙两个字,就会让人联想到香喷喷的面包。软件开发要关注于是否可以最大限度的实现资源的复用,特别是针对资源有限的手机应用平台。那么对于 TTS这么奢侈的应用如何才能更高效的使用资源呢?这次一起来体验比烘焙面包更加让人激动的功能,将TTS Engine输出的Audio Stream作为永久的音频文件保存在当前的存储空间中(SDCard)。这样可以对需要重复播放的某些语音内容实现快速的回放功能,从而实现国际倡导的 “减排”目的,能省就省吧!在下边的例子用通过TTS的synthesizeToFile方法,将合成的语音Stream保存在参数所指定的地址中。

HashMap myHashRender = new HashMap();
String wakeUpText = "Are you up yet?";
String destFileName = "/sdcard/myAppCache/wakeUp.wav";
myHashRender.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, wakeUpText);
mTts.synthesizeToFile(wakuUpText, myHashRender, destFileName); 
当完成以上操作之后会收到系统的完成通知,同时可以像其它音频资源一样,通过android.media.MediaPlayer方法来播放。但这有悖于 TextToSpeech的应用流程,可以将刚刚输出的语音资源通过addSpeech()的方法将其语音和文字描述一同存储于TTS库中。

mTts.addSpeech(wakeUpText, destFileName); 
在当前的TTS Instance中,任何利用Speak()方法执行相同内容的调用都将复用刚刚所生成的音频文件。如果资源丢失或者SDCard等存储设备移除,那么系统将再次通过TTS Engine合成所指定的语音内容。

mTts.speak(wakeUpText, TextToSpeech.QUEUE_ADD, myHashAlarm); 
回收TTS:

当确定应用程序不再需要TTS的相关功能后,可以在Activity的OnDestroy()方法中调用shutDown()释放当前TTS实体所占用的资源。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Text-To-Speech(TTS)语音朗读 的相关文章

  • 新的 Material Design 底部导航应使用哪个视图? [复制]

    这个问题在这里已经有答案了 我相信你们都听说过添加底部导航 https www google com design spec components bottom navigation html材料设计指南 我计划将其添加到我的应用程序中 但
  • Android:处理电话中的语音

    我目前正在寻找有关如何在 Android 上操作音频的选项 目标是在通话期间实时处理来自麦克风的音频 最好的解决方案是在本机调用中执行此操作 但重建一个电话应用程序 无 VOIP 也可以 有没有什么方法可以使用 Android API 来实
  • chrome 检查器,远程调试在我的移动应用程序上不再正常工作

    我使用 Cordova Ionic 构建了一个渐进式 Web 应用程序 三年来的大部分时间里 我一直在使用开发工具来排除故障并分析我的应用程序的内部工作原理 然而 在过去的几周里 我认为自从 Chrome 更新到 v70 以来 开发工具无法
  • Android 滚动分页

    Android 操作系统有可以实现滚动分页的功能吗 Edit滚动分页是指像主屏幕上一样的分页 您可以左右滑动并转到下一页或上一页 您可以在 android git kernel org 上查看 Launcher 的源代码作为示例 查找名为
  • Android 自定义对话框因布局而膨胀 - 对齐问题

    我有一个自定义对话框 它是从dialog xml 中膨胀的 当我打开对话框时 它看起来如下所示 我在列表视图和它下面的 确定 按钮之间有一些空间 我想消除列表视图与其下方的按钮之间的空间 我怎样才能做到这一点 对话框 xml
  • android中.so文件的实际用途是什么? [复制]

    这个问题在这里已经有答案了 我想在我的应用程序中实现类似聊天的环聊 我一直在使用 opentok 库 我在其中看到了 libopentok so 文件 谁能告诉我 libopentok so 文件的确切用法是什么 在Android中 我们可
  • 使用 iOS 分布式应用程序时 Google Cloud Messaging 显示“notRegistered”

    我在 iOS 应用程序上实现了 GCM 服务 我使用 PHP 在服务器上发送 GCM 当应用程序由开发配置文件签名时 它可以完美运行 也就是说 当应用程序使用 GCM 配置注册自身时 它始终返回一个正常运行的设备令牌 我可以使用令牌向设备发
  • 如何使用 ArrayAdapter

    ArrayList
  • 如何将 ThreeJS 与 PhoneGap 一起使用?

    这个探索是非常自我描述的 我已经用一个简单的 3D 立方体进行了测试 它在浏览器中运行良好 但只在模拟器中显示空白页面 有人说 Threejs 不能与 PhoneGap 一起使用 但也有人说他们使用过并且工作正常 在 Android 中 您
  • Camera.Parameters.FLASH_MODE_ON 在 Moto X 上不起作用

    我正在 moto x 上测试我的应用程序 即使打开闪光灯模式后 闪光灯也无法工作 应用程序在其他设备上运行良好 但在 Moto X 上运行不佳 这是一个代码片段 cameraInstance getCameraInstance camera
  • 在较低的 SDK 上运行具有较高 SDK 的应用程序

    我想知道在 Android 3 0 中开发的应用程序是否可以在 Android 2 1 上运行 如果是这样 我该怎么做 如果我使用 3 0 中的库 例如片段 开发应用程序 它可以在 2 1 中使用吗 不会 但是 2 1 应用程序可以在 3
  • 如何计算android中位图擦除区域的百分比?

    我是安卓新手 我正在制作一个可以使用手指擦除画布上的位图的应用程序 像手指画橡皮擦之类的东西 我想计算擦除区域的百分比 例如 60 已从完整图像中擦除 请帮助我做到这一点 提前致谢 我尝试了一些方法 它总是给我 0 它不起作用 请参阅该方法
  • Eclipse Oxygen - 该项目未构建,因为其构建路径不完整

    我刚刚安装了 Eclipse Oxygen 并尝试在工作台中打开现有项目 但收到此错误 该项目未构建 因为其构建路径不完整 不能 找到 java lang Object 的类文件 修复构建路径然后尝试 建设这个项目 我尝试右键单击该项目 转
  • 如何使用Multipart将图像上传到php服务器

    我一直很头疼 如何将图像上传到服务器 这对我来说是新任务 但对我来说很困惑 我在 stackoverflow 上搜索并用谷歌搜索 但我遇到了问题 我的意图是从 SD 卡上传照片并从相机拍照并上传到服务器 在ios中 这个任务已经完成 在io
  • Android 对 Runtime.getRuntime().exec() 的权限

    我有一个应用程序在清单上具有以下权限 我的应用程序在 Android JB 4 1 2 上运行 UPDATE 我尝试在 JB 上运行该应用程序 但它不起作用 它适用于早期的 API 版本
  • 如何在java中从包含.0的浮点数中删除小数部分

    我只想删除包含的浮点数的小数部分 0 所有其他数字都是可以接受的 例如 I P 1 0 2 2 88 0 3 56666 4 1 45 00 99 560 O P 1 2 2 88 3 567 4 1 45 99 560 有什么方法可以做到
  • Android - 带动画的可扩展 TextView

    我有一个TextView首先显示长文本的一小部分 用户可以按 查看更多 按钮来展开TextView并查看该文本的其余部分 进行测试 我可以通过简单地交换以下值来实现这一点TextView setMaxLines介于 4 之间 用于折叠 和
  • 从前台服务的活动中释放内存

    我有一个带有前台服务和一项活动的应用程序 该服务可以在启动时自行启动 也可以从 Activity 中启动 我注意到当服务在启动时自行启动时 内存使用量约为 3MB 一旦我打开该 Activity 内存使用量就会跃升至约 9mB 一旦 Act
  • 如何在Android 11中获取dir文件列表

    我想编写自己的精简版文件浏览器 文件 API 现在不适用于外部存储 该版本还提供了对范围存储的改进 这使得开发人员可以更轻松地迁移到使用此存储模型 我不明白如何使用范围存储来访问 sdcard 如果您正在寻找文件选择器体验 存储访问框架 h
  • android 填充包含片段的布局

    问题是什么 我如何膨胀包含片段的布局 我不知道错误消息的含义 请帮我 谢谢 错误信息 09 01 18 44 58 698 E AndroidRuntime 20617 Caused by java lang IllegalArgument

随机推荐

  • Python3语法笔记(前篇)

    文章目录 前言 基础杂项 变量和数据 变量与运算 数值 字符串 列表 list 元组 tuple 和range 序列类型 sequence types 和切片 slicing 集合 set 和字典 dict 引用 浅拷贝 深拷贝 流程控制语
  • ubuntu环境下通过launch文件和shell脚本启动ROS小海龟项目 一键启动多个终端和节点

    1 roslaunch文件启动小海龟 我们在学习ROS时都启动过自带的小海龟范例 安装ROS环境后也会通过启动小海龟来验证环境是否安装成功 尝试使用roslaunch文件启动小海龟项目时 在根目录下新建turtlesim launch文件
  • selenium如何定位属性一样的div、span元素

    在做自动化测试时 我们需要定位元素属性来进行操作 今天在做自动化时发现我要定位的元素找不到 我看了下代码发现 要定位的元素 A 属性与另一个元素 B 属性一样 我用xpath获取绝对路径后 发现找不到 找的是B元素 试了几次之后结果还是找不
  • C++ 变量类型

    变量其实只不过是程序可操作的存储区的名称 C 中每个变量都有指定的类型 类型决定 了变量存储的大小和布局 该范围内的值都可以存储在内存中 运算符可应用于变量上 变量的名称可以由字母 数字和下划线字符组成 必须以字母或下划线开头 因为 C 对
  • webpack--loader执行顺序

    正常来讲一个文件只能被一个loader处理 当一个文件要被多个loader处理 那么一定要指定loader的先后顺序 test js exclude node modules 以下属性是设置优先执行 pre true loader esli
  • 在线调整ext3磁盘容量

    调整前先用 tar cf disk home tar home 进行打包备份 1 查看磁盘分区情况 fdisk l Disk dev sda 291 9 GB 291999055872 bytes 255 heads 63 sectors
  • shiro ajax权限拦截器,Shiro Ajax请求权限不满足,拦截后解决方案

    Java模拟Http请求 Java模拟Http请求 使用的是org apache httpcomponents中的httpclient 因为post请求涉及到传输文件 所以需要使用httpmime这个包 centos7 上安装mysql5
  • 交换机的三种端口

    交换机 一个wan口多个lan接口 交换机功能 实现连接lan接口的设备之间与wan口连接的网络的通信与通信控制 交换机有三种类型的端口 access trunk hybind access 端口连接 pc等设备 可将此类端口划入某vlan
  • 微信小程序 延时执行 设置固定时间间隔

    setTimeout function 要延时执行的代码 2000 延迟时间 这里是2秒 微信小程序中的函数想要延时执行 等一段时间后再执行采用以上代码
  • K最近邻算法(KNN)---sklearn+python实现

    k 近邻算法概述 简单地说 k近邻算法采用测量不同特征值之间的距离方法进行分类 k 近邻算法 优点 精度高 对异常值不敏感 无数据输入假定 缺点 计算复杂度高 空间复杂度高 适用数据范围 数值型和标称型 k 近邻算法 kNN 它的工作原理是
  • Http的GET请求与POST请求调用接口

    GET请求 public static String doGet Map
  • FFmpeg,Fplay,clion调试环境搭建

    本系列 以 ffmpeg4 4 源码为准 本文主要讲解如何搭建 ffplay 的CLion调试环境 ffmpeg 在 Linux 环境下更好调试 本文系统是 Ubuntu 18 首先下载 FFmpeg n4 4 1 zip 虽然 FFmpe
  • ESP8266与网络服务器实时通讯

    目前 所有已呈现的通信都是基于请求响应方法的 其中一个实体正在发送请求 另一实体正在发送回响应 但是在某些情况下 您需要ESP8266模块与服务器之间的实时通信 而不仅仅是事务 实时通讯协议 ESP8266流数据 要从ESP8266流传输数
  • 【Ranger】编译问题An Ant BuildException has occured: exec returned: 1

    先看一下报错的信息 ERROR Failed to execute goal org apache maven plugins maven antrun plugin 1 7 run generate version annotation
  • 数学建模竞赛常考四大模型总结【预测模型、分类模型、优化模型、评价模型】

    目录 1 预测模型 1 1 神经网络预测 1 2 灰色预测 1 3 拟合 插值预测 线性回归 1 4 时间序列预测 1 5 马尔科夫链预测 1 6 微分方程预测 1 7 Logistic 回归 逻辑回归 1 8 线性回归 总结 应用场景 2
  • centos7中iptables配置log日志记录所有流量

    CentOS 7 0默认使用的是firewall作为防火墙 使用iptables必须重新设置一下 1 直接关闭防火墙 systemctl stop firewalld service 停止firewall systemctl disable
  • c语言编译器mingw的使用说明,C语言编译器MINGW的使用说明

    在mingw环境中生成和使用dll都是十分方便的 1 生成dll gcc g shared o test dll test c 一直用VS 看现在Eclipse很火 便想弄一下玩玩 用到了MINGW 继而用到了GCC 对GCC相当的不熟悉
  • [JS] Flatten array

    拍平数组 这个在lodash里也是很常见的方法 那自己实现一个看看 普通拍平 const flatten arr gt concat arr map v gt Array isArray v v v 测试 flatten 1 2 3 4 5
  • 【历史上的今天】1 月 16 日:互联网工程任务组(IETF)成立;AMD 收购 NexGen;eBay 的第一位员工出生

    整理 王启隆 透过 历史上的今天 从过去看未来 从现在亦可以改变未来 今天是 2022 年 1 月 16 日 在 25 年前的今天 国家电力公司组建成立 电力是运作着我们生活的基本 国家电力公司成立于 1997 年 1 月 16 日 于 2
  • Text-To-Speech(TTS)语音朗读

    Text To Speech TTS 语音朗读 更新 2010 04 08 来源 互联网 字体 大 中 小 TextToSpeech简称 TTS 是Android 1 6版本中比较重要的新功能 将所指定的文本转成不同语言音频输出 它可以方便