如何从语音识别中提取变量?基于System.Speech实现带时长的定时命令
实现带变量的语音定时器命令(System.Speech)
当然可行!这正是System.Speech组件里Grammar类的核心能力之一——帮你创建带变量的语音命令,轻松提取你需要的时长参数。作为新手也不用担心,跟着下面的步骤来就能搞定~
核心思路
我们需要用GrammarBuilder构建包含数字变量的语音规则,给这个变量命名(比如seconds),这样当识别到命令时,就能从识别结果里直接提取出这个变量的值,再用它来设置定时器。
完整代码示例
我把你的初始化代码和扩展逻辑整合到了一起,直接就能运行测试:
using System; using System.Linq; using System.Speech.Recognition; using System.Speech.Synthesis; using System.Timers; class TimerVoiceControl { static SpeechRecognitionEngine _recognizer; static SpeechSynthesizer _speaker = new SpeechSynthesizer(); static void Main() { // 你的现有初始化代码,在此基础上扩展 _recognizer = new SpeechRecognitionEngine(); _recognizer.SetInputToDefaultAudioDevice(); // 构建带变量的语音语法 var timerGrammarBuilder = new GrammarBuilder(); timerGrammarBuilder.Append("Set timer for"); // 添加数字变量,命名为"seconds",方便后续提取 timerGrammarBuilder.Append(new GrammarBuilder(new Choices(GetNumberOptions())), "seconds"); timerGrammarBuilder.Append("seconds"); // 加载语法到识别引擎 var timerGrammar = new Grammar(timerGrammarBuilder); _recognizer.LoadGrammar(timerGrammar); // 订阅识别完成事件,处理命令 _recognizer.SpeechRecognized += OnTimerCommandRecognized; // 开始持续识别 _recognizer.RecognizeAsync(RecognizeMode.Multiple); _speaker.Speak("Ready! Say 'Set timer for X seconds' to start a timer."); Console.WriteLine("Press any key to exit..."); Console.ReadKey(); _recognizer.RecognizeAsyncStop(); } // 生成可选的数字范围(这里是1-60秒,你可以按需扩展) static string[] GetNumberOptions() { return Enumerable.Range(1, 60).Select(num => num.ToString()).ToArray(); } // 识别事件处理:提取秒数并启动定时器 static void OnTimerCommandRecognized(object sender, SpeechRecognizedEventArgs e) { // 检查是否匹配我们的定时器命令 if (e.Result.Semantics.TryGetValue("seconds", out var semanticValue)) { // 把提取到的变量转换成整数 if (int.TryParse(semanticValue.Value.ToString(), out int seconds)) { _speaker.Speak($"Got it! Setting timer for {seconds} seconds."); StartCountdownTimer(seconds); } else { _speaker.Speak("Sorry, I didn't catch that number."); } } } // 简单的倒计时定时器实现 static void StartCountdownTimer(int seconds) { var timer = new Timer(seconds * 1000); timer.AutoReset = false; timer.Elapsed += (_, __) => { _speaker.Speak("Time's up!"); timer.Dispose(); }; timer.Start(); } }
关键部分解释
- 带变量的语法构建:用
Append(..., "seconds")给数字部分加上名称,这样识别后就能通过e.Result.Semantics["seconds"]直接拿到这个变量值,不用自己去拆分字符串。 - 数字选项生成:
GetNumberOptions生成了1到60的数字字符串,你可以改成更大的范围(比如1-300),或者支持英文数字(比如"ten"、"twenty")——只要把数组内容换成对应的单词就行。 - 识别事件处理:在
SpeechRecognized事件里,我们先判断是否匹配定时器命令,再提取变量转换成整数,最后启动定时器。
新手注意事项
- 确保你的项目引用了
System.Speech程序集:右键项目 → 添加引用 → 框架 → 找到并勾选System.Speech。 - 测试时尽量在安静的环境下发音,清晰说出命令,能提高识别准确率。
- 如果需要支持更复杂的数字表达(比如"thirty five"),可以用
Choices组合单词,或者直接用new GrammarBuilder(typeof(Number))来支持系统预定义的数字识别规则。
内容的提问来源于stack exchange,提问作者user4189129
相关产品推荐
相关产品推荐

