陈程的技术博客

  • 关于作者
全栈软件工程师
一个专注于技术研究创新的程序员
  1. 首页
  2. .NET
  3. 正文

NAudio监听系统声音,屏蔽麦克风其他声音

2019年5月17日 920点热度 0人点赞 0条评论

使用WasapiLoopbackCapture记录声卡输出
很多人问他们如何使用NAudio来录制另一个节目播放的音频。
答案是,遗憾的是,Windows不提供允许您将一个特定程序的输出作为目标进行记录的API。
但是,通过WASAPI环回捕获,您可以记录从特定输出设备播放的所有音频。

必须在WaveFormat设备已经使用的情况下捕获音频。这
通常是立体声44.1kHz(有时是48kHz)IEEE浮点。
显然,您可以在将音频捕获为另一种格式后手动操作音频,但是对于此示例,我们将直接将其传递到WAV文件中。

让我们从选择要记录的路径开始,创建一个实例WasapiLoopbackCapture(使用默认的系统设备,但我们可以传递MMDevice我们想要的任何渲染MMDeviceEnumerator)。

我们还将创建一个WaveFileWriter使用捕获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();
var writer = new WaveFileWriter(outputFilePath, capture.WaveFormat);

我们需要处理DataAvailable事件,这与从常规WaveIn设备录制到WAV文件的方法非常相似。
我们只是写BytesRecorded在字节Buffer进入WaveFileWriter。
在这个例子中,当我们通过呼叫捕获了20秒的音频时,我正在停止录音StopRecording。

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

当RecordingStopped事件触发时,我们Dispose我们的WaveFileWriter,所以我们创建一个有效的WAV文件,而且我们做记录,所以我们将Dispose我们的捕获设备为好。

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

剩下的就是我们开始录制StartRecording并等待录制完成,通过监听CaptureState。

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

现在有一个问题WasapiLoopbackCapture。
如果没有播放任何音频,则该DataAvailable事件不会触发。
因此,如果你想录制“沉默”,一个简单的诀窍就是简单地使用一个NAudio播放设备在你录制的那段时间内通过该设备播放静音。
或者,当您检测传入音频中的间隙时,您可以自己插入静音。

标签: C# NAudio
最后更新:2021年4月2日

博主

全栈工程师,侧重项目技术解决方案规划和开发

打赏 点赞
< 上一篇
下一篇 >

文章评论

取消回复

分类
  • .NET (65)
  • docker (3)
  • linux (12)
  • python (20)
  • web (14)
  • 小程序 (4)
  • 数据库 (2)
  • 未分类 (4)
  • 杂七杂八 (10)
标签聚合
nginx centos js C# python DevExpress winform linux
最新 热点 随机
最新 热点 随机
.NET开发手册标准参考 招募兼职前端开发 Centos安装dotnet6环境 VS上切换分支,vs编译运行出现bug,A fatal error was encountered彻底解决方案 用C#封装一个线程安全的缓存器,达到目标定时定量更新入库 C#通过特性的方式去校验指定数据是否为空
使用C#+Jumony开发网络爬虫并对数据做相关分析 JsonHelper序列化和反序列化 sqlserver 查询数据库名 表名 字段名 字段类型等 winform 绘制无边框四周阴影 python 常用命令安装 fastapi做后台的跨域官方BUG以及修复方式

COPYRIGHT © 2021 陈程的技术博客. ALL RIGHTS RESERVED.

THEME KRATOS MADE BY VTROIS