mirror of
https://github.com/real-zony/ZonyLrcToolsX.git
synced 2025-07-01 20:30:41 +00:00
feat: Completed KuGouLyricDownloader.
完成了酷狗音乐歌词下载器。
This commit is contained in:
parent
dca66caadb
commit
e45319f048
@ -0,0 +1,27 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace ZonyLrcTools.Cli.Infrastructure.Lyric.KuGou.JsonModel
|
||||
{
|
||||
public class GetLyricAccessKeyRequest
|
||||
{
|
||||
[JsonProperty("ver")]
|
||||
public int UnknownParameters1 { get; }
|
||||
|
||||
[JsonProperty("man")]
|
||||
public string UnknownParameters2 { get; }
|
||||
|
||||
[JsonProperty("client")]
|
||||
public string UnknownParameters3 { get; }
|
||||
|
||||
[JsonProperty("hash")]
|
||||
public string FileHash { get; }
|
||||
|
||||
public GetLyricAccessKeyRequest(string fileHash)
|
||||
{
|
||||
UnknownParameters1 = 1;
|
||||
UnknownParameters2 = "yes";
|
||||
UnknownParameters3 = "mobi";
|
||||
FileHash = fileHash;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace ZonyLrcTools.Cli.Infrastructure.Lyric.KuGou.JsonModel
|
||||
{
|
||||
public class GetLyricAccessKeyResponse
|
||||
{
|
||||
[JsonProperty("status")]
|
||||
public int Status { get; set; }
|
||||
|
||||
[JsonProperty("errcode")]
|
||||
public int ErrorCode { get; set; }
|
||||
|
||||
[JsonProperty("candidates")]
|
||||
public List<GetLyricAccessKeyDataObject> AccessKeyDataObjects { get; set; }
|
||||
}
|
||||
|
||||
public class GetLyricAccessKeyDataObject
|
||||
{
|
||||
[JsonProperty("accesskey")]
|
||||
public string AccessKey { get; set; }
|
||||
|
||||
[JsonProperty("id")]
|
||||
public string Id { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace ZonyLrcTools.Cli.Infrastructure.Lyric.KuGou.JsonModel
|
||||
{
|
||||
public class GetLyricRequest
|
||||
{
|
||||
[JsonProperty("ver")] public int UnknownParameters1 { get; }
|
||||
|
||||
[JsonProperty("client")] public string UnknownParameters2 { get; }
|
||||
|
||||
[JsonProperty("fmt")] public string UnknownParameters3 { get; }
|
||||
|
||||
[JsonProperty("charset")] public string UnknownParameters4 { get; }
|
||||
|
||||
[JsonProperty("id")] public string Id { get; }
|
||||
|
||||
[JsonProperty("accesskey")] public string AccessKey { get; }
|
||||
|
||||
public GetLyricRequest(string id, string accessKey)
|
||||
{
|
||||
UnknownParameters1 = 1;
|
||||
UnknownParameters2 = "iphone";
|
||||
UnknownParameters3 = "lrc";
|
||||
UnknownParameters4 = "utf8";
|
||||
Id = id;
|
||||
AccessKey = accessKey;
|
||||
}
|
||||
}
|
||||
|
||||
public class GetLyricResponse
|
||||
{
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
using System.Text;
|
||||
using System.Web;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace ZonyLrcTools.Cli.Infrastructure.Lyric.KuGou.JsonModel
|
||||
{
|
||||
public class SongSearchRequest
|
||||
{
|
||||
[JsonProperty("filter")]
|
||||
public int Filter { get; }
|
||||
|
||||
[JsonProperty("platform")]
|
||||
public string Platform { get; }
|
||||
|
||||
[JsonProperty("keyword")]
|
||||
public string Keyword { get; }
|
||||
|
||||
public SongSearchRequest(string musicName, string artistName)
|
||||
{
|
||||
Filter = 2;
|
||||
Platform = "WebFilter";
|
||||
Keyword = HttpUtility.UrlEncode($"{musicName}+{artistName}", Encoding.UTF8);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace ZonyLrcTools.Cli.Infrastructure.Lyric.KuGou.JsonModel
|
||||
{
|
||||
public class SongSearchResponse
|
||||
{
|
||||
[JsonProperty("status")]
|
||||
public int Status { get; set; }
|
||||
|
||||
[JsonProperty("data")]
|
||||
public SongSearchResponseInnerData Data { get; set; }
|
||||
|
||||
[JsonProperty("error_code")]
|
||||
public int ErrorCode { get; set; }
|
||||
|
||||
[JsonProperty("error_msg")]
|
||||
public string ErrorMessage { get; set; }
|
||||
}
|
||||
|
||||
public class SongSearchResponseInnerData
|
||||
{
|
||||
[JsonProperty("lists")]
|
||||
public List<SongSearchResponseSongDetail> List { get; set; }
|
||||
}
|
||||
|
||||
public class SongSearchResponseSongDetail
|
||||
{
|
||||
public string FileHash { get; set; }
|
||||
}
|
||||
}
|
@ -1,4 +1,9 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using ZonyLrcTools.Cli.Infrastructure.Exceptions;
|
||||
using ZonyLrcTools.Cli.Infrastructure.Lyric.KuGou.JsonModel;
|
||||
using ZonyLrcTools.Cli.Infrastructure.Network;
|
||||
|
||||
namespace ZonyLrcTools.Cli.Infrastructure.Lyric.KuGou
|
||||
@ -10,6 +15,10 @@ namespace ZonyLrcTools.Cli.Infrastructure.Lyric.KuGou
|
||||
private readonly IWarpHttpClient _warpHttpClient;
|
||||
private readonly ILyricItemCollectionFactory _lyricItemCollectionFactory;
|
||||
|
||||
private const string KuGouSearchMusicUrl = @"https://songsearch.kugou.com/song_search_v2";
|
||||
private const string KuGouGetLyricAccessKeyUrl = @"http://lyrics.kugou.com/search";
|
||||
private const string KuGouGetLyricUrl = @"http://lyrics.kugou.com/download";
|
||||
|
||||
public KuGourLyricDownloader(IWarpHttpClient warpHttpClient,
|
||||
ILyricItemCollectionFactory lyricItemCollectionFactory)
|
||||
{
|
||||
@ -17,14 +26,43 @@ namespace ZonyLrcTools.Cli.Infrastructure.Lyric.KuGou
|
||||
_lyricItemCollectionFactory = lyricItemCollectionFactory;
|
||||
}
|
||||
|
||||
protected override ValueTask<byte[]> DownloadDataAsync(LyricDownloaderArgs args)
|
||||
protected override async ValueTask<byte[]> DownloadDataAsync(LyricDownloaderArgs args)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
var searchResult = await _warpHttpClient.GetAsync<SongSearchResponse>(KuGouSearchMusicUrl,
|
||||
new SongSearchRequest(args.SongName, args.Artist));
|
||||
|
||||
ValidateSongSearchResponse(searchResult, args);
|
||||
|
||||
// 获得特殊的 AccessToken 与 Id,真正请求歌词数据。
|
||||
var accessKeyResponse = await _warpHttpClient.GetAsync<GetLyricAccessKeyResponse>(KuGouGetLyricAccessKeyUrl,
|
||||
new GetLyricAccessKeyRequest(searchResult.Data.List[0].FileHash));
|
||||
|
||||
var accessKeyObject = accessKeyResponse.AccessKeyDataObjects[0];
|
||||
var lyricResponse = await _warpHttpClient.GetAsync(KuGouGetLyricUrl,
|
||||
new GetLyricRequest(accessKeyObject.Id, accessKeyObject.AccessKey));
|
||||
|
||||
return Encoding.UTF8.GetBytes(lyricResponse);
|
||||
}
|
||||
|
||||
protected override ValueTask<LyricItemCollection> GenerateLyricAsync(byte[] data, LyricDownloaderArgs args)
|
||||
protected override async ValueTask<LyricItemCollection> GenerateLyricAsync(byte[] data, LyricDownloaderArgs args)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
await ValueTask.CompletedTask;
|
||||
var lyricJsonObj = JObject.Parse(Encoding.UTF8.GetString(data));
|
||||
if (lyricJsonObj.SelectToken("$.status").Value<int>() != 200)
|
||||
{
|
||||
throw new ErrorCodeException(ErrorCodes.NoMatchingSong, attachObj: args);
|
||||
}
|
||||
|
||||
var lyricText = Encoding.UTF8.GetString(Convert.FromBase64String(lyricJsonObj.SelectToken("$.content").Value<string>()));
|
||||
return _lyricItemCollectionFactory.Build(lyricText);
|
||||
}
|
||||
|
||||
protected virtual void ValidateSongSearchResponse(SongSearchResponse response, LyricDownloaderArgs args)
|
||||
{
|
||||
if (response.ErrorCode != 0 && response.Status != 1 || response.Data.List == null)
|
||||
{
|
||||
throw new ErrorCodeException(ErrorCodes.NoMatchingSong, attachObj: args);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -3,7 +3,6 @@ using System.Net.Http.Headers;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
using ZonyLrcTools.Cli.Infrastructure.DependencyInject;
|
||||
using ZonyLrcTools.Cli.Infrastructure.Exceptions;
|
||||
using ZonyLrcTools.Cli.Infrastructure.Lyric.NetEase.JsonModel;
|
||||
using ZonyLrcTools.Cli.Infrastructure.Network;
|
||||
|
@ -0,0 +1,25 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Shouldly;
|
||||
using Xunit;
|
||||
using ZonyLrcTools.Cli.Infrastructure.Lyric;
|
||||
|
||||
namespace ZonyLrcTools.Tests.Infrastructure.Lyric
|
||||
{
|
||||
public class KuGouLyricDownloaderTests : TestBase
|
||||
{
|
||||
[Fact]
|
||||
public async Task DownloadAsync_Test()
|
||||
{
|
||||
var downloaderList = ServiceProvider.GetRequiredService<IEnumerable<ILyricDownloader>>();
|
||||
var kuGouDownloader = downloaderList.FirstOrDefault(t => t.DownloaderName == InternalLyricDownloaderNames.KuGou);
|
||||
|
||||
kuGouDownloader.ShouldNotBeNull();
|
||||
var lyric = await kuGouDownloader.DownloadAsync("东方红", null);
|
||||
lyric.ShouldNotBeNull();
|
||||
lyric.IsPruneMusic.ShouldBe(false);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user