The RPC server is not available (Excep_FromHResult 0x800706BA) when calling Background Task in UWP

2

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.

  1. Created Universal Project (Windows Universal)
  2. Added following code to send Background Message

    BackgroundMediaPlayer.MessageReceivedFromBackground += BackgroundMediaPlayer_MessageReceivedFromBackground;

  3. Added Windows Component Runtime (Windows Universal) with following code

  4. 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!

win-universal-app
windows-10
windows-10-universal
windows-10-mobile
asked on Stack Overflow Mar 16, 2016 by ARH • edited Mar 16, 2016 by Mehrzad Chehraz

1 Answer

1

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;
         }
     }
 }
answered on Stack Overflow Mar 18, 2016 by Sunteen Wu

User contributions licensed under CC BY-SA 3.0