一. ? 簡單介紹
在上一篇里
http://blog.csdn.net/ichliebephone/archive/2010/08/13/5810370.aspx
我們介紹了TTS提供的接口 ? OnUtteranceCompletedListener ? 的使用,這個接口的作用是監聽語音片段的朗讀,并在語音片段朗讀結束后調用其定義的回調函數,在回調函數里可以進行需要的操作。
在這一篇里我們介紹一下TTS提供的另一個有用的功能,把合成的語音以音頻文件的形式保存在系統里,然后就可以直接用播放音頻文件的方式來播放。
這個功能調用的函數為:
public?int? ? synthesizeToFile ? ( ? String ? ?text,? ? HashMap ? < ? String ? ,? ? String ? >?params,? String ? ?filename)
第一個參數為要進行語音合成的文本;第二個參數我們在上一個Demo中有所介紹,是一個鍵值對形式的HashMap類型變量,可以設置語音片段的ID等;第三個參數為保存到系統中的文件名。
當你想和朋友分享一份精彩的文本合成語音后的效果時,你可以使用這個功能把它保存為音頻文件發送給朋友,這樣即使朋友的手機不具備TTS功能,也可以用播放音頻的方式分享到;當你要對同一段較長的文本多次進行語音合成時,你可以把這段文本的語音保存為音頻文件,然后使用時播放,這樣會更省資源,運行速度更快,因為使用TTS是比較費資源的一個過程。因此我們會在某些場合用到這個功能。
下面我們就用這個功能完成一個Demo例子,當你害羞當面向她表白你對她的喜歡時,讓Android幫你語音合成你想說的話,然后你就可以向她發送保存了對她喜歡的這個音頻文件。
二. ? 實例開發
?
我們希望做的效果如下:
?
圖 1? 實現效果圖
?
第一個文本框里可以輸入需要語音合成的文本,第二個文本框里輸入要保存成的音頻文件的文件名,點擊第一個 Speak ?按鈕你可以預聽一下 TTS ?語音合成的效果,點擊第二個 Record ?按鈕,就會以音頻文件的形式保存,然后就可以點擊第三個 Play ?按鈕播放保存的這個音頻文件。
創建一個 Android ?工程,工程名為 AndroidTTSDemoFourth ?,其中 SDK ?版本需選擇 1.6 ?及以上。
其中 Main.xml ?文件很簡單,如下所示:
?
- <? xml ? version = "1.0" ? encoding = "utf-8" ?> ??
- < LinearLayout ? xmlns:android = "http://schemas.android.com/apk/res/android" ??
- ???? android:orientation = "vertical" ??
- ???? android:layout_width = "fill_parent" ??
- ???? android:layout_height = "fill_parent" ??
- ???? > ??
- ???? < EditText ? android:id = "@+id/inputText" ???
- ???????????????? android:hint = "Input?the?text?here!" ???
- ???????????????? android:layout_width = "fill_parent" ???
- ???????????????? android:layout_height = "wrap_content" > ??
- ???????????????? </ EditText > ??
- ???? < Button ? android:text = "Speak" ???
- ???????????????? android:id = "@+id/speakBtn" ???
- ???????????????? android:layout_width = "wrap_content" ???
- ???????????????? android:layout_height = "wrap_content" ??
- ???????????????? android:layout_gravity = "center_horizontal" ??
- ???????????????? android:enabled = "false" ??
- ???????????????? > </ Button > ??
- ???? < TextView ? android:id = "@+id/filenameLabel" ??
- ???????????????? android:text = "Save?as:" ??
- ???????????????? android:layout_width = "fill_parent" ???
- ???????????????? android:layout_height = "wrap_content" ??????????????????
- ???????????????? > </ TextView > ?????
- ???? < EditText ? android:id = "@+id/filenameText" ??
- ???????????????? android:hint = "Input?the?saving?file?name?here!" ??
- ???????????????? android:layout_width = "fill_parent" ???
- ???????????????? android:layout_height = "wrap_content" > ??????????????????
- ???????????????? > </ EditText > ??
- ???? < LinearLayout ? xmlns:android = "http://schemas.android.com/apk/res/android" ??
- ???????????????????? android:orientation = "horizontal" ??
- ???????????????????? android:layout_width = "fill_parent" ??
- ???????????????????? android:layout_height = "fill_parent" ??
- ???????????????????? android:gravity = "center_horizontal" ??
- ???????????????????? > ??
- ???????? < Button ? android:id = "@+id/recordBtn" ??
- ???????????????????? android:text = "Record" ??
- ???????????????????? android:layout_width = "wrap_content" ???
- ???????????????????? android:layout_height = "wrap_content" ??
- ???????????????????? > </ Button > ??
- ???????? < Button ? android:id = "@+id/playBtn" ??
- ???????????????????? android:text = "Play" ??
- ???????????????????? android:layout_width = "wrap_content" ???
- ???????????????????? android:layout_height = "wrap_content" ??
- ???????????????????? android:enabled = "false" ??
- ???????????????????? > </ Button > ??
- ???? </ LinearLayout > ?????????????????????????????
- </ LinearLayout > ??
?
?
Java ? 文件的編寫:
有了前面這些 Demo ?的實例開發,這個 Demo ?實現起來就比較簡單了,程序的代碼如下所示:
?
- public ? class ?AndroidTTSDemoFourth? extends ?Activity? implements ?OnInitListener{??
- ???? //實現初始接口 ??
- ???? /**?Called?when?the?activity?is?first?created.?*/ ??
- ???? //定義變量 ??
- ???? private ?EditText?inputText?=? null ;??
- ???? private ?Button?speakBtn?=? null ;??
- ???? private ?EditText?filenameText?=? null ;??
- ???? private ?Button?recordBtn?=? null ;??
- ???? private ?Button?playBtn?=? null ;??
- ???? private ?TextToSpeech?mTts;??
- ???? private ? static ? final ?String?TAG?=? "TTS?Demo" ;??
- ???? private ? static ? final ?String?loveConfession?=? "jia?jia,?I?love?you.?" ;??
- ???? private ?String?loveFileName?=? null ;??
- ???? private ?File?loveFile?=? null ;??
- ???? private ?MediaPlayer?player?=? null ;??
- ??????
- ???? @Override ??
- ???? public ? void ?onCreate(Bundle?savedInstanceState)?{??
- ???????? super .onCreate(savedInstanceState);??
- ????????setContentView(R.layout.main);??
- ???????? //創建TextToSpeech實例,初始化完成后會調用OnInitListener(第二個參數)的回調函數 ??
- ????????mTts?=? new ?TextToSpeech( this ,??
- ???????????????? this ?? //?TextToSpeech.OnInitListener ??
- ????????????????);??
- ???????? //設置控件 ??
- ????????inputText?=?(EditText)findViewById(R.id.inputText);??
- ????????speakBtn?=?(Button)findViewById(R.id.speakBtn);??
- ????????filenameText?=?(EditText)findViewById(R.id.filenameText);??
- ????????recordBtn?=?(Button)findViewById(R.id.recordBtn);??
- ????????playBtn?=?(Button)findViewById(R.id.playBtn);??
- ????????????????
- ????????inputText.setText(loveConfession);????
- ????????filenameText.setText( "/sdcard/love.wav" );??
- ????????speakBtn.setOnClickListener( new ?OnClickListener()?{???????
- ???????????? public ? void ?onClick(View?v)?{??
- ???????????????? //?TODO?Auto-generated?method?stub ??
- ???????????????? //朗讀輸入框里的內容 ??
- ????????????????mTts.speak(inputText.getText().toString(),?TextToSpeech.QUEUE_ADD,? null );??
- ????????????}??
- ????????});??
- ????????recordBtn.setOnClickListener( new ?OnClickListener()?{??????????????
- ???????????? @Override ??
- ???????????? public ? void ?onClick(View?v)?{??
- ???????????????? //?TODO?Auto-generated?method?stub ??
- ???????????????? //把TTS語音合成的結果保存為音頻文件 ??
- ????????????????loveFileName?=?filenameText.getText().toString();??
- ????????????????loveFile?=? new ?File(loveFileName);??
- ???????????????? if (loveFile.exists())??
- ????????????????{??
- ????????????????????loveFile.delete();??
- ????????????????}??
- ???????????????? //把語音合成的結果保存到文件中 ??
- ???????????????? if (TextToSpeech.SUCCESS?==?mTts.synthesizeToFile(inputText.getText().toString(),? null ,?loveFileName))??
- ????????????????{??
- ????????????????????Toast.makeText(getBaseContext(),? "sound?file?created!" ,?Toast.LENGTH_SHORT).show();??
- ????????????????????playBtn.setEnabled( true );??
- ????????????????}??
- ???????????????? else ??
- ????????????????{??
- ????????????????????Toast.makeText(getBaseContext(),? "failed?to?create?sound?file!" ,?Toast.LENGTH_SHORT).show();??
- ????????????????}??
- ????????????}??
- ????????});??
- ????????playBtn.setOnClickListener( new ?OnClickListener()?{????????????
- ???????????? @Override ??
- ???????????? public ? void ?onClick(View?v)?{??
- ???????????????? //?TODO?Auto-generated?method?stub ??
- ???????????????? //播放保存著的音頻文件 ??
- ???????????????? try ??
- ????????????????{??
- ????????????????????player?=? new ?MediaPlayer();??
- ????????????????????player.setDataSource(loveFileName);??
- ????????????????????player.prepare();??
- ????????????????????player.start();??
- ????????????????}??
- ???????????????? catch ?(Exception?e)?{??
- ???????????????????? //?TODO:?handle?exception ??
- ????????????????????Toast.makeText(getBaseContext(),? "failed?to?play?sound?file!" ,?Toast.LENGTH_SHORT).show();??
- ????????????????????e.printStackTrace();??
- ????????????????}??
- ????????????}??
- ????????});??
- ????}??
- ??????
- ???? public ? void ?onInit( int ?status)?{??
- ???????? //?TODO?Auto-generated?method?stub ??
- ???????? //TTS?Engine初始化完成 ??
- ???????? if (status?==?TextToSpeech.SUCCESS)??
- ????????{??
- ???????????? int ?result?=?mTts.setLanguage(Locale.US);??
- ???????????? //設置發音語言 ??
- ???????????? if (result?==?TextToSpeech.LANG_MISSING_DATA?||?result?==?TextToSpeech.LANG_NOT_SUPPORTED)??
- ???????????? //判斷語言是否可用 ??
- ????????????{??
- ????????????????Log.v(TAG,? "Language?is?not?available" );??
- ????????????????speakBtn.setEnabled( false );??
- ????????????}??
- ???????????? else ??
- ????????????{??
- ????????????????speakBtn.setEnabled( true );??
- ????????????}??
- ????????}??
- ????}??
- ??????
- ???? @Override ??
- ???? protected ? void ?onDestroy()?{??
- ???????? //?TODO?Auto-generated?method?stub ??
- ???????? //釋放TTS的資源 ??
- ???????? if (mTts?!=? null )??
- ????????{??
- ????????????mTts.stop();??
- ????????????mTts.shutdown();??
- ????????}?????
- ???????? super .onDestroy();??
- ????}??
- }??
?
?
和 TTS ?相關的新的部分為 recordBtn ?的 onClick ?事件的處理,先根據指定的文件名創建一個 File ?變量,來判斷文件是否已經存在,如果已存在就先刪除。然后調用函數
mTts ? .synthesizeToFile( ? inputText ? .getText().toString(),? null ? ,? loveFileName ? )
把文本框中的內容語音合成后保存到文件中。
另一個 playBtn ?的 onClick ?事件的處理,主要就是創建一個 MediaPlayer ?實例,播放上一步保存的音頻文件。
?
至此,這個 Demo ?就完成了,但是在運行前,需創建一個帶 SD ?卡的 AVD ?,因為要往 SD ?卡上保存文件,如下所示:
圖 2? 必須創建帶 SD ?卡的 AVD
?
同時還需在 AndroidManifest.xml ?文件中添加寫外部存儲設備的權限:
< ? uses-permission ? android:name ? = ? "android.permission.WRITE_EXTERNAL_STORAGE" ? ></ uses-permission ? >
接著就可以運行這個 Demo ?了,運行程序后在 Eclipse ?中切換到 DDMS ?視圖,接著選擇查看 File Explorer ?,我們看到在沒有點擊程序的 Record ?按鈕進行語音合成到文件保存時, sdcard ?目錄下沒有額外的文件,如下圖所示:
?
圖 3? 原始的 SD ?卡目錄
?
?
然后我們在程序中點擊 Record ?按鈕,讓 TTS ?把語音合成到文件,合成成功的話會彈出“ sound file created! ?”的提示,并且 Play ?按鈕變成可用。點擊 Play ?按鈕就會播放剛剛保存的音頻文件,和點擊第一個的 Speak ?按鈕朗讀的內容是一樣的。這時,我們再來查看下 SD ?卡的目錄,會發現多了一個文件: love.wav ?,正是我們設定保存的文件名,如下圖所示:
?
圖 4? 語音合成到文件后的 SD ?卡目錄
?
?
并且,我們還可以使用 adb pull ?命令把這個文件從 SD ?卡上提取出來,在 CMD ?窗口中運行 adb pull ./sdcard/love.wav? 就可以把 SD ?卡上的這個音頻文件保存的當前目錄下,如下圖所示:
?
圖 5? 提取 SD ?卡上保存的音頻文件
最后,也可以在電腦上播放記錄了你對她的喜歡的這個音頻文件了,或者也可以把這個文件發送給你喜歡的她。
?
注:文章參加“ ?首屆Google暑期大學生博客分享大賽——2010 Andriod篇 ”
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
