测试.net开源音频库NAudio

news/2025/3/20 0:07:30/

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


http://www.ppmy.cn/news/1065934.html

相关文章

ubuntu安装goland

下载并解压goland sudo tar -C /opt/ -xzvf goland-2023.1.3.tar.gz配置应用图标 新建文件: vim /usr/share/applications/goland.desktop文件中写入如下内容: [Desktop Entry] TypeApplication NameGoLand Icon/opt/GoLand/bin/goland.png Exec/op…

springboot之@Async异步定时任务自定义线程池

在应用中经常会遇到定时执行任务的需求,这时采用异步的方式开启一个定时任务,通常引用Async注解,但直接使用会有风险,当我们没有指定线程池时,会默认使用其Spring自带的 SimpleAsyncTaskExecutor 线程池,会…

04_21 slab分配器 分配对象实战

目的 ( slab块分配器分配内存)&#xff0c;编写个内核模块&#xff0c;创建名称为 “mycaches"的slab描述符&#xff0c;小为40字节, align为8字节&#xff0c; flags为0。 从这个slab描述符中分配个空闲对象。 代码大概 内核模块中 #include <linux/version.h>…

Linux 基金会宣布正式进驻中国

在 LinuxCon 2017 &#xff08;北京&#xff09;即将召开前夕&#xff0c;我们Linux 中国会同 51CTO、开源中国对 Linux 基金会执行董事 Jim Zemlin 进行了一场远跨大洋的视频专访。 在这次专访中&#xff0c;Jim 先生回答了几个开源界和互联网领域关注的问题&#xff0c;并披…

Leetcode刷题之1658. 将 x 减到 0 的最小操作数

题目: 算法分析: 可以看出,这道题本意是从计算两侧和为x 的数字, 要求数量最少, 那我们可以反向思考, 假如整个数组的和为sum, 那么我们就可以求中间部分和为sum-x的数字(当然必须连续), 当中间部分的数字同时达到和为sum-x以及长度最长两个要求时, 两侧数字也就达到了和为x以…

Arduino开发Seeed Studio XIAO RP2040

前言 准备一些硬件设备 Seeed Studio XIAO RP2040 一块电脑——window 或 Mac 一台Type-C数据线 某些USB线只支持充电&#xff0c;无传输数据功能。 连接电脑 按住boot按钮&#xff0c;然后将 Seeed Studio XIAO RP2040 连接到 PC。 2. 如果电脑文件管理器上显示了“RPI-RP2…

前端性能优化之js优化

文章目录 引言一、浏览器加载js文件过程二、浏览器加载js和图片的对比三、浏览器加载js资源占总资源加载时间的比例四、v8的编译原理概述五、代码层面优化&#xff0c;提高V8编译效率1. 函数优化1. 减少函数大小和复杂度2. 避免使用动态特性3. 避免使用eval()和with语句4. 使用…

昇腾Ascend+C编程入门教程(纯干货)

2023年5月6日&#xff0c;在昇腾AI开发者峰会上&#xff0c;华为正式发布了面向算子开发场景的昇腾Ascend C编程语言。Ascend C原生支持C/C编程规范&#xff0c;通过多层接口抽象、并行编程范式、孪生调试等技术&#xff0c;极大提高了算子的开发效率&#xff0c;帮助AI开发者低…