如何在后台播放音频
语言: HTML | XAML

如何在后台播放音频 (XAML)

[ 本文适用于编写 Windows 运行时应用的 Windows 8.x 和 Windows Phone 8.x 开发人员。如果你要针对 Windows 10 进行开发,请参阅 最新文档 ]

若要在后台播放音频,请声明 Audio 后台任务,并处理 SystemMediaTransportControls 按钮。

要点  Windows 8.1 引入了 SystemMediaTransportControls 类,它可以替代 MediaControl 类。 你应该在应用中使用 SystemMediaTransportControls
 
注意  如果使视频流能够在后台播放,则当应用被切换到后台时,你将可以听到音频却看不到视频。这是设计使然。 这降低了设备在后台播放视频时的电量需求。
 

若要在操作中将此功能作为完整媒体播放示例的一部分进行查看,请参阅媒体播放详细信息

先决条件

本主题假定你知道如何使用 C++、C# 或 Visual Basic 创建基本的 Windows 应用商店应用。有关创建你的第一个应用的帮助,请参阅使用 C# 或 Visual Basic 创建你的第一个 Windows 应用商店应用

本主题假定你熟悉 MediaElement 类。 有关使用 MediaElement 类的介绍,请参阅快速入门:视频和音频

说明

步骤 1: 声明后台音频任务

你必须显式声明你的应用将执行后台任务。

  1. 在 Microsoft Visual Studio 中打开应用的项目文件。
  2. 在解决方案资源管理器中双击 Package.appmanifest 文件以打开 Package.appmanifest 对话框。
  3. 单击“声明” 选项卡,然后从“可用声明” 下拉框中选择“后台任务”
  4. 单击“添加”,然后选中“音频”复选框。

    也可以通过使用在上面步骤中为音频创建的相同清单文件为视频流进行后台声明。若要执行此操作,请将“任务类型”属性设置为音频。

  5. 指定入口点。在大多数情况下,如果你的项目被命名为 Foo,则你将指定 Foo.App

步骤 2: 设置 AudioCategory

MediaElement 上的 AudioCategory 属性设置为 CommunicationsBackgroundCapableMedia。你也可以在代码中指定该属性。

以下 XAML 将会创建一个 MediaElement 并将 AudioCategory 设置为 BackgroundCapableMedia


<MediaElement Name="media" 
              AudioCategory="BackgroundCapableMedia" 
              Source="Somesong.mp3" />


步骤 3: 支持 SystemMediaTransportControls

Windows 8.1 引入了 SystemMediaTransportControls 类,它可以替代 MediaControl 类。 你应该在应用中使用 SystemMediaTransportControls。为了完整性,下面包含了使用 MediaControl 实现后台音频支持的步骤,但你只应当使用 SystemMediaTransportControls。请参阅如何使用系统媒体传输控件来获得关于使用 SystemMediaTransportControls 的更详细的操作方法。

即使应用声明要在后台播放音频,该应用必须通过将 IsPlayEnabledIsPauseEnabled 设置为 true 来启用 SystemMediaTransportControls 播放和暂停按钮。该应用还必须处理 ButtonPressed 事件,它可以在按下系统媒体传输控件按钮时通知应用。通过提供此最小事件处理支持,你可以为用户提供在无需将应用带至前台的情况下,播放或暂停音频的功能。

要从 ButtonPressed 事件处理程序更新 UI 线程上的对象(例如 MediaElement 对象),你必须通过 CoreDispatcher 来封送调用。 这是因为不会从 UI 线程调用 ButtonPressed 事件处理程序。 只有 UI 线程可以修改 UI 线程上的对象。 如果你尝试从非 UI 线程修改 UI 对象,则会引发异常。 以下代码示例展示了如何执行此操作。

除了处理 ButtonPressed 事件,还必须在媒体状态更改(例如,当它暂停或播放)时通知 SystemMediaTransportControls。 若要向 SystemMediaTransportControl 通知媒体状态更改,请将其 PlaybackStatus 属性设置为 MediaPlaybackStatus 中的值之一。

以下是某个代码,它可以在后台播放音频的应用中设置 SystemMediaTransportControls。该代码执行以下步骤:

以下代码创建 MediaElement


<MediaElement x:Name="musicPlayer" 
          Source="Music/music1.mp3"
          AudioCategory="BackgroundCapableMedia"
          CurrentStateChanged="MusicPlayer_CurrentStateChanged" />


以下代码设置 SystemMediaTransportControls


SystemMediaTransportControls systemControls;

void InitializeTransportControls()
{
    // Hook up app to system transport controls.
    systemControls = SystemMediaTransportControls.GetForCurrentView();
    systemControls.ButtonPressed += SystemControls_ButtonPressed;

    // Register to handle the following system transpot control buttons.
    systemControls.IsPlayEnabled = true;
    systemControls.IsPauseEnabled = true;
}


以下代码用于处理 MediaElementCurrentStateChanged 事件,并更新 SystemMediaTransportControlsPlaybackStatus 属性。


void MusicPlayer_CurrentStateChanged(object sender, RoutedEventArgs e)
{
    switch (musicPlayer.CurrentState)
    {
        case MediaElementState.Playing:
            systemControls.PlaybackStatus = MediaPlaybackStatus.Playing;
            break;
        case MediaElementState.Paused:
            systemControls.PlaybackStatus = MediaPlaybackStatus.Paused;
            break;
        case MediaElementState.Stopped:
            systemControls.PlaybackStatus = MediaPlaybackStatus.Stopped;
            break;
        case MediaElementState.Closed:
            systemControls.PlaybackStatus = MediaPlaybackStatus.Closed;
            break;
        default:
            break;
    }
}


以下是用来播放和暂停 MediaElementButtonPressed 事件处理程序和相应的帮助程序方法的代码。请注意,对 PlayPause 的调用都使用 Dispatcher.RunAsync 通过 CoreDispatcher 封送到 UI 线程。


void SystemControls_ButtonPressed(SystemMediaTransportControls sender,
    SystemMediaTransportControlsButtonPressedEventArgs args)
{
    switch (args.Button)
    {
        case SystemMediaTransportControlsButton.Play:
            PlayMedia();
            break;
        case SystemMediaTransportControlsButton.Pause:
            PauseMedia();
            break;
        default:
            break;
    }
}

async void PlayMedia()
{
    await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
    {
        musicPlayer.Play();
    });
}

async void PauseMedia()
{
    await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
    {
        musicPlayer.Pause();
    });
}


有关 SystemMediaTransportControl 的详细信息,请参阅如何使用系统媒体传输控件SystemMediaTransportControls 示例

步骤 4: 在 MediaControl 上注册处理程序(仅适用于 Windows 8)

要点  

MediaControl 在 Windows 8.1 中已被替换 SystemMediaTransportControl。你应当改用 SystemMediaTransportControl

 

即使应用注册为在后台播放音乐或视频,应用也必须处理以下 MediaControl 事件:PlayPressedPausePressedStopPressedPlayPauseTogglePressed。通过提供此最小事件处理支持,你可以为用户提供在无需将应用程序带至前台的情况下,在后台播放或暂停音乐或视频流的功能。

在大多数情况下,你可能希望创建传输控件(用于播放、停止、暂停的按钮)以控制 MediaElement。本文不介绍这些内容,但有关如何执行这些操作的示例,请参阅快速入门:视频和音频快速入门:创建媒体播放器应用程序

MediaControl 是一个静态类,从而你只可以直接在类事件上添加事件处理程序。

  1. 在“解决方案资源管理器”窗格中,单击应用的 C# 文件以打开该文件。 在此示例中,我们使用 MainPage.xaml.cs 文件。
  2. 使用以下代码为应用注册“播放”、“暂停”、“停止”和“播放/暂停”切换按钮:
    
    MediaControl.PlayPauseTogglePressed += MediaControl_PlayPauseTogglePressed;
    MediaControl.PlayPressed += MediaControl_PlayPressed;
    MediaControl.PausePressed += MediaControl_PausePressed;
    MediaControl.StopPressed += MediaControl_StopPressed;
    
    
    
    
  3. 使用以下代码处理“播放”、“暂停”、“停止”和“播放/暂停”事件发生时所引发的事件。
    
    void MediaControl_StopPressed(object sender, object e)
    {
        // media is a MediaElement defined in XAML
        media.Stop();
    }
    
    void MediaControl_PausePressed(object sender, object e)
    {
        // media is a MediaElement defined in XAML
        media.Pause();
    }
    
    void MediaControl_PlayPressed(object sender, object e)
    {
        // media is a MediaElement defined in XAML
        media.Play();
    }
    
    void MediaControl_PlayPauseTogglePressed(object sender, object e)
    {
        if (MediaControl.IsPlaying == true)
        {
            // media is a MediaElement defined in XAML
            media.Pause();
        }
        else
        {
            // media is a MediaElement defined in XAML
            media.Play();
        }
    }
    
    
    

备注

注意  如果你的应用执行除流式播放音频或视频任务之外的其他任务,则当应用失去焦点并且不再是活动窗口时,该应用应停止执行非媒体相关工作。 你的应用仍流式播放音频,并且如果播放的是音频-视频流,则视频流将自动停止。
 

完整示例

有关如何流式播放音频和视频的完整示例,请参阅 XAML 媒体播放示例

相关主题

如何使用系统媒体传输控件
SystemMediaTransportControls 示例
播放管理器示例
快速入门:视频和音频
快速入门:创建媒体播放器应用程序
媒体播放详细信息

 

 

显示:
© 2016 Microsoft