Skip to content

Commit

Permalink
Add: Online audio previews for missing beatmaps
Browse files Browse the repository at this point in the history
  • Loading branch information
Piotrekol committed Jul 15, 2022
1 parent 797033b commit 98549cc
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 15 deletions.
48 changes: 33 additions & 15 deletions App/Presenters/Controls/MusicControlPresenter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand All @@ -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)
{
Expand Down
30 changes: 30 additions & 0 deletions MusicPlayer/MusicPlayerManager.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System;
using System.IO;
using System.Linq;
using System.Net;

namespace MusicPlayer
{
Expand Down Expand Up @@ -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);
}

Expand Down

0 comments on commit 98549cc

Please sign in to comment.