开发带音频频谱的音乐播放器:如何结合Bass.dll实现后台播放?
用Bass.dll实现UWP后台音频播放的完整方案
我之前帮不少开发者解决过类似的问题——用第三方音频库(比如Bass)做UWP播放器时,后台音频总是掉链子。核心问题在于:Bass本身并不直接对接UWP的系统后台音频管道,光加清单权限远远不够,得把Bass的音频流和SystemMediaTransportControls(SMTC)绑定起来,让系统“认”这是需要后台保持的媒体播放。下面是一步步的实操方案:
1. 确认基础配置(别漏这步!)
先检查你的Package.appxmanifest是否配置正确,这是前提:
- 打开清单文件,切换到Capabilities标签,勾选Background Media Playback
- 同时确保Internet (Client)(如果播放网络音频)相关权限已正确设置
- 手动编辑XML的话,要确保Capabilities节点下有:
<Capability Name="backgroundMediaPlayback"/>
2. 让Bass的音频流适配后台播放
Bass默认的音频会话不会被系统识别为“后台可保留”的,所以要先调整Bass的配置:
- 在初始化Bass之前,先设置
BASS_CONFIG_DEV_NONSTOP配置项,告诉Bass不要因为应用进入后台就停止音频设备:
这个配置会让Bass的音频设备保持活跃,即使应用不在前台。// 初始化Bass前调用 BASS_SetConfig(BASS_CONFIG_DEV_NONSTOP, 1); // 然后正常初始化Bass if (!BASS_Init(-1, 44100, BASS_DEVICE_DEFAULT, IntPtr.Zero, IntPtr.Zero)) { // 处理初始化失败逻辑 }
3. 集成SystemMediaTransportControls(SMTC)核心
这是让系统“接管”后台音频管理的关键,SMTC负责和系统锁屏、媒体按键、音量面板交互,同时告诉系统“这个音频需要后台保持”:
3.1 初始化SMTC
在播放器初始化时,获取SMTC实例并启用必要的控制:
private SystemMediaTransportControls _smtc; private void InitSMTC() { _smtc = SystemMediaTransportControls.GetForCurrentView(); // 启用需要的媒体控制按钮 _smtc.IsPlayEnabled = true; _smtc.IsPauseEnabled = true; _smtc.IsNextEnabled = true; _smtc.IsPreviousEnabled = true; // 启用SMTC _smtc.Enabled = true; // 绑定按钮点击事件,响应锁屏/媒体按键的操作 _smtc.ButtonPressed += Smtc_ButtonPressed; // 设置初始播放状态 _smtc.PlaybackStatus = MediaPlaybackStatus.Closed; }
3.2 同步Bass播放状态到SMTC
每次Bass的播放状态变化(播放/暂停/停止),都要更新SMTC的状态,让系统同步感知:
// 当你调用BASS_ChannelPlay开始播放时 private void StartPlayback() { if (BASS_ChannelPlay(_streamHandle, false)) { _smtc.PlaybackStatus = MediaPlaybackStatus.Playing; // 同时可以更新媒体信息,让锁屏显示 UpdateSMTCMediaInfo("歌曲名", "艺术家", "专辑名"); } } // 当暂停播放时 private void PausePlayback() { BASS_ChannelPause(_streamHandle); _smtc.PlaybackStatus = MediaPlaybackStatus.Paused; } // 更新锁屏显示的媒体信息 private void UpdateSMTCMediaInfo(string title, string artist, string album) { var updater = _smtc.DisplayUpdater; updater.Type = MediaPlaybackType.Music; updater.MusicProperties.Title = title; updater.MusicProperties.Artist = artist; updater.MusicProperties.AlbumTitle = album; // 如果有专辑封面,可以设置Thumbnail // updater.Thumbnail = RandomAccessStreamReference.CreateFromUri(new Uri("封面URL")); updater.Update(); }
3.3 响应SMTC的控制事件
当用户在锁屏或按下媒体按键时,要同步操作Bass的播放:
private void Smtc_ButtonPressed(SystemMediaTransportControls sender, SystemMediaTransportControlsButtonPressedEventArgs args) { switch (args.Button) { case SystemMediaTransportControlsButton.Play: StartPlayback(); break; case SystemMediaTransportControlsButton.Pause: PausePlayback(); break; case SystemMediaTransportControlsButton.Next: // 实现下一曲逻辑 LoadNextTrack(); break; case SystemMediaTransportControlsButton.Previous: // 实现上一曲逻辑 LoadPreviousTrack(); break; } }
4. 处理应用生命周期
UWP应用进入后台时,要确保音频播放不被中断,同时避免不必要的操作:
- 在
App.xaml.cs的Suspending事件中,不要暂停音频,反而要确保SMTC状态正确:private void OnSuspending(object sender, SuspendingEventArgs e) { var deferral = e.SuspendingOperation.GetDeferral(); // 不要在这里暂停Bass播放,只需要确保SMTC状态正确 if (_smtc != null) { // 如果当前正在播放,保持状态 if (BASS_ChannelIsActive(_streamHandle) == BASS_ACTIVE_PLAYING) { _smtc.PlaybackStatus = MediaPlaybackStatus.Playing; } } deferral.Complete(); } - 当应用从后台恢复时,同步Bass的状态到SMTC即可。
常见坑点提醒
- 用对Bass版本:确保你用的是适配UWP的Bass版本(比如BassUWP.dll),桌面版的Bass.dll在UWP中可能会有会话权限问题,导致后台播放失效。
- 不要滥用后台资源:后台播放时,不要做大量的CPU/IO操作,否则系统可能会终止你的应用进程。
- 测试锁屏状态:一定要在锁屏状态下测试,有时候前台正常,但锁屏下因为SMTC状态没同步导致停止。
内容的提问来源于stack exchange,提问作者jason_wun




