微信公众号“dotNET跨平台”看到一篇文章《【.NET】使用NAudio实现录音功能》介绍基于NAudio实现录音功能(参考文献1)。NAudio是开源.net音频库,其支持播放多种格式的音频(WAV、AIFF、MP3、WMA等)、音频格式转换、录音等,功能十分强大(GitHub近5000星),本文测试其音频播放及录制视频相关功能的基本用法。
创建Winform项目,添加NAudio的NuGet引用,如下图所示:
NAudio中通过WaveOutEvent和AudioFileReader实现音频的播放,其中WaveOutEvent用于打开音频输出设备,AudioFileReader用于读取音频文件,最终调用WaveOutEvent类的Play、Pause、Stop函数实现音频的播放、暂停、停止功能,主要代码及程序效果如下所示(代码主要参考自参考文献2):
private WaveOutEvent m_outputDevice;
private AudioFileReader m_audioFile;
private bool m_close = false;
public frmMain()
{
InitializeComponent();
m_outputDevice = new WaveOutEvent();
m_outputDevice.PlaybackStopped += OnPlaybackStopped;
}
private void OnPlaybackStopped(object sender, StoppedEventArgs args)
{
if(!m_close)
{
return;
}
m_outputDevice.Dispose();
m_outputDevice = null;
m_audioFile.Dispose();
m_audioFile = null;
}
private void btnBrowse_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
txtSoundFile.Text = openFileDialog.FileName;
}
}
private void btnPlay_Click(object sender, EventArgs e)
{
if(m_audioFile != null)
{
m_audioFile.Dispose();
}
m_close = false;
m_audioFile = new AudioFileReader(txtSoundFile.Text);
m_outputDevice.Init(m_audioFile);
m_outputDevice.Play();
}
private void btnPause_Click(object sender, EventArgs e)
{
if(m_outputDevice.PlaybackState== PlaybackState.Paused)
{
m_outputDevice.Play();
btnPause.Text = "暂 停";
}
else
{
m_outputDevice.Pause();
btnPause.Text = "继 续";
}
}
private void btnStop_Click(object sender, EventArgs e)
{
m_close = true;
m_outputDevice.Stop();
}
NAudio中通过WaveInEvent和WaveFileWriter实现音频的录制,其中WaveInEvent用于打开音频输入设备,WaveFileWriter用于写入音频文件,最终调用WaveInEvent类的StartRecording、StopRecording函数实现录音的开始、停止功能,主要代码及程序效果如下所示(代码主要参考自参考文献2):
private void btnStartRecord_Click(object sender, EventArgs e)
{
m_waveFileWriter = new WaveFileWriter(Path.Combine(txtOutputDir.Text, String.Format("{0}.wav", txtOutputFileName.Text)), m_waveInEvent.WaveFormat);
m_waveInEvent.DataAvailable += (s, a) =>
{
m_waveFileWriter.Write(a.Buffer, 0, a.BytesRecorded);
if (m_waveFileWriter.Position > m_waveInEvent.WaveFormat.AverageBytesPerSecond * 30)
{
m_waveInEvent.StopRecording();
}
};
m_waveInEvent.StartRecording();
}
private void btnEndRecord_Click(object sender, EventArgs e)
{
m_waveInEvent.StopRecording();
}
录制好的音频,再使用NAudio播放时会提示“Invalid WAV file - No fmt chunk ”,但是可以在KMPlayer中播放,暂时还未找到解决办法。还有一个问题,就是录音时把电脑播放的声音和人在电脑前说话的声音都录进去了,后续看能不能只录电脑播放的声音。
补充说明:报错的问题已经解决,详见参考文献3,只需停止录制后,将m_waveFileWriter和m_waveInEvent释放掉即可,参考文献3中说的是Dispose掉m_waveFileWriter,不过我是全都给dispose掉了。后续测试的时候发现调用m_waveFileWriter.Flush()也行,输出的文件也不会报错。
参考文献:
[1]https://it.sohu.com/a/710438265_121124363
[2]https://github.com/naudio/NAudio
[3]https://stackoverflow.com/questions/38523255/invalid-wav-file-no-fmt-chunk-found-after-recording-using-naudio