2

我開發了UWP應用程序,它在後臺播放音頻文件或手機被鎖定。該應用程序工作正常,一切似乎完美的5-10分鐘。之後,當我運行該應用程序時,我無法播放音頻文件,並且獲取了該主題中附帶的例外。但是,如果我重新啓動應用程序,一切都可以正常工作。我已經按照以下步驟操作,並添加了以下代碼和項目來完成此任務。當調用UWP中的後臺任務時,RPC服務器不可用(Excep_FromHResult 0x800706BA)

  1. 創建通用項目(視窗通用)
  2. 添加以下代碼來發送背景消息

    BackgroundMediaPlayer.MessageReceivedFromBackground + = BackgroundMediaPlayer_MessageReceivedFromBackground;

  3. 添加了Windows組件運行時(視窗通用)與下面的代碼

  4. 新增的切入點和後臺任務在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 
        } 
    } 
    

爲什麼我收到上述錯誤?

注意:我已按照Microsoft Sample Background Audio for Windows Phone 8.1 Sample啓用背景音頻播放器。

謝謝!

+0

@Mehrzad我試圖格式化,但它沒有工作,謝謝 – ARH

回答

1

某些情況下可能會導致此異常BackgroundAudio.Reference到Windows-universal-samples/Samples/BackgroundAudio/cs/BackgroundAudio/Scenario1.xaml.cs,功能ResetAfterLostBackground()

後臺任務確實是存在的評論,但它已經消失了。將前景放回初始狀態。不幸的是,任何企圖註銷上BackgroundMediaPlayer.Current東西會與RPC錯誤失敗,一旦後臺任務已丟失..

所以添加此功能,並調用它,你趕上了錯誤。

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; 
     } 
    } 
} 
相關問題