微信公众号“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