最近正在研究录音机功能,偶然发现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)
{
}
}
}
需要注意的一点是,WaveIn类在控制台中调用会报错,估计是找不到句柄之类的,控制台可尝试用WaveInEvent。