2012-05-06 10 views
0

私は無限のオーディオストリームを再生するアプリケーションを作成しています。現在再生中のトラックのタイトルとアーティストを取得するためにクエリできる別のWebサービスがあります。私がしたいことは、20秒ごとにそのサービスを照会し、それに応じてトラックタイトル/アーティストを設定することです。現在、私は背景がAudioPlayerAgentを使用しているので、ストリームは自分のアプリケーションの外で再生できます。AudioPlayerAgentのHttpWebRequest

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

      }); 
      trackTimer = new Timer(TrackTimerTick, null, 1000, 5000); 
     } 
    } 

    public void TrackTimerTick(object state) {    
      // Create a HttpWebrequest object to the desired URL. 
      HttpWebRequest trackRequest = (HttpWebRequest)HttpWebRequest.Create("<stream url>"); 
      // Start the asynchronous request. 
      IAsyncResult result = (IAsyncResult)trackRequest.BeginGetResponse(new AsyncCallback(TrackCallback), trackRequest); 
    } 

    public void TrackCallback(IAsyncResult result) { 
     if (BackgroundAudioPlayer.Instance.PlayerState == PlayState.Playing && result != null) { 
      try { 
       // State of request is asynchronous. 
       HttpWebRequest trackRequest = (HttpWebRequest)result.AsyncState; 
       HttpWebResponse trackResponse = (HttpWebResponse)trackRequest.EndGetResponse(result); 
       using (StreamReader httpwebStreamReader = new StreamReader(trackResponse.GetResponseStream())) { 
        string results = httpwebStreamReader.ReadToEnd(); 
        StringReader str = new StringReader(results); 
        XDocument trackXml = XDocument.Load(str); 

        string title = (from t in trackXml.Descendants("channel") select t.Element("title").Value).First<string>(); 
        string artist = (from t in trackXml.Descendants("channel") select t.Element("artist").Value).First<string>(); 
        if (BackgroundAudioPlayer.Instance.Track != null) { 
         AudioTrack track = BackgroundAudioPlayer.Instance.Track; 
         track.BeginEdit(); 
         track.Title = title; 
         track.Artist = artist; 
         track.EndEdit(); 
        } 

       } 
       trackResponse.Close(); 
       NotifyComplete(); 
      } catch (WebException e) { 
       Debug.WriteLine(e); 
       Debug.WriteLine(e.Response); 
      } catch (Exception e) { 
       Debug.WriteLine(e); 
      } 
     } 
    } 

ウェブ例外はいつでも私は、HttpWebRequestのからの応答を読み取ろうというスローされます。ここに私はこれまで持っているコードです。これはこれを行う正しい方法ですか?私はこれをどのように修正することができるかに関して誰かが提案をしていますか?

+0

例外をキャッチしないでください。 http://stackoverflow.com/questions/1742940/why-not-catch-general-exceptions http://msdn.microsoft.com/en-us/library/ms182137%28v=vs.100%29.aspx –

+0

何も修正されません。 – bfink

+0

@Sedgwickzのコメントが部分的に修正されているようですが、トラックデータを正しく取得できます。しかし、一度私はNotifyComplete()を呼び出すと、タイマーはもはや目立たない - これを修正する方法のヒント? – bfink

答えて

0

あなたはHttpWebResponseを閉じる必要はありません。また、XDocument.Load()のオーバーロードにはStreamが必要なので、StreamReaderをまったく使用する必要はありません。

EDIT:申し訳ありませんが、最後にClose()コールを見落としました。しかし、もう1つのコメントはまだ適用されます。私はあなたは自分のHttpWebRequestのresponse.MaybeこれにOnUserAction()内NotifyComplete()関数を移動するべきだと思い

public void TrackCallback(IAsyncResult result) { 
    if (BackgroundAudioPlayer.Instance.PlayerState == PlayState.Playing && result != null) { 
     try { 
      // State of request is asynchronous. 
      HttpWebRequest trackRequest = (HttpWebRequest)result.AsyncState; 
      using (HttpWebResponse trackResponse = (HttpWebResponse)trackRequest.EndGetResponse(result)){ 
       XDocument trackXml = XDocument.Load(trackResponse.GetResponseStream()); 

       string title = (from t in trackXml.Descendants("channel") select t.Element("title").Value).First<string>(); 
       string artist = (from t in trackXml.Descendants("channel") select t.Element("artist").Value).First<string>(); 
       if (BackgroundAudioPlayer.Instance.Track != null) { 
        AudioTrack track = BackgroundAudioPlayer.Instance.Track; 
        track.BeginEdit(); 
        track.Title = title; 
        track.Artist = artist; 
        track.EndEdit(); 
       } 
      } 
      } 
      NotifyComplete(); 
     } catch (WebException e) { 
      Debug.WriteLine(e); 
      Debug.WriteLine(e.Response); 
     } catch (Exception e) { 
      Debug.WriteLine(e); 
     } 
    } 
} 
+0

返事をありがとう。残念ながらそれはまだ動作しませんが、私のコードは良く見えます:) – bfink

0

:それは問題が解決しない場合は

は、少なくともそれはあなたのコードを見クリーナーを作ります記事はあなたにいくつかの助け:)これは、それが音楽を演奏し始めた後AudioPlayerは、スコープの外に行くとしなければならない

http://tmango.com/?p=952

0

を与えることができます。 AudioPlayerは、一度の割合のために住んでおり、それがこの投稿への私の返事を見てみNotifyComplete

への呼び出し後に終了: AudioPlayerAgent, timer and webservice

さらに詳しい情報: バックグラウンドオーディオのスレッドは、「一時停止」します後NotifyCompleteが呼び出されます。戻り値は、ユーザーが再生を変更したとき(OnUserAction)、または曲が終了したとき(OnPlayStateChanged)です。演奏を続ける場合は、OnPlayStateChangedメソッド内で新しい情報を入手してください。

+0

返事をありがとう。あなたがあなたの返信で参照するSongsクラスの中にタイマーを作成すると、そのタイマーは継続して刻々と変化するでしょうか? – bfink

+0

私はそれがうまくいくはずだと思う方法を試しましたが、NotifyCompleteを呼び出すとタイマーと非同期のHttpWebRequest呼び出しが終了します。 NotifyCompleteが呼び出されたときに終了しないバックグラウンドスレッドにこれらを配置するためのヒント – bfink

+0

修正します、私の更新を参照してください –