3

我的應用程序閱讀shoutcast。AudioPlayerAgent,定時器和webservice

音樂播放的元數據是從一個web服務收集我返回一個JSON(所以我不必解碼流)。我所說的Web服務每20秒計時器,這部作品在我的應用程序,但不工作的AudioPlayer.cs

//Timer 
    private DispatcherTimer timer; 


    /// <remarks> 
    /// AudioPlayer instances can share the same process. 
    /// Static fields can be used to share state between AudioPlayer instances 
    /// or to communicate with the Audio Streaming agent. 
    /// </remarks> 
    public AudioPlayer() 
    { 
     if (!_classInitialized) 
     { 
      _classInitialized = true; 
      // Subscribe to the managed exception handler 
      Deployment.Current.Dispatcher.BeginInvoke(delegate 
      { 
       Application.Current.UnhandledException += AudioPlayer_UnhandledException; 

      }); 
     } 

     //I activate the timer 
     timer = new DispatcherTimer 
     { 
      Interval = TimeSpan.FromSeconds(20) // <------- Error here UnauthorizedAccessException was unhandled. Invalid cross-thread access. 
     }; 
     timer.Tick += timer_Tick; 
     timer.Start(); 
    } 


    private void timer_Tick(object sender, EventArgs e) 
    { 
     HttpWebRequest request = WebRequest.Create("http://127.0.0.81:8003/getmeta") as HttpWebRequest; 
     request.BeginGetResponse(new AsyncCallback(AsyncBack), request); 
    } 

    private void AsyncBack(IAsyncResult ias) 
    { 
      HttpWebRequest req = (HttpWebRequest)ias.AsyncState; 

      try 
      { 
       using (HttpWebResponse res = req.EndGetResponse(ias) as HttpWebResponse) 
       { 
        StreamReader stream = new StreamReader(res.GetResponseStream()); 
        String jsonToParse = stream.ReadToEnd(); 
        JObject jObject = JObject.Parse(jsonToParse); 

        AudioTrack track = BackgroundAudioPlayer.Instance.Track; 

        track.BeginEdit(); 
        track.Title = (string) jObject["title"]; 
        track.Artist = (string) jObject["artist"]; 
        track.Album = (string) jObject["album"]; 
        track.EndEdit(); 


        res.Close(); 
       } 
      } 
      catch (WebException e) 
      { 
       timer.Stop(); 
      } 
    } 

感謝大家的幫助

回答

4

的AudioPlayer類是相當獨特的。它只能存活一段時間。在使用BackgroundAudioPlayer的應用程序中,您的AudioPlayer類實現將僅保持活動狀態,以完成更改播放狀態的任務。所以,當用戶開始玩東西時,會創建一個AudioPlayer類的實例來完成開始播放的任務。一旦在OnUserAction或OnPlayStateChanged中調用NotifyComplete(),AudioPlayer的實例就會消失。

AudioPlayer所關聯的後臺線程仍然處於活動狀態,並且您可以在該線程中存在其他對象,但AudioPlayer將被終止。創建的默認AudioPlayer使用_classInitialized字段提示。這是靜態的,因爲AudioPlayer會被創建很多次,但我們只想對該事件執行一次。

我會建議兩件事之一。首先是隻有在需要前進到下一首歌時才能獲得json響應。在響應返回之前,您不會調用NotifyComplete()。 下面是一些僞代碼:

override OnUserAction(BackgroundAudioPlayer player, AudioTrack track, UserAction action, object param) 
{ 
    GetJsonResponse(); 
} 
private void GetJsonResponce() 
{ 
    // async call to your service 
    // When async completes: 
    track.BeginEdit(); 
    track.Title = (string) jObject["title"]; 
    track.Artist = (string) jObject["artist"]; 
    track.Album = (string) jObject["album"]; 
    track.EndEdit(); 
    NotifyComplete(); 
} 

第二是有一類,這是否在後臺運行。該類將具有靜態屬性以獲取線程中活動的實例。然後你的音頻播放器將獲得它需要的信息從該對象

public class Songs 
{ 
    static Songs _instance; 
    public static Songs Instance 
    { 
     get { return _instance ?? new Songs(); } 
    } 
    // Do you timer stuff here 

    // Allow the ability to access the timer stuff also. 
} 
// in AudioPlayer 
override OnUserAction(BackgroundAudioPlayer player, AudioTrack track, UserAction action, object param) 
{ 
    Songs.Instance.GetStuff 
    NotifyComplete(); 
} 
+0

它的作品,但只是當用戶與UVC交互。我的流是一個無限的獨特shoutcast,所以沒有結束的軌道,我不得不使用一個計時器,但一旦NotifyComplete()被調用,計時器不再工作了。我試圖刪除NotifyComplete(),但是當播放時暫停流是不可能的......有沒有真正的解決方案呢?不僅在用戶與UVC交互時如何在BackgroundAgentPlayer中使用計時器? – Mentezza 2012-03-19 09:44:33

+0

如果您實施第二種解決方案,我認爲Songs類應該能夠通過BackgroundAudioPlayer.Instance – 2012-03-19 15:06:59

+0

@ShawnKendrot調用暫停該代理程序在不同的進程或線程中運行?這個線程活多久? – onmyway133 2012-10-09 09:01:09