mirror of
https://github.com/real-zony/ZonyLrcToolsX.git
synced 2025-07-01 12:11:13 +00:00
feat: Enhanced song matching logic (NetEaseMusic).
This commit is contained in:
parent
c583a9c278
commit
140043db79
@ -8,6 +8,8 @@ using System.Threading.Tasks;
|
||||
using McMaster.Extensions.CommandLineUtils;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using NAudio.Wave;
|
||||
using TagLib.Mpeg;
|
||||
using ZonyLrcTools.Cli.Config;
|
||||
using ZonyLrcTools.Cli.Infrastructure;
|
||||
using ZonyLrcTools.Cli.Infrastructure.Album;
|
||||
@ -17,6 +19,7 @@ using ZonyLrcTools.Cli.Infrastructure.IO;
|
||||
using ZonyLrcTools.Cli.Infrastructure.Lyric;
|
||||
using ZonyLrcTools.Cli.Infrastructure.Tag;
|
||||
using ZonyLrcTools.Cli.Infrastructure.Threading;
|
||||
using File = System.IO.File;
|
||||
|
||||
namespace ZonyLrcTools.Cli.Commands.SubCommand
|
||||
{
|
||||
@ -131,7 +134,11 @@ namespace ZonyLrcTools.Cli.Commands.SubCommand
|
||||
var warpTaskList = files.Select(file => warpTask.RunAsync(() => Task.Run(async () => await _tagLoader.LoadTagAsync(file))));
|
||||
var result = (await Task.WhenAll(warpTaskList))
|
||||
.Where(m => m != null)
|
||||
.Where(m => !string.IsNullOrEmpty(m.Name) || !string.IsNullOrEmpty(m.Artist));
|
||||
.Where(m => !string.IsNullOrEmpty(m.Name) || !string.IsNullOrEmpty(m.Artist))
|
||||
.ToList();
|
||||
|
||||
// Load music total time info.
|
||||
result.Foreach(m => { m.TotalTime = (long?)new AudioFileReader(m.FilePath).TotalTime.TotalMilliseconds; });
|
||||
|
||||
_logger.LogInformation($"已成功加载 {files.Count} 个音乐文件的标签信息。");
|
||||
|
||||
@ -173,7 +180,7 @@ namespace ZonyLrcTools.Cli.Commands.SubCommand
|
||||
{
|
||||
try
|
||||
{
|
||||
var lyric = await downloader.DownloadAsync(info.Name, info.Artist);
|
||||
var lyric = await downloader.DownloadAsync(info.Name, info.Artist, info.TotalTime);
|
||||
var lyricFilePath = Path.Combine(Path.GetDirectoryName(info.FilePath)!,
|
||||
$"{Path.GetFileNameWithoutExtension(info.FilePath)}.lrc");
|
||||
|
||||
|
@ -51,7 +51,7 @@ namespace ZonyLrcTools.Cli.Infrastructure.Album.NetEase
|
||||
|
||||
var songDetailJsonStr = await _warpHttpClient.GetAsync(
|
||||
GetMusicInfoApi,
|
||||
new GetSongDetailsRequest(searchResult.GetFirstMatchSongId(songName)),
|
||||
new GetSongDetailsRequest(searchResult.GetFirstMatchSongId(songName, null)),
|
||||
_defaultOption);
|
||||
|
||||
var url = JObject.Parse(songDetailJsonStr).SelectToken("$.songs[0].album.picUrl")?.Value<string>();
|
||||
|
@ -12,8 +12,9 @@ namespace ZonyLrcTools.Cli.Infrastructure.Lyric
|
||||
/// </summary>
|
||||
/// <param name="songName">歌曲的名称。</param>
|
||||
/// <param name="artist">歌曲的作者。</param>
|
||||
/// <param name="duration">歌曲的时长。</param>
|
||||
/// <returns>歌曲的歌词数据对象。</returns>
|
||||
ValueTask<LyricItemCollection> DownloadAsync(string songName, string artist);
|
||||
ValueTask<LyricItemCollection> DownloadAsync(string songName, string artist, long? duration = null);
|
||||
|
||||
/// <summary>
|
||||
/// 下载器的名称。
|
||||
|
@ -16,10 +16,11 @@ namespace ZonyLrcTools.Cli.Infrastructure.Lyric
|
||||
/// </summary>
|
||||
/// <param name="songName">歌曲名称。</param>
|
||||
/// <param name="artist">歌曲作者/艺术家。</param>
|
||||
/// <param name="duration">歌曲的时长。</param>
|
||||
/// <returns>下载完成的歌曲数据。</returns>
|
||||
public virtual async ValueTask<LyricItemCollection> DownloadAsync(string songName, string artist)
|
||||
public virtual async ValueTask<LyricItemCollection> DownloadAsync(string songName, string artist, long? duration = null)
|
||||
{
|
||||
var args = new LyricDownloaderArgs(songName, artist);
|
||||
var args = new LyricDownloaderArgs(songName, artist, duration ?? 0);
|
||||
await ValidateAsync(args);
|
||||
var downloadDataBytes = await DownloadDataAsync(args);
|
||||
return await GenerateLyricAsync(downloadDataBytes, args);
|
||||
|
@ -6,10 +6,13 @@ namespace ZonyLrcTools.Cli.Infrastructure.Lyric
|
||||
|
||||
public string Artist { get; set; }
|
||||
|
||||
public LyricDownloaderArgs(string songName, string artist)
|
||||
public long Duration { get; set; }
|
||||
|
||||
public LyricDownloaderArgs(string songName, string artist, long duration)
|
||||
{
|
||||
SongName = songName;
|
||||
Artist = artist;
|
||||
Duration = duration;
|
||||
}
|
||||
}
|
||||
}
|
@ -49,7 +49,7 @@ namespace ZonyLrcTools.Cli.Infrastructure.Lyric.NetEase.JsonModel
|
||||
Type = 1;
|
||||
Offset = 0;
|
||||
IsTotal = true;
|
||||
Limit = 5;
|
||||
Limit = 10;
|
||||
}
|
||||
|
||||
public SongSearchRequest(string musicName, string artistName) : this()
|
||||
|
@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
@ -10,10 +11,20 @@ namespace ZonyLrcTools.Cli.Infrastructure.Lyric.NetEase.JsonModel
|
||||
|
||||
[JsonProperty("code")] public int StatusCode { get; set; }
|
||||
|
||||
public int GetFirstMatchSongId(string songName)
|
||||
public int GetFirstMatchSongId(string songName, long? duration)
|
||||
{
|
||||
var item = Items.SongItems.FirstOrDefault(x => x.Name == songName);
|
||||
return item?.Id ?? Items.SongItems[0].Id;
|
||||
var perfectMatch = Items.SongItems.FirstOrDefault(x => x.Name == songName);
|
||||
if (perfectMatch != null)
|
||||
{
|
||||
return perfectMatch.Id;
|
||||
}
|
||||
|
||||
if (duration is null or 0)
|
||||
{
|
||||
return Items.SongItems.First().Id;
|
||||
}
|
||||
|
||||
return Items.SongItems.OrderBy(t => Math.Abs(t.Duration - duration.Value)).First().Id;
|
||||
}
|
||||
}
|
||||
|
||||
@ -49,6 +60,12 @@ namespace ZonyLrcTools.Cli.Infrastructure.Lyric.NetEase.JsonModel
|
||||
/// </summary>
|
||||
[JsonProperty("album")]
|
||||
public SongAlbumModel Album { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 歌曲的实际长度。
|
||||
/// </summary>
|
||||
[JsonProperty("duration")]
|
||||
public long Duration { get; set; }
|
||||
}
|
||||
|
||||
public class SongArtistModel
|
||||
|
@ -48,7 +48,7 @@ namespace ZonyLrcTools.Cli.Infrastructure.Lyric.NetEase
|
||||
|
||||
var lyricResponse = await _warpHttpClient.GetAsync(
|
||||
NetEaseGetLyricUrl,
|
||||
new GetLyricRequest(searchResult.GetFirstMatchSongId(args.SongName)),
|
||||
new GetLyricRequest(searchResult.GetFirstMatchSongId(args.SongName, args.Duration)),
|
||||
msg => msg.Headers.Referrer = new Uri(NetEaseRequestReferer));
|
||||
|
||||
return Encoding.UTF8.GetBytes(lyricResponse);
|
||||
|
@ -1,3 +1,5 @@
|
||||
using System;
|
||||
|
||||
namespace ZonyLrcTools.Cli.Infrastructure
|
||||
{
|
||||
/// <summary>
|
||||
@ -10,6 +12,11 @@ namespace ZonyLrcTools.Cli.Infrastructure
|
||||
/// </summary>
|
||||
public string FilePath { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 歌曲的实际歌曲长度。
|
||||
/// </summary>
|
||||
public long? TotalTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 歌曲的名称。
|
||||
/// </summary>
|
||||
|
@ -10,6 +10,7 @@
|
||||
<PackageReference Include="McMaster.Extensions.Hosting.CommandLine" Version="4.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Http" Version="6.0.0" />
|
||||
<PackageReference Include="NAudio" Version="2.1.0" />
|
||||
<PackageReference Include="NetEscapades.Configuration.Yaml" Version="2.2.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="Refit" Version="6.3.2" />
|
||||
|
Loading…
x
Reference in New Issue
Block a user