当前位置: 首页 > news >正文

实时采集到的语音进行语音识别

要在.NET Framework 4.8中使用C#实现离线实时语音识别,可以使用开源库Vosk(支持离线ASR)配合音频处理库NAudio。

步骤 1:安装依赖库
1.1.
安装NuGet包:
- Install-Package NAudio(处理音频输入)
- Install-Package Vosk(离线语音识别引擎)
2.2.
下载语音模型:
- 前往 Vosk Models 下载适合的模型(如小型英文模型 vosk-model-small-en-us-0.15)。
- 解压模型到项目目录(如 Models/vosk-model-small-en-us-0.15)。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NAudio.Wave;
using Vosk;
using System.Windows.Forms;
namespace 语音识别
{
public class RealTimeSpeechRecognizer
{
    private readonly VoskRecognizer _recognizer;
    private readonly WaveInEvent _waveIn;
    private readonly RichTextBox _rtb;

    public RealTimeSpeechRecognizer(string modelPath, RichTextBox rtb)
    {
        _rtb = rtb;

        // 初始化Vosk
        Model model = new Model(modelPath);
        _recognizer = new VoskRecognizer(model, 16000.0f);
        _recognizer.SetWords(true);

        // 初始化音频输入
        _waveIn = new WaveInEvent
        {
            WaveFormat = new WaveFormat(16000, 16, 1),
            DeviceNumber = 0
        };
        _waveIn.DataAvailable += OnAudioDataAvailable;
    }

    public void StartListening() => _waveIn.StartRecording();
    public void StopListening() => _waveIn.StopRecording();

    

    // 解析JSON结果(兼容部分结果)
    private string ParseJsonResult(string json, bool isPartial = false)
    {
        dynamic obj = Newtonsoft.Json.JsonConvert.DeserializeObject(json);
        return isPartial ? obj.partial : obj.text;
    }

    // 线程安全更新RichTextBox
    private void ShowText(string text)
    {
        if (_rtb.InvokeRequired)
        {
            _rtb.BeginInvoke(new Action<string>(ShowText), text);
        }
        else
        {
            _rtb.AppendText(text);
            _rtb.ScrollToCaret();
        }
    }

    // 其他字段和构造函数保持不变...
    private string _lastPartialText = string.Empty;

    

    private void OnAudioDataAvailable(object sender, WaveInEventArgs e)
    {
        if (_recognizer.AcceptWaveform(e.Buffer, e.BytesRecorded))
        {
            string result = ParseJsonResult(_recognizer.Result());
            ClearLastPartial(); // 清理临时部分
            AppendFinalText(result);
        }
        else
        {
            string partial = ParseJsonResult(_recognizer.PartialResult(), isPartial: true);
            UpdatePartialText(partial);
        }
    }

    private void UpdatePartialText(string newPartial)
    {
        if (newPartial == _lastPartialText) return;

        // 在主线程更新UI
        _rtb.BeginInvoke(new Action(() =>
        {
            int selectionStart = _rtb.TextLength - _lastPartialText.Length;

            // 删除旧临时内容
            if (selectionStart >= 0 && _lastPartialText.Length > 0)
            {
                _rtb.Select(selectionStart, _lastPartialText.Length);
                _rtb.SelectedText = "";
            }

            // 追加新内容
            _rtb.AppendText(newPartial);
            _rtb.ScrollToCaret();

            // 更新临时记录
            _lastPartialText = newPartial;
        }));
    }

    private void AppendFinalText(string text)
    {
        _rtb.BeginInvoke(new Action(() =>
        {
            _rtb.AppendText(text + "\n");
            _lastPartialText = string.Empty; // 重置临时部分
        }));
    }

    private void ClearLastPartial()
    {
        if (string.IsNullOrEmpty(_lastPartialText)) return;

        _rtb.BeginInvoke(new Action(() =>
        {
            int start = _rtb.TextLength - _lastPartialText.Length;
            if (start >= 0)
            {
                _rtb.Select(start, _lastPartialText.Length);
                _rtb.SelectedText = "";
            }
        }));
    }
}

}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace 语音识别
{
public partial class Form1 : Form
{
private RealTimeSpeechRecognizer _recognizer;
public Form1()
{
InitializeComponent();
btnStop.Enabled = false;
}
    private void button1_Click(object sender, EventArgs e)
    {
        _recognizer.StopListening();
        btnStart.Enabled = true;
        btnStop.Enabled = false;
    }
    

    private void btnStart_Click(object sender, EventArgs e)
    {
        string modelPath = @"E:\Models\vosk-model-small-cn-0.22"; // 中文模型路径
        _recognizer = new RealTimeSpeechRecognizer(modelPath, richTextBox1);

        btnStart.Enabled = false;
        btnStop.Enabled = true;
        _recognizer.StartListening();
    }
}

}

相关文章:

  • Spring(2)——Cookie和Session
  • 【时间序列聚类】Feature-driven Time Series Clustering(特征驱动的时间序列聚类)
  • 008-Trae换用DeepSeek后编程能力大幅提升至中级水平
  • Python 实现非对称加密的 A 端和 B 端软件的详细步骤及代码示例
  • Python 实现机器学习的 房价预测回归项目
  • 【算法学习之路】8.栈和队列
  • Flutter中使用NetworkImage加载网络图片缓存问题学习实践
  • HTML 学习路线图
  • !C++中的位运算
  • 大语言模型-全文
  • linux应用:静态文件、 inode(i 节点)、vnode、流
  • Python 网络爬虫教程:从入门到高级的全面指南
  • 自然语言处理:无监督朴素贝叶斯模型
  • Spring Security 官网文档学习
  • GIS工具箱选择指南:四款软件满足多样化空间分析需求
  • Driver com.p6spy.engine.spy.P6SpyDriver claims to not accept jdbcUrl报错
  • 自动化App测试Appium(真机测试)准备
  • 基于SpringBoot+Vue的校园跑腿原生小程序
  • 用 Vue 3.5 TypeScript 做了一个日期选择器(改进版)
  • git subtree管理的仓库怎么删除子仓库
  • 国家主席习近平同普京总统出席签字和合作文本交换仪式
  • 2025江西跨境电子商务发展交流会召开,探索行业发展新趋势
  • 国铁集团:铁路五一假期运输收官,多项运输指标创历史新高
  • 中国电信财务部总经理周响华调任华润集团总会计师
  • 郭旭涛转任河北省科协党组书记、常务副主席,曾任团省委书记
  • 100%关税!特朗普要让美国电影100%美国制造