当前位置: 首页 > 新闻动态 > 网络资讯

C# NAudio音频处理方法 C#如何录制和播放音频

作者:畫卷琴夢 浏览: 发布日期:2026-01-30
[导读]:用C#+NAudio录播音频关键在于选对类、配对格式、关好资源:WaveInEvent兼容性好但延迟高,WasapiCapture低延迟但需Win8+;WAV用WaveFileWriter,MP3需NAudio.Lame且须匹配WaveFormat;播放用WaveFileReader(WAV)或AudioFileReader(MP3),资源必须按事件顺序释放。
用 C# + NAudio 录播音频关键在于选对类、配对格式、关好资源:WaveInEvent 兼容性好但延迟高,WasapiCapture 低延迟但需 Win8+;WAV 用 WaveFileWriter,MP3 需 NAudio.Lame 且须匹配 WaveFormat;播放用 WaveFileReader(WAV)或 AudioFileReader(MP3),资源必须按事件顺序释放。

用 C# + NAudio 录制和播放音频,不是“能不能”,而是“选对类、配对格式、关好资源”——三者错一个,就卡在无声、崩溃或文件打不开。

WaveInEvent 还是 WasapiCapture?看你要不要低延迟

两者都能录麦克风,但底层机制不同:

  • WaveInEvent:基于 Windows WaveIn API,兼容性极好(Win7+ 都行),但延迟偏高(通常 100–300ms),适合普通录音、语音笔记等对实时性不敏感的场景
  • WasapiCapture:基于 WASAPI Loopback 或 Capture 模式,支持独占模式,延迟可压到 20–50ms,适合监听、ASR 前置采集、伴奏跟唱等;但 Win7 不支持,且需注意默认设备权限(尤其静音/禁用时会抛异常)

实操建议:开发初期先用 WaveInEvent 快速验证流程;上线前若需低延迟,再切 WasapiCapture 并加设备存在性检查(capture.DeviceState == DeviceState.Active)。

WaveFileWriter 写 WAV vs LameMP3FileWriter 直出 MP3

NAudio 本身不原生支持 MP3 编码,LameMP3FileWriter 是靠 NAudio.Lame 封装了 LAME 库。关键差异在格式与资源管理:

  • WAV:无压缩,WaveFileWriter 只做容器封装,写入快、无依赖,但文件大(1 分钟 ≈ 10MB);必须用 WaveFormat 显式声明采样率/位深/通道数,且要和录音源一致(否则播放失真)
  • MP3:需额外安装 NAudio.Lame NuGet 包;编码过程占 CPU(尤其多路并发时),比特率选 128 是音质/体积平衡点;注意 LameMP3FileWriter 构造后必须调用 Dispose()Flush(),否则末尾几帧丢失,MP3 文件无法播放

常见错误:LameMP3FileWriter 构造时传了 new WaveFormat(44100, 16, 1),但录音设备实际输出是立体声 → 编码器静默失败,无报错,生成空文件。

WaveOutEvent 播放时卡顿/爆音?检查缓冲与线程安全

WaveOutEvent 是事件驱动播放器,不是“丢进去就完事”。典型问题都出在数据供给节奏上:

  • 播放 WAV:用 WaveFileReader 最稳妥,它内部已处理好缓冲和 seek;别直接用 FileStream +

    WaveFormat 手动喂数据,容易因读取阻塞导致断续
  • 播放 MP3:必须用 AudioFileReader(它自动识别格式并转为 PCM),不能用 WaveFileReader —— 后者只认 RIFF 头,读 MP3 会抛 ArgumentException: Not a WAVE file
  • 播放中修改音量:WaveOutEvent.Volume 是 float 类型(0.0–1.0),设 1.5 会静音;动态调节务必在 UI 线程外用 InvokeDispatcher 同步,否则偶发 ObjectDisposedException

实操建议:播放前加一句 if (!reader.CanRead) throw new InvalidOperationException("音频流不可读");,比事后抓耳挠腮强。

最常被忽略的其实是资源释放顺序:录音时 capture.StopRecording() 后,要等 RecordingStopped 事件触发再 Dispose() lameWriterwaveWriter;播放时 player.Stop() 后,必须等 PlaybackStopped 事件再释放 reader。跳过这一步,下次录音/播放大概率遇到“设备忙”或“文件被占用”。

免责声明:转载请注明出处:http://shjed.com/news/775014.html

扫一扫高效沟通

多一份参考总有益处

免费领取网站策划SEO优化策划方案

请填写下方表单,我们会尽快与您联系
感谢您的咨询,我们会尽快给您回复!