Android開發(fā)之自動朗讀TTS用法分析
本文實例講述了Android自動朗讀TTS用法。分享給大家供大家參考,具體如下:
TextToSpeech簡稱 TTS,是自Android 1.6版本開始比較重要的新功能。將所指定的文本轉(zhuǎn)成不同語言音頻輸出。它可以方便的嵌入到游戲或者應(yīng)用程序中,增強用戶體驗。
在講解TTS API和將這項功能應(yīng)用到你的實際項目中的方法之前,先對這套TTS引擎有個初步的了解。
對TTS資源的大體了解:
TTS engine依托于當(dāng)前Android Platform所支持的幾種主要的語言:English、French、German、Italian和Spanish五大語言(暫時沒有我們偉大的中文,至少google的 科學(xué)家們還沒有把中文玩到爐火純青的地步,先易后難也是理所當(dāng)然。)TTS可以將文本隨意的轉(zhuǎn)換成以上任意五種語言的語音輸出。與此同時,對于個別的語言 版本將取決于不同的時區(qū),例如:對于English,在TTS中可以分別輸出美式和英式兩種不同的版本(由此看出Google的做事風(fēng)格真夠細(xì)致,而正因 為如此估計Google不加入中文的另外一種理由是中文的方言太多了)。
能支持如此龐大的數(shù)據(jù)量,TTS 引擎對于資源的優(yōu)化采取預(yù)加載的方法。根據(jù)一系列的參數(shù)信息(參數(shù)的用法將在后邊有詳細(xì)的介紹)從庫中提取相應(yīng)的資源,并加載到當(dāng)前系統(tǒng)中。
盡管當(dāng)前大部分加載有Android操作系統(tǒng)的設(shè)備都通過這套引擎來提供TTS功能,但由于一些設(shè)備的存儲空間非常有限而影響到TTS無法最大限度的發(fā) 揮功能,算是當(dāng)前的一個瓶頸。為此,開發(fā)引入了檢測模塊,讓利用這項技術(shù)的應(yīng)用程序或者游戲針對于不同的設(shè)備可以有相應(yīng)的優(yōu)化調(diào)整,從而避免由于此項功能 的限制,影響到整個應(yīng)用程序的使用。比較穩(wěn)妥的做法是讓用戶自行選擇是否有足夠的空間或者需求來加載此項資源,下邊給出一個標(biāo)準(zhǔn)的檢測方法:
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)建一個 “android.speech.tts.TextToSpeech” 的彩虹簡譜字庫 下載Object, 說明已經(jīng)提供TTS功能的支持,將檢測返回結(jié)果中給出“ CHECK_VOICE_DATA_PASS ” 的標(biāo)記。如果系統(tǒng)不支持這項功能,那么用戶可以選擇是否加載這項功能,從而讓設(shè)備支持輸出多國語言的語音功能“Multi-lingual Talking”?!癆CTION_INSTALL_TTS_DATA” intent將用戶引入Android market中的TTS下載界面。下載完成后將自動完成安裝,下邊是實現(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實體和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大會上,官方給出了一段關(guān)于應(yīng)用這項功能的鮮活體驗,將翻譯結(jié)果直接通過五種不同國家語言的語音輸出。加載語言的方法非常簡單:
mTts.setLanguage(Locale.US);
上邊代碼表示當(dāng)前TTS實體加載美式英語。其參數(shù)并沒有指示某種語言的名稱,而是利用國家代碼來表示,這樣做的好處是不但可以確定語言的選擇,而且可以 根據(jù)地區(qū)的不同而有所區(qū)別。例如:英語作為最廣泛被應(yīng)用的語種,在多個不同的地區(qū)都有一定的差別。判斷當(dāng)前系統(tǒng)是否支持某個地區(qū)的語言資源,可以通過調(diào)用 isLanguageAvailable()方法的返回值,根據(jù)返回值的描述來選擇正確的處理方式。讓應(yīng)用某些絢麗功能的應(yīng)用程序更加健壯,這個是貫穿整 個開發(fā)過程都要考慮的技術(shù)環(huán)節(jié)。下邊是一些應(yīng)用實例 (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實體,那么可以利用isLanguageAvailable()方法來替代 Start “ACTION_CHECK_TTS_DATA ” intent 檢測。當(dāng)無法找到任何可用資源匹配所指定的參數(shù)時,將會返回“ TextToSpeech.LANG_MISSING_DATA ”的結(jié)果。下邊給出另外兩個返回其它不同狀態(tài)信息的例子:
mTts.isLanguageAvailable(Locale.CANADA_FRENCH))
mTts.isLanguageAvailable(new Locale("spa"))
兩個語句的返回值均為“ TextToSpeech.LANG_AVAILABLE ” 。第一個是檢測當(dāng)前系統(tǒng)是否支持加拿*****語,由于系統(tǒng)在資源庫中無法找到這個地區(qū)的法語分支,其含義是僅支持這項語言(法語),而不支持當(dāng)前紫光 v4.0下載地區(qū)的語言分支。
另外,相比于上面強制用戶應(yīng)用預(yù)定的語音設(shè)置,更加提倡利用Locale.getDefault() 方法根據(jù)用戶默認(rèn)的地區(qū)設(shè)置來選擇合適的語言庫。
執(zhí)行Speak的具體方法:
根據(jù)上邊的介紹,基本實現(xiàn)了 TextToSpeech的初始化和參數(shù)配置。下面是一個有關(guān)鬧鐘的應(yīng)用實例,利用Speak()方法可以直接在應(yīng)用程序中發(fā)揮強大的語音功能。沒錯,用起來就是這么簡單:
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的工作原理:
每個獨立的應(yīng)用程序都可以單獨創(chuàng)建一個TTS實體,而他們需要執(zhí)行的語音消息列隊(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)。
每個獨立的TTS實例管理語音消息列隊請求的優(yōu)先級和順序等。當(dāng)引用 “TextToSpeech.QUEUE_FLUSH” 調(diào)用Speak()方法時,會中斷當(dāng)前實例正在運行的任務(wù)(也可以理解為清除當(dāng)前語音任務(wù),轉(zhuǎn)而執(zhí)行新的列隊任務(wù))。引用 “TextToSpeech.QUEUE_ADD”標(biāo)簽的發(fā)音任務(wù)將被添加到當(dāng)前任務(wù)列隊之后。
為語音任務(wù)關(guān)聯(lián)Stream Type:
在Android操作系統(tǒng)中所有的AudioStream任務(wù)都是通過AudioManager類來實現(xiàn),而它會針對不同的StreamType來改變語音的播放模式。StreamType可以理解為語音的播放屬性,這個屬性是用戶根據(jù)自己的需要在系統(tǒng)中配置的應(yīng)用方案。如果將語音任務(wù)都 清楚的分門別類,可以方便的統(tǒng)一管理相同類別任務(wù)的屬性。基于上一個Alarm Clock例子的基礎(chǔ)上,將Speak()方法的最后一個Null參數(shù)替換成具有實際含義的數(shù)值。這個參數(shù)的類型是HashMap,如果希望將當(dāng)前的 Stream Type設(shè)置為系統(tǒng)中Alarm類型,對上一個例子稍作改動:
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)??梢岳眠@個方法追加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的方法。在這里將會把Speak()中HashMap參數(shù)傳進Listener中,作為條件的判斷依據(jù):
public void onUtteranceCompleted(String uttId) {
if (uttId == "end of wakeup message ID") {
playAnnoyingMusic();
}
}
“烘焙”當(dāng)前實時的語音數(shù)據(jù):
看到烘焙兩個字,就會讓人聯(lián)想到香噴噴的面包。軟件開發(fā)要關(guān)注于是否可以最大限度的實現(xiàn)資源的復(fù)用,特別是針對資源有限的手機應(yīng)用平臺。那么對于TTS 這么奢侈的應(yīng)用如何才能更高效的使用資源呢?這次一起來體驗比烘焙面包更加讓人激動的功能,將TTS Engine輸出的Audio Stream作為永久的音頻文件保存在當(dāng)前的存儲空間中(SDCard)。這樣可以對需要重復(fù)播放的某些語音內(nèi)容實現(xiàn)快速的回放功能,從而實現(xiàn)國際倡導(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)完成以上操作之后會收到系統(tǒng)的完成通知,同時可以像其它音頻資源一樣,通過 android.media.MediaPlayer方法來播放。但這有悖于TextToSpeech的應(yīng)用流程,可以將剛剛輸出的語音資源通過 addSpeech()的方法將其語音和文字描述一同存儲于TTS庫中。
mTts.addSpeech(wakeUpText, destFileName);
在當(dāng)前的TTS Instance中,任何利用Speak()方法執(zhí)行相同內(nèi)容的調(diào)用都將復(fù)用剛剛所生成的音頻文件。如果資源丟失或者SDCard等存儲設(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實體所占用的資源。
更多關(guān)于Android相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Android數(shù)據(jù)庫操作技巧總結(jié)》、《Android編程之a(chǎn)ctivity操作技巧總結(jié)》、《Android文件操作技巧匯總》、《Android編程開發(fā)之SD卡操作方法匯總》、《Android開發(fā)入門與進階教程》、《Android資源操作技巧匯總》、《Android視圖View技巧總結(jié)》及《Android控件用法總結(jié)》
希望本文所述對大家Android程序設(shè)計有所幫助。
相關(guān)文章
Android開發(fā)中日期工具類DateUtil完整實例
這篇文章主要介紹了Android開發(fā)中日期工具類DateUtil,結(jié)合完整實例形式分析了Android針對日期與時間的計算、轉(zhuǎn)換、格式化、獲取等相關(guān)操作技巧,需要的朋友可以參考下2017-11-11
Android實現(xiàn)自定義Crash handler記錄崩潰信息實例代碼
這篇文章主要給大家介紹了Android實現(xiàn)自定義Crash handler記錄崩潰信息的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2018-02-02
Android自定義控件ViewGroup實現(xiàn)標(biāo)簽云
這篇文章主要為大家詳細(xì)介紹了Android自定義控件ViewGroup實現(xiàn)標(biāo)簽云,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-05-05
Android開發(fā)者常見的UI組件總結(jié)大全
Android開發(fā)中UI組件是構(gòu)建用戶界面的基本元素,下面這篇文章主要給大家介紹了關(guān)于Android開發(fā)者常見的UI組件總結(jié)的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-04-04

