【问题标题】:How to switch from MediaElement to BackgroundMediaPlayer on Application lose focus如何在应用程序失去焦点时从 MediaElement 切换到 BackgroundMediaPlayer
【发布时间】:2015-01-31 09:02:18
【问题描述】:

我有一个像 PlayMusic.xaml 这样的音乐播放器页面,它使用MediaPlayer 元素来播放音乐。

每当用户单击返回按钮或 Windows 按钮或锁定屏幕时,我想切换 BackgroundMediaPlayer

我也想在有歌曲的地方继续。 (就像BackgroundMediaPlayer 应该从第 30 秒开始)

Windows phone 中是否有任何机制,例如当我从MediaPlayer 失去焦点时,我可以切换到BackgroundMediaPlayer 并继续播放音乐?

注意:我可以直接使用BackgroundMediaPlayer,然后它总是播放音乐,但在这种情况下,我不能在 PlayMusic.xaml 中使用MediaPlayer,它提供了观看视频剪辑、全屏和搜索控件的能力。

【问题讨论】:

    标签: c# xaml windows-store-apps windows-phone-8.1


    【解决方案1】:

    据我所知,没有具体的机制。您可以自己构建一个,但这并不简单:

    1. 首先,您需要有一个工作的后台音频任务并知道如何与之通信(这本身并不容易,this example 帮助了我一点)。
    2. 当您开始播放MediaPlayer 中的任何内容时,您的后台音频任务将被取消。当您再次使用它时,它的Run 方法会在同一进程中再次调用。因此,后台任务必须对其生命周期进行妥善管理,即您需要在Run 方法中订阅事件并获得延迟,并取消订阅事件,调用BackgroundMediaPlayer.Shutdown() 并在Cancel 中释放延迟事件。另外,我发现任务重启后,需要再次在前台进程订阅BackgroundMediaPlayer.MessageReceivedFromBackground,因为重启后好像清除了。
    3. 您可以在导航页面时检测到MediaPlayer“失去焦点”(并开始后台播放)。但是,这不会涵盖用户远离您的应用程序进行多任务处理的情况或屏幕被关闭的情况。您可以使用 CoreWindow.GetForCurrentThread().Activated 事件捕获这些。
    4. 当您切换到背景音频时,您需要将当前位置传递给它。这可以使用消息传递 (BackgroundMediaPlayer.SendMessageToBackground) 来完成。
    5. 您可以通过关闭AutoPlay 并在MediaOpened 触发后设置位置来在指定位置开始后台播放。

    我希望这会有所帮助。我仍在与此作斗争(这是一项巨大的试错工作),但它似乎正在发挥作用。

    【讨论】:

      【解决方案2】:

      在您的包清单中,您需要转到 Declarations Tab 并选择 Background Tasks,然后选择 Audio 并选择一个入口点您的应用程序。

      Xaml 内部

      <MediaElement AutoPlay="True"
          AreTransportControlsEnabled="True"
          x:Name="musicPlayer"
          Source="Assets/video1.mp4"
          AudioCategory="BackgroundCapableMedia"
          CurrentStateChanged="MusicPlayer_CurrentStateChanged"/>
      

      C# 背后的代码

      SystemMediaTransportControls systemControls;
      
      public BlankPage7()
      {
          this.InitializeComponent();
      
          // 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;
      
      }
      
      private void SystemControls_ButtonPressed(SystemMediaTransportControls sender, SystemMediaTransportControlsButtonPressedEventArgs args)
      {
          switch (args.Button)
          {
              case SystemMediaTransportControlsButton.Play:
                  PlayMedia();
                  break;
      
              case SystemMediaTransportControlsButton.Pause:
                  PauseMedia();
                  break;
      
              default:
                  break;
          }
      }
      
      private 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;
          }
      }
      
      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();
          });
      }
      
      protected override void OnNavigatedFrom(NavigationEventArgs e)
      {
          if (systemControls != null)
          {
              systemControls.ButtonPressed -= SystemControls_ButtonPressed;
              systemControls.IsPlayEnabled = false;
              systemControls.IsPauseEnabled = false;
      
              systemControls.PlaybackStatus = MediaPlaybackStatus.Closed;
          }
      }
      

      我希望这能解决您的目的...有关更多详细信息,您可以参考MSDN Link.

      【讨论】:

      • 感谢您的信息,但我特别要求 Windows Phone 8.1。您提供的解决方案适用于 Windows 应用商店应用。 (不是电话)请在此处查看我的相关问题stackoverflow.com/questions/28185424/…
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-08-05
      • 1970-01-01
      • 1970-01-01
      • 2020-10-02
      • 2016-01-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多