SpeechLib 語音播報


    SpeechLib這的dll專門用來播放語音,能夠識別英語、簡體和繁體。並且可以播放聲音文件,支持WAV格式,但不支持MP3。在報警場合下已經夠用了。

   基本播放語音及文件。支持異步。

using System;
using System.Threading;
using SpeechLib;

namespace  Model.AlarmHandle
{
   
    /// <summary>
    ///語音播報
    /// </summary>
    public class SpeechVoice
    {
        /// <summary>
        /// The _voice
        /// </summary>
        private SpVoice _voice;
        private SpVoiceClass spVoice;
        private readonly SpFileStreamClass spFile;



        /// <summary>
        /// Initializes a new instance of the <see cref="SpeechVoice"/> class.
        /// </summary>
        public SpeechVoice()
        {
            _voice = new SpVoice();
            spVoice = new SpVoiceClass();
            spFile = new SpFileStreamClass();
        }



        /// <summary>
        /// 播放
        /// </summary>
        /// <param name="text">The text.</param>
        /// <param name="speakFlag">The speak flag.</param>
        public void Speak(string text, SpeechVoiceSpeakFlags speakFlag = SpeechVoiceSpeakFlags.SVSFDefault)
        {
            _voice.Speak(string.Empty); _voice.Speak(text, speakFlag);
        }


        /// <summary>
        /// 異步播放
        /// </summary>
        /// <param name="text">The text.</param>
        public void SpeakAsync(string text)
        {
            _voice.Speak(text, SpeechVoiceSpeakFlags.SVSFlagsAsync);
        }

        /// <summary>
        /// Plays the sound.
        /// </summary>
        /// <param name="fileName">Name of the file.</param>
        public void PlaySound(string fileName)
        {
            //要加載COM組件:Microsoft speech object Library
            if (!System.IO.File.Exists(fileName)) return;
            spFile.Open(fileName, SpeechStreamFileMode.SSFMOpenForRead, true);
            var istream = spFile as ISpeechBaseStream;
            spVoice.SpeakStream(istream, SpeechVoiceSpeakFlags.SVSFIsFilename);
            spFile.Close();
        }

        /// <summary>
        /// 暫停
        /// </summary>
        public void Pause()
        {
            if (_voice != null)
                _voice.Pause();
        }

        /// <summary>
        /// Stops the voice.
        /// </summary>
        public void StopVoice()
        {
            _voice.Pause(); 
            _voice.Speak(string.Empty, SpeechVoiceSpeakFlags.SVSFPurgeBeforeSpeak);
        }

        /// <summary>
        /// Pauses the file. 
        /// </summary>
        public void StopFile()
        {
            try
            {
                spFile.ISpStream_Close();
            }
            catch (Exception)
            {
            }
        }

        /// <summary>
        /// 恢復
        /// </summary>
        public void Resume()
        {
            if (_voice != null)
                _voice.Resume();
        }


    }
    /// <summary>
    ///語音播報狀態
    /// </summary>
    public enum VoiceStatus
    {
        /// <summary>
        /// The play
        /// </summary>
        Play,
        /// <summary>
        /// The ready
        /// </summary>
        Ready,
        /// <summary>
        /// The pause
        /// </summary>
        Pause,
    }

}
View Code

   但真的運用時,還需要支持循環播放,以及播放狀態。

   

   private SpeechVoice _speaker;
   private bool _isLoopAudioFile; // 是否循環播放聲音文件
   private bool _isLoopSpeech;  //循環語音
  private VoiceStatus speakStatus=VoiceStatus.Ready;
  private bool IsStopPlayFile;    //是否停止
 private bool IsStopPlayVoice;

     /// <summary>
        /// 播放文件結束
        /// </summary>
        public event EventHandler PlayFileComplete;
        /// <summary>
        /// 播放文件開始
        /// </summary>
        public event EventHandler PlayFileStart;

        /// <summary>
        /// 播放文件結束
        /// </summary>
        public event EventHandler PlayAudioComplete;
        /// <summary>
        /// 播放文件開始
        /// </summary>
        public event EventHandler PlayAudioStart;

  /// <summary>
        /// 播放語言
        /// </summary>
        /// <param name="voiceContent">Content of the voice.</param>
        public void SpeechVoice(string voiceContent)
        {
            IsStopPlayVoice = false;
            if (speakStatus == VoiceStatus.Play) return; //正在播放就返回
            Speaker.Resume();
            Action invoke = () =>
            {
                OnPlayAudioStart();//觸發開始播放事件 
                speakStatus = VoiceStatus.Play;
                Speaker.Speak(voiceContent);
            };
            invoke.BeginInvoke(VoiceCallback, invoke);
        }
  private void VoiceCallback(IAsyncResult ar)
        {
            var ac = ar.AsyncState as Action;
            if (ac != null)
            {
                try//原dll不能多次停止 所以加了try catch 和狀態判斷
                {
                    if ((IsLoopSpeech) && !IsStopPlayVoice)
                    {
                        //一次播放結束之后如果是循環播放 就繼續播放
                        ac.BeginInvoke(VoiceCallback, ac);
                    }
                    else
                    {
                        speakStatus = VoiceStatus.Pause;
                        //觸發停止事件
                        OnPlayAudioComplete(this, new EventArgs());
                        ac.EndInvoke(ar);
                    }
                }
                catch (Exception)
                {

                }
            }
        }

//以下同理
  /// <summary>
        /// 暫停播放
        /// </summary>
        public void StopSpeechVoice()
        {
            if (IsStopPlayVoice) return;
            IsStopPlayVoice = true;
            speakStatus = VoiceStatus.Pause;
            Action invoke = () => Speaker.StopVoice();
            invoke.BeginInvoke(null, invoke);
            OnPlayAudioComplete(this, new EventArgs());
        }
        /// <summary>
        /// 停止播放聲音文件
        /// </summary>
        public void StopPlayer()
        {
            if (IsStopPlayVoice) return;
            IsStopPlayFile = true;
            speakStatus = VoiceStatus.Pause;
            Speaker.PauseFile();
            OnPlayFileComplete(this, new EventArgs());
        }

        /// <summary>
        /// 播放聲音文件
        /// </summary>
        public void PlayAudioFile()
        {
            player = new SoundPlayer { SoundLocation = _audioFile.FilePath };
            if(speakStatus==VoiceStatus.Play) return;
            IsStopPlayFile = false;
            if (File.Exists(_audioFile.FilePath))
            {
                Action invoke = () =>
                {
                    OnPlayFileStart();
                    speakStatus = VoiceStatus.Play;
                    Speaker.PlaySound(_audioFile.FilePath);
                };
                invoke.BeginInvoke(Callback, invoke);
            }
        }
  
       /// <summary>
        /// Called when [play start].
        /// </summary>
        public void OnPlayFileStart()
        {
            var handler = PlayFileStart;
            if (handler != null) handler(this, EventArgs.Empty);
        }

        /// <summary>
        /// Called when [play start].
        /// </summary>
        public void OnPlayAudioStart()
        {
            var handler = PlayAudioStart;
            if (handler != null) handler(this, EventArgs.Empty);
        }

        /// <summary>
        /// Called when [play complete].
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
        public void OnPlayAudioComplete(object sender, EventArgs e)
        {
            EventHandler handler = PlayAudioComplete;
            if (handler != null) handler(this, EventArgs.Empty);
        }


        /// <summary>
        /// Called when [play complete].
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
        public void OnPlayFileComplete (object sender, EventArgs e)
        {
            EventHandler handler = PlayFileComplete;
            if (handler != null) handler(this, EventArgs.Empty);
        }

             /// <summary>
        /// Callbacks the specified ar.
        /// </summary>
        /// <param name="ar">The ar.</param>
        private void Callback(IAsyncResult ar)
        {
            var ac = ar.AsyncState as Action;
            if (ac != null)
            {
                OnPlayFileComplete(this,new EventArgs());
                try
                {
                    if ((IsLoopAudioFile)&& !IsStopPlayFile)
                    {
                        ac.BeginInvoke(Callback, ac);
                    }
                    else
                    {
                        speakStatus = VoiceStatus.Pause; 
                        ac.EndInvoke(ar);
                    }
                }
                catch (Exception)
                {
                  
                }
            }
        }

語音播放小Demo:SpeechVoice  

在繁體系統,或者英文系統下面,有時候出現只能播報英文的情況,這個是猶豫語言資源沒有安裝。

判斷操作系統是否安裝中文最簡單的方法:

64位系統:查看C:\Program Files (x86)\Common Files\SpeechEngines\Microsoft\TTS20路徑下是否有zh-CHS文件夾

32位系統:查看C:\Program Files\Common Files\SpeechEngines\Microsoft\TTS20路徑下是否有zh-CHS文件夾

 

如果不存在則表明缺少中文語言包,一般情況下,win7及以上的中文操作系統都自帶了,不需要安裝,其他操作系統基本上都沒有安裝,簡體XP系統也沒有安裝

安裝方法是:

1、  打開控制面板的window update,見下圖:

2. 選擇檢查更新按鈕,然后再更新列表中選擇“可用的附件程序”

3、   選擇簡體中文語言包,勾選並安裝即可

 

4、  安裝完成后可以檢查C:\Program Files (x86)\Common Files\SpeechEngines\Microsoft\TTS20路徑下是否有zh-CHS文件夾,有則表明安裝成功

 

安裝成功以后就可以使用語音播報功能了。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM