You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

如何在UWP两层架构后台音乐播放器中实现播放/暂停等键盘快捷键

嘿,针对你开发的这款采用旧版前台后台分离架构的UWP音乐播放器,要实现播放、暂停、上一曲、下一曲的键盘控制功能,我整理了一套经过验证的规范实现方案,分步骤给你拆解:

一、核心依赖:SystemMediaTransportControls

UWP系统自带的SystemMediaTransportControls是处理全局媒体键(比如键盘上的播放/暂停、上一曲/下一曲专用按键)的核心组件,不管你的应用是前台活跃还是后台静默播放,它都能捕获这些按键事件并触发对应操作。因为你的架构是前后台分离的,所以核心配置要放在后台播放任务中,确保后台播放时也能响应按键指令。

二、后台播放任务的SMTC配置

在你的后台播放任务类(继承自IBackgroundTask)的Run方法里,完成以下配置:

2.1 初始化并启用SMTC按钮

var smtc = SystemMediaTransportControls.GetForCurrentView();
// 启用需要响应的媒体按键
smtc.IsPlayEnabled = true;
smtc.IsPauseEnabled = true;
smtc.IsPreviousEnabled = true;
smtc.IsNextEnabled = true;
// 注册按键按下的回调事件
smtc.ButtonPressed += Smtc_ButtonPressed;
// 告诉系统当前的播放状态,让系统媒体控件同步显示
smtc.PlaybackStatus = MediaPlaybackStatus.Playing;

2.2 实现按键事件处理逻辑

在回调方法里,根据按下的按键类型,调用你的后台播放逻辑:

private void Smtc_ButtonPressed(SystemMediaTransportControls sender, SystemMediaTransportControlsButtonPressedEventArgs args)
{
    switch (args.Button)
    {
        case SystemMediaTransportControlsButton.Play:
            // 调用你自己封装的后台播放方法
            YourBackgroundPlayer.Play();
            sender.PlaybackStatus = MediaPlaybackStatus.Playing;
            break;
        case SystemMediaTransportControlsButton.Pause:
            YourBackgroundPlayer.Pause();
            sender.PlaybackStatus = MediaPlaybackStatus.Paused;
            break;
        case SystemMediaTransportControlsButton.Previous:
            YourBackgroundPlayer.SwitchToPreviousTrack();
            // 可选:更新系统媒体控件上显示的歌曲信息
            UpdateSmtcMediaMetadata();
            break;
        case SystemMediaTransportControlsButton.Next:
            YourBackgroundPlayer.SwitchToNextTrack();
            UpdateSmtcMediaMetadata();
            break;
    }
}

2.3 可选:更新媒体元数据(优化体验)

如果想让系统通知中心或全局媒体控件显示当前播放的歌曲名、歌手等信息,可以添加这个方法:

private void UpdateSmtcMediaMetadata()
{
    var smtc = SystemMediaTransportControls.GetForCurrentView();
    var displayUpdater = smtc.DisplayUpdater;
    
    displayUpdater.Type = MediaPlaybackType.Music;
    displayUpdater.MusicProperties.Title = "当前播放歌曲名";
    displayUpdater.MusicProperties.Artist = "歌手名称";
    // 可选:设置专辑封面图
    // displayUpdater.Thumbnail = RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/AlbumCover.jpg"));
    
    displayUpdater.Update();
}
三、前台UI的普通键盘快捷键支持(可选)

如果需要在前台页面活跃时,支持普通键盘按键(比如空格键暂停/播放、左右箭头切换曲目),可以在前台页面的KeyDown事件中处理:

private void MainPage_KeyDown(object sender, KeyRoutedEventArgs e)
{
    switch (e.Key)
    {
        case VirtualKey.Space:
            // 发送指令给后台播放任务
            var currentStatus = YourBackgroundPlayer.CurrentPlaybackStatus;
            if (currentStatus == MediaPlaybackStatus.Playing)
            {
                BackgroundMediaPlayer.SendMessageToBackground(new ValueSet { { "Command", "Pause" } });
            }
            else
            {
                BackgroundMediaPlayer.SendMessageToBackground(new ValueSet { { "Command", "Play" } });
            }
            e.Handled = true;
            break;
        case VirtualKey.Left:
            BackgroundMediaPlayer.SendMessageToBackground(new ValueSet { { "Command", "Previous" } });
            e.Handled = true;
            break;
        case VirtualKey.Right:
            BackgroundMediaPlayer.SendMessageToBackground(new ValueSet { { "Command", "Next" } });
            e.Handled = true;
            break;
    }
}

同时,后台播放任务需要监听前台发来的消息:

// 在后台任务初始化时注册消息监听
BackgroundMediaPlayer.MessageReceivedFromForeground += BackgroundMediaPlayer_MessageReceivedFromForeground;

private void BackgroundMediaPlayer_MessageReceivedFromForeground(object sender, MediaPlayerDataReceivedEventArgs args)
{
    if (args.Data.TryGetValue("Command", out object commandObj) && commandObj is string command)
    {
        var smtc = SystemMediaTransportControls.GetForCurrentView();
        switch (command)
        {
            case "Play":
                YourBackgroundPlayer.Play();
                smtc.PlaybackStatus = MediaPlaybackStatus.Playing;
                break;
            case "Pause":
                YourBackgroundPlayer.Pause();
                smtc.PlaybackStatus = MediaPlaybackStatus.Paused;
                break;
            case "Previous":
                YourBackgroundPlayer.SwitchToPreviousTrack();
                UpdateSmtcMediaMetadata();
                break;
            case "Next":
                YourBackgroundPlayer.SwitchToNextTrack();
                UpdateSmtcMediaMetadata();
                break;
        }
    }
}
四、关键注意事项
  • 后台任务注册:一定要在Package.appxmanifest中添加"Background Tasks"声明,选择"Audio"类型,这样系统才会允许后台任务持续运行处理音频播放。
  • 状态同步:前台UI和后台播放状态要保持一致,可以通过监听BackgroundMediaPlayer.Current的状态变化事件,或者让后台主动发送消息给前台来同步UI。
  • 权限问题:不需要额外申请权限,音频播放和媒体键控制是UWP音频类应用的默认能力。

内容的提问来源于stack exchange,提问作者Keval Langalia

火山引擎 最新活动