I have a music player page like PlayMusic.xaml and it uses MediaPlayer
element to play music.
I want to switch BackgroundMediaPlayer
whenever user clicks back button or Windows Button or Lock Screen.
I also would like to continue where ever song is remained. (Like BackgroundMediaPlayer
should continue from 30th second)
Is there any mechanism in Windows phone like when ever when I lose focus from MediaPlayer
I can switch to BackgroundMediaPlayer
and continue playing music?
Note: I can directly use BackgroundMediaPlayer
then it always plays music but on this case I cannot use MediaPlayer
in PlayMusic.xaml which gives ability to watch video clip, fullscreen and seek controls.
There is no specific mechanism for this that I know of. You can build one yourself, but it is not simple:
- First, you need to have a working background audio task and know how to communicate with it (this is not easy in itself, this example helped me a bit).
- When you start playing anything in the
MediaPlayer
, your background audio task gets canceled. When you use it again, its Run
method is called once more in the same process. Because of this, the background task must have its lifecycle properly managed, i.e. you need to subscribe to events and get a deferral in the Run
method, and unsubscribe from events, call BackgroundMediaPlayer.Shutdown()
and release the deferral in the Cancel
event. Also, I found that I need to subscribe to BackgroundMediaPlayer.MessageReceivedFromBackground
in the foreground process again after the task is restarted, because the restart seems to clear it.
- You can detect that the
MediaPlayer
"lost focus" (and start background playback) when the page is being navigated from. However, this will not cover the case of the user multitasking away from your application or the case of the screen being turned off. You can catch these using the CoreWindow.GetForCurrentThread().Activated
event.
- When you are switching to background audio, you need to pass it the current position. This can be done using messaging (
BackgroundMediaPlayer.SendMessageToBackground
).
- You can start the background playback on the specified position by turning
AutoPlay
off and setting the position after MediaOpened
fires.
I hope this helps. I am still battling with this (it is one giant trial and error endeavor), but it seems to be working.
In Your Package Manifest you need to go to Declarations Tab and select Background Tasks and then select Audio and also select an entry point for your applications.
Inside Your Xaml
<MediaElement AutoPlay="True"
AreTransportControlsEnabled="True"
x:Name="musicPlayer"
Source="Assets/video1.mp4"
AudioCategory="BackgroundCapableMedia"
CurrentStateChanged="MusicPlayer_CurrentStateChanged"/>
Code Behind 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;
}
}
This would i hope solve your purpose... For further details you can refer MSDN Link.