為了方便調用暫停、繼續的方法。要將speech的功能寫成一個類。直接附上代碼:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Speech.Synthesis; 5 using System.Text; 6 using System.Speech; 7 8 namespace WindowsFormsApplication1 9 { 10 public class TextToSpeak 11 { 12 //想要實現暫停等功能,要調用朗讀時使用的SpeechSynthesizer對象 13 SpeechSynthesizer speech = new SpeechSynthesizer(); 14 15 /// <summary> 16 /// 朗讀 17 /// </summary> 18 /// <param name="text">文本</param> 19 /// <param name="rate">語速</param> 20 public void Speak(string text, int rate) 21 { 22 speech.Rate = rate; 23 speech.Speak(text); 24 speech.Dispose(); 25 } 26 27 /// <summary> 28 /// 朗讀 29 /// </summary> 30 /// <param name="text">文本</param> 31 /// <param name="rate">語速</param> 32 /// <param name="gender">性別</param> 33 public void Speak(string text, int rate, string gender) 34 { 35 36 speech.Rate = rate; 37 try 38 { 39 if (gender.ToLower() == "male") 40 { 41 speech.SelectVoice("VW Paul"); 42 } 43 else if (gender.ToLower() == "female") 44 { 45 speech.SelectVoice("VW Kate"); 46 } 47 48 } 49 //這個異常是語音庫未安裝 50 catch (ArgumentException) 51 { 52 53 throw; 54 } 55 finally 56 { 57 speech.Speak(text); 58 speech.Dispose(); 59 } 60 } 61 62 /// <summary> 63 /// 保存音頻文件 64 /// </summary> 65 /// <param name="path">路徑</param> 66 /// <param name="text">文本</param> 67 /// <param name="rate">語速</param> 68 /// <param name="gender">性別,可為null</param> 69 public void SaveWaveFile(string path, string text, int rate, string gender) 70 { 71 speech.Rate = rate; 72 try 73 { 74 if (gender.ToLower() == "male") 75 { 76 speech.SelectVoice("VW Paul"); 77 } 78 else if (gender.ToLower() == "female") 79 { 80 speech.SelectVoice("VW Kate"); 81 } 82 83 } 84 catch (ArgumentException) 85 { 86 87 throw; 88 } 89 finally 90 { 91 speech.SetOutputToWaveFile(path); 92 speech.Speak(text); 93 speech.SetOutputToNull(); 94 } 95 } 96 97 public void SpeakPause() 98 { 99 speech.Pause(); 100 } 101 102 public void SpeakResume() 103 { 104 speech.Resume(); 105 } 106 107 public void SpeakStop() 108 { 109 speech.Dispose(); 110 } 111 } 112 }
我使用的是winfrom實現這個類的。一開始想都沒想直接給按鈕加上click事件,調用TextToSpeak類的Speak方法,給另一個按鈕添加SpeakPause功能。運行時復制了好幾段英文,發現窗體出現假死,但是依然有聲音輸出,這叫我怎麼暫停嘛,有點小凌亂。想想這情況應該類似於多線程,不要笑話我,winfrom沒怎麼弄過,之前一直搞的時asp.net。在網上搜了下進度條的實現方法,最後定下來使用backgroundWorker,不因為別的,就是看著別人寫的比較方便~~~
簡單介紹下backgroundWorker吧。它就在工具欄裡躺著。它有好幾個方法。
1. 這個就是後台運行的進程 backgroundWorker1_DoWork(objectsender,DoWorkeventArgs e)。在這裡就放extToSpeak類的Speak方法。它用backgroundWorker1.RunWokerAsync(參數,可不加)來調用。所以就把這個方法放到播放按鈕的click事件裡咯。
2.backgroundWorker1_ProgressChanged這個是運行時可以執行的方法。用backgroundWorker1.ReportProgress(int)調用。
3.backgroundWorker1_RunWorkerCompleted這個是進程結束時執行的。
具體的請看:http://www.cnblogs.com/inforasc/archive/2009/10/12/1582110.html
我是直接在winfrom裡放了個richtextbox,用來寫入要讀的英文。一開始我想當然在backgroundWorker1_DoWork(objectsender,DoWorkeventArgs e)裡的speak中,直接把richtextbox.text的值傳進去,但運行時沒有一點反應。一開始不懂哪錯了,一點一點的試。後台代碼不好調哇,又不能直接調試到代碼,只能用個提示語句來幫忙了。最後才發現是卡在richtextbox.text,它讀取不到這個值。好像是啥原因的~~~但為啥我那個語速的插件值能讀到呢,就因為它是int型麼。。那怎麼辦呢,只能在click事件裡調用時傳參啦。我有兩個參數,一個是text一個是性別,那就string數組了。
上代碼:
1 _ttSpeak = new TextToSpeak(); 2 string[] parameter = { richTextBox1.Text, cbbsex.Text }; 3 backgroundWorker1.RunWorkerAsync(parameter);
細心的小伙伴應該發現了_ttSpeak = new TextToSpeak(),這個實例化語句怪怪的。其實和TextToSpeak類似,都是把實例化的類對象聲明為成員變量。為啥這裡要重新實例化呢,一開始我也沒注意。運行程序時,第二次點朗讀按鈕時沒反應了。原來是第一次運行時已經把Synthesis的資源釋放了。所以要重新實例化一個,即重寫成員變量。
之後想要使用暫停、繼續功能就很方便了。
1 _ttSpeak.SpeakPause();
_ttSpeak.SpeakResume();
還有個注意點,在執行朗讀功能是要把朗讀按鈕禁用,否則在執行時再click就會報錯哦,等運行結束後再啟用。
就是把啟用的方法寫在backgroundWorker1_RunWorkerCompleted裡就行啦~~~