2014-01-08 78 views
2

所以我在WP 7.5中遇到了背景音頻播放代理的問題,我認爲它在播放過程中被操作系統隨機終止。背景音頻播放代理在播放過程中終止Windows Phone 7.5

我有一個應用程序,它實現了一個基於UI中所選章節播放多個mp3文件的BAP代理。每一章都有多個經文,這些經文在隔離的存儲器中有一個關聯的mp3文件。

一旦在用戶界面中選擇了一個章節並且用戶按下播放按鈕BackgroundAudio.Instance.Play()被調用並且該章節的第一節(mp3文件)被加載爲AudioTrack。當軌道結束時,下一個軌道在狀態下的OnPlayStateChanged事件方法中加載。

我在TrackEnded中也有一些邏輯,用於檢查是否已經到達章節的末尾(即當前章節的最後一個mp3文件已被播放),如果是,則檢索下一章節的第一個mp3文件。

現在所有上述工作正常使用Windows Phone 7仿真器(包括512Mb和256Mb仿真器)時,mp3文件播放正常,當章節結束時,下一章的下一個mp3文件是正確加載和播放。

我遇到的問題是,當我將這個應用程序部署到Win 8設備(Lumia 920)時,音頻開始播放正常,突然看起來隨機的音頻停止!沒有錯誤信息,應用程序不會崩潰,只是音頻停止播放。另外,當我點擊設備上的UVC按鈕NO AudioTrack信息顯示爲在音頻播放或音頻暫停(僅音量信息顯示)期間的情況。

我不知道發生了什麼,我認爲操作系統可能會終止背景音頻播放代理,但我不知道爲什麼(我不認爲我達到了任何內存限制,但我無法證實這一點因爲我不知道如何檢查我是否)。

任何意見/幫助將不勝感激。

感謝

更新14/01/14

要確認爲15兆字節(WP7)和20MB的(WP8)的內存限制沒有被我的BAP達到我實現了一些代碼,記錄BAP在不同階段的當前內存使用情況。

內存使用不會達到操作系統對BAP施加的限制,我達到的峯值是7Mb我上面描述的問題仍然存在,我可以從日誌中看到下一個軌道已經存在設置,但狀態Trackready從未命中,也不會引發異常/錯誤。這真的讓我難住了!

更新15/01/14 下面是BAP的如何我已經實現了一個例子:

public AudioPlayer() 
    { 

     if (!_classInitialized) 
     { 
      _classInitialized = true; 
      // Subscribe to the managed exception handler 
      Deployment.Current.Dispatcher.BeginInvoke(delegate 
      { 
       Application.Current.UnhandledException += AudioPlayer_UnhandledException; 
      }); 
      lastPlayedVerse = currentVerseNumber; 

     } 
    } 

    /// Code to execute on Unhandled Exceptions 
    private void AudioPlayer_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e) 
    { 
    //Helper class to help log any exceptions 
     IsolatedStore.WriteToIS("unhandeled Ex: " + e.ExceptionObject.Message, IsolatedStore.MemLogFileName); 
     if (System.Diagnostics.Debugger.IsAttached) 
     { 
      // An unhandled exception has occurred; break into the debugger 
      System.Diagnostics.Debugger.Break(); 
     } 
    } 

    protected override void OnError(BackgroundAudioPlayer player, AudioTrack track, Exception error, bool isFatal) 
    { 

     //Helper class to help log any exceptions 
     IsolatedStore.WriteToIS("OnError Called: " + error.Message, IsolatedStore.MemLogFileName); 

     if (isFatal) 
     { 
      Abort(); 
     } 
     else 
     { 
      NotifyComplete(); 
     } 

    } 

    protected override void OnPlayStateChanged(BackgroundAudioPlayer player, AudioTrack track, PlayState playState) 
    { 
     switch (playState) 
     { 
      case PlayState.TrackEnded: 

       track = null; 
    IsolatedStore.AppendToFileIS(string.Format("Track Ended::Time: {0}",DateTime.Now.ToLongTimeString()), IsolatedStore.MemLogFileName); 

       #region Track Ended logic 
       //IN here I have some logic to determine what the next track should be and then I call a function that returns an AudioTrack 
       player.Track = GetNextTrack(); //this method returns an AudioTrack     
       #endregion 
       break; 
      case PlayState.TrackReady: 
       IsolatedStore.AppendToFileIS(string.Format("Track Ready::Time: {0}, Track: {1}", DateTime.Now.ToLongTimeString(),track.Title), IsolatedStore.MemLogFileName); 

       //Put this try catch in here becoz i thought that this is where the issue was (not sure if its needed as any exception should be caught by the AudioPlayer_UnhandledException function. 
       try 
       { 
        player.Play(); 
       } 
       catch (Exception ex) 
       { 

        IsolatedStore.AppendToFileIS(string.Format("Track Ready play exception: {0}", ex.Message), IsolatedStore.MemLogFileName); 

       }   
       break; 

     } 

     NotifyComplete(); 
    } 

    protected override void OnUserAction(BackgroundAudioPlayer player, AudioTrack track, UserAction action, object param) 
    { 
     switch (action) 
     { 
      case UserAction.Play: 
       if (player.PlayerState != PlayState.Playing) 
       { 
        IsolatedStore.AppendToFileIS(string.Format("UA-PLAY::Time: {0}, Track: {1}", DateTime.Now.ToLongTimeString(),track.Title), IsolatedStore.MemLogFileName); 
        player.Play(); 

       } 
       break; 
     } 

     NotifyComplete(); 
    } 

    private AudioTrack GetNextTrack(int audioType2Get, string filePath, int verserNum, bool incrementTrackCount) 
    { 

     #region Memusage 

     //Code to log the memory usage 
     long currMemUsage = (long)DeviceExtendedProperties.GetValue("ApplicationCurrentMemoryUsage"); 
     currMemUsage = (currMemUsage/1024)/1024; 
     long peakMemUsage = (long)DeviceExtendedProperties.GetValue("ApplicationPeakMemoryUsage"); 
     peakMemUsage = (peakMemUsage/1024)/1024; 
     IsolatedStore.AppendToFileIS(string.Format("Getting Track-Time: {0}, Curr:{1}, Track: {2}", DateTime.Now.ToLongTimeString(), currMemUsage, verserNum), IsolatedStore.MemLogFileName); 

     #endregion 
     AudioTrack track = null; 
     #region AudioTrack Set region 
     //Some logic to return the AudioTrack 
     #endregion 

    } 

更新24/01/2014解決的問題

我終於得到了一些時間去各地試圖什麼@Soonts在我標記爲答案答案建議,並首先我使用的是WP8設備,所以我跳過了第一SETP他提到,未來我一樣在步驟2中提到的再次最大內存使用量僅爲8Mb。

然後幾天後有一個更新爲我的WP8設備(WP8 Update 3),我安裝此更新後,我試圖重現該問題,並猜測什麼!這個問題沒有任何更多的!,我有我的音頻連續播放了一個多小時沒有問題!內存使用量穩定在8Mb左右。所以看起來BG BG Audio可能會有一個靜音更新。

爲什麼我打上@snoots回答的答案是,因爲他在這個問題的答案,這個問題可以通過靜默更新固定提到的原因。

+0

有我的WP8應用的音頻同樣的問題,我無法確定爲什麼它停下來,我從來沒有能夠在調試 –

+0

@ShawnKendrot我目前工作的投入一些代碼來記錄記憶重現我的BAP的使用只是爲了確認它不是一個內存限制問題,我會在完成時更新結果的問題。我在你的評論中看到你在調試時無法重現錯誤,請注意,在調試時,內存限制不會施加在BAP代理上,因此如果它是調試時不顯示的內存問題,請參閱[this鏈接](http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh394039(v = vs.105).aspx),看看內存和運行時約束節 – user1573896

+0

@ShawnKendrot似乎最新操作系統更新爲我解決了這個問題。 – user1573896

回答

1

如果我是你,我可能會做以下,按照這個順序:

  1. 確保您有最新的操作系統更新。他們已經在7.8更新中靜靜地修復了一些與BAP相關的內存問題。如果您不使用最新的操作系統,請升級並嘗試重現。在與BAP交互的GUI程序代碼,每一個地方
  2. 廣場斷點,以確保你不會誤例如主叫BackgroundAudioPlayer.Stop()或BackgroundAudioPlayer.Track = null,嘗試重現。
  3. 而不是「記錄在不同階段的BAP的當前內存使用」,在一些代理類的靜態構造函數,創建一個線程,在無限循環,附加在獨立存儲一些CSV文件,記錄當前時間戳+當前內存,然後睡眠500-1000毫秒。重現問題,使用ISETool。EXE下載日誌,使用Excel來建立RAM使用圖...
  4. 如果(3)不會顯示RAM使用接近極限,實施跟蹤到孤立的存儲或網絡(順便說一句,我已經實現了SysLog RFC 5426客戶端,並在我的PC上安裝名爲「SysRose Syslog Desktop」的免費軟件),然後嘗試執行printf樣式的調試。
+0

請參閱我對該問題的最新更新,我已將您的答案標記爲答案,因爲您提到無提示更新可能會解決問題(步驟1),但只是它是WP8而不是7.8,再次感謝您的建議。 – user1573896

2
  1. 這可能發生在未處理的異常。訂閱Application.Current.UnhandledException(如果您使用異步等待TaskScheduler.UnobservedTaskException)並將它們記錄在某處。此外,重寫您的代理的OnError方法,並記錄。

  2. 如果在完成處理請求(即玩家代理,OnPlayStateChanged和OnUserAction)後忘記調用BackgroundAgent.NotifyComplete(),可能會發生這種情況。在這種情況下,操作系統無法及時處理請求,並終止BAP流程。

  3. RAM的問題,但你已經想通了。

P.S.這是我的Sky.fm播放器應用程序的相關部分。它不播放本地MP3,而是從互聯網播放音樂,但是播放器代理應該或多或少相同。

/// <summary>This class wraps AudioPlayerAgent API into the async-friendly abstract class.</summary> 
/// <remarks>Logging and exception handling are added, as well.</remarks> 
public abstract class PlayerAgentAsync: AudioPlayerAgent 
{ 
    static PlayerAgentAsync() 
    { 
     UnhandledExceptionHandler.subscribe(); 
    } 

    public PlayerAgentAsync() 
    { 
     Logger.info("constructed"); 
    } 

    protected override void OnError(BackgroundAudioPlayer player, AudioTrack track, Exception ex, bool isFatal) 
    { 
     if(isFatal) 
     { 
      BackgroundErrorNotifier.addError(ex); 
      ex.log(); 
      Abort(); 
     } 
     else 
     { 
      ex.logWarning(); 
      try 
      { 
       // Force the track to stop 
       // http://blogs.msdn.com/b/wpukcoe/archive/2012/02/11/background-audio-in-windows-phone-7-5-part-3.aspx 
       player.Track = null; 
      } 
      catch (System.Exception ex2) 
      { 
       ex2.logWarning("Exception while trying to stop da playa"); 
      } 
      NotifyComplete(); 
     } 
    } 

    /// <summary>Called when the play state changes, except for the error state.</summary> 
    protected override async void OnPlayStateChanged(BackgroundAudioPlayer player, AudioTrack track, PlayState playState) 
    { 
     Logger.info("new playState = {0}", playState.ToString()); 

     try 
     { 
      await this.playStateChangedAsync(player, track, playState).ConfigureAwait(false); 
      NotifyComplete(); 
     } 
     catch (System.Exception ex) 
     { 
      this.onException(ex); 
     } 
    } 

    /// <summary>Called when the user requests an action using some application-provided UI or the Universal Volume Control (UVC) and the application has requested notification of the action.</summary> 
    protected override async void OnUserAction(BackgroundAudioPlayer player, AudioTrack track, UserAction action, object param) 
    { 
     Logger.info("action = {0};", action.ToString()); 

     try 
     { 
      await this.userActionAsync(player, track, action, param).ConfigureAwait(false); 
      NotifyComplete(); 
     } 
     catch(System.Exception ex) 
     { 
      this.onException(ex); 
     } 
    } 

    private void onException(Exception ex) 
    { 
     if(ex.shouldBeIgnored()) 
     { 
      ex.logWarning(); 
      this.NotifyComplete(); 
      return; 
     } 
     ex.log(); 
     BackgroundErrorNotifier.addError(ex); 
     this.Abort(); 
    } 

    protected override void OnCancel() 
    { 
     Logger.trace(); 
     base.OnCancel(); 
    } 

    /// <summary>Handle OnPlayStateChanged asyncronously.</summary> 
    /// <param name="player">The Microsoft.Phone.BackgroundAudio.BackgroundAudioPlayer.</param> 
    /// <param name="track">The track playing at the time that the play state changed.</param> 
    /// <param name="playState">The new state of the player.</param> 
    protected abstract Task playStateChangedAsync(BackgroundAudioPlayer player, AudioTrack track, PlayState playState); 

    /// <summary>Handle OnUserAction asyncronously</summary> 
    /// <param name="player">The Microsoft.Phone.BackgroundAudio.BackgroundAudioPlayer.</param> 
    /// <param name="track">The track playing at the time of the user action.</param> 
    /// <param name="action">The action that the user has requested.</param> 
    /// <param name="param">The data associated with the requested action.</param> 
    protected abstract Task userActionAsync(BackgroundAudioPlayer player, AudioTrack track, UserAction action, object param); 
} 
+0

感謝您的回答,我已經使用BAP中使用的代碼更新了問題。基本上我已經記錄了任何未處理的異常和OnError方法中的任何錯誤(請參閱我的代碼)。另外NotifyComplete()在OnPlayStateChanged和OnUserAction方法的末尾被調用。我將很快用日誌的內容更新我的問題。但是,從OnError方法或UnhandledException方法中不會記錄任何錯誤。附:我試圖提高你的答案,但我沒有足夠的代表。 – user1573896