最近正在研究录音机功能,偶然发现NAudio;发现挺好用的除了实现基础的录音功能,还支持录音变声、驱动采样、播放一些音频格式等,本文只实现了c#录音功能和获取本机的扬声器和获取本机麦克风,其他功能陆续研究后更新,大家也可以直接去github上自己钻研。
Github地址

using NAudio.Wave;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Record
{
    public class RecordCtrl
    {
        public WaveIn mWavIn;
        public WaveFileWriter mWavWriter;

        /// <summary>
        /// 获取本机所有输入设备
        /// </summary>
        /// <returns></returns>
        public List<Device> GetIputDevices()
        {
            List<Device> res = new List<Device>();
            for (int n = 0; n < WaveIn.DeviceCount; n++)
            {
                WaveInCapabilities waveOutCaps = WaveIn.GetCapabilities(n);
                res.Add(new Device
                {
                    Index = waveOutCaps.Channels,
                    Name = waveOutCaps.ProductName
                });
            }
            return res;
        }

        /// <summary>
        /// 获取本机所有输出设备
        /// </summary>
        /// <returns></returns>
        public List<Device> GetOutputDevices()
        {
            List<Device> res = new List<Device>();
            for (int n = 0; n < WaveOut.DeviceCount; n++)
            {
                WaveOutCapabilities waveOutCaps = WaveOut.GetCapabilities(n);
                res.Add(new Device
                {
                    Index = waveOutCaps.Channels,
                    Name = waveOutCaps.ProductName
                });
            }
            return res;
        }

        /// <summary>
        /// 开始录音
        /// </summary>
        /// <param name="filePath">文件存储路径,包含文件名</param>
        /// <param name="deviceNumber">录音设备索引号,默认第一个设备</param>
        public void StartRecord(string filePath, int deviceNumber = 0)
        {
            //判断是否有接入麦克风,否则会抛出异常
            if (WaveIn.DeviceCount > 0)
            {
                //winform程序用WaveIn,控制台程序用WaveInEvent
                mWavIn = new WaveIn();
                mWavIn.DeviceNumber = deviceNumber;
                mWavIn.DataAvailable += MWavIn_DataAvailable;
                mWavIn.RecordingStopped += MWavIn_RecordingStopped;
                mWavWriter = new WaveFileWriter(filePath, mWavIn.WaveFormat);
                mWavIn.StartRecording();
            }
        }

        /// <summary>
        /// 停止录音
        /// </summary>
        public void StopRecord()
        {
            mWavIn?.StopRecording();
            mWavIn?.Dispose();
            mWavIn = null;
            mWavWriter?.Close();
            mWavWriter = null;
        }

        private void MWavIn_RecordingStopped(object sender, StoppedEventArgs e)
        {

        }

        private void MWavIn_DataAvailable(object sender, WaveInEventArgs e)
        {
            mWavWriter.Write(e.Buffer, 0, e.BytesRecorded);
            int secondsRecorded = (int)mWavWriter.Length / mWavWriter.WaveFormat.AverageBytesPerSecond;
        }
    }
    public class Device
    {
        public int Index { get; set; }
        public string Name { get; set; }
    }
}

调用示例

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Record
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private RecordCtrl ctrl = new RecordCtrl();
        private void button1_Click(object sender, EventArgs e)
        {
            ctrl.StartRecord("test.wav");
        }

        private void button2_Click(object sender, EventArgs e)
        {
            ctrl.StopRecord();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }
    }
}

c#录音机

需要注意的一点是,WaveIn类在控制台中调用会报错,估计是找不到句柄之类的,控制台可尝试用WaveInEvent

最后修改:2022 年 10 月 10 日
如果觉得我的文章对你有用,请随意赞赏