mirror of
https://github.com/real-zony/ZonyLrcToolsX.git
synced 2025-07-01 20:30:41 +00:00
feat: Modified the lyrics interface for Netease Cloud Music to support higher concurrency.
This commit is contained in:
parent
493f48cefe
commit
f935f07609
@ -47,7 +47,7 @@ namespace ZonyLrcTools.Cli.Commands.SubCommand
|
|||||||
public bool DownloadAlbum { get; set; }
|
public bool DownloadAlbum { get; set; }
|
||||||
|
|
||||||
[Option("-n|--number", CommandOptionType.SingleValue, Description = "指定下载时候的线程数量。(默认值 2)")]
|
[Option("-n|--number", CommandOptionType.SingleValue, Description = "指定下载时候的线程数量。(默认值 2)")]
|
||||||
public int ParallelNumber { get; set; } = 2;
|
public int ParallelNumber { get; set; } = 1;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
|
using Polly;
|
||||||
using ZonyLrcTools.Common.Configuration;
|
using ZonyLrcTools.Common.Configuration;
|
||||||
using ZonyLrcTools.Common.Infrastructure.DependencyInject;
|
using ZonyLrcTools.Common.Infrastructure.DependencyInject;
|
||||||
using ZonyLrcTools.Common.Infrastructure.Exceptions;
|
using ZonyLrcTools.Common.Infrastructure.Exceptions;
|
||||||
@ -36,7 +37,7 @@ public class LyricsDownloader : ILyricsDownloader, ISingletonDependency
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async Task DownloadAsync(List<MusicInfo> needDownloadMusicInfos,
|
public async Task DownloadAsync(List<MusicInfo> needDownloadMusicInfos,
|
||||||
int parallelCount = 2,
|
int parallelCount = 1,
|
||||||
CancellationToken cancellationToken = default)
|
CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
await _logger.InfoAsync("开始下载歌词文件数据...");
|
await _logger.InfoAsync("开始下载歌词文件数据...");
|
||||||
@ -106,6 +107,7 @@ public class LyricsDownloader : ILyricsDownloader, ISingletonDependency
|
|||||||
{
|
{
|
||||||
_logger.LogWarningInfo(ex);
|
_logger.LogWarningInfo(ex);
|
||||||
info.IsSuccessful = false;
|
info.IsSuccessful = false;
|
||||||
|
throw;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -8,7 +8,7 @@ namespace ZonyLrcTools.Common.Lyrics.Providers.NetEase.JsonModel
|
|||||||
{
|
{
|
||||||
public GetLyricRequest(long songId)
|
public GetLyricRequest(long songId)
|
||||||
{
|
{
|
||||||
OS = "ios";
|
OS = "pc";
|
||||||
Id = songId;
|
Id = songId;
|
||||||
Lv = Kv = Tv = Rv = -1;
|
Lv = Kv = Tv = Rv = -1;
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,7 @@ namespace ZonyLrcTools.Common.Lyrics.Providers.NetEase.JsonModel
|
|||||||
var regex = new Regex(@"\([^)]*\)");
|
var regex = new Regex(@"\([^)]*\)");
|
||||||
musicName = regex.Replace(musicName, string.Empty);
|
musicName = regex.Replace(musicName, string.Empty);
|
||||||
|
|
||||||
SearchKey = HttpUtility.UrlEncode($"{musicName}+{artistName}", Encoding.UTF8);
|
SearchKey = $"{musicName}+{artistName}";
|
||||||
Limit = limit;
|
Limit = limit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ using System.Net.Http.Headers;
|
|||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using ZonyLrcTools.Common.Configuration;
|
using ZonyLrcTools.Common.Configuration;
|
||||||
|
using ZonyLrcTools.Common.Infrastructure.Encryption;
|
||||||
using ZonyLrcTools.Common.Infrastructure.Exceptions;
|
using ZonyLrcTools.Common.Infrastructure.Exceptions;
|
||||||
using ZonyLrcTools.Common.Infrastructure.Network;
|
using ZonyLrcTools.Common.Infrastructure.Network;
|
||||||
using ZonyLrcTools.Common.Lyrics.Providers.NetEase.JsonModel;
|
using ZonyLrcTools.Common.Lyrics.Providers.NetEase.JsonModel;
|
||||||
@ -16,8 +17,8 @@ namespace ZonyLrcTools.Common.Lyrics.Providers.NetEase
|
|||||||
private readonly ILyricsItemCollectionFactory _lyricsItemCollectionFactory;
|
private readonly ILyricsItemCollectionFactory _lyricsItemCollectionFactory;
|
||||||
private readonly GlobalOptions _options;
|
private readonly GlobalOptions _options;
|
||||||
|
|
||||||
private const string NetEaseSearchMusicUrl = @"https://music.163.com/api/search/get/web";
|
private const string NetEaseSearchMusicUrl = @"https://music.163.com/weapi/cloudsearch/get/web";
|
||||||
private const string NetEaseGetLyricUrl = @"https://music.163.com/api/song/lyric";
|
private const string NetEaseGetLyricUrl = @"https://music.163.com/weapi/song/lyric?csrf_token=";
|
||||||
|
|
||||||
private const string NetEaseRequestReferer = @"https://music.163.com";
|
private const string NetEaseRequestReferer = @"https://music.163.com";
|
||||||
private const string NetEaseRequestContentType = @"application/x-www-form-urlencoded";
|
private const string NetEaseRequestContentType = @"application/x-www-form-urlencoded";
|
||||||
@ -33,25 +34,30 @@ namespace ZonyLrcTools.Common.Lyrics.Providers.NetEase
|
|||||||
|
|
||||||
protected override async ValueTask<object> DownloadDataAsync(LyricsProviderArgs args)
|
protected override async ValueTask<object> DownloadDataAsync(LyricsProviderArgs args)
|
||||||
{
|
{
|
||||||
var searchResult = await _warpHttpClient.PostAsync<SongSearchResponse>(
|
var secretKey = NetEaseMusicEncryptionHelper.CreateSecretKey(16);
|
||||||
NetEaseSearchMusicUrl,
|
var encSecKey = NetEaseMusicEncryptionHelper.RsaEncode(secretKey);
|
||||||
new SongSearchRequest(args.SongName, args.Artist, _options.Provider.Lyric.GetLyricProviderOption(DownloaderName).Depth),
|
|
||||||
true,
|
var searchResult = await _warpHttpClient.PostAsync<SongSearchResponse>(NetEaseSearchMusicUrl,
|
||||||
msg =>
|
requestOption: request =>
|
||||||
{
|
{
|
||||||
msg.Headers.Referrer = new Uri(NetEaseRequestReferer);
|
request.Headers.Referrer = new Uri(NetEaseRequestReferer);
|
||||||
if (msg.Content != null)
|
request.Content = new FormUrlEncodedContent(HandleRequest(
|
||||||
{
|
new SongSearchRequest(args.SongName, args.Artist, _options.Provider.Lyric.GetLyricProviderOption(DownloaderName).Depth),
|
||||||
msg.Content.Headers.ContentType = MediaTypeHeaderValue.Parse(NetEaseRequestContentType);
|
secretKey,
|
||||||
}
|
encSecKey));
|
||||||
});
|
});
|
||||||
|
|
||||||
ValidateSongSearchResponse(searchResult, args);
|
ValidateSongSearchResponse(searchResult, args);
|
||||||
|
|
||||||
return await _warpHttpClient.GetAsync(
|
return await _warpHttpClient.PostAsync(NetEaseGetLyricUrl,
|
||||||
NetEaseGetLyricUrl,
|
requestOption: request =>
|
||||||
new GetLyricRequest(searchResult.GetFirstMatchSongId(args.SongName, args.Duration)),
|
{
|
||||||
msg => msg.Headers.Referrer = new Uri(NetEaseRequestReferer));
|
request.Headers.Referrer = new Uri(NetEaseRequestReferer);
|
||||||
|
request.Content = new FormUrlEncodedContent(HandleRequest(
|
||||||
|
new GetLyricRequest(searchResult.GetFirstMatchSongId(args.SongName, args.Duration)),
|
||||||
|
secretKey,
|
||||||
|
encSecKey));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async ValueTask<LyricsItemCollection> GenerateLyricAsync(object lyricsObject, LyricsProviderArgs args)
|
protected override async ValueTask<LyricsItemCollection> GenerateLyricAsync(object lyricsObject, LyricsProviderArgs args)
|
||||||
@ -86,5 +92,18 @@ namespace ZonyLrcTools.Common.Lyrics.Providers.NetEase
|
|||||||
throw new ErrorCodeException(ErrorCodes.NoMatchingSong, attachObj: args);
|
throw new ErrorCodeException(ErrorCodes.NoMatchingSong, attachObj: args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Dictionary<string, string> HandleRequest(object srcParams, string secretKey, string encSecKey)
|
||||||
|
{
|
||||||
|
return new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{
|
||||||
|
"params", NetEaseMusicEncryptionHelper.AesEncode(
|
||||||
|
NetEaseMusicEncryptionHelper.AesEncode(
|
||||||
|
JsonConvert.SerializeObject(srcParams), NetEaseMusicEncryptionHelper.Nonce), secretKey)
|
||||||
|
},
|
||||||
|
{ "encSecKey", encSecKey }
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -14,6 +14,7 @@
|
|||||||
<PackageReference Include="MusicDecrypto.Library" Version="2.2.0" />
|
<PackageReference Include="MusicDecrypto.Library" Version="2.2.0" />
|
||||||
<PackageReference Include="NetEscapades.Configuration.Yaml" Version="3.0.0" />
|
<PackageReference Include="NetEscapades.Configuration.Yaml" Version="3.0.0" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
|
<PackageReference Include="Polly" Version="7.2.3" />
|
||||||
<PackageReference Include="QRCoder" Version="1.4.3" />
|
<PackageReference Include="QRCoder" Version="1.4.3" />
|
||||||
<PackageReference Include="TagLibSharp" Version="2.3.0" />
|
<PackageReference Include="TagLibSharp" Version="2.3.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -105,5 +105,12 @@ namespace ZonyLrcTools.Tests.Infrastructure.Lyrics
|
|||||||
var lyric = await _lyricsProvider.DownloadAsync("橄榄树", "苏曼");
|
var lyric = await _lyricsProvider.DownloadAsync("橄榄树", "苏曼");
|
||||||
lyric.ToString().ShouldNotBeNullOrEmpty();
|
lyric.ToString().ShouldNotBeNullOrEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task DownloadAsync_Issue133_Test()
|
||||||
|
{
|
||||||
|
var lyric = await _lyricsProvider.DownloadAsync("Everything", "Yinyues");
|
||||||
|
lyric.ToString().ShouldNotBeNullOrEmpty();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -37,5 +37,12 @@ namespace ZonyLrcTools.Tests.Infrastructure.Lyrics
|
|||||||
lyric.IsPruneMusic.ShouldBeFalse();
|
lyric.IsPruneMusic.ShouldBeFalse();
|
||||||
lyric.ToString().ShouldContain("你好像快要不能呼吸");
|
lyric.ToString().ShouldContain("你好像快要不能呼吸");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task DownloadAsync_Issue133_Test()
|
||||||
|
{
|
||||||
|
var lyric = await _lyricsProvider.DownloadAsync("天ノ弱", "漆柚");
|
||||||
|
lyric.ToString().ShouldNotBeNullOrEmpty();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user