最近在看小众西语电影,但苦于没字幕,只能自己想办法弄实时语音识别。然而网上给出的很多相关代码,大部分是基于已有的wav文件或者麦克风外录的方式实现的。我这里就稍微改进了一下,可以在内录(英文资料说的的是loopback audio recording)的情况下进行语音转文字。这里最简单的思路是采用Vosk这个比较成熟的离线语音识别API,然后在.NET平台上,用NAudio库自带的WasapiLoopbackCapture进行内录,并在DataAvaliable事件处理代码块中,对采集到的音频数据字节流进行部分识别,最后输出完整识别出来的内容。
Vosk和NAudio这两个3rd模块需要通过nuget包管理器安装,然后语音识别用到的模型文件可以在VOSK Models上下载。一般情况下,每个语种至少有两个模型文件,其中一个带"small"的模型是精简版模型,用在低性能电脑、手机和嵌入式设备上跑比较好,不过识别准确率不太高:( ;还有一个普通的模型,大小在1GB以上的,这个识别准确率非常高,但是放在手机上跑不太合适。
大家根据自己的需求下载对应语种、对应规模的语言模型包,然后解压到程序执行目录。
下面废话不多说,直接上代码:
using NAudio.Wave;
using System.Text;
using Vosk;
class SpeechToText
{
static void Main()
{
Console.OutputEncoding = Encoding.UTF8;
// Initialize Vosk API
Model model = new Model("model-small-es");
using (var waveIn = new WasapiLoopbackCapture())
{
waveIn.WaveFormat = new WaveFormat(44100, 1);
var rec = new VoskRecognizer(model, waveIn.WaveFormat.SampleRate);
rec.SetMaxAlternatives(0);
rec.SetWords(true);
waveIn.DataAvailable += (_, e) =>
{
if (rec.AcceptWaveform(e.Buffer, e.BytesRecorded))
{
Console.WriteLine(rec.Result());
}
else
{
Console.WriteLine(rec.PartialResult());
}
};
waveIn.StartRecording();
Console.WriteLine("Press ENTER to quit...");
Console.ReadLine();
waveIn.StopRecording();
}
}
}
代码逻辑很简单这里就不再赘述,不过有几点需要注意一下:
1. WaveFormat的参数设置问题:一定不能用双声道!Vosk似乎不怎么支持双声道数据的处理,我用这个参数的时候程序总是跑到一半就崩了。然后采样率,很多人给出的代码都配置的是16kHz,我觉得质量太低识别效果不好,尝试了一下改到44.1kHz,程序仍然能跑,而且识别准确率高了很多,但是再往上我就没试了,而且没必要。
2. MaxAlternatives这个参数是告诉vosk识别完成后给出多少种备选结果,我们只需要一种结果就行了,也就是不需要备选结果,这里设置为0即可。
3. SetWords这个函数是告诉vosk识别完成后是否需要显示每个单词出现和结束的时间(从录音起始开始算起),这个对做滚动歌词和字幕的伙计们就非常有用了,如果大家觉得烦人可以把它设成false。
4. 如果你用的语言模型包和我的不一样,一定不要忘记修改上面代码中的模型路径!!!
我给出的是一个简单的控制台程序代码,主要在于简便,方便给大家复制并用到自己的项目中。程序启动后会一直运行,直到用户按下回车键才会退出。
效果:
文章来源:https://www.toymoban.com/news/detail-622233.html
文章来源地址https://www.toymoban.com/news/detail-622233.html
到了这里,关于Vosk 扬声器内录语音识别转文字 最简洁的C#代码的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!