C# 如何在应用程序上从MediaElement切换到BackgroundMediaPlayer失去焦点

C# 如何在应用程序上从MediaElement切换到BackgroundMediaPlayer失去焦点,c#,xaml,windows-store-apps,windows-phone-8.1,C#,Xaml,Windows Store Apps,Windows Phone 8.1,我有一个类似PlayMusic.xaml的音乐播放器页面,它使用MediaPlayer元素播放音乐 每当用户单击后退按钮、Windows按钮或锁定屏幕时,我想切换BackgroundMediaPlayer 我还想继续唱这首歌。(如BackgroundMediaPlayer应从第30秒开始继续) Windows phone中是否有任何机制,比如当我从MediaPlayer失去焦点时,我可以切换到BackgroundMediaPlayer继续播放音乐 注意:我可以直接使用BackgroundMedi

我有一个类似PlayMusic.xaml的音乐播放器页面,它使用
MediaPlayer
元素播放音乐

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

我还想继续唱这首歌。(如
BackgroundMediaPlayer
应从第30秒开始继续)

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


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

在您的软件包清单中,您需要转到声明选项卡并选择后台任务,然后选择音频,并为您的应用程序选择入口点

在您的Xaml中

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

我希望这能解决你的目的。。。有关更多详细信息,请参考

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

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

  • 我希望这有帮助。我仍在努力解决这个问题(这是一个巨大的尝试和错误尝试),但它似乎正在发挥作用。

    感谢您提供的信息,但我特别要求Windows Phone 8.1。您提供的解决方案适用于Windows应用商店应用程序。(不是电话)请看我的相关问题
    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;
        }
    }