UWP 的视频后台播放

Windows App 和 iOS App 一样,只有前台 App 会保持运行,切换到后台的会自动被系统暂停。Win10 Desktop 可以窗口化运行 Windows App 了,这个限制就被改成了最小化1 的 App 会被暂停,只要窗口还在,没有焦点也能继续运行。

可是这仍然解决不了视频播放器的问题,一旦被最小化,视频就会暂停播放。于是 Win10 Desktop 提供了 API,让 App 最小化之后,视频的 声音2 还能继续播放。

ps. 隔壁 iOS 的 App Switcher 里视频还是能继续播放,Win10 Desktop 的 Aero Peek 和 Win10 Mobile 的 App Switcher 全是一张截图了事。

按照官方文档,对于使用 XAML 的 App 来说,配置后台播放很简单。只需要

  1. 在 App Manifest (package.manifest) 里新建 Background Task,type 选择 Audio,Entry point 指向自己(一般是 <Project Name>.App
  2. MediaElementAudioCategory 属性设置为 BackgroundCapableMedia
  3. 配置 SystemMediaTransportControlsIsPlayEnabledIsPauseEnabled 属性为 true

之前做了斗鱼 (http://www.douyutv.com) 的非官方播放器 豆奶直播,于是用上了这个特性,也遇到了几个坑。

1. SystemMediaTransportControlsIsEnabled 属性?

SystemMediaTransportControls 这个类提供了系统级播放控制支持,对于 Win10 Desktop,所有设备都能看到的有任务栏上的 Thumbnail Toolbar

系统也会响应实体音量键和键盘上的媒体控制键,显示这个

这两个地方的按键是否启用,就对应 SystemMediaTransportControlsIsXXXEnabled 属性,IsPlayEnabledIsPauseEnabled 就是播放和暂停键。

但是光设置 IsXXXEnabled 属性并没有什么卯月,仔细一看还有个 IsEnabled 属性,要设置成 true,这些按键才能真正启用。于是一开始想当然就觉得:

  • 既然官方说要把 IsPlayEnabledIsPauseEnabled 属性设置为 true
  • 那就是说必须要让用户可以不打开 App 就能暂停和恢复播放
  • IsEnabled 必然也要设置成 true

所以豆奶直播虽然是做实时直播,App 内没有播放控制,但是我仍然响应了系统的控制。

然而

这并不需要。

即使系统播放控制处在禁用状态,只要 IsPlayEnabledIsPauseEnabledtrue,你的 App 就能在后台继续播放视频的音频。

2. 我不播放了,要把 IsPlayEnabledIsPauseEnabled 改回 false 吗?

其实对于我来说,1 解决之后,2 就不存在了。不过遇到了,还是提一下,而且对于一般播放器也有用。

视频播放完毕,离开播放界面,自然需要禁用系统播放控制,就顺手把 IsEnabled, IsPlayEnabledIsPauseEnabled 全设置回 false 了,这样的后果就是:

下一次打开视频,就没法后台播放了

很明显这是个 bug!对于这样一个赶工出来的系统,有 bug 也很正常。

因为我的 App 本来就不需要播放控制,就没有改 IsEnabled,就完全不影响使用。至于一般播放器,我就没测试了,说不定只设置 IsEnabled 可以保留后台播放能力。

其它

  • 其实这个方法,就是让系统在 App 最小化的时候不暂停。因此使用此方法,大概可以实现任意 UWP 在 Win10 Desktop 上后台运行,而且是直接 App 主 exe 运行,不像以前通过地理位置跟踪实现 background task 持续运行。具体待测试。

  • 其实不只是最小化,非激活的虚拟桌面上的 App 也会被暂停。

  • 只有 Win10 Desktop (其实是 Win 8+) 上可用,Win10 Mobile 没有效果。而 WPA81 的 BackgroundMediaPlayer 则在 Win10 全平台上可用了。

结束

那么就是以上了,总之写了一篇出来凑数,下次再见,大概。