Logo

同声翻译-先从录制音频开始

photo

2025年06月05日

同声翻译的核心:录制音频——调用接口(讯飞,百度,微软都有)语音转文字-调用翻译接口(讯飞,百度,微软都有)。

1:使用Naudio

为什么用这个,因为它可以调用扬声器和麦克风,为什么两个都要兼容,因为有些场景人家喜欢在电脑上放国外的电影,想着实时翻译……我能有什么办法……

NAudio/Docs/WasapiLoopbackCapture.md at master · naudio/NAudio · GitHub

这个技术可以检测声卡和麦克风,但是不能同时检测(虽然我写过,但是后来忘记了……)。

Lots of people ask how they can use NAudio to record the audio being played by another program. The answer is that unfortunately Windows does not provide an API that lets you target the output of one specific program to record. However, with WASAPI loopback capture, you can record all the audio that is being played out of a specific output device.

Since NAudio 2.1.0, the audio can be captured at a sample rate of your choosing, although it will make sense to match the sound card’s format.

Let’s start off by selecting a path to record to, creating an instance of WasapiLoopbackCapture (uses the default system device, but we can pass any rendering MMDevice that we want which we can find with MMDeviceEnumerator). We’ll also create a WaveFileWriter using the capture WaveFormat.

var outputFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "NAudio");
Directory.CreateDirectory(outputFolder);
var outputFilePath = Path.Combine(outputFolder, "recorded.wav");
var capture = new WasapiLoopbackCapture();
// optionally we can set the capture waveformat here: e.g. capture.WaveFormat = new WaveFormat(44100, 16,2);
var writer = new WaveFileWriter(outputFilePath, capture.WaveFormat);

We need to handle the DataAvailable event, and it’s very much the same approach here as recording to a WAV file from a regular WaveIn device. We just write BytesRecorded bytes from the Buffer into the WaveFileWriter. And in this example, I am stopping recording when we’ve captured 20 seconds worth of audio, by calling StopRecording.

capture.DataAvailable += (s, a) =>
{
    writer.Write(a.Buffer, 0, a.BytesRecorded);
    if (writer.Position > capture.WaveFormat.AverageBytesPerSecond * 20)
    {
        capture.StopRecording();
    }
};

When the RecordingStopped event fires, we Dispose our WaveFileWriter so we create a valid WAV file, and we’re done recording so we’ll Dispose our capture device as well.

capture.RecordingStopped += (s, a) =>
{
    writer.Dispose();
    writer = null;
    capture.Dispose();
};

All that remains is for us to start recording with StartRecording and wait for recording to finish by monitoring the CaptureState.

capture.StartRecording();
while (capture.CaptureState != NAudio.CoreAudioApi.CaptureState.Stopped)
{
    Thread.Sleep(500);
}

Now there is one gotcha with WasapiLoopbackCapture. If no audio is playing whatsoever, then the DataAvailable event won’t fire. So if you want to record “silence”, one simple trick is to simply use an NAudio playback device to play silence through that device for the duration of time you’re recording. Alternatively, you could insert silence yourself when you detect gaps in the incoming audio.

核心代码如下:

string mainpath = DateTime.Now.ToString("yyyyMMddHHmmss");

var outputFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "temp", mainpath);

Directory.CreateDirectory(outputFolder);

var outputFilePath = Path.Combine(outputFolder, DateTime.Now.ToString("yyyyMMddHHmmss") + ".wav");

//声卡/扬声器录音
//var capture = new WasapiLoopbackCapture();
//var capture = new WasapiCapture();
//麦克风
var capture = new WasapiCapture();
// optionally we can set the capture waveformat here: e.g. capture.WaveFormat = new WaveFormat(44100, 16,2);
var writer = new WaveFileWriter(outputFilePath, capture.WaveFormat);

capture.DataAvailable += (s, a) =>
{
    writer.Write(a.Buffer, 0, a.BytesRecorded);

    if (writer.Position > capture.WaveFormat.AverageBytesPerSecond * 20)
    {
        var outputFilePath = Path.Combine(outputFolder, DateTime.Now.ToString("yyyyMMddHHmmss") + ".wav");
        //var capture = new WasapiLoopbackCapture();
        writer = new WaveFileWriter(outputFilePath, capture.WaveFormat);
        //capture.StopRecording();
    }
};
capture.RecordingStopped += (s, a) =>
{
    writer.Dispose();
    writer = null;
    capture.Dispose();
};

capture.StartRecording();

while (capture.CaptureState != NAudio.CoreAudioApi.CaptureState.Stopped)
{
    Thread.Sleep(500);
}

Console.WriteLine($"录音完成,文件保存到: {outputFilePath}");

这个代码的意思就是打开麦克风开始检测,每20S一个音频文件,你拿着去做语音转文字就行。

橙子主题打折出售

其实我不卖,主要是这里是放广告的,所以就放了一个
毕竟主题都没做完,卖了也是坑.

购买它
所有附件
该文章没有附件.
本文为原创文章,请注意保留出处!

留言板

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

热门文章

无法握住的故土 在我们心灵最温暖的角落,总有一寸土地是属于故乡的。虽然我们看似已远离故土,可骨子里对故乡的依恋却是从未冷却过。我们无论漂泊他乡,还是在繁华都市平步青云,可故乡的悠悠情思总会潜入梦乡与你缠绵。是儿时那一缕缕茉莉的清香萦绕在梦境,也是邻家那已锈迹斑斑的铁壶里,开出艳丽的花儿在梦的边缘摇曳。故土就这样根深蒂固地在我们的灵魂深处烙下深深的印记。 作者:Pastore Antonio
1596 浏览量
EWS(Exchange Service)基本使用(获取个人会议,会议室会议内容,会议室列表,发送会议,修改会议,删除会议) 最近公司要求和exchange服务对接,所以稍微研究了一下官方文档,做出以下总结,欢迎大家补充。先...EWS(ExchangeService)基本使用(获取个人会议,会议室会议内容,会议室列表,发送会议,修改会议,删除会议) 作者:Pastore Antonio
1585 浏览量
Sql Server 部署SSIS包完成远程数据传输 本篇介绍如何使用SSIS和作业完成自动更新目标数据任务。**温馨提示:如需转载本文,请注明...SqlServer部署SSIS包完成远程数据传输 作者:Pastore Antonio
1579 浏览量
SQL Server AG集群启动不起来的临时自救大招 背景前晚一朋友遇到AG集群发生来回切换不稳定的情况,情急之下,朋友在命令行使用命令重启WSFC集群...SQLServerAG集群启动不起来的临时自救大招 作者:Pastore Antonio
1573 浏览量
windows 下安装 memcahce 官网上并未提供Memcached的Windows平台安装包,我们可以使用以下链接来下载,你需...windows下安装memcahce 作者:Pastore Antonio
1566 浏览量