diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Extensions/SongInfoExtensions.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Extensions/SongInfoExtensions.cs index f5cb0bf..4b7f7a2 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Extensions/SongInfoExtensions.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Extensions/SongInfoExtensions.cs @@ -36,6 +36,12 @@ namespace BetterLyrics.WinUI3.Extensions return songInfo; } + public SongInfo WithSongId(string value) + { + songInfo.SongId = value; + return songInfo; + } + public PlayHistoryItem? ToPlayHistoryItem(double actualPlayedMs) { if (songInfo == null) return null; diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/MetadataComparer.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/MetadataComparer.cs index 3d5b343..3caa937 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/MetadataComparer.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/MetadataComparer.cs @@ -10,27 +10,27 @@ namespace BetterLyrics.WinUI3.Helper { public static partial class MetadataComparer { - private const double WeightTitle = 0.40; - private const double WeightArtist = 0.40; + private const double WeightTitle = 0.30; + private const double WeightArtist = 0.30; private const double WeightAlbum = 0.10; - private const double WeightDuration = 0.10; + private const double WeightDuration = 0.30; // JaroWinkler 适合短字符串匹配 private static readonly JaroWinkler _algo = new(); public static int CalculateScore(SongInfo songInfo, LyricsCacheItem remote) { - return CalculateScore(songInfo, remote.Title, remote.Artist, remote.Album, remote.Duration * 1000); + return CalculateScore(songInfo, remote.Title, remote.Artist, remote.Album, remote.Duration); } public static int CalculateScore(SongInfo songInfo, FilesIndexItem local) { - return CalculateScore(songInfo, local.Title, local.Artist, local.Album, local.Duration * 1000, local.FileName); + return CalculateScore(songInfo, local.Title, local.Artist, local.Album, local.Duration, local.FileName); } public static int CalculateScore( SongInfo songInfo, - string? compareTitle, string? compareArtist, string? compareAlbum, double? compareDurationMs, string? compareFileName = null) + string? compareTitle, string? compareArtist, string? compareAlbum, double? compareDuration, string? compareFileName = null) { double totalScore = 0; @@ -42,7 +42,7 @@ namespace BetterLyrics.WinUI3.Helper double titleScore = GetStringSimilarity(songInfo.Title, compareTitle); double artistScore = GetStringSimilarity(songInfo.Artist, compareArtist); double albumScore = GetStringSimilarity(songInfo.Album, compareAlbum); - double durationScore = GetDurationSimilarity(songInfo.DurationMs, compareDurationMs); + double durationScore = GetDurationSimilarity(songInfo.Duration, compareDuration); totalScore = (titleScore * WeightTitle) + (artistScore * WeightArtist) + @@ -94,19 +94,18 @@ namespace BetterLyrics.WinUI3.Helper return _algo.Similarity(s1, s2); } - private static double GetDurationSimilarity(double localMs, double? remoteSeconds) + private static double GetDurationSimilarity(double localSeconds, double? remoteSeconds) { if (remoteSeconds == null || remoteSeconds == 0) return 0.0; // 远程没有时长数据,不匹配 - double localSeconds = localMs / 1000.0; double diff = Math.Abs(localSeconds - remoteSeconds.Value); - // 差距 <= 3秒:100% 相似 - // 差距 >= 20秒:0% 相似 + // 差距 <= 1 秒:100 % 相似 + // 差距 >= 10 秒:0 % 相似 // 中间线性插值 - const double PerfectTolerance = 3.0; - const double MaxTolerance = 20.0; + const double PerfectTolerance = 1.0; + const double MaxTolerance = 10.0; if (diff <= PerfectTolerance) return 1.0; if (diff >= MaxTolerance) return 0.0; diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/Lyrics/LyricsLine.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/Lyrics/LyricsLine.cs index bec7696..b54a993 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/Lyrics/LyricsLine.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/Lyrics/LyricsLine.cs @@ -19,6 +19,9 @@ namespace BetterLyrics.WinUI3.Models.Lyrics public string SecondaryText { get; set; } = ""; public string TertiaryText { get; set; } = ""; + public new string Text => PrimaryText; + public new int StartIndex = 0; + public LyricsLine() { for (int charStartIndex = 0; charStartIndex < PrimaryText.Length; charStartIndex++) diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/GSMTCService/GSMTCService.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/GSMTCService/GSMTCService.cs index 4f94e58..fcb6a0e 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/GSMTCService/GSMTCService.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/GSMTCService/GSMTCService.cs @@ -206,7 +206,6 @@ namespace BetterLyrics.WinUI3.Services.GSMTCService private void InitMediaManager() { _mediaManager.Start(); - _mediaManager.CurrentMediaSessions.ToList().ForEach(x => RecordMediaSession(x.Value.Id)); _mediaManager.OnAnySessionOpened += MediaManager_OnAnySessionOpened; diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/LyricsCacheService/LyricsCacheService.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/LyricsCacheService/LyricsCacheService.cs index 7810805..c0a7057 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/LyricsCacheService/LyricsCacheService.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/LyricsCacheService/LyricsCacheService.cs @@ -55,6 +55,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsCacheService existingItem.Title = result.Title; existingItem.Artist = result.Artist; existingItem.Album = result.Album; + existingItem.Duration = result.Duration; existingItem.TransliterationProvider = result.TransliterationProvider; existingItem.TranslationProvider = result.TranslationProvider; diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/LyricsSearchService/LyricsSearchService.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/LyricsSearchService/LyricsSearchService.cs index d02f462..73a9303 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/LyricsSearchService/LyricsSearchService.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/LyricsSearchService/LyricsSearchService.cs @@ -1,5 +1,6 @@ // 2025/6/23 by Zhe Fang +using BetterLyrics.WinUI3.Constants; using BetterLyrics.WinUI3.Enums; using BetterLyrics.WinUI3.Extensions; using BetterLyrics.WinUI3.Helper; @@ -29,7 +30,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService { private readonly HttpClient _amllTtmlDbHttpClient; private readonly HttpClient _lrcLibHttpClient; - private readonly AppleMusic _appleMusic; + private readonly Providers.AppleMusic _appleMusic; private readonly ISettingsService _settingsService; private readonly IFileSystemService _fileSystemService; @@ -54,10 +55,10 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService _lrcLibHttpClient = new(); _lrcLibHttpClient.DefaultRequestHeaders.Add( "User-Agent", - $"{Constants.App.AppName} {MetadataHelper.AppVersion} ({Constants.Link.BetterLyricsGitHub})" + $"{Constants.App.AppName} {MetadataHelper.AppVersion} ({Link.BetterLyricsGitHub})" ); _amllTtmlDbHttpClient = new(); - _appleMusic = new AppleMusic(); + _appleMusic = new Providers.AppleMusic(); } private static bool IsAmllTtmlDbIndexInvalid() @@ -402,6 +403,8 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService } string? rawLyricFile = null; + string? bestNcmMusicId = null; + await foreach (var line in File.ReadLinesAsync(PathHelper.AmllTtmlDbIndexPath)) { if (string.IsNullOrWhiteSpace(line)) @@ -416,6 +419,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService string? title = null; string? artist = null; string? album = null; + string? ncmMusicId = null; foreach (var meta in metadataArr.EnumerateArray()) { @@ -429,6 +433,8 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService artist = string.Join(" / ", valueArr.EnumerateArray()); if (key == "album" && valueArr.GetArrayLength() > 0) album = valueArr[0].GetString(); + if (key == "ncmMusicId" && valueArr.GetArrayLength() > 0) + ncmMusicId = valueArr[0].GetString(); } int score = MetadataComparer.CalculateScore(songInfo, new LyricsCacheItem @@ -436,12 +442,12 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService Title = title, Artist = artist, Album = album, - Duration = 0, }); if (score > lyricsSearchResult.MatchPercentage) { if (root.TryGetProperty("rawLyricFile", out var rawLyricFileProp)) { + bestNcmMusicId = ncmMusicId; rawLyricFile = rawLyricFileProp.GetString(); lyricsSearchResult.Title = title; lyricsSearchResult.Artist = artist; @@ -458,19 +464,28 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService return lyricsSearchResult; } - // 下载歌词内容 - var url = $"{_settingsService.AppSettings.GeneralSettings.AmllTtmlDbBaseUrl}/{Constants.AmllTTmlDB.QueryPrefix}/{rawLyricFile}"; + var url = $"{_settingsService.AppSettings.GeneralSettings.AmllTtmlDbBaseUrl}/{AmllTTmlDB.QueryPrefix}/{rawLyricFile}"; lyricsSearchResult.Reference = url; try { + // 下载写入歌词 using var response = await _amllTtmlDbHttpClient.GetAsync(url); if (!response.IsSuccessStatusCode) { return lyricsSearchResult; } string lyrics = await response.Content.ReadAsStringAsync(); - lyricsSearchResult.Raw = lyrics; + + // 反查时长 + if (bestNcmMusicId != null && lyricsSearchResult.Duration == null) + { + var tmp = await SearchQQNeteaseKugouAsync( + ((SongInfo)songInfo.Clone()).WithSongId($"{ExtendedGenreFiled.NetEaseCloudMusicTrackID}{bestNcmMusicId}"), + Searchers.Netease); + lyricsSearchResult.Duration = tmp.Duration; + lyricsSearchResult.MatchPercentage = MetadataComparer.CalculateScore(songInfo, lyricsSearchResult); + } } catch { @@ -633,7 +648,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService } lyricsSearchResult.Title = result?.Title; - lyricsSearchResult.Artist = string.Join(" / ", result?.Artists ?? []); + lyricsSearchResult.Artist = result?.Artist; lyricsSearchResult.Album = result?.Album; lyricsSearchResult.Duration = result?.DurationMs / 1000;