Android開發(fā)之自動朗讀TTS用法分析
本文實例講述了Android自動朗讀TTS用法。分享給大家供大家參考,具體如下:
TextToSpeech簡稱 TTS,是自Android 1.6版本開始比較重要的新功能。將所指定的文本轉(zhuǎn)成不同語言音頻輸出。它可以方便的嵌入到游戲或者應用程序中,增強用戶體驗。
在講解TTS API和將這項功能應用到你的實際項目中的方法之前,先對這套TTS引擎有個初步的了解。
對TTS資源的大體了解:
TTS engine依托于當前Android Platform所支持的幾種主要的語言:English、French、German、Italian和Spanish五大語言(暫時沒有我們偉大的中文,至少google的 科學家們還沒有把中文玩到爐火純青的地步,先易后難也是理所當然。)TTS可以將文本隨意的轉(zhuǎn)換成以上任意五種語言的語音輸出。與此同時,對于個別的語言 版本將取決于不同的時區(qū),例如:對于English,在TTS中可以分別輸出美式和英式兩種不同的版本(由此看出Google的做事風格真夠細致,而正因 為如此估計Google不加入中文的另外一種理由是中文的方言太多了)。
能支持如此龐大的數(shù)據(jù)量,TTS 引擎對于資源的優(yōu)化采取預加載的方法。根據(jù)一系列的參數(shù)信息(參數(shù)的用法將在后邊有詳細的介紹)從庫中提取相應的資源,并加載到當前系統(tǒng)中。
盡管當前大部分加載有Android操作系統(tǒng)的設備都通過這套引擎來提供TTS功能,但由于一些設備的存儲空間非常有限而影響到TTS無法最大限度的發(fā) 揮功能,算是當前的一個瓶頸。為此,開發(fā)引入了檢測模塊,讓利用這項技術(shù)的應用程序或者游戲針對于不同的設備可以有相應的優(yōu)化調(diào)整,從而避免由于此項功能 的限制,影響到整個應用程序的使用。比較穩(wěn)妥的做法是讓用戶自行選擇是否有足夠的空間或者需求來加載此項資源,下邊給出一個標準的檢測方法:
Intent checkIntent = new Intent(); checkIntent.setAction(TextToSpeech.Engine.ACTION_C HECK_TTS_DATA); startActivityForResult(checkIntent, MY_DATA_CHECK_CODE);
如果當前系統(tǒng)允許創(chuàng)建一個 “android.speech.tts.TextToSpeech” 的彩虹簡譜字庫 下載Object, 說明已經(jīng)提供TTS功能的支持,將檢測返回結(jié)果中給出“ CHECK_VOICE_DATA_PASS ” 的標記。如果系統(tǒng)不支持這項功能,那么用戶可以選擇是否加載這項功能,從而讓設備支持輸出多國語言的語音功能“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都需要引用當前Activity的Context作為構(gòu)造參數(shù)。 OnInitListener()的用處是通知系統(tǒng)當前TTS Engine已經(jīng)加載完成,并處于可用狀態(tài)。
根據(jù)需求設置語言參數(shù):
早在Google I/O大會上,官方給出了一段關(guān)于應用這項功能的鮮活體驗,將翻譯結(jié)果直接通過五種不同國家語言的語音輸出。加載語言的方法非常簡單:
mTts.setLanguage(Locale.US);
上邊代碼表示當前TTS實體加載美式英語。其參數(shù)并沒有指示某種語言的名稱,而是利用國家代碼來表示,這樣做的好處是不但可以確定語言的選擇,而且可以 根據(jù)地區(qū)的不同而有所區(qū)別。例如:英語作為最廣泛被應用的語種,在多個不同的地區(qū)都有一定的差別。判斷當前系統(tǒng)是否支持某個地區(qū)的語言資源,可以通過調(diào)用 isLanguageAvailable()方法的返回值,根據(jù)返回值的描述來選擇正確的處理方式。讓應用某些絢麗功能的應用程序更加健壯,這個是貫穿整 個開發(fā)過程都要考慮的技術(shù)環(huán)節(jié)。下邊是一些應用實例 (androidres) :
mTts.isLanguageAvailable(Locale.UK)) mTts.isLanguageAvailable(Locale.FRANCE)) mTts.isLanguageAvailable(new Locale("spa", "ESP")))
如果返回值是“ TextToSpeech.LANG_COUNTRY_AVAILABLE ” 說明所選擇的地區(qū)被包含在當前TTS系統(tǒng)中。如果系統(tǒng)中已經(jīng)創(chuàng)建了TTS實體,那么可以利用isLanguageAvailable()方法來替代 Start “ACTION_CHECK_TTS_DATA ” intent 檢測。當無法找到任何可用資源匹配所指定的參數(shù)時,將會返回“ TextToSpeech.LANG_MISSING_DATA ”的結(jié)果。下邊給出另外兩個返回其它不同狀態(tài)信息的例子:
mTts.isLanguageAvailable(Locale.CANADA_FRENCH)) mTts.isLanguageAvailable(new Locale("spa"))
兩個語句的返回值均為“ TextToSpeech.LANG_AVAILABLE ” 。第一個是檢測當前系統(tǒng)是否支持加拿*****語,由于系統(tǒng)在資源庫中無法找到這個地區(qū)的法語分支,其含義是僅支持這項語言(法語),而不支持當前紫光 v4.0下載地區(qū)的語言分支。
另外,相比于上面強制用戶應用預定的語音設置,更加提倡利用Locale.getDefault() 方法根據(jù)用戶默認的地區(qū)設置來選擇合適的語言庫。
執(zhí)行Speak的具體方法:
根據(jù)上邊的介紹,基本實現(xiàn)了 TextToSpeech的初始化和參數(shù)配置。下面是一個有關(guān)鬧鐘的應用實例,利用Speak()方法可以直接在應用程序中發(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的工作原理:
每個獨立的應用程序都可以單獨創(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)先級和順序等。當引用 “TextToSpeech.QUEUE_FLUSH” 調(diào)用Speak()方法時,會中斷當前實例正在運行的任務(也可以理解為清除當前語音任務,轉(zhuǎn)而執(zhí)行新的列隊任務)。引用 “TextToSpeech.QUEUE_ADD”標簽的發(fā)音任務將被添加到當前任務列隊之后。
為語音任務關(guān)聯(lián)Stream Type:
在Android操作系統(tǒng)中所有的AudioStream任務都是通過AudioManager類來實現(xiàn),而它會針對不同的StreamType來改變語音的播放模式。StreamType可以理解為語音的播放屬性,這個屬性是用戶根據(jù)自己的需要在系統(tǒng)中配置的應用方案。如果將語音任務都 清楚的分門別類,可以方便的統(tǒng)一管理相同類別任務的屬性?;谏弦粋€Alarm Clock例子的基礎(chǔ)上,將Speak()方法的最后一個Null參數(shù)替換成具有實際含義的數(shù)值。這個參數(shù)的類型是HashMap,如果希望將當前的 Stream Type設置為系統(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);
應用語音功能的Completion Callback:
TTS中的Speak()的是異步調(diào)用,無論應用QUEUE_FLUSH 或者QUEUE_ADD作為參數(shù)都可以通過定義Listener監(jiān)聽當前任務的完成狀態(tài)??梢岳眠@個方法追加Speak()執(zhí)行之后的一些額外操作。下 接下來的例子中,當完成第二次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(); } }
“烘焙”當前實時的語音數(shù)據(jù):
看到烘焙兩個字,就會讓人聯(lián)想到香噴噴的面包。軟件開發(fā)要關(guān)注于是否可以最大限度的實現(xiàn)資源的復用,特別是針對資源有限的手機應用平臺。那么對于TTS 這么奢侈的應用如何才能更高效的使用資源呢?這次一起來體驗比烘焙面包更加讓人激動的功能,將TTS Engine輸出的Audio Stream作為永久的音頻文件保存在當前的存儲空間中(SDCard)。這樣可以對需要重復播放的某些語音內(nèi)容實現(xiàn)快速的回放功能,從而實現(xiàn)國際倡導的 “減排”目的,能省就省吧!在下邊的例子用通過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);
當完成以上操作之后會收到系統(tǒng)的完成通知,同時可以像其它音頻資源一樣,通過 android.media.MediaPlayer方法來播放。但這有悖于TextToSpeech的應用流程,可以將剛剛輸出的語音資源通過 addSpeech()的方法將其語音和文字描述一同存儲于TTS庫中。
mTts.addSpeech(wakeUpText, destFileName);
在當前的TTS Instance中,任何利用Speak()方法執(zhí)行相同內(nèi)容的調(diào)用都將復用剛剛所生成的音頻文件。如果資源丟失或者SDCard等存儲設備移除,那么系統(tǒng)將再次通過TTS Engine合成所指定的語音內(nèi)容。
mTts.speak(wakeUpText, TextToSpeech.QUEUE_ADD, myHashAlarm);
回收TTS:
當確定應用程序不再需要TTS的相關(guān)功能后,可以在Activity的OnDestroy()方法中調(diào)用shutDown()釋放當前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程序設計有所幫助。
相關(guān)文章
Flutter 重構(gòu)屬性透傳及函數(shù)透傳使用示例
這篇文章主要為大家介紹了Flutter 重構(gòu)屬性透傳及函數(shù)透傳使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-01-01android中實現(xiàn)在ImageView上隨意畫線涂鴉的方法
今天小編就為大家分享一篇android中實現(xiàn)在ImageView上隨意畫線涂鴉的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-10-10