介绍Text-To-Speech在Android中的用法
TextToSpeech简称 TTS,是Android中比较重要的新功能。将所指定的文本转成不同语言音频输出。它可以方便的嵌入到游戏或者应用程序中,增强用户体验。 在讲解TTS API和将这项功能应用到你的实际项目中的方法之前,先对这套TTS引擎有个初步的了解。 对TTS资源的大体了解: 中文,至少Google的科学家们还没有把中文玩到炉火纯青的地步,先易后难也是理所当然。)TTS可以将文本随意的转换成以上任意五种语言的语音输出。与此同时,对于个别的语言版本将取决于不同的时区,例如:对于English,在TTS中可以分别输出美式和英式两种不同的版本(由此看出Google的做事风格真够细致,而正因为如此估计Google不加入中文的另外一种理由是中文的方言太多了)。 系统中。 空间非常有限而影响到TTS无法最大限度的发挥功能,算是当前的一个瓶颈。为此,开发小组引入了检测模块,让利用这项技术的应用程序或者游戏针对于不同的设备可以有相应的优化调整,从而避免由于此项功能的限制,影响到整个应用程序的使用。比较稳妥的做法是让用户自行选择是否有足够的空间或者需求来加载此项资源,下边给出一个标准的检测方法: 1.Intent checkIntent = new Intent(); 2.checkIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA); 3.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) :
TextToSpeech实体和OnInitListener都需要引用当前Activity的Context作为构造参数。OnInitListener()的用处是通知系统当前TTS Engine已经加载完成,并处于可用状态。 根据需求设置语言参数: 官方给出了一段关于应用这项功能的鲜活体验,将翻译结果直接通过五种不同国家语言的语音输出。加载语言的方法非常简单:
而且可以根据地区的不同而有所区别。例如:英语作为最广泛被应用的语种,在多个不同的地区都有一定的差别。判断当前系统是否支持某个地区的语言资源,可以通过调用isLanguageAvailable()方法的返回值,根据返回值的描述来选择正确的处理方式。让应用某些绚丽功能的应用程序更加健壮,这个是贯穿整个开发过程都要考虑的技术环节。下边是一些应用实例 (androidres.com) :
TextToSpeech.LANG_COUNTRY_AVAILABLE ” 说明所选择的地区被包含在当前TTS系统中。如果系统中已经创建了TTS实体,那么可以利用isLanguageAvailable()方法来替代 Start “ACTION_CHECK_TTS_DATA ” intent 检测。当无法找到任何可用资源匹配所指定的参数时,将会返回 “TextToSpeech.LANG_MISSING_DATA
TextToSpeech.LANG_AVAILABLE 另外,相比于上面强制用户应用预定的语音设置,更加提倡利用Locale.getDefault()方法根据用户默认的地区设置来选择合适的语言库。 执行Speak的具体方法: 根据上边的介绍,基本实现了TextToSpeech的初始化和参数配置。下面是一个有关闹钟的应用实例,利用Speak()方法可以直接在应用程序中发挥强大的语音功能。没错,用起来就是这么简单:
TTS Engine的工作原理: 每个独立的应用程序都可以单独创建一个TTS实体,而他们需要执行的语音消息列队(Queue)都统一由TTS Engine管理和语音合成。
TextToSpeech.QUEUE_FLUSH” 调用Speak()方法时,会中断当前实例正在运行的任务(也可以理解为清除当前语音任务,转而执行新的列队任务)。引用 “TextToSpeech.QUEUE_ADD”标签的发音任务将被添加到当前任务列队之后。 为语音任务关联Stream Type: 在Android操作系统中所有的Audio Stream任务都是通过AudioManager类来实现,而它会针对不同的Stream Type来改变语音的播放模式。StreamType可以理解为语音的播放属性,这个属性是用户根据自己的需要在系统中配置的应用方案。如果将语音任务都清楚的分门别类,可以方便的统一管理相同类别任务的属性。基于上一个Alarm Clock例子的基础上,将Speak()方法的最后一个Null参数替换成具有实际含义的数值。这个参数的类型是HashMap,如果希望将当前的Stream Type设置为系统中Alarm类型,对上一个例子稍作改动:
应用语音功能的Completion Callback: QUEUE_FLUSH 或者QUEUE_ADD作为参数都可以通过定义Listener监听当前任务的完成状态。可以利用这个方法追加Speak()执行之后的一些额外操作。下接下来的例子中,当完成第二次Speak()方法调用之后,利用OnUtteranceCompletedListener接口来调用其它方法:
下边是定义Listener的代码,类似与监听按钮或者其它View Events的方法。在这里将会把Speak()中HashMap参数传进Listener中,作为条件的判断依据:
“烘焙”当前实时的语音数据: 软件开发要关注于是否可以最大限度的实现资源的复用,特别是针对资源有限的手机应用平台。那么对于TTS这么奢侈的应用如何才能更高效的使用资源呢?这次一起来体验比烘焙面包更加让人激动的功能,将TTS Engine输出的Audio Stream作为永久的音频文件保存在当前的存储空间中(SDCard)。这样可以对需要重复播放的某些语音内容实现快速的回放功能,从而实现国际倡导的“减排”目的,能省就省吧!在下边的例子用通过TTS的synthesizeToFile方法,将合成的语音Stream保存在参数所指定的地址中。
当完成以上操作之后会收到系统的完成通知,同时可以像其它音频资源一样,通过android.media.MediaPlayer方法来播放。但这有悖于TextToSpeech的应用流程,可以将刚刚输出的语音资源通过addSpeech()的方法将其语音和文字描述一同存储于TTS库中。 1.mTts.addSpeech(wakeUpText, destFileName); 在当前的TTS Instance中,任何利用Speak()方法执行相同内容的调用都将复用刚刚所生成的音频文件。如果资源丢失或者SDCard等存储设备移除,那么系统将再次通过TTS Engine合成所指定的语音内容。 1.mTts.speak(wakeUpText, TextToSpeech.QUEUE_ADD, myHashAlarm); 回收TTS: 当确定应用程序不再需要TTS的相关功能后,可以在Activity的OnDestroy()方法中调用shutDown()释放当前TTS实体所占用的资源。 杂谈: 想必在你的脑袋中已经冒出好多可以很好利用这个功能的Idea!那么现在就停止想象,开始付诸于行动吧!无论是给手机用户带来方便,或是提升游戏体验等。Let’s move! 查看原文:Android官方Blog |