zoukankan      html  css  js  c++  java
  • System.Speech.Synthesis 添加暂停、继续功能

    为了方便调用暂停、继续的方法。要将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 }

         我使用的是WinForm实现这个类的。一开始想都没想直接给按钮加上click事件,调用TextToSpeak类的Speak方法,给另一个按钮添加SpeakPause功能。运行时复制了好几段英文,发现窗体出现假死,但是依然有声音输出,这叫我怎么暂停嘛,有点小凌乱。想想这情况应该类似于多线程,不要笑话我,WinForm没怎么弄过,之前一直搞的时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

       我是直接在WinForm里放了个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里就行啦~~~

  • 相关阅读:
    Spring标签@Aspect-实现面向方向编程(@Aspect的多数据源自动加载)——SKY
    easyUI参数传递Long型时,前台解析出错的问题——SKY
    javax.servlet.ServletException: Could not resolve view with name‘ XXXX’in servlet with name 'spring'的解决方案-----SKY
    Netty实现java多线程Post请求解析(Map参数类型)—SKY
    java并发编程基础---Sky
    创建100个1k的随机文件到FSxL
    RAID磁盘阵列与LVM逻辑卷管理
    The beginners’ guide to farming Chia Coin on Windows.
    有赞移动Crash平台建设
    Comparisons Serverless
  • 原文地址:https://www.cnblogs.com/WMTcore/p/3831767.html
Copyright © 2011-2022 走看看