FunASR C 实时语音识别客户端实战:基于 WebSocket 的 Online/2pass 流式识别与离线文件转录
FunASR C# 实时语音识别客户端实战基于 WebSocket 的 Online/2pass 流式识别与离线文件转录【免费下载链接】FunASROpen-source speech recognition toolkit for training, inference, streaming ASR, VAD, punctuation, speaker diarization pipelines, and OpenAI-compatible/MCP serving.项目地址: https://gitcode.com/GitHub_Trending/fun/FunASR本指南以 FunASR 仓库 runtime/csharp/ws-client/FunASRWSClient_Online 目录下的 C# 客户端为主体讲解如何构建一个连接 FunASR WebSocket 服务端的实时语音识别程序既支持麦克风实时流式识别online / 2pass 两种模式也支持对本地音频文件进行离线转录。读完本文你将掌握该客户端的工程结构、WebSocket 协议消息的构造方式、麦克风采集与音频分块发送的实现细节以及从编译到联调运行的全流程操作。一、客户端能力概览FunASRWSClient_Online 是一个基于 FunASR WebSocket 服务器的 C# 控制台客户端核心能力在 README.md 中有明确说明实时语音识别使用online或2pass模式对麦克风采集到的音频流进行持续识别离线文件转录默认使用offline模式转录本地音频文件配置驱动将配置文件放在与程序相同目录下的 config 文件夹中在config.ini中配置服务器 IP 地址和端口号开箱即测配置好服务端 IP 和端口后在 Visual Studio 中打开项目添加NAudio和Websocket.Client两个 NuGet 程序包即可直接测试按控制台提示操作即可。该客户端在 Windows 11 下完成测试编译环境为 VS2022。工程目录中包含四个核心文件Program.cs主流程与交互、WebScoketClient.csWebSocket 通信与协议封装、WaveCollect.cs麦克风采集、FunASRWSClient_Online.csproj工程配置。同仓库还提供了只做离线文件转录的姊妹工程 FunASRWSClient_Offline并支持热词与时间戳热词需将 config 文件夹下的hotword.txt放置在执行路径下且热词与时间戳为不同模型需注意后台部署时模型选择。二、环境要求与编译运行2.1 依赖清单从 FunASRWSClient_Online.csproj 可以看到工程的目标框架与依赖Project SdkMicrosoft.NET.Sdk PropertyGroup OutputTypeExe/OutputType TargetFrameworknet6.0/TargetFramework ImplicitUsingsenable/ImplicitUsings Nullableenable/Nullable /PropertyGroup ItemGroup PackageReference IncludeNAudio Version2.1.0 / PackageReference IncludeWebsocket.Client Version4.6.1 / /ItemGroup /Project目标框架net6.0.NET 6NAudio 2.1.0负责麦克风音频采集、WAV 格式处理如WaveInEvent、WaveFileWriter、MMDeviceEnumeratorWebsocket.Client 4.6.1负责与 FunASR WebSocket 服务端的连接、收发与断线重连基于 System.Reactive 提供MessageReceived等可观察订阅。2.2 服务端与客户端配置客户端通过 config.ini 读取服务端地址注意仓库中目录名为confghost127.0.0.1 port10095配置解析逻辑位于 Program.cs 的loadconfig()方法中逐行读取config.ini忽略空行以及;、#开头的注释行按keyvalue形式解析仅识别host与port两个键程序内默认值分别为0.0.0.0与10095对应 FunASR WebSocket 服务端默认端口。启动前需先运行 FunASR 的 WebSocket 服务端如funasr-wss-server或其 2pass 版本确保服务端监听端口与config.ini一致。2.3 编译与运行步骤用 VS2022 打开解决方案 FunASRClient_CShape.sln仓库中实际文件名为FunASRClient_CShape.sln下的FunASRWSClient_Online工程通过 NuGet 还原NAudio与Websocket.Client程序包将config.ini放到程序运行目录或与程序同目录的 config 文件夹中填写服务端 IP 与端口编译运行程序会先做麦克风与通信自检随后进入菜单交互。三、程序主流程启动自检与双线程架构3.1 启动自检FunASR_Main()Program.cs启动后依次执行两类自检麦克风状态监测通过GetCurrentMicVolume()枚举系统录音设备返回-2表示麦克风被静音、-1表示麦克风未连接、0表示音量被调为 0任一异常都会在控制台给出提示并退出通信连接测试ClientConnTest()尝试建立 WebSocket 连接若返回信息不包含成功字样则判定连接失败并退出。3.2 双线程并发架构自检通过后主程序启动两个后台线程再进入交互循环SendAudioThread执行SendAudioToSeverAsync()持续从ActiveAudioSet并发队列取出麦克风音频块调用ClientSendAudioFunc()发送给服务端AudioFileThread执行SendAudioFileToSeverAsync()轮询AudioFileQueue有文件路径入队即调用ClientSendFileFunc()进行离线转录。主线程则循环读取控制台输入提供交互菜单输入1进入离线文件转写随后输入文件路径输入2进入实时语音识别再选择1为 online、2为 2pass。两个并发队列ActiveAudioSet、AudioFileQueue均声明为ConcurrentQueueT保证多线程安全。四、麦克风采集WaveCollect 的实现细节WaveCollect.cs 基于 NAudio 实现音频采集关键参数参数值说明wave_buffer_milliseconds600每次采集缓冲的毫秒数BufferMillisecondswave_buffer_collectbits16位深 16bitwave_buffer_collectchannels1单声道wave_buffer_collectfrequency16000采样率 16kHz采集流程StartRec()先枚举并打印系统录音设备信息随后创建WaveInEvent16kHz / 16bit / 单声道在DataAvailable事件回调中将e.Buffer入队到静态并发队列voicebuff同时用WaveFileWriter写入tmp.wavStopRec()停止录制并释放资源。实时识别循环中主线程不断从voicebuff出队并转存到ActiveAudioSet供发送线程消费。五、WebSocket 协议交互客户端与服务端的消息约定5.1 首帧识别启动参数实时识别开始前ClientFirstConnOnline()构造首帧 JSON 文本发送给服务端WebScoketClient.cs{mode: online, chunk_size: [5,10,5], chunk_interval: 10, wav_name: microphone, is_speaking: true}modeonline或2pass由用户选择2pass 会在流式识别结果基础上输出修正后的最终结果chunk_size[5,10,5]服务端在 websocket-server-2pass.cpp 中会校验其长度为 3 且第二个元素非 0否则报Wrong chunk_size!chunk_interval10毫秒客户端据此计算发送切片大小wav_namemicrophone实时识别会话标识is_speakingtrue正在说话流式会话进行中。5.2 音频数据帧采集线程送来的每个缓冲块在ClientSendAudioFunc()中按公式CHUNK 采样率/1000 * 60 * chunk_size[1] / chunk_interval切成更小的片段逐段发送每个片段之间Thread.Sleep(1)限速保证与服务端流式处理节奏匹配。当连接断开时调用client.Reconnect()触发重连。5.3 结束帧实时识别退出捕获 CtrlC后ClientLastConnOnline()发送{is_speaking: false}通知服务端当前说话结束finally块中同时执行StopRec()停止采集。服务端收到is_speakingfalse后结束本次会话并返回最终结果。5.4 离线文件转录的消息约定ClientSendFileFunc()按扩展名区分处理WebScoketClient.cswav / pcm发送{mode: office, chunk_size: [5,10,5], chunk_interval: 10, wav_name: xxx.wav, is_speaking: true, wav_format: pcm}随后 wav 文件跳过 44 字节 WAV 头按 102400 字节分块发送pcm 文件按 1024000 字节分块发送mp3 / mp4发送{mode: offline, chunk_size: 5,10,5, chunk_interval: 10, wav_name: xxx.mp3, is_speaking: true, wav_format: mp3}chunk_size为字符串形式同样分块发送不支持的扩展名返回-1通信断开返回-2。发送完所有数据后统一发送{is_speaking: false}收尾。5.5 服务端响应与结果解析rec_message()解析服务端返回的 JSON读取mode、text、is_final、wav_name字段mode 2pass-online流式中间结果累积到onlinebuff后与recbuff拼接打印mode 2pass-offline2pass 修正后的最终结果累积到recbuff打印is_final true当前识别段结束清空recbuff缓存。这一消息结构与服务端 websocket-server-2pass.cpp 中的行为一致在线阶段返回mode: 2pass-online的临时文本离线修正阶段返回mode: 2pass-offline的最终文本并在会话结束时返回is_final: true与wav_name。协议细节可进一步参阅 WebSocket 协议文档。六、完整运行流程实操启动 FunASR WebSocket 服务端online 或 2pass 版本确认端口默认 10095在config.ini中配置服务端host与port与程序放在同一运行目录VS2022 编译运行程序自动完成麦克风与通信自检按提示输入1离线文件转写并给出音频文件路径等待转录结果打印输入2实时语音识别再选择1online或22pass对着麦克风说话控制台实时打印识别文本按 CtrlC 结束本次会话并返回菜单。七、结合仓库源码的扩展提示服务端对应实现客户端的 JSON 消息字段mode、chunk_size、chunk_interval、wav_name、is_speaking、wav_format与 runtime/websocket/bin 下的服务端解析逻辑一一对应联调时可直接对照该目录源码排查字段不匹配问题离线纯转录场景若只需批量转写本地文件可改用 FunASRWSClient_Offline 工程其还支持热词hotword.txt与时间戳能力多语言服务端仓库中 runtime/websocket 目录下包含 online / 2pass 多种服务端实现均可与本 C# 客户端配合使用。结语FunASRWSClient_Online 演示了在 .NET 生态中对接 FunASR WebSocket 服务端的完整路径从 config.ini 配置、NAudio 麦克风采集到符合 FunASR 协议的 JSON 首帧、分块音频数据帧与结束帧发送再到 2pass 中间/最终结果解析。理解其消息约定与线程模型后你可以轻松将此客户端改造为 WinForms / WPF 图形界面、集成到现有 C# 业务系统或扩展支持更多音频格式与热词功能。【免费下载链接】FunASROpen-source speech recognition toolkit for training, inference, streaming ASR, VAD, punctuation, speaker diarization pipelines, and OpenAI-compatible/MCP serving.项目地址: https://gitcode.com/GitHub_Trending/fun/FunASR创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联
返回资讯列表 →