You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

开发带音频频谱的音乐播放器:如何结合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_SetConfig(BASS_CONFIG_DEV_NONSTOP, 1);
    // 然后正常初始化Bass
    if (!BASS_Init(-1, 44100, BASS_DEVICE_DEFAULT, IntPtr.Zero, IntPtr.Zero))
    {
        // 处理初始化失败逻辑
    }
    
    这个配置会让Bass的音频设备保持活跃,即使应用不在前台。

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.csSuspending事件中,不要暂停音频,反而要确保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

火山引擎 最新活动