Skip to content

Commit

Permalink
WIP Changes
Browse files Browse the repository at this point in the history
  • Loading branch information
PercyDan54 committed Oct 30, 2024
1 parent 436d7c7 commit 7ad2b65
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,18 @@ public static int Compute(string s, string t)

return d[n, m];
}

public static float ComputeSimilarPercentage(string s, string t)
{
string source = s.Length > t.Length ? s : t;
string target = s.Length > t.Length ? t : s;

if (string.IsNullOrEmpty(source) || string.IsNullOrEmpty(target))
return 0;

int distance = Compute(source, target);
float percentage = 1 - (distance / (float)source.Length);
return Math.Abs(percentage);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ public void Search(SearchOption searchOption)

//处理要搜索的歌名: "标题 艺术家"
string title = beatmap.Metadata.GetTitle();
string artist = searchOption.NoArtist ? string.Empty : $" {beatmap.Metadata.GetArtist()}";
string artist = searchOption.NoArtist ? string.Empty :beatmap.Metadata.GetArtist();
string target = encoder.Encode($"{title} {artist}");

var req = new APISearchRequest(target);
Expand Down Expand Up @@ -209,45 +209,78 @@ private void onSongSearchRequestFinish(RequestFinishMeta meta, APISearchRequest?
return;
}

var titleMatches = songs.Select(s => new { Song = s, SimilarPercentage = s.GetSimilarPercentage(sourceBeatmap) })
.Where(p => p.SimilarPercentage >= meta.TitleSimilarThreshold)
.OrderBy(p => p.SimilarPercentage);
var artistMatches = titleMatches.OrderBy(s => LevenshteinDistance.Compute(s.Song.GetArtist(), sourceBeatmap.Metadata.GetArtist()));
var perfectMatch = artistMatches.FirstOrDefault();
songs.ForEach(s => s.CalculateSimilarPercentage(sourceBeatmap));

if (perfectMatch != null && perfectMatch.SimilarPercentage > meta.TitleSimilarThreshold)
var titleMatches = songs.Where(p => p.TitleSimilarPercentage >= meta.TitleSimilarThreshold)
.OrderByDescending(p => p.TitleSimilarPercentage);
var artistMatches = titleMatches.OrderByDescending(s => s.ArtistSimilarPercentage);
var match = artistMatches.FirstOrDefault();

if (match != null)
{
Logging.Log($"Beatmap: '{sourceBeatmap.Metadata.GetTitle()}' <-> '{perfectMatch.Song.Name}' -> {perfectMatch.SimilarPercentage} > {meta.TitleSimilarThreshold}");
//标题匹配,发送歌词查询请求
var req = new APILyricRequest(perfectMatch.Song.ID);
req.Finished += () =>
{
if (currentLyricRequest == req)
setState(SearchState.Success);
string title = sourceBeatmap.Metadata.GetTitle();

meta.OnFinish?.Invoke(req.ResponseObject);
};
req.Failed += e =>
if (match.ArtistSimilarPercentage >= (meta.NoRetry ? 0 : meta.TitleSimilarThreshold))
{
if (currentLyricRequest == req)
setState(SearchState.Fail);
Logging.Log($"Beatmap: '{title}' <-> '{match.Name}' -> {match.TitleSimilarPercentage} > {meta.TitleSimilarThreshold}");
}
else
{
Logging.Log($"对 {title} 的匹配失败,尝试不匹配歌手");
match = titleMatches.FirstOrDefault();

Logging.LogError(e, "获取歌词失败");
};
req.PerformAsync(cancellationTokenSource.Token).ConfigureAwait(false);
if (match == null)
{
meta.OnFail?.Invoke("标题匹配失败, 将不会继续搜索歌词...");
setState(SearchState.Fail);
return;
}

currentLyricRequest = req;
Logging.Log($"Beatmap: '{sourceBeatmap.Metadata.GetTitle()}' <-> '{match.Name}' -> {match.TitleSimilarPercentage} < {meta.TitleSimilarThreshold}");
}
}
else

if (match == null)
{
//Logging.Log("标题匹配失败, 将不会继续搜索歌词...");
setState(SearchState.Fail);
if (!meta.NoRetry)
{
var searchMeta = SearchOption.FromRequestFinishMeta(meta);
searchMeta.NoArtist = true;
searchMeta.NoRetry = true;
searchMeta.NoLocalFile = true;

Logging.Log($"对 {sourceBeatmap?.Metadata.GetTitle() ?? "未知谱面"} 的标题匹配失败:");
//Logging.Log($"Beatmap: '{sourceBeatmap?.Metadata.GetTitle() ?? "???"}' <-> '{meta.GetNeteaseTitle()}' -> {similarPercentage} < {meta.TitleSimilarThreshold}");
if (searchRequest != null && searchRequest == currentSearchRequest)
setState(SearchState.FuzzySearching);

meta.OnFail?.Invoke("标题匹配失败, 将不会继续搜索歌词...");
Search(searchMeta);
}
else
{
meta.OnFail?.Invoke("标题匹配失败, 将不会继续搜索歌词...");
setState(SearchState.Fail);
}

return;
}

var req = new APILyricRequest(match.ID);
req.Finished += () =>
{
if (currentLyricRequest == req)
setState(SearchState.Success);

meta.OnFinish?.Invoke(req.ResponseObject);
};
req.Failed += e =>
{
if (currentLyricRequest == req)
setState(SearchState.Fail);

Logging.LogError(e, "获取歌词失败");
};
req.PerformAsync(cancellationTokenSource.Token).ConfigureAwait(false);

currentLyricRequest = req;
}

#endregion
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace osu.Game.Rulesets.IGPlayer.Feature.Player.Plugins.Bundle.CloudMusic.Mi
public class APISearchResultInfo
{
[JsonProperty("songs")]
public IList<APISongInfo>? Songs { get; set; }
public List<APISongInfo>? Songs { get; set; }

[JsonProperty("songCount")]
public int SongCount { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.IGPlayer.Feature.Player.Misc;
using osu.Game.Rulesets.IGPlayer.Feature.Player.Plugins.Bundle.CloudMusic.Helper;

namespace osu.Game.Rulesets.IGPlayer.Feature.Player.Plugins.Bundle.CloudMusic.Misc
Expand All @@ -14,30 +13,34 @@ public class APISongInfo
{
public long ID { get; set; }

public long Duration { get; set; }

public string? Name { get; set; }

public List<APIArtistInfo> Artists { get; set; } = [];

public float TitleSimilarPercentage { get; set; }

public float ArtistSimilarPercentage { get; set; }

/// <summary>
/// 获取网易云歌曲标题和搜索标题的相似度
/// </summary>
/// <returns>相似度百分比</returns>
public float GetSimilarPercentage(WorkingBeatmap? beatmap)
public void CalculateSimilarPercentage(WorkingBeatmap? beatmap)
{
string neteaseTitle = Name?.ToLowerInvariant() ?? string.Empty;
string ourTitle = beatmap?.Metadata.GetTitle().ToLowerInvariant() ?? string.Empty;

string source = neteaseTitle.Length > ourTitle.Length ? neteaseTitle : ourTitle;
string target = neteaseTitle.Length > ourTitle.Length ? ourTitle : neteaseTitle;

if (string.IsNullOrEmpty(neteaseTitle) || string.IsNullOrEmpty(ourTitle)) return 0;
string ourTitle = beatmap?.Metadata.Title.ToLowerInvariant() ?? string.Empty;

int distance = LevenshteinDistance.Compute(source, target);
float percentage = 1 - (distance / (float)source.Length);
float titleSimilarPercentage = LevenshteinDistance.ComputeSimilarPercentage(neteaseTitle, ourTitle);
ourTitle = beatmap?.Metadata.TitleUnicode.ToLowerInvariant() ?? string.Empty;
float titleSimilarPercentageUnicode = LevenshteinDistance.ComputeSimilarPercentage(neteaseTitle, ourTitle);
TitleSimilarPercentage = Math.Max(titleSimilarPercentageUnicode, titleSimilarPercentage);

return Math.Abs(percentage);
neteaseTitle = GetArtist();
ArtistSimilarPercentage = Artists.Count(a => neteaseTitle.Contains(a.Name)) / (float)Artists.Count;
}

public string GetArtist() => string.Join(' ', Artists.Select(a => a.Name));
public string GetArtist() => string.Join(" / ", Artists.Select(a => a.Name));
}
}

0 comments on commit 7ad2b65

Please sign in to comment.