在后台播放媒体Play media in the background

本文介绍了如何配置应用,以便在应用从前台移至后台后,媒体可以继续播放。This article shows you how to configure your app so that media continues to play when your app moves from the foreground to the background. 这意味着,即使在用户已最小化你的应用、返回到主屏幕,或已以其他方式离开你的应用后,你的应用仍可继续播放音频。This means that even after the user has minimized your app, returned to the home screen, or has navigated away from your app in some other way, your app can continue to play audio.

后台音频播放的方案包括:Scenarios for background audio playback include:

  • 长期运行的播放列表: 用户可以简单地弹出前台应用以选择并启动一个播放列表,在此之后,用户期望该播放列表在后台继续播放。Long-running playlists: The user briefly brings up a foreground app to select and start a playlist, after which the user expects the playlist to continue playing in the background.

  • 使用任务切换器: 用户可以简单地打开前台应用以开始播放音频,然后使用任务切换程序切换到另一个打开的应用。Using task switcher: The user briefly brings up a foreground app to start playing audio, then switches to another open app using the task switcher. 用户期望该音频在后台继续播放。The user expects the audio to continue playing in the background.

本文所述的后台音频实现将使你的应用通常在所有 Windows 设备(包括移动设备、桌面设备和 Xbox)上运行。The background audio implementation described in this article will allow your app to run universally on all Windows devices including Mobile, Desktop, and Xbox.

备注

本文中的代码改编自 UWP 后台音频示例The code in this article was adapted from the UWP Background Audio sample.

单进程模型说明Explanation of one-process model

Windows 10 版本 1607 引入的全新单进程模型极大地简化了启用后台音频的进程。With Windows 10, version 1607, a new single-process model has been introduced that greatly simplifies the process of enabling background audio. 以前,需要你的应用管理后台进程以及前台应用,然后在两个进程之间手动通知状态更改。Previously, your app was required to manage a background process in addition to your foreground app and then manually communicate state changes between the two processes. 在新的模型下,只需将后台音频功能添加到应用部件清单,该应用就会在移至后台之后自动继续播放音频。Under the new model, you simply add the background audio capability to your app manifest, and your app will automatically continue playing audio when it moves to the background. EnteredBackgroundLeavingBackground 这两个新的应用程序生命周期事件使应用可以得知它何时进入和退出后台。Two new application lifecycle events, EnteredBackground and LeavingBackground let your app know when it is entering and leaving the background. 当你的应用移至、过渡到后台或从中移出时,系统强制执行的内存约束可能会发生改变,因此你可以使用这些事件检查当前内存消耗并释放资源,以便保持在限制之下。When your app moves into the transitions to or from the background, the memory constraints enforced by the system may change, so you can use these events to check your current memory consumption and free up resources in order to stay below the limit.

通过消除复杂的进程间通信和状态管理,新模型使你可以使用明显减少的代码极快地实现后台音频。By eliminating the complex cross-process communication and state management, the new model allows you to implement background audio much more quickly with a significant reduction in code. 但是,当前版本中仍支持双进程模型,以实现向后兼容性。However, the two-process model is still supported in the current release for backwards compatibility. 有关详细信息,请参阅传统后台音频模型For more information, see Legacy background audio model.

后台音频要求Requirements for background audio

当应用在后台运行时,该应用必须满足音频播放的以下要求。Your app must meet the following requirements for audio playback while your app is in the background.

  • 后台媒体播放功能添加到应用部件清单,如本文中的后面部分所述。Add the Background Media Playback capability to your app manifest, as described later in this article.
  • 如果应用禁止自动将 MediaPlayer 与系统媒体传输控件 (SMTC) 集成(例如,将 CommandManager.IsEnabled 属性设置为 false),那么必须手动实现与 SMTC 的集成,才可以支持后台媒体播放。If your app disables the automatic integration of MediaPlayer with the System Media Transport Controls (SMTC), such as by setting the CommandManager.IsEnabled property to false, then you must implement manual integration with the SMTC in order to enable background media playback. 如果使用的是 MediaPlayer 之外的 API(如 AudioGraph),还必须手动与 SMTC 集成,才可以播放音频(如果你希望应用移至后台之后音频继续播放)。You must also manually integrate with SMTC if you are using an API other than MediaPlayer, such as AudioGraph, to play audio if you want to have the audio continue to play when your app moves to the background. 手动控制系统媒体传输控件的“将系统媒体传输控件用于后台音频”部分介绍了 SMTC 集成的最低要求。The minimum SMTC integration requirements are described in the "Use the system media transport controls for background audio" section of Manual control of the System Media Transport Controls.
  • 应用处于后台时,不得超出系统为后台应用设置的内存使用量限制。While your app is in the background, you must stay under the memory usage limits set by the system for background apps. 管理后台内存的指南将在文本后面部分提供。Guidance for managing memory while in the background is provided later in this article.

后台媒体播放清单功能Background media playback manifest capability

若要支持后台音频,必须将后台媒体播放功能添加到应用部件清单文件(即 Package.appxmanifest)。To enable background audio, you must add the background media playback capability to the app manifest file, Package.appxmanifest.

使用清单设计器将功能添加到应用部件清单To add capabilities to the app manifest using the manifest designer

  1. 在 Microsoft Visual Studio 的 解决方案资源管理器中,双击 " appxmanifest.xml " 项,打开应用程序清单的设计器。In Microsoft Visual Studio, in Solution Explorer, open the designer for the application manifest by double-clicking the package.appxmanifest item.
  2. 选择“功能”选项卡。Select the Capabilities tab.
  3. 选中 " 后台媒体播放 " 复选框。Select the Background Media Playback check box.

若要通过手动编辑应用部件清单 xml 来设置功能,请首先确保已在 Package 元素中定义 uap3 命名空间前缀。To set the capability by manually editing the app manifest xml, first make sure that the uap3 namespace prefix is defined in the Package element. 如果尚未定义,请如下所示进行添加。If not, add it as shown below.

<Package
  xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
  xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
  xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
  xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3"
  IgnorableNamespaces="uap uap3 mp">

接下来,将 backgroundMediaPlayback 功能添加到 Capabilities 元素:Next, add the backgroundMediaPlayback capability to the Capabilities element:

<Capabilities>
    <uap3:Capability Name="backgroundMediaPlayback"/>
</Capabilities>

处理前台和后台之间的转换Handle transitioning between foreground and background

当应用从前台移至后台时,将引发 EnteredBackground 事件。When your app moves from the foreground to the background, the EnteredBackground event is raised. 并且当应用返回前台时,将引发 LeavingBackground 事件。And when your app returns to the foreground, the LeavingBackground event is raised. 由于这些事件都是应用生命周期事件,因此应该在创建应用时为这些事件注册处理程序。Because these are app lifecycle events, you should register handlers for these events when your app is created. 在默认项目模板中,这意味着将它添加到 App.xaml.cs 中的 App 类构造函数。In the default project template, this means adding it to the App class constructor in App.xaml.cs.

public App()
{
    this.InitializeComponent();
    this.Suspending += OnSuspending;

    this.EnteredBackground += App_EnteredBackground;
    this.LeavingBackground += App_LeavingBackground;
}

添加一个变量以跟踪你当前是否在后台运行。Create a variable to track whether you are currently running in the background.

bool _isInBackgroundMode = false;

当引发 EnteredBackground 事件时,请设置跟踪变量以指示当前正在后台运行。When the EnteredBackground event is raised, set the tracking variable to indicate that you are currently running in the background. 不得在 EnteredBackground 事件中执行长时间运行的任务,因为这可能会导致用户感觉过渡到后台非常慢。You should not perform long-running tasks in the EnteredBackground event because this may cause the transition to the background to appear slow to the user.

private void App_EnteredBackground(object sender, EnteredBackgroundEventArgs e)
{
    _isInBackgroundMode = true;
}

LeavingBackground 事件处理程序中,应该设置跟踪变量,以指示应用不再在后台运行。In the LeavingBackground event handler, you should set the tracking variable to indicate that your app is no longer running in the background.

private void App_LeavingBackground(object sender, LeavingBackgroundEventArgs e)
{
    _isInBackgroundMode = false;
}

内存管理要求Memory management requirements

处理前台和后台之间转换的最重要部分是管理你的应用使用的内存。The most important part of handling the transition between foreground and background is managing the memory that your app uses. 由于在后台运行会减少系统允许应用保留的内存资源,因此还应该注册 AppMemoryUsageIncreasedAppMemoryUsageLimitChanging 事件。Because running in the background will reduce the memory resources your app is allowed to retain by the system, you should also register for the AppMemoryUsageIncreased and AppMemoryUsageLimitChanging events. 引发这些事件时,你应该检查应用的当前内存使用量和当前限制,然后根据需要减少内存使用量。When these events are raised, you should check your app's current memory usage and the current limit, and then reduce your memory usage if needed. 有关如何在后台运行时减少内存使用量的信息,请参阅在将应用移动到后台时释放内存For information about reducing your memory usage while running in the background, see Free memory when your app moves to the background.

后台媒体应用的网络可用性Network availability for background media apps

不会从流或文件创建的所有网络感知的媒体源将使网络连接保持活动状态(在检索远程内容时),不需要检索时会释放网络连接。All network aware media sources, those that are not created from a stream or a file, will keep the network connection active while retrieving remote content, and they release it when they are not. 尤其是 MediaStreamSource,依赖应用程序使用 SetBufferedRange 向平台正确报告已正确缓存的范围。MediaStreamSource, specifically, relies on the application to correctly report the correct buffered range to the platform using SetBufferedRange. 完全缓存整个内容后,网络不再以应用的名义保留。After the entire content is fully buffered, the network will no longer be reserved on the app’s behalf.

如果需要在媒体不在下载时在后台执行网络调用,则必须在诸如 MaintenanceTriggerTimeTrigger 等相应任务中包括这些网络调用。If you need to make network calls that occur in the background when media is not downloading, these must be wrapped in an appropriate task like MaintenanceTrigger or TimeTrigger. 有关详细信息,请参阅 通过后台任务支持应用For more information, see Support your app with background tasks.