1. 项目准备
首先需要安装必要的 NuGet 包:
<PackageReference Include="Vosk" Version="0.3.38" />
<PackageReference Include="NAudio" Version="2.2.1" />
图片
2. 下载语音模型
- 访问 Vosk 模型下载页面
https://alphacephei.com/vosk/models
图片
- 下载中文模型 中文 或其他语言模型
图片
- 解压模型文件到项目目录下的 Models 文件夹
3. 完整代码实现
using NAudio.Wave;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using Vosk;
namespace AppVosk
{
public class SpeechToTextConverter
{
private readonly string _modelPath;
public SpeechToTextConverter(string modelPath)
{
_modelPath = modelPath;
// 初始化 Vosk
Vosk.Vosk.SetLogLevel(0);
if (!Directory.Exists(_modelPath))
{
throw new DirectoryNotFoundException($"请确保模型文件夹存在: {_modelPath}");
}
}
public async Task<string> ConvertToText(string audioFilePath)
{
if (!File.Exists(audioFilePath))
{
throw new FileNotFoundException($"音频文件不存在: {audioFilePath}");
}
// 将音频转换为 WAV 格式(如果是 MP3)
string wavFile = audioFilePath;
bool needsDisposal = false;
if (Path.GetExtension(audioFilePath).ToLower() == ".mp3")
{
wavFile = Path.Combine(Path.GetTempPath(), Path.GetFileNameWithoutExtension(audioFilePath) + ".wav");
using (var reader = new Mp3FileReader(audioFilePath))
using (var writer = new WaveFileWriter(wavFile, reader.WaveFormat))
{
reader.CopyTo(writer);
}
needsDisposal = true;
}
try
{
using (var model = new Model(_modelPath))
using (var recognizer = new VoskRecognizer(model, 16000.0f))
using (var waveStream = new WaveFileReader(wavFile))
{
// 重采样到 16kHz (如果需要)
var outFormat = new WaveFormat(16000, 1);
using (var resampler = new MediaFoundationResampler(waveStream, outFormat))
{
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = resampler.Read(buffer, 0, buffer.Length)) > 0)
{
if (recognizer.AcceptWaveform(buffer, bytesRead))
{
// 处理中间结果(如果需要)
}
}
}
// 获取最终识别结果
var result = JsonDocument.Parse(recognizer.FinalResult());
return result.RootElement.GetProperty("text").GetString() ?? string.Empty;
}
}
finally
{
// 清理临时 WAV 文件
if (needsDisposal && File.Exists(wavFile))
{
try
{
File.Delete(wavFile);
}
catch { /* 忽略删除失败 */ }
}
}
}
}
}
4. 使用示例
图片
class Program
{
static async Task Main(string[] args)
{
try
{
// 指定模型路径和音频文件路径
string modelPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Models", "vosk-model-small-cn-0.22");
string audioFile = "test.mp3"; // 或 test.wav
var converter = new SpeechToTextConverter(modelPath);
string result = await converter.ConvertToText(audioFile);
Console.WriteLine("识别结果:");
Console.WriteLine(result);
}
catch (Exception ex)
{
Console.WriteLine($"发生错误: {ex.Message}");
}
}
}
图片
我下载的是1.3G的模型,这个速度会有点慢。
5. 主要功能说明
- 格式转换:支持 MP3 和 WAV 格式的输入,自动将 MP3 转换为 WAV
- 重采样:自动将音频重采样至 16kHz,以符合 Vosk 的要求
- 错误处理:包含完整的错误处理和资源清理
- 内存优化:使用流式处理,适合处理大文件
- 临时文件管理:自动清理转换过程中产生的临时文件
6. 总结
本文介绍了如何使用 Vosk 和 NAudio 库实现语音转文字的功能,支持 MP3 和 WAV 格式的音频输入,并自动将 MP3 转换为 WAV 格式,同时对音频进行重采样至 16kHz,以满足 Vosk 的要求。文章详细讲解了代码实现,包括模型文件的加载、音频格式转换、重采样处理以及最终的语音识别流程。通过将模型加载放在应用程序启动时,可以提高识别效率,避免重复加载模型。整体方案简单高效,适合需要实现语音识别功能的开发者参考和使用。