C#使用NAudio实现监听系统声音

 更新时间:2024年02月06日 09:24:46   作者:搬砖的诗人Z  
这篇文章主要为大家详细介绍了C#如何使用NAudio实现监听系统声音并屏蔽麦克风其他声音,文中的示例代码讲解详细,有需要的小伙伴可以参考下

使用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除了可以监听系统声音,还可以实现声音的录制,下面是实现方法,希望对大家有所帮助

NAudio 简介:

NAudio是个相对成熟、开源的C#音频开发工具,它包含录音、播放录音、格式转换、混音调整等功能。本次介绍主要功能有音频、录音文件播放、实时音频流波形图显示等。

第一步:添加引用,在NuGet中搜索NAudio,并安装

第二步:在代码中使用,下面直接提供本人封装好的类,暴露了3个接口,一个初始化,一个开始,一个暂停,比较基础的应用

using System;

using NAudio.Wave;

  public class NAudioRecordHelper
    {

        public enum RecordType
        {
            loudspeaker = 0, // 扬声器
            microphone = 1 //麦克风
        }

        //录制的类型
        RecordType t = RecordType.microphone;

        //录制麦克风的声音
        WaveInEvent waveIn = null; //new WaveInEvent();
        //录制扬声器的声音
        WasapiLoopbackCapture capture = null; //new WasapiLoopbackCapture();
        //生成音频文件的对象
        WaveFileWriter writer = null;

        string audioFile = "";

        public NAudioRecordHelper(RecordType x, string filePath)
        {
            t = x;
            audioFile = filePath;
        }

        /// <summary>
        /// 开始录制
        /// </summary>
        public void StartRecordAudio()
        {
            try
            {
                if (audioFile == "")
                {
                    System.Windows.Forms.MessageBox.Show("请设置录制文件的路径!");
                    return;
                }

                if (t == RecordType.microphone)
                {
                    waveIn = new WaveInEvent();
                    writer = new WaveFileWriter(audioFile, waveIn.WaveFormat);
                    //开始录音,写数据
                    waveIn.DataAvailable += (s, a) =>
                    {
                        writer.Write(a.Buffer, 0, a.BytesRecorded);
                    };

                    //结束录音
                    waveIn.RecordingStopped += (s, a) =>
                    {
                        writer.Dispose();
                        writer = null;
                        waveIn.Dispose();

                    };

                    
                    waveIn.StartRecording();
                }
                else
                {
                    capture = new WasapiLoopbackCapture();
                    writer = new WaveFileWriter(audioFile, capture.WaveFormat);

                    capture.DataAvailable += (s, a) =>
                    {
                        writer.Write(a.Buffer, 0, a.BytesRecorded);
                    };
                    //结束录音
                    capture.RecordingStopped += (s, a) =>
                    {
                        writer.Dispose();
                        writer = null;
                        capture.Dispose();
                    };


                    
                    capture.StartRecording();
                }

            }
            catch (Exception ex)
            {

            }
        }


        //结束录制
        public void StopRecordAudio()
        {
            if (t == RecordType.microphone)
                waveIn.StopRecording();
            else
                capture.StopRecording();
        }

到此这篇关于C#使用NAudio实现监听系统声音的文章就介绍到这了,更多相关C# NAudio监听系统声音内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C#实现人民币大写转换示例代码

    C#实现人民币大写转换示例代码

    这篇文章主要介绍了C#实现人民币大写转换,需要的朋友可以参考使用
    2013-12-12
  • c#数据绑定之将datatabel的data添加listView

    c#数据绑定之将datatabel的data添加listView

    这篇文章主要介绍了c#将DataTabel的data添加ListView的示例,实现功能是通过响应UI Textbox 的值向ListView 绑定新添加的纪录。 ,需要的朋友可以参考下
    2014-04-04
  • c#中list.FindAll与for循环的性能对比总结

    c#中list.FindAll与for循环的性能对比总结

    这篇文章主要给大家总结介绍了关于c#中list.FindAll与for循环的性能,文中通过详细的示例代码给大家介绍了这两者之间的性能,对大家的学习或工作具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧。
    2017-10-10
  • protobuf对象二进制序列化存储(详解)

    protobuf对象二进制序列化存储(详解)

    下面小编就为大家带来一篇protobuf对象二进制序列化存储(详解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-02-02
  • Expression操作运算符、表达式和操作方法总结

    Expression操作运算符、表达式和操作方法总结

    这篇文章详细介绍了Expression操作运算符、表达式和操作方法总结,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-01-01
  • C#跨平台开发之使用C/C++生成的动态链接库

    C#跨平台开发之使用C/C++生成的动态链接库

    这篇文章介绍了C#跨平台开发之使用C/C++生成的动态链接库,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-01-01
  • c#中判断字符串是不是数字或字母的方法

    c#中判断字符串是不是数字或字母的方法

    这篇文章介绍了C#判断字符串是否数字或字母的实例,有需要的朋友可以参考一下
    2013-06-06
  • 基于C#的winform实现数字华容道游戏

    基于C#的winform实现数字华容道游戏

    这篇文章主要为大家详细介绍了基于C#的winform实现数字华容道游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • C#删除字符串中重复字符的方法

    C#删除字符串中重复字符的方法

    这篇文章主要介绍了C#删除字符串中重复字符的方法,涉及C#针对字符串的遍历及移除等操作的技巧,非常具有实用价值,需要的朋友可以参考下
    2015-02-02
  • C#使用NUnit进行单元测试详解

    C#使用NUnit进行单元测试详解

    NUnit是一个开源的.Net单元测试框架,经常被用来在.Net体系下做白盒测试,本文主要为大家详细介绍了如何C#如何使用NUnit进行单元测试,感兴趣的可以了解下
    2023-12-12

最新评论