Windows服务中的语音识别引擎未触发事件

问题描述 投票:8回答:4

因此,我有一个使用system.speech识别引擎实现的带有语音识别的Windows服务。启动服务时,我的语音识别代码运行良好,但是没有语音识别事件触发。奇怪的是,如果我运行完全相同的代码,但是在控制台或WPF应用程序中,用于语音识别的事件触发效果很好。我已经在服务过程中附加了调试器,以检查幕后情况。似乎语音识别引擎正确加载了语法,将其模式设置为连续收听,并正确设置了语音识别事件。没有异常被抛出,所以我不太确定这里出了什么问题。有什么想法吗?

c# windows-services speech-recognition
4个回答
2
投票

您是否正在使用麦克风或正在处理WAV文件?如果您尝试使用默认音频设备,我不确定音频管道将如何在服务中工作。如果尝试从音频文件或流转换,请确保使用的是InProc识别器。

[如果要创建服务器应用程序,则可能应该考虑使用Microsoft.Speech API和服务器重新生成器。请参阅What is the difference between System.Speech.Recognition and Microsoft.Speech.Recognition?和Microsoft Speech Platform SDK-[C​​0]

[如果您尝试在不将应用程序放在前台的情况下进行连续识别,那么我相信共享识别器可能能够满足您的需求。 Windows 7和Vista中附带的Microsoft桌面识别器可以在两种模式下工作:inproc或共享。共享识别器在使用语音命令控制任何打开的应用程序的桌面上非常有用。在System.Speech中,您可以使用http://www.microsoft.com/en-us/download/details.aspx?id=27226访问共享桌面识别器,或使用SpeechRecognizer为您的应用程序使用专用的inproc识别器。即使您的应用程序不在前台,您也可以使用共享识别器为应用程序提供连续的识别。

[几年前在SpeechRecognitionEngine发表了一篇非常好的文章。这可能是我到目前为止找到的最好的入门文章。它说:

...识别引擎可以在另一个称为SAPISVR.EXE。这提供了一个共享的识别引擎,可以由多个应用程序同时使用。这个设计有一些的好处。首先,识别器通常需要更多运行时资源而不是合成器,并且共享识别器是减少开销的有效方法。其次,共享识别器是Windows Vista的内置语音功能也使用了该功能。因此,使用共享识别器的应用程序可以从系统的麦克风和反馈UI。没有其他代码可以编写,没有新的UI供用户学习。SAPI5.3的新功能]


4
投票

SpeechRecognition应该在单独的线程上运行,并且从SpeechRecognitionEngine到OOTB,应该是这样的:

http://msdn.microsoft.com/en-us/magazine/cc163663.aspx

当我使用SpeechRecognition而不是SpeechRecognitionEngine时,也有类似的问题。上面是用法及其侦听另一个线程中的事件的一个很好的示例。附:我从一篇很棒的文章中得到了参考:static ManualResetEvent _completed = null; static void Main(string[] args) { _completed = new ManualResetEvent(false); SpeechRecognitionEngine _recognizer = new SpeechRecognitionEngine(); _recognizer.RequestRecognizerUpdate(); // request for recognizer update _recognizer.LoadGrammar(new Grammar(new GrammarBuilder("test")) Name = { "testGrammar" }); // load a grammar _recognizer.RequestRecognizerUpdate(); // request for recognizer update _recognizer.LoadGrammar(new Grammar(new GrammarBuilder("exit")) Name = { "exitGrammar" }); // load a "exit" grammar _recognizer.SpeechRecognized += _recognizer_SpeechRecognized; _recognizer.SetInputToDefaultAudioDevice(); // set the input of the speech recognizer to the default audio device _recognizer.RecognizeAsync(RecognizeMode.Multiple); // recognize speech asynchronous _completed.WaitOne(); // wait until speech recognition is completed _recognizer.Dispose(); // dispose the speech recognition engine } void _recognizer_SpeechRecognized(object sender, SpeechRecognizedEventArgs e) { if (e.Result.Text == "test") // e.Result.Text contains the recognized text { Console.WriteLine("The test was successful!"); } else if (e.Result.Text == "exit") { _completed.Set(); } } 有好玩:)


1
投票

您是否尝试过将服务设置为允许与桌面交互?

“

我相信此设置涵盖了与用户接口设备(如麦克风)的交互。


0
投票

如果@Robocide答案对您不起作用,就像我的情况,您要做的就是将SpeechRecognitionEngine声明为字段,而不是Main方法中的局部变量。

示例:

Speech recognition, speech to text, text to speech, and speech synthesis in C#

如果您注意到,我删除了ManualResetEvent,因为它在无法识别语音的情况下不允许某些进程运行。

© www.soinside.com 2019 - 2024. All rights reserved.