I have developed UWP application where it play audio files in Background or when the phone is locked. The application works fine and everything seems perfect for 5-10 minutes. After that when I run the app, I cannot play audio file and I am getting the exception attached in the subject. However, If I restart the app, everything works fine again. I have followed below steps and added following code and projects to do the task.
Added following code to send Background Message
BackgroundMediaPlayer.MessageReceivedFromBackground += BackgroundMediaPlayer_MessageReceivedFromBackground;
Added Windows Component Runtime (Windows Universal) with following code
Added Entry Point and Background Task in Package.appxmanifest
public sealed class AudioPlayer : IBackgroundTask {
private BackgroundTaskDeferral deferral;
private SystemMediaTransportControls systemmediatransportcontrol;
public void Run(IBackgroundTaskInstance taskInstance) {
systemmediatransportcontrol = BackgroundMediaPlayer.Current.SystemMediaTransportControls;
systemmediatransportcontrol.ButtonPressed += systemmediatransportcontrol_ButtonPressed;
systemmediatransportcontrol.PropertyChanged += systemmediatransportcontrol_PropertyChanged;
systemmediatransportcontrol.IsEnabled = true;
systemmediatransportcontrol.IsPauseEnabled = true;
systemmediatransportcontrol.IsPlayEnabled = true;
systemmediatransportcontrol.IsNextEnabled = true;
systemmediatransportcontrol.IsPreviousEnabled = true;
BackgroundMediaPlayer.Current.CurrentStateChanged += Current_CurrentStateChanged;
BackgroundMediaPlayer.MessageReceivedFromForeground += BackgroundMediaPlayer_MessageReceivedFromForeground;
deferral = taskInstance.GetDeferral();
taskInstance.Canceled += TaskInstance_Canceled;
taskInstance.Task.Completed += Taskcompleted;
}
void Taskcompleted(BackgroundTaskRegistration sender, BackgroundTaskCompletedEventArgs args) {
deferral.Complete();
}
private void TaskInstance_Canceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason) {
try {
systemmediatransportcontrol.ButtonPressed -= systemmediatransportcontrol_ButtonPressed;
systemmediatransportcontrol.PropertyChanged -= systemmediatransportcontrol_PropertyChanged;
BackgroundMediaPlayer.Shutdown(); // shutdown media pipeline
}
catch (Exception) {
}
deferral.Complete();
}
void Current_CurrentStateChanged(MediaPlayer sender, object args) {
MediaPlayer player = sender;
switch (player.CurrentState) {
case MediaPlayerState.Playing:
systemmediatransportcontrol.PlaybackStatus = MediaPlaybackStatus.Playing;
break;
case MediaPlayerState.Paused:
systemmediatransportcontrol.PlaybackStatus = MediaPlaybackStatus.Stopped;
break;
}
}
void systemmediatransportcontrol_ButtonPressed(SystemMediaTransportControls sender, SystemMediaTransportControlsButtonPressedEventArgs args) {
try {
switch (args.Button) {
case SystemMediaTransportControlsButton.Play:
playTrack();
break;
case SystemMediaTransportControlsButton.Pause:
stopBeforePlaying();
break;
case SystemMediaTransportControlsButton.Next:
stopBeforePlaying();
nextTrack();
break;
case SystemMediaTransportControlsButton.Previous:
stopBeforePlaying();
previousTrack();
break;
}
}
catch (Exception) {
//Debug.WriteLine(ex.Message);
}
}
void stopBeforePlaying() {
MediaPlayer player = BackgroundMediaPlayer.Current;
if (player != null)
player.Pause();
}
void BackgroundMediaPlayer_MessageReceivedFromForeground(object sender, MediaPlayerDataReceivedEventArgs e) {
object foregroundMessageType;
if (e.Data.TryGetValue(ApplicationSettingsConstants.ChapterStatus, out foregroundMessageType)) {
//do something here
}
}
void UpdateUVCOnNewTrack() {
//update buttons here
}
async void playTrack() {
MediaPlayer player = BackgroundMediaPlayer.Current;
try {
if (...) {
//load track
player.Play();
}
else {
player.Pause();
MessageService.SendMessageToForeground(ApplicationSettingsConstants.ChapterStatus, (short)ChapterStatus.ForegroundFileNotFound);
}
}
catch (System.IO.DirectoryNotFoundException) {
player.Pause();
MessageService.SendMessageToForeground(ApplicationSettingsConstants.ChapterStatus, (short)ChapterStatus.ForegroundFileNotFound);
}
catch (System.IO.FileNotFoundException) {
player.Pause();
MessageService.SendMessageToForeground(ApplicationSettingsConstants.ChapterStatus, (short)ChapterStatus.ForegroundFileNotFound);
}
finally {
UpdateUVCOnNewTrack();
}
}
void nextTrack() {
//load next track
}
void previousTrack() {
//load previous here
}
}
Why I am getting the above error?
Note: I have followed Microsoft Sample Background Audio for Windows Phone 8.1 Sample to enable background audio player.
Thanks!
Some situations may cause this exception in BackgroundAudio.Reference to Windows-universal-samples/Samples/BackgroundAudio/cs/BackgroundAudio/Scenario1.xaml.cs, the comment of function ResetAfterLostBackground()
The background task did exist, but it has disappeared. Put the foreground back into an initial state. Unfortunately, any attempts to unregister things on BackgroundMediaPlayer.Current will fail with the RPC error once the background task has been lost..
So add this function, and invoke it where you catch the error.
const int RPC_S_SERVER_UNAVAILABLE = -2147023174; // 0x800706BA
private void ResetAfterLostBackground()
{
BackgroundMediaPlayer.Shutdown();
try
{
BackgroundMediaPlayer.MessageReceivedFromBackground += BackgroundMediaPlayer_MessageReceivedFromBackground;
}
catch (Exception ex)
{
if (ex.HResult == RPC_S_SERVER_UNAVAILABLE)
{
throw new Exception("Failed to get a MediaPlayer instance.");
}
else
{
throw;
}
}
}
User contributions licensed under CC BY-SA 3.0