C#中SoundPlayer循环播放的背景音乐被其他音效打断如何解决?
解决方案
问题原因
SoundPlayer 底层依赖Windows原生的 PlaySound API,该API的设计限制是同一进程同一时间仅支持单路音频播放,新的播放请求会直接中断正在进行的播放任务,这就是背景音乐被音效打断的根本原因。
无需额外线程的实现方案
方案1:使用Windows Media Player COM组件(适用于WinForm/WPF/.NET Framework项目)
该方案不需要手动创建线程,媒体播放逻辑由系统媒体服务后台托管,和其他音效播放通道完全独立。
操作步骤:
- 右键项目 → 选择「添加」→「引用」→ 切换到COM选项卡 → 找到并勾选「Windows Media Player」,确认添加引用
- 背景音乐播放代码如下:
// 实例化独立的WMP播放器 WMPLib.WindowsMediaPlayer bgMusicPlayer = new WMPLib.WindowsMediaPlayer(); // 配置音频文件路径 bgMusicPlayer.URL = @"bgmusic.wav"; // 开启循环播放 bgMusicPlayer.settings.setMode("loop", true); // 调整音量(可选,取值范围0-100) bgMusicPlayer.settings.volume = 40; // 启动播放 bgMusicPlayer.controls.play();
后续使用SoundPlayer播放其他短音效时,不会对正在播放的背景音乐产生任何影响。需要停止背景音乐时调用 bgMusicPlayer.controls.stop() 即可。
方案2:使用AudioGraph(适用于.NET Core 3.0+/ .NET 5+ 跨平台项目)
如果使用新版.NET开发,不需要依赖COM组件,可以用AudioGraph类实现,它原生支持多路音频混合播放,不需要额外线程:
// 初始化音频图 AudioGraphSettings settings = new AudioGraphSettings(AudioRenderCategory.Media); CreateAudioGraphResult result = await AudioGraph.CreateAsync(settings); if (result.Status != AudioGraphCreationStatus.Success) return; AudioGraph graph = result.Graph; // 创建音频文件输入节点 StorageFile bgFile = await StorageFile.GetFileFromPathAsync(@"bgmusic.wav"); CreateAudioFileInputNodeResult fileInputResult = await graph.CreateFileInputNodeAsync(bgFile); if (fileInputResult.Status != AudioFileNodeCreationStatus.Success) return; AudioFileInputNode fileInput = fileInputResult.FileInputNode; // 配置无限循环 fileInput.LoopCount = null; // 连接到系统输出设备 fileInput.AddOutgoingConnection(graph.QuantumSizeSelectionMode = QuantumSizeSelectionMode.LowestLatency); // 启动播放 graph.Start();
该方案的所有播放逻辑由音频引擎后台处理,不需要手动维护线程,多路音频会自动混音输出。
内容的提问来源于stack exchange,提问作者user456789
相关产品推荐
相关产品推荐

