Compare commits

...

2 Commits

Author SHA1 Message Date
Thord Johansson 90eca9e76a Enhance config handling and album art logic
- Refactored variable names for clarity, changing `data` to `config_data` to better indicate its purpose related to configuration settings.
- Significantly enhanced the album art determination logic to prioritize MusicBrainz data when configured, with a fallback to YouTube thumbnails if necessary.
- Introduced `FindMusicBrainzRelease` method for searching MusicBrainz releases based on the release name, aiming for exact alphanumeric matches or the highest scoring match.
- Added `EqualsAlphanumeric` utility method for accurate alphanumeric string comparisons, supporting the MusicBrainz release search functionality.
2024-06-18 23:40:12 +02:00
Thord Johansson c349ead544 Fix to ensure the Youtube thumbnail is used where available 2024-06-11 13:32:52 +02:00

View File

@ -44,9 +44,9 @@ public class LbzRpcService
throw new ApplicationException("Configuration file not found. Please create a config.ini file with your tokens and user information.");
}
IniData data = config.ReadFile("config.ini");
IniData config_data = config.ReadFile("config.ini");
listenBrainz = new ListenBrainz();
client = new DiscordRpcClient(data["general"]["discord_token"]);
client = new DiscordRpcClient(config_data["general"]["discord_token"]);
void InitializeDiscordRpc()
{
@ -84,8 +84,8 @@ public class LbzRpcService
continue;
}
var username = data["general"]["listenbrainz_username"];
var ignoredPlayers = data["general"]["ignored_sources"].Split(",", StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
var username = config_data["general"]["listenbrainz_username"];
var ignoredPlayers = config_data["general"]["ignored_sources"].Split(",", StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
var listen = listenBrainz.GetPlayingNow(username);
if (listen != null)
@ -137,7 +137,7 @@ public class LbzRpcService
else
{
var youtubeId = GetYoutubeId(listenData.AdditionalInfo.OriginUrl);
albumArtUrl = "https://img.youtube.com/vi/" + youtubeId + "/0.jpg";
albumArtUrl = "https://img.youtube.com/vi/" + youtubeId + "/mqdefault.jpg";
}
}
else if (lastRecording != listenData.AdditionalInfo?.RecordingId.ToString()) // MusicBrainz ID available
@ -154,28 +154,45 @@ public class LbzRpcService
buttons.Add(new Button() { Label = $"{username} on ListenBrainz", Url = $"https://listenbrainz.org/user/{username}" });
if (listenData.AdditionalInfo?.ReleaseId != null)
string? newAlbumArt = null;
if (config_data["general"]["prioritise_musicbrainz"] == "true" && listenData.AdditionalInfo?.ReleaseId != null)
{
albumArtUrl = "https://coverartarchive.org/release/" + listenData.AdditionalInfo?.ReleaseId + "/front-250.jpg";
newAlbumArt = "https://coverartarchive.org/release/" + listenData.AdditionalInfo?.ReleaseId + "/front-250.jpg";
}
else if (listenData.Release != null)
else if (config_data["general"]["prioritise_musicbrainz"] == "true" && listenData.Release != null)
{
Console.WriteLine("Searching for release {0} on MusicBrainz", listenData.Release);
Query q = new("LBZ-DRPC", new Version(1, 0, 0));
var release = q.FindReleases(listenData.Release, 1).Results?.FirstOrDefault();
if (release != null)
{
albumArtUrl = "https://coverartarchive.org/release/" + release?.Item.Id + "/front-250.jpg";
}
var release = FindMusicBrainzRelease(listenData.Release);
newAlbumArt = "https://coverartarchive.org/release/" + release?.Item.Id + "/front-250.jpg";
}
Console.WriteLine("Album art URL: " + albumArtUrl);
if (newAlbumArt == null)
{
if ((listenData.AdditionalInfo?.OriginUrl?.ToString().Contains("youtube") == true
|| listenData.AdditionalInfo?.OriginUrl?.ToString().Contains("youtu.be") == true)
&& GetYoutubeId(listenData.AdditionalInfo.OriginUrl) != null)
{
newAlbumArt = "https://img.youtube.com/vi/" + GetYoutubeId(listenData.AdditionalInfo.OriginUrl) + "/0.jpg";
}
else if (listenData.AdditionalInfo?.ReleaseId != null)
{
newAlbumArt = "https://coverartarchive.org/release/" + listenData.AdditionalInfo?.ReleaseId + "/front-250.jpg";
}
else if (listenData.Release != null)
{
var release = FindMusicBrainzRelease(listenData.Release);
newAlbumArt = "https://coverartarchive.org/release/" + release?.Item.Id + "/front-250.jpg";
}
}
Console.WriteLine("Album art URL: " + (newAlbumArt ?? "(none)"));
albumArtUrl = newAlbumArt ?? "";
}
client.SetPresence(new RichPresence()
{
Details = $"{listenData.Name}",
State = (listenData.Release != null && listenData.Release != listenData.Name) ? $"{listenData.Artist} ({listenData.Release})" : listenData.Artist,
State = (listenData.Release != null && listenData.Release != listenData.Name) ? $"{listenData.Release} ({listenData.Artist})" : listenData.Artist,
Buttons = buttons.ToArray(),
Assets = new Assets()
{
@ -198,7 +215,7 @@ public class LbzRpcService
client.ClearPresence();
}
var interval = int.Parse(data["general"]["poll_interval"]);
var interval = int.Parse(config_data["general"]["poll_interval"]);
while (interval > 0 && running)
{
Thread.Sleep(1000);
@ -207,12 +224,49 @@ public class LbzRpcService
}
}
private ISearchResult<IRelease>? FindMusicBrainzRelease(string release)
{
Console.WriteLine("Searching for release {0} on MusicBrainz", release);
Query q = new("LBZ-DRPC", new Version(1, 0, 0));
var results = q.FindReleases(release, 5).Results;
if (results != null && results.Any())
{
// Find the result with the exact release title
var exactMatch = results.FirstOrDefault(r => EqualsAlphanumeric(r.Item.Title, release));
if (exactMatch != null)
{
Console.WriteLine("Found match (alphanumeric): {0}", release);
return exactMatch;
}
// If exact match not found, return the result with the highest score
var highestScore = results.OrderByDescending(r => r.Score).FirstOrDefault();
Console.WriteLine("Found match (highest scoring): {0}", release);
return highestScore;
}
return null;
}
private bool EqualsAlphanumeric(string? a, string b)
{
return a?.Where(b => char.IsLetterOrDigit(b) || char.IsWhiteSpace(b)).SequenceEqual(b.Where(c => char.IsLetterOrDigit(c) || char.IsWhiteSpace(c))) == true;
}
private string? GetYoutubeId(Uri originUrl)
{
var query = HttpUtility.ParseQueryString(originUrl.Query);
if (query["v"] != null)
if (originUrl.ToString().Contains("youtu.be"))
{
return query["v"];
return originUrl.Segments.Last();
}
else
{
var query = HttpUtility.ParseQueryString(originUrl.Query);
if (query["v"] != null)
{
return query["v"];
}
}
return null;
}