You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从语音识别中提取变量?基于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事件里,我们先判断是否匹配定时器命令,再提取变量转换成整数,最后启动定时器。

新手注意事项

  1. 确保你的项目引用了System.Speech程序集:右键项目 → 添加引用 → 框架 → 找到并勾选System.Speech。
  2. 测试时尽量在安静的环境下发音,清晰说出命令,能提高识别准确率。
  3. 如果需要支持更复杂的数字表达(比如"thirty five"),可以用Choices组合单词,或者直接用new GrammarBuilder(typeof(Number))来支持系统预定义的数字识别规则。

内容的提问来源于stack exchange,提问作者user4189129

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:13:20