信息
您所需的主题如下所示。但此主题未包含在此库中。

Windows Phone 8 的后台音频概述

2014/6/18

适用于:Windows Phone 8

您可以编写在后台播放音频的 Windows Phone 应用。这意味着,即使用户已通过按“返回”按键或“开始”按键离开您的应用,您的应用程序也可以继续播放音频。本文讨论后台音频应用程序的组件和它们的协作方式。

本主题包括以下部分。

后台音频应用程序利用后台代理(在 Windows Phone OS 7.1 中引入)。有关后台代理的更多信息,请参见 Windows Phone 8 的多任务处理

Windows Phone 上的所有媒体都是通过 Zune 媒体队列播放的。后台音频应用程序向 Zune 媒体队列发送命令以设置当前堆栈、开始播放、暂停、快进、后退等。通过在 BackgroundAudioPlayer 类中调用方法来完成该操作。然后,Instance 对象与 Zune 媒体队列通信以操作音频的播放。

通用音量控制 (UVC) 是一组控件,当正在播放音频或当用户按音量控制开关时显示这些控件。UVC 还操作 Zune 媒体队列。因此,当您随后从应用程序开始播放某些内容时,可以使用 UVC 控制音频。UVC 向您应用程序中的 AudioPlayerAgent 发送事件,从而允许您实现播放列表逻辑。将在本主题的后面部分对 AudioPlayerAgent 进行详细讨论。

后台音频应用无需特殊配置,即可在锁定屏幕下运行。

有两种类型的后台音频应用程序。一种类型实现简单的播放列表并将一个包含媒体文件地址的 Uri 传递给 Zune 媒体队列以设置当前曲目。Uri 可以是手机的本地或远程地址。在任何一种情况下,音频需要是 Windows Phone 支持的类型才能播放。有关有效的视频文件类型,请参见支持的 Windows Phone 8 媒体编解码器

另一种类型的后台音频应用程序使用 MediaStreamSource 实现音频流以向播放系统输送音频示例。此流的格式可以是您需要的任何格式,因为您实现一个从 MediaStreamSource 派生的类来处理音频的流处理以及对音频的解码。实现 MediaStreamSource 不在本文的讨论范围内。

这两种类型的应用程序共享多个部分。我们将开始讨论实现播放列表的应用程序。然后,我们将讨论使用 MediaStreamSource (MSS) 实现流处理的部分。

播放列表应用程序

若要创建后台音频播放列表应用程序,您必须实现两个部分:提供用于控制播放的用户界面的应用程序和实现从 AudioPlayerAgent 派生的类的程序集。您必须实现的这两个部分在下图中以绿色显示。

Background audio playlist app architecture

应用程序 UI

应用程序用户界面是您实现您应用程序的用户界面的位置。如果您使用 Visual Studio 模板创建您的初始应用程序,则该应用程序将在 MainPage.xaml 和 MainPage.xaml.cs 文件中。您的主应用程序使用 Instance 设置 Zune 媒体队列中的当前曲目,启动播放等等。

AudioPlayerAgent

您的 AudioPlayerAgent 由操作系统进行实例化,以通过您应用程序的用户界面或通过 UVC 处理用户所请求的操作。

您的 AudioPlayerAgent 在后台运行并调用 BackgroundAudioPlayer 的实例,该实例随后调用 Zune 媒体队列以实际播放音频。

您的代理完成处理 OnUserAction(BackgroundAudioPlayer, AudioTrack, UserAction, Object)OnPlayStateChanged(BackgroundAudioPlayer, AudioTrack, PlayState)OnError(BackgroundAudioPlayer, AudioTrack, Exception, Boolean) 之后,调用 NotifyComplete() 以让操作系统知道您已完成并且可以安全地从内存中删除代理。

使用 Visual Studio 中的“Windows Phone 音频播放代理”模板创建新的 AudioPlayerAgent 项目并将该项目添加到您的解决方案中。

Background audio playback agent template

然后,从主应用程序项目中添加对新 AudioPlayerAgent 的引用。

BackgroundAudioSolution

右键单击应用程序项目中的“引用”节点,然后选择“添加引用...”

对音频应用程序进行流处理

若要创建流音频应用程序,您必须实现与播放列表应用程序相同的部分。具体来说,就是您必须创建一个提供用户界面的主应用程序,以及一个 AudioPlayerAgent。对于流音频应用程序,您还必须实现从 AudioStreamingAgent 派生的一个类以及从 MediaStreamSource 派生的一个类。您必须实现的这些部分在下图中以绿色显示。

Background audio streaming app architecture

音频流代理

AudioStreamingAgent 负责通过在传递到 OnBeginStreaming(AudioTrack, AudioStreamer) 方法的 AudioStreamer 实例上调用 SetSource(MediaStreamSource) 来创建并将 Zune 媒体队列指向 MediaStreamSource

使用 Visual Studio 中的“Windows Phone 音频流代理”模板创建新的 AudioStreamingAgent 项目并将该项目添加到您的解决方案中。

Background audio streaming agent template

MediaStreamSource

Zune 媒体队列调用您的 MediaStreamSource 来请求音频示例。创建 MediaStreamSource 不在本主题的讨论范围内。有关更多信息,请参见 MediaStreamSource 示例

后台代理生命周期

您的 AudioPlayerAgent 是由 BackgroundAudioPlayer 在需要时创建的,用于处理来自您应用程序的用户界面或来自 UVC 的 UserAction 请求。

您的 AudioStreamingAgent 是由 BackgroundAudioPlayer 在需要新流时创建的。创建代理之后,BackgroundAudioPlayer 在您的 AudioStreamingAgent 中调用 OnBeginStreaming(AudioTrack, AudioStreamer) 方法。

当后台代理调用 Abort()NotifyComplete() 时释放后台代理。

其他后台音频类

后台音频应用程序利用其他类来实现音频播放器体验。

BackgroundAudioPlayer

BackgroundAudioPlayer 类与 Zune 媒体队列连接。在 Instance 上调用方法以影响设备上正在播放的音频。

AudioTrack

AudioTrack 类表示有关某个曲目的元数据,包括标题、艺术家、专辑以及曲目的 URI。如果 URI 设置为 null,系统假设您设置对 MediaStreamSource 的跟踪。在此情况下,可以使用 Tag 属性将信息从 AudioPlayerAgent 传递到 AudioStreamingAgent

AudioStreamer

AudioStreamer 的实例传递给 OnBeginStreaming(AudioTrack, AudioStreamer)。在 OnBeginStreaming 的实现中,调用 SetSource(MediaStreamSource) 以指向从 MediaStreamSource(提供音频示例)派生的一个类。

本节详细介绍了创建播放后台音频的应用程序时要实现的一些最佳做法。

调试

在编码、调试、编辑代码和重新启动调试的过程中,调试器可能会在您重新启动调试时将自身连接到后台音频代理,而不是您的应用程序。若要避免出现这种情况,您需要确保后台代理在应用程序启动时处于关闭状态。要实现这一点,有一种简便的方法是将对 Close() 的调用放到 App 类的构造函数中。如果您是通过 Visual Studio 模板创建的应用,则 App 类构造函数中会包含一项检查,以了解该应用程序是否正在调试器下运行。可将对 BackgroundAudioPlayer.Instance.Close 的调用放在此 if 语句中。

// Show graphics profiling information while debugging.
if (System.Diagnostics.Debugger.IsAttached)
{
    // Close the background audio player in case it 
    // was running from a previous debugging session.
    BackgroundAudioPlayer.Instance.Close();

    // ...

处理用户操作

BackgroundAudioPlayer 未对 UserAction 请求的数量施加任何限制。通过 UI(通过您的应用或通用音量控制 (UVC))调用的操作排成队列并一个个地进行处理。AudioPlayerAgent 没有确定是否存在连续调用的方法。需要网络请求的 SkipNextSkipPreviousPlay 调用可能需要几秒钟的时间。

对用户体验的影响是:

  1. 无论调用花费的时间长短,都将按顺序处理对 SkipNextSkipPreviousPlay 的连续调用。

  2. 每次调用允许 30 秒的时间。

  3. 由于 PlayPause 操作未获得优先权,因此代理可能花费几秒钟(甚至几分钟)的时间才能响应用户操作。这与立即响应 PlayPause 的预期用户体验产生矛盾。

因此限制排队的 SkipNextSkipPrevious 请求的数量并给予 PlayPause 较高的优先级。后台音频播放器示例只是在处理请求之前禁用“下一个”“上一个”按钮。

处理状态转换

BackgroundAudioPlayer 的状态更改时,可以从 PlayStateChangedEventArgs 捕获有关状态转换的信息。您可以确定在音频播放器进入当前播放状态之前发生的 CurrentPlayStateIntermediatePlayState

以下为可使用由事件参数提供的信息来处理的状态转换的一些示例。

  1. IntermediatePlayState = BufferingStopped

  2. CurrentPlayState = Playing

  1. IntermediatePlayState = TrackEnded

  2. CurrentPlayState = Stopped

MediaElement 和 BackgroundAudioPlayer

混合 BackgroundAudioPlayerMediaElement 进行音频播放时,要十分小心。

  1. Close()必须在切换到 MediaElement 播放之前调用 。

  2. 只有一个媒体队列。您的应用程序不能暂停后台音频,不能使用 MediaElement 播放某些内容,而且不能继续播放后台音频流。

内存和运行时约束

  • AudioPlayerAgent 的实现必须在 30 秒内调用 NotifyComplete()Abort()

  • AudioStreamingAgent 的实现则允许无限时运行。

  • 两种类型的后台音频代理都托管在同一进程中,并且共享以下最大内存限制。

    • 在具有 Windows Phone 8 Update 3(即版本 8.0.10492 或更高版本)的 Windows Phone 8 上为 25 MB。

    • 在不具有 Windows Phone 8 Update 3(即 8.0.10492 之前的版本)的 Windows Phone 8 上为 20 MB。

    • 在 Windows Phone OS 7.1 上为 15 MB。

  • 在调试器下运行时,Windows Phone 操作系统会忽略内存和运行时约束。

显示: