diff --git a/App/Presenters/Controls/MusicControlPresenter.cs b/App/Presenters/Controls/MusicControlPresenter.cs index c7088fc..5bf1d34 100644 --- a/App/Presenters/Controls/MusicControlPresenter.cs +++ b/App/Presenters/Controls/MusicControlPresenter.cs @@ -112,7 +112,7 @@ private void ModelOnBeatmapChanged(object sender, EventArgs eventArgs) if (map == null || !_view.IsAutoPlayEnabled) return; var audioLocation = ((BeatmapExtension)map).FullAudioFileLocation(); - if (ShouldSkipTrack(audioLocation)) + if (ShouldSkipTrack(map, audioLocation)) { //Run as worker to avoid eventual stack overflow exception (eg. too many maps with no audio file in a row) RunAsWorker(() => _model.EmitNextMapRequest()); @@ -122,29 +122,47 @@ private void ModelOnBeatmapChanged(object sender, EventArgs eventArgs) PlayBeatmap(map); } - private bool ShouldSkipTrack(string audioLocation) + private bool ShouldSkipTrack(Beatmap map, string audioLocation) { - if ((_lastAudioFileLocation == audioLocation || string.IsNullOrWhiteSpace(audioLocation)) && - _view.IsMusicPlayerMode && !musicPlayer.IsPlaying) + //Skip repeating _audio files_(diferent diffs in same mapset) whenever _playing_ in _music player mode_ + if (_view.IsMusicPlayerMode && _lastAudioFileLocation == audioLocation && !musicPlayer.IsPlaying) return true; - return !File.Exists(audioLocation); + //Play if we have _audio file_ localy + if (File.Exists(audioLocation)) + return false; + + //Skip since we don't have local audio file in _music player mode_ + if (_view.IsMusicPlayerMode) + return true; + + //this is user-invoked play request (_music player mode_ check above) + //Is there a chance that preview of this beatmap exists in online source? + return map.MapSetId <= 20; } + private void PlayBeatmap(Beatmap map) { var audioLocation = ((BeatmapExtension)map).FullAudioFileLocation(); - if (audioLocation != string.Empty) + bool onlineSource = false; + if (audioLocation == string.Empty) { - RunAsWorker(() => - { - resetEvent.WaitOne(250); - if (map.Equals(_model.CurrentBeatmap)) - { - musicPlayer.Play(audioLocation, - _view.IsMusicPlayerMode ? 0 : Convert.ToInt32(Math.Round(map.PreviewTime / 1000f))); - } - }); + if (map.MapSetId <= 20) + return; + + onlineSource = true; + audioLocation = $@"https://b.ppy.sh/preview/{map.MapSetId}.mp3"; } + + RunAsWorker(() => + { + resetEvent.WaitOne(250); + if (map.Equals(_model.CurrentBeatmap)) + { + musicPlayer.Play(audioLocation, + _view.IsMusicPlayerMode || onlineSource ? 0 : Convert.ToInt32(Math.Round(map.PreviewTime / 1000f))); + } + }); } private void RunAsWorker(Action action) { diff --git a/MusicPlayer/MusicPlayerManager.cs b/MusicPlayer/MusicPlayerManager.cs index 9159705..5eae08d 100644 --- a/MusicPlayer/MusicPlayerManager.cs +++ b/MusicPlayer/MusicPlayerManager.cs @@ -1,5 +1,7 @@ using System; using System.IO; +using System.Linq; +using System.Net; namespace MusicPlayer { @@ -45,6 +47,34 @@ public void SetSpeed(float speed) public void Play(string audioFile, int startTime) { + Uri uri = new Uri(audioFile); + + if (uri.HostNameType == UriHostNameType.Dns) + { + var tempFolderPath = Path.Combine(Path.GetTempPath(), "CM-previews"); + Directory.CreateDirectory(tempFolderPath); + var directoryInfo = new DirectoryInfo(tempFolderPath); + var files = directoryInfo.GetFiles(); + if (files.Length > 100) + { + foreach (var file in files.OrderBy(f => f.LastWriteTimeUtc).Take(30)) + { + file.Delete(); + } + } + + var tempFilePath = Path.Combine(tempFolderPath, uri.Segments.Last()); + if (!File.Exists(tempFilePath)) + { + using (WebClient ws = new WebClient()) + { + ws.DownloadFile(audioFile, tempFilePath); + } + } + + audioFile = tempFilePath; + } + musicPlayer.Play(audioFile, startTime); }