.NET C# WinForms:实现音频同时播放避免背景音中断
解决Windows Forms中背景音乐与点击音效同时播放的问题
问题根源
SoundPlayer依赖Windows原生波形音频播放机制,同一时间仅能播放一个音频流,因此播放点击音效时会中断背景音乐。- 额外注意:
SoundPlayer仅支持WAV格式,你的点击音效使用MP3格式,本身就无法通过SoundPlayer正常播放,需先转格式或更换播放方式。
方案一:使用NAudio库(推荐)
NAudio是.NET生态中轻量灵活的音频处理库,支持多音频流同时播放,兼容MP3、WAV等多种格式。
- 安装NAudio
在NuGet包管理器中搜索并安装NAudio,或在Package Manager Console执行命令:
Install-Package NAudio
- 代码实现
在窗体类中声明全局音频对象避免播放中断,同时实现多音频流播放:
// 全局变量,维持背景音乐播放实例 private WaveOutEvent _backgroundPlayer; private AudioFileReader _backgroundAudio; private void FormMain_Load(object sender, EventArgs e) { WindowState = FormWindowState.Maximized; // 初始化背景音乐并设置循环 _backgroundAudio = new AudioFileReader(@"D:\Escola\Licenciatura\4º Ano\1º Semestre\Progig\Projeto\beyblade\Assets\Sounds\soundtrack.wav"); _backgroundPlayer = new WaveOutEvent(); _backgroundPlayer.Init(_backgroundAudio); _backgroundPlayer.Play(); _backgroundAudio.LoopCount = int.MaxValue; // 设置循环播放 } private void exitToolStripMenuItem_Click_1(object sender, EventArgs e) { // 播放点击音效,使用using自动释放资源 using (var clickPlayer = new WaveOutEvent()) { var clickAudio = new AudioFileReader(@"D:\Escola\Licenciatura\4º Ano\1º Semestre\Progig\Projeto\beyblade\Assets\Sounds\click.mp3"); clickPlayer.Init(clickAudio); clickPlayer.Play(); // 等待音效播放完成,避免提前释放导致中断 while (clickPlayer.PlaybackState == PlaybackState.Playing) { Application.DoEvents(); System.Threading.Thread.Sleep(10); } } } // 窗体关闭时释放背景音乐资源 private void FormMain_FormClosing(object sender, FormClosingEventArgs e) { _backgroundPlayer?.Stop(); _backgroundAudio?.Dispose(); _backgroundPlayer?.Dispose(); }
方案二:使用WindowsMediaPlayer控件(无需额外库)
利用WindowsForms自带的WindowsMediaPlayer控件,支持多实例同时播放不同音频。
添加控件
在工具箱中找到WindowsMediaPlayer控件拖到窗体上,设置Visible = false隐藏,命名为wmpBackground。代码实现
private void FormMain_Load(object sender, EventArgs e) { WindowState = FormWindowState.Maximized; // 播放背景音乐并开启循环 wmpBackground.URL = @"D:\Escola\Licenciatura\4º Ano\1º Semestre\Progig\Projeto\beyblade\Assets\Sounds\soundtrack.wav"; wmpBackground.settings.setMode("loop", true); wmpBackground.Ctlcontrols.play(); } private void exitToolStripMenuItem_Click_1(object sender, EventArgs e) { // 动态创建实例播放点击音效 using (var wmpClick = new WMPLib.WindowsMediaPlayer()) { wmpClick.URL = @"D:\Escola\Licenciatura\4º Ano\1º Semestre\Progig\Projeto\beyblade\Assets\Sounds\click.mp3"; wmpClick.Ctlcontrols.play(); // 等待音效播放完成 while (wmpClick.playState != WMPLib.WMPPlayState.wmppsStopped) { Application.DoEvents(); System.Threading.Thread.Sleep(10); } } }
额外建议
- 尽量使用相对路径替代硬编码的绝对路径,避免程序在其他设备上因路径问题无法运行。
- 不推荐用
SoundPlayer通过多线程实现多音频播放,不仅不支持MP3,还容易出现同步异常。
内容的提问来源于stack exchange,提问作者Filipe Cruz
相关产品推荐
相关产品推荐

