Android開發(fā)之自動(dòng)朗讀TTS用法分析
本文實(shí)例講述了Android自動(dòng)朗讀TTS用法。分享給大家供大家參考,具體如下:
TextToSpeech簡(jiǎn)稱 TTS,是自Android 1.6版本開始比較重要的新功能。將所指定的文本轉(zhuǎn)成不同語言音頻輸出。它可以方便的嵌入到游戲或者應(yīng)用程序中,增強(qiáng)用戶體驗(yàn)。
在講解TTS API和將這項(xiàng)功能應(yīng)用到你的實(shí)際項(xiàng)目中的方法之前,先對(duì)這套TTS引擎有個(gè)初步的了解。
對(duì)TTS資源的大體了解:
TTS engine依托于當(dāng)前Android Platform所支持的幾種主要的語言:English、French、German、Italian和Spanish五大語言(暫時(shí)沒有我們偉大的中文,至少google的 科學(xué)家們還沒有把中文玩到爐火純青的地步,先易后難也是理所當(dāng)然。)TTS可以將文本隨意的轉(zhuǎn)換成以上任意五種語言的語音輸出。與此同時(shí),對(duì)于個(gè)別的語言 版本將取決于不同的時(shí)區(qū),例如:對(duì)于English,在TTS中可以分別輸出美式和英式兩種不同的版本(由此看出Google的做事風(fēng)格真夠細(xì)致,而正因 為如此估計(jì)Google不加入中文的另外一種理由是中文的方言太多了)。
能支持如此龐大的數(shù)據(jù)量,TTS 引擎對(duì)于資源的優(yōu)化采取預(yù)加載的方法。根據(jù)一系列的參數(shù)信息(參數(shù)的用法將在后邊有詳細(xì)的介紹)從庫中提取相應(yīng)的資源,并加載到當(dāng)前系統(tǒng)中。
盡管當(dāng)前大部分加載有Android操作系統(tǒng)的設(shè)備都通過這套引擎來提供TTS功能,但由于一些設(shè)備的存儲(chǔ)空間非常有限而影響到TTS無法最大限度的發(fā) 揮功能,算是當(dāng)前的一個(gè)瓶頸。為此,開發(fā)引入了檢測(cè)模塊,讓利用這項(xiàng)技術(shù)的應(yīng)用程序或者游戲針對(duì)于不同的設(shè)備可以有相應(yīng)的優(yōu)化調(diào)整,從而避免由于此項(xiàng)功能 的限制,影響到整個(gè)應(yīng)用程序的使用。比較穩(wěn)妥的做法是讓用戶自行選擇是否有足夠的空間或者需求來加載此項(xiàng)資源,下邊給出一個(gè)標(biāo)準(zhǔn)的檢測(cè)方法:
Intent checkIntent = new Intent(); checkIntent.setAction(TextToSpeech.Engine.ACTION_C HECK_TTS_DATA); startActivityForResult(checkIntent, MY_DATA_CHECK_CODE);
如果當(dāng)前系統(tǒng)允許創(chuàng)建一個(gè) “android.speech.tts.TextToSpeech” 的彩虹簡(jiǎn)譜字庫 下載Object, 說明已經(jīng)提供TTS功能的支持,將檢測(cè)返回結(jié)果中給出“ CHECK_VOICE_DATA_PASS ” 的標(biāo)記。如果系統(tǒng)不支持這項(xiàng)功能,那么用戶可以選擇是否加載這項(xiàng)功能,從而讓設(shè)備支持輸出多國(guó)語言的語音功能“Multi-lingual Talking”。“ACTION_INSTALL_TTS_DATA” intent將用戶引入Android market中的TTS下載界面。下載完成后將自動(dòng)完成安裝,下邊是實(shí)現(xiàn)這一過程的完整代碼 (androidres) :
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) { // sess, 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實(shí)體和OnInitListener都需要引用當(dāng)前Activity的Context作為構(gòu)造參數(shù)。 OnInitListener()的用處是通知系統(tǒng)當(dāng)前TTS Engine已經(jīng)加載完成,并處于可用狀態(tài)。
根據(jù)需求設(shè)置語言參數(shù):
早在Google I/O大會(huì)上,官方給出了一段關(guān)于應(yīng)用這項(xiàng)功能的鮮活體驗(yàn),將翻譯結(jié)果直接通過五種不同國(guó)家語言的語音輸出。加載語言的方法非常簡(jiǎn)單:
mTts.setLanguage(Locale.US);
上邊代碼表示當(dāng)前TTS實(shí)體加載美式英語。其參數(shù)并沒有指示某種語言的名稱,而是利用國(guó)家代碼來表示,這樣做的好處是不但可以確定語言的選擇,而且可以 根據(jù)地區(qū)的不同而有所區(qū)別。例如:英語作為最廣泛被應(yīng)用的語種,在多個(gè)不同的地區(qū)都有一定的差別。判斷當(dāng)前系統(tǒng)是否支持某個(gè)地區(qū)的語言資源,可以通過調(diào)用 isLanguageAvailable()方法的返回值,根據(jù)返回值的描述來選擇正確的處理方式。讓應(yīng)用某些絢麗功能的應(yīng)用程序更加健壯,這個(gè)是貫穿整 個(gè)開發(fā)過程都要考慮的技術(shù)環(huán)節(jié)。下邊是一些應(yīng)用實(shí)例 (androidres) :
mTts.isLanguageAvailable(Locale.UK)) mTts.isLanguageAvailable(Locale.FRANCE)) mTts.isLanguageAvailable(new Locale("spa", "ESP")))
如果返回值是“ TextToSpeech.LANG_COUNTRY_AVAILABLE ” 說明所選擇的地區(qū)被包含在當(dāng)前TTS系統(tǒng)中。如果系統(tǒng)中已經(jīng)創(chuàng)建了TTS實(shí)體,那么可以利用isLanguageAvailable()方法來替代 Start “ACTION_CHECK_TTS_DATA ” intent 檢測(cè)。當(dāng)無法找到任何可用資源匹配所指定的參數(shù)時(shí),將會(huì)返回“ TextToSpeech.LANG_MISSING_DATA ”的結(jié)果。下邊給出另外兩個(gè)返回其它不同狀態(tài)信息的例子:
mTts.isLanguageAvailable(Locale.CANADA_FRENCH)) mTts.isLanguageAvailable(new Locale("spa"))
兩個(gè)語句的返回值均為“ TextToSpeech.LANG_AVAILABLE ” 。第一個(gè)是檢測(cè)當(dāng)前系統(tǒng)是否支持加拿*****語,由于系統(tǒng)在資源庫中無法找到這個(gè)地區(qū)的法語分支,其含義是僅支持這項(xiàng)語言(法語),而不支持當(dāng)前紫光 v4.0下載地區(qū)的語言分支。
另外,相比于上面強(qiáng)制用戶應(yīng)用預(yù)定的語音設(shè)置,更加提倡利用Locale.getDefault() 方法根據(jù)用戶默認(rèn)的地區(qū)設(shè)置來選擇合適的語言庫。
執(zhí)行Speak的具體方法:
根據(jù)上邊的介紹,基本實(shí)現(xiàn)了 TextToSpeech的初始化和參數(shù)配置。下面是一個(gè)有關(guān)鬧鐘的應(yīng)用實(shí)例,利用Speak()方法可以直接在應(yīng)用程序中發(fā)揮強(qiáng)大的語音功能。沒錯(cuò),用起來就是這么簡(jiǎn)單:
String myText1 = "This Translation is from androidRes"; 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的工作原理:
每個(gè)獨(dú)立的應(yīng)用程序都可以單獨(dú)創(chuàng)建一個(gè)TTS實(shí)體,而他們需要執(zhí)行的語音消息列隊(duì)(Queue)都統(tǒng)一由TTS Engine管理和語音合成。
名詞解釋:
synthesize [snθsaz] DJ ['snθsaz] KK:to produce sounds, music or speech using electronic equipment (音響)合成
utterances [trns] DJ [trns] KK :說話方式,語音/語調(diào)。
每個(gè)獨(dú)立的TTS實(shí)例管理語音消息列隊(duì)請(qǐng)求的優(yōu)先級(jí)和順序等。當(dāng)引用 “TextToSpeech.QUEUE_FLUSH” 調(diào)用Speak()方法時(shí),會(huì)中斷當(dāng)前實(shí)例正在運(yùn)行的任務(wù)(也可以理解為清除當(dāng)前語音任務(wù),轉(zhuǎn)而執(zhí)行新的列隊(duì)任務(wù))。引用 “TextToSpeech.QUEUE_ADD”標(biāo)簽的發(fā)音任務(wù)將被添加到當(dāng)前任務(wù)列隊(duì)之后。
為語音任務(wù)關(guān)聯(lián)Stream Type:
在Android操作系統(tǒng)中所有的AudioStream任務(wù)都是通過AudioManager類來實(shí)現(xiàn),而它會(huì)針對(duì)不同的StreamType來改變語音的播放模式。StreamType可以理解為語音的播放屬性,這個(gè)屬性是用戶根據(jù)自己的需要在系統(tǒng)中配置的應(yīng)用方案。如果將語音任務(wù)都 清楚的分門別類,可以方便的統(tǒng)一管理相同類別任務(wù)的屬性?;谏弦粋€(gè)Alarm Clock例子的基礎(chǔ)上,將Speak()方法的最后一個(gè)Null參數(shù)替換成具有實(shí)際含義的數(shù)值。這個(gè)參數(shù)的類型是HashMap,如果希望將當(dāng)前的 Stream Type設(shè)置為系統(tǒng)中Alarm類型,對(duì)上一個(gè)例子稍作改動(dòng):
HashMap myHashAlarm = new HashMap(); myHashAlarm.put(TextToSpeech.Engine.KEY_PARAM_STRE AM, String.valueOf(AudioManager.STREAM_ALARM)); mTts.speak(myText1, TextToSpeech.QUEUE_FLUSH, myHashAlarm); mTts.speak(myText2, TextToSpeech.QUEUE_ADD, myHashAlarm);
應(yīng)用語音功能的Completion Callback:
TTS中的Speak()的是異步調(diào)用,無論應(yīng)用QUEUE_FLUSH 或者QUEUE_ADD作為參數(shù)都可以通過定義Listener監(jiān)聽當(dāng)前任務(wù)的完成狀態(tài)??梢岳眠@個(gè)方法追加Speak()執(zhí)行之后的一些額外操作。下 接下來的例子中,當(dāng)完成第二次Speak()方法調(diào)用之后,利用OnUtteranceCompletedListener接口來調(diào)用其它方法:
mTts.setOnUtteranceCompletedListener(this); myHashAlarm.put(TextToSpeech.Engine.KEY_PARAM_STRE AM, String.valueOf(AudioManager.STREAM_ALARM)); mTts.speak(myText1, TextToSpeech.QUEUE_FLUSH, myHashAlarm); myHashAlarm.put(TextToSpeech.Engine.KEY_PARAM_UTTE RANCE_ID, "end of wakeup message ID"); // myHashAlarm now contains two optional parameters mTts.speak(myText2, TextToSpeech.QUEUE_ADD, myHashAlarm);
下邊是定義Listener的代碼,類似與監(jiān)聽按 CuteFTP Home 8.3.3.0054下載鈕或者其它View Events的方法。在這里將會(huì)把Speak()中HashMap參數(shù)傳進(jìn)Listener中,作為條件的判斷依據(jù):
public void onUtteranceCompleted(String uttId) { if (uttId == "end of wakeup message ID") { playAnnoyingMusic(); } }
“烘焙”當(dāng)前實(shí)時(shí)的語音數(shù)據(jù):
看到烘焙兩個(gè)字,就會(huì)讓人聯(lián)想到香噴噴的面包。軟件開發(fā)要關(guān)注于是否可以最大限度的實(shí)現(xiàn)資源的復(fù)用,特別是針對(duì)資源有限的手機(jī)應(yīng)用平臺(tái)。那么對(duì)于TTS 這么奢侈的應(yīng)用如何才能更高效的使用資源呢?這次一起來體驗(yàn)比烘焙面包更加讓人激動(dòng)的功能,將TTS Engine輸出的Audio Stream作為永久的音頻文件保存在當(dāng)前的存儲(chǔ)空間中(SDCard)。這樣可以對(duì)需要重復(fù)播放的某些語音內(nèi)容實(shí)現(xiàn)快速的回放功能,從而實(shí)現(xiàn)國(guó)際倡導(dǎo)的 “減排”目的,能省就省吧!在下邊的例子用通過TTS的synthesizeToFile方法,將合成的語音Stream保存在參數(shù)所指定的地址中。
HashMap myHashRender = new HashMap(); String wakeUpText = "Are you up yet?"; String destFileName = "/sdcard/myAppCache/wakeUp.wav"; myHashRender.put(TextToSpeech.Engine.KEY_PARAM_UTT ERANCE_ID, wakeUpText); mTts.synthesizeToFile(wakuUpText, myHashRender, destFileName);
當(dāng)完成以上操作之后會(huì)收到系統(tǒng)的完成通知,同時(shí)可以像其它音頻資源一樣,通過 android.media.MediaPlayer方法來播放。但這有悖于TextToSpeech的應(yīng)用流程,可以將剛剛輸出的語音資源通過 addSpeech()的方法將其語音和文字描述一同存儲(chǔ)于TTS庫中。
mTts.addSpeech(wakeUpText, destFileName);
在當(dāng)前的TTS Instance中,任何利用Speak()方法執(zhí)行相同內(nèi)容的調(diào)用都將復(fù)用剛剛所生成的音頻文件。如果資源丟失或者SDCard等存儲(chǔ)設(shè)備移除,那么系統(tǒng)將再次通過TTS Engine合成所指定的語音內(nèi)容。
mTts.speak(wakeUpText, TextToSpeech.QUEUE_ADD, myHashAlarm);
回收TTS:
當(dāng)確定應(yīng)用程序不再需要TTS的相關(guān)功能后,可以在Activity的OnDestroy()方法中調(diào)用shutDown()釋放當(dāng)前TTS實(shí)體所占用的資源。
更多關(guān)于Android相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Android數(shù)據(jù)庫操作技巧總結(jié)》、《Android編程之a(chǎn)ctivity操作技巧總結(jié)》、《Android文件操作技巧匯總》、《Android編程開發(fā)之SD卡操作方法匯總》、《Android開發(fā)入門與進(jìn)階教程》、《Android資源操作技巧匯總》、《Android視圖View技巧總結(jié)》及《Android控件用法總結(jié)》
希望本文所述對(duì)大家Android程序設(shè)計(jì)有所幫助。
相關(guān)文章
Android消息通知欄的實(shí)現(xiàn)方法介紹
本篇文章是對(duì)Android消息通知欄的實(shí)現(xiàn)方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06

Android 如何攔截用戶頻繁操作(點(diǎn)擊事件)

Android控件之ScrollView用法實(shí)例分析

Android基于騰訊云實(shí)時(shí)音視頻仿微信視頻通話最小化懸浮

android中實(shí)現(xiàn)在ImageView上隨意畫線涂鴉的方法

Android實(shí)現(xiàn)可復(fù)用的選擇頁面