diff --git a/trunk/Sources/Server/Config.cs b/trunk/Sources/Server/Config.cs index 8256b73..e9fadcb 100644 --- a/trunk/Sources/Server/Config.cs +++ b/trunk/Sources/Server/Config.cs @@ -53,6 +53,8 @@ public static Config GetInstance() bool playRandomFromCache = true; // debug file string debugFileName = "debug.txt"; + // max count of parallel downloading + int maxItemsInDownloadingQueue = 5; public int VotesToSkip { @@ -203,6 +205,18 @@ public string DebugFileName } } + public int MaxItemsInDownloadingQueue + { + get + { + return maxItemsInDownloadingQueue; + } + set + { + maxItemsInDownloadingQueue = value; + } + } + private bool ExistDevice(string deviceId) { ISoundDeviceList outputDevices = new ISoundDeviceList(SoundDeviceListType.PlaybackDevice); @@ -323,6 +337,20 @@ public void LoadConfig() try { PlayRandomFromCache = Convert.ToBoolean(config.AppSettings.Settings["playRandomFromCache"].Value); } catch { } } + if ((config.AppSettings.Settings["debugFileName"] != null) && + (config.AppSettings.Settings["debugFileName"].Value != null) && + (config.AppSettings.Settings["debugFileName"].Value != "")) + { + try { DebugFileName = config.AppSettings.Settings["debugFileName"].Value; } + catch { } + } + if ((config.AppSettings.Settings["maxItemsInDownloadingQueue"] != null) && + (config.AppSettings.Settings["maxItemsInDownloadingQueue"].Value != null) && + (config.AppSettings.Settings["maxItemsInDownloadingQueue"].Value != "")) + { + try { MaxItemsInDownloadingQueue = Convert.ToInt32(config.AppSettings.Settings["maxItemsInDownloadingQueue"].Value); } + catch { } + } // dialog for special devices diff --git a/trunk/Sources/Server/DataProviders/VKComDataProvider_new.cs b/trunk/Sources/Server/DataProviders/VKComDataProvider_new.cs index d23ffd4..79e32ab 100644 --- a/trunk/Sources/Server/DataProviders/VKComDataProvider_new.cs +++ b/trunk/Sources/Server/DataProviders/VKComDataProvider_new.cs @@ -53,7 +53,7 @@ public IList Search(string query) requestStream.Close(); } - var responseStream = request.GetResponse().GetResponseStream(); + Stream responseStream = request.GetResponse().GetResponseStream(); string content = ""; using (var reader = new StreamReader(responseStream, Encoding.GetEncoding(1251))) @@ -73,7 +73,7 @@ public IList Search(string query) content = StripHtmlEntities(content); var doc = XDocument.Load(new StringReader(content)); XElement audioElement; - + content = null; var elements = doc.Root.Elements(); foreach (var divTrack in elements) @@ -96,13 +96,12 @@ public IList Search(string query) track.Id = terms[0].Substring(startId, finishId - startId); track.Uri = new Uri(terms[0]); - string titleTag = audioElement.XPathSelectElements("div/table/tr/td/div/span").First().ToString(SaveOptions.DisableFormatting); + string titleTag = audioElement.XPathSelectElement("div/table/tr/td/div/span").ToString(SaveOptions.DisableFormatting); track.Title = PrepareTitle(titleTag); - string singerTag = audioElement.XPathSelectElements("div/table/tr/td/div/b/a").First().ToString(SaveOptions.DisableFormatting); + string singerTag = audioElement.XPathSelectElement("div/table/tr/td/div/b/a").ToString(SaveOptions.DisableFormatting); track.Singer = PrepareTitle(singerTag); - var duration = audioElement.XPathSelectElements("div/table/tr/td/div"). - Where(el => el.Attribute("class").Value == "duration fl_r").First().Value; + var duration = audioElement.XPathSelectElement("div/table/tr/td/div[@class='duration fl_r']").Value; TimeSpan tmp; TimeSpan.TryParse("00:" + duration, out tmp); @@ -118,10 +117,12 @@ public IList Search(string query) } catch (Exception e) { - Console.WriteLine("VKComDataProvider error: " + e.Message); - Console.WriteLine("Query: " + query); + Debug.WriteLine("VKComDataProvider error: " + e.Message); + Debug.WriteLine("Query: " + query); } + + return new ReadOnlyCollection(result); } @@ -165,7 +166,9 @@ public byte[] Download(Track track) { try { - WebClient c = new WebClient(); + WebDownload c = new WebDownload(); + c.Timeout = Config.GetInstance().DownloadTimeout; + return c.DownloadData(track.Uri); } catch (Exception e) diff --git a/trunk/Sources/Server/Player.cs b/trunk/Sources/Server/Player.cs index a25be37..09cdc54 100644 --- a/trunk/Sources/Server/Player.cs +++ b/trunk/Sources/Server/Player.cs @@ -20,6 +20,7 @@ public Player() { Instance = this; Engine = new ISoundEngine(SoundOutputDriver.AutoDetect, SoundEngineOptionFlag.DefaultOptions, Config.GetInstance().DeviceId); Playlist = new Playlist(); + ItemsInDownloadingQueue = 0; //Playlist.Tracks.CollectionChanged += OnPlaylistChanged; new Thread(() => { @@ -59,10 +60,10 @@ private void PlayerThread() } foreach (Track t in Playlist.Tracks.Where(x => x.State == TrackState.Unknown)) - { - Debug.Print("[" + DateTime.Now.ToString("HH:mm:ss") + "] " + "Track has been enqueued: " + t); + { if (File.Exists(Config.GetInstance().CacheDir + t.GetHash() + ".mp3")) { + Debug.Print("[" + DateTime.Now.ToString("HH:mm:ss") + "] " + "Track has been enqueued: " + t); Debug.Print("[" + DateTime.Now.ToString("HH:mm:ss") + "] " + "Track has been loaded from cache: " + t); t.State = TrackState.Ready; Debug.Print("[" + DateTime.Now.ToString("HH:mm:ss") + "] " + "Track has state: {0} {1}", t, t.State); @@ -70,22 +71,28 @@ private void PlayerThread() } else { - new Thread(() => + if (ItemsInDownloadingQueue < Config.GetInstance().MaxItemsInDownloadingQueue) { - t.State = TrackState.Downloading; - TrackStateChanged(this, new PlayerEventArgs() { Track = t }); - - byte[] data = DataProviderManager.Instance.Download(t); - if ((data != null) && !File.Exists(Config.GetInstance().CacheDir + t.Id + ".mp3")) + Debug.Print("[" + DateTime.Now.ToString("HH:mm:ss") + "] " + "Track has been enqueued: " + t); + new Thread(() => { - File.WriteAllBytes(Config.GetInstance().CacheDir + t.Id + ".mp3", data); - File.AppendAllText(Config.GetInstance().CacheDir + "hashmap.txt", t.Id + "|" + t.Singer.Trim() + "|" + t.Title.Trim() + "|" + t.Duration.ToString() + "\r\n"); - } - t.State = data != null ? TrackState.Ready : TrackState.Failed; - Debug.Print("[" + DateTime.Now.ToString("HH:mm:ss") + "] " + "Track has state: {0} {1}", t, t.State); + t.State = TrackState.Downloading; + TrackStateChanged(this, new PlayerEventArgs() { Track = t }); + ItemsInDownloadingQueue++; + + byte[] data = DataProviderManager.Instance.Download(t); + if ((data != null) && !File.Exists(Config.GetInstance().CacheDir + t.Id + ".mp3")) + { + File.WriteAllBytes(Config.GetInstance().CacheDir + t.Id + ".mp3", data); + File.AppendAllText(Config.GetInstance().CacheDir + "hashmap.txt", t.Id + "|" + t.Singer.Trim() + "|" + t.Title.Trim() + "|" + t.Duration.ToString() + "\r\n"); + } + t.State = data != null ? TrackState.Ready : TrackState.Failed; + Debug.Print("[" + DateTime.Now.ToString("HH:mm:ss") + "] " + "Track has state: {0} {1}", t, t.State); - TrackStateChanged(this, new PlayerEventArgs() { Track = t }); - }).Start(); + TrackStateChanged(this, new PlayerEventArgs() { Track = t }); + ItemsInDownloadingQueue--; + }).Start(); + } } } @@ -124,6 +131,7 @@ public double VolumeLevel { private ISoundEngine Engine { get; set; } public ISound CurrentISound { get; set; } + public int ItemsInDownloadingQueue { get; set; } /// /// Прерывает воспроизведение текущей песни.