Skip to content

Commit

Permalink
fix: Fixed the issue where Kuwo Music could not download lyrics.
Browse files Browse the repository at this point in the history
  • Loading branch information
real-zony committed Dec 22, 2023
1 parent 2ce7b00 commit fea5e11
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,49 @@ namespace ZonyLrcTools.Common.Lyrics.Providers.KuWo.JsonModel;

public class SongSearchRequest
{
[JsonProperty("key")] public string Keyword { get; set; }
[JsonProperty("all")] public string Keyword { get; set; }

[JsonProperty("pn")] public int PageNumber { get; }

[JsonProperty("rn")] public int PageSize { get; }

public SongSearchRequest(string name, string artist, int pageNumber = 1, int pageSize = 20)
[JsonProperty("ft")] public string Unknown1 { get; } = "music";

[JsonProperty("newsearch")] public string Unknown2 { get; } = "1";

[JsonProperty("alflac")] public string Unknown3 { get; } = "1";

[JsonProperty("itemset")] public string Unknown4 { get; } = "web_2013";

[JsonProperty("client")] public string Unknown5 { get; } = "kt";

[JsonProperty("cluster")] public string Unknown6 { get; } = "0";

[JsonProperty("vermerge")] public string Unknown7 { get; } = "1";

[JsonProperty("rformat")] public string Unknown8 { get; } = "json";

[JsonProperty("encoding")] public string Unknown9 { get; } = "utf8";

[JsonProperty("show_copyright_off")] public string Unknown10 { get; } = "1";

[JsonProperty("pcmp4")] public string Unknown11 { get; } = "1";

[JsonProperty("ver")] public string Unknown12 { get; } = "mbox";

[JsonProperty("plat")] public string Unknown13 { get; } = "pc";

[JsonProperty("vipver")] public string Unknown14 { get; } = "MUSIC_9.2.0.0_W6";

[JsonProperty("devid")] public string Unknown15 { get; } = "11404450";

[JsonProperty("newver")] public string Unknown16 { get; } = "1";

[JsonProperty("issubtitle")] public string Unknown17 { get; } = "1";

[JsonProperty("pcjson")] public string Unknown18 { get; } = "1";

public SongSearchRequest(string name, string artist, int pageNumber = 0, int pageSize = 20)
{
Keyword = $"{name} {artist}";
PageNumber = pageNumber;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,43 +4,57 @@ namespace ZonyLrcTools.Common.Lyrics.Providers.KuWo.JsonModel;

public class SongSearchResponse
{
[JsonProperty("code")] public int Code { get; set; }
[JsonProperty("TOTAL")] public int TotalCount { get; set; }

[JsonProperty("data")] public SongSearchResponseInnerData InnerData { get; set; } = null!;

[JsonProperty("msg")] public string? ErrorMessage { get; set; }
[JsonProperty("abslist")]
public IList<SongSearchResponseSongDetail> SongList { get; set; }

public long GetMatchedMusicId(string musicName, string artistName, long? duration)
{
var prefectMatch = InnerData.SongItems.FirstOrDefault(x => x.Name == musicName && x.Artist == artistName);
var prefectMatch = SongList.FirstOrDefault(x => x.Name == musicName && x.Artist == artistName);
if (prefectMatch != null)
{
return prefectMatch.MusicId;
}

if (duration is null or 0)
{
return InnerData.SongItems.First().MusicId;
return SongList.First().MusicId;
}

return InnerData.SongItems.OrderBy(t => Math.Abs(t.Duration - duration.Value)).First().MusicId;
return SongList.OrderBy(t => Math.Abs(t.Duration - duration.Value)).First().MusicId;
}
}

public class SongSearchResponseInnerData
{
[JsonProperty("total")] public string? Total { get; set; }

[JsonProperty("list")] public ICollection<SongSearchResponseDetail> SongItems { get; set; } = null!;
}

public class SongSearchResponseDetail
public class SongSearchResponseSongDetail
{
[JsonProperty("artist")] public string? Artist { get; set; }

[JsonProperty("name")] public string? Name { get; set; }

[JsonProperty("rid")] public long MusicId { get; set; }

[JsonProperty("duration")] public long Duration { get; set; }
/// <summary>
/// 专辑名称。
/// </summary>
[JsonProperty("ALBUM")]
public string Album { get; set; }

/// <summary>
/// 歌手名称。
/// </summary>
[JsonProperty("ARTIST")]
public string Artist { get; set; }

/// <summary>
/// 歌曲名称。
/// </summary>
[JsonProperty("SONGNAME")]
public string Name { get; set; }

/// <summary>
/// 歌曲的 ID。
/// </summary>
[JsonProperty("DC_TARGETID")]
public long MusicId { get; set; }

/// <summary>
/// 歌曲的时间长度。
/// </summary>
[JsonProperty("DURATION")]
public long Duration { get; set; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,29 +13,27 @@ public class KuWoLyricsProvider : LyricsProvider
{
public override string DownloaderName => InternalLyricsProviderNames.KuWo;

private const string KuWoSearchMusicUrl = @"https://www.kuwo.cn/api/www/search/searchMusicBykeyWord";
private const string KuWoSearchMusicUrl = @"https://search.kuwo.cn/r.s";
private const string KuWoSearchLyricsUrl = @"https://m.kuwo.cn/newh5/singles/songinfoandlrc";
private const string KuWoDefaultToken = "ABCDE12345";

private readonly IWarpHttpClient _warpHttpClient;
private readonly ILyricsItemCollectionFactory _lyricsItemCollectionFactory;
private readonly GlobalOptions _options;

private static readonly ProductInfoHeaderValue UserAgent = new("Chrome", "81.0.4044.138");

public KuWoLyricsProvider(IWarpHttpClient warpHttpClient,
ILyricsItemCollectionFactory lyricsItemCollectionFactory,
IOptions<GlobalOptions> options)
{
_warpHttpClient = warpHttpClient;
_lyricsItemCollectionFactory = lyricsItemCollectionFactory;
_options = options.Value;
}

protected override async ValueTask<object> DownloadDataAsync(LyricsProviderArgs args)
{
var songSearchResponse = await _warpHttpClient.GetAsync<SongSearchResponse>(KuWoSearchMusicUrl,
new SongSearchRequest(args.SongName, args.Artist, pageSize: _options.Provider.Lyric.GetLyricProviderOption(DownloaderName).Depth),
new SongSearchRequest(args.SongName, args.Artist,
pageSize: _options.Provider.Lyric.GetLyricProviderOption(DownloaderName).Depth),
op =>
{
op.Headers.UserAgent.Add(UserAgent);
Expand All @@ -55,7 +53,8 @@ protected override async ValueTask<object> DownloadDataAsync(LyricsProviderArgs
});
}

protected override async ValueTask<LyricsItemCollection> GenerateLyricAsync(object lyricsObject, LyricsProviderArgs args)
protected override async ValueTask<LyricsItemCollection> GenerateLyricAsync(object lyricsObject,
LyricsProviderArgs args)
{
await ValueTask.CompletedTask;

Expand All @@ -69,7 +68,8 @@ protected override async ValueTask<LyricsItemCollection> GenerateLyricAsync(obje
{
var position = double.Parse(l.Position);
var positionSpan = TimeSpan.FromSeconds(position);
return new LyricsItem(positionSpan.Minutes, double.Parse($"{positionSpan.Seconds}.{positionSpan.Milliseconds}"), l.Text);
return new LyricsItem(positionSpan.Minutes,
double.Parse($"{positionSpan.Seconds}.{positionSpan.Milliseconds}"), l.Text);
});

var lyricsItemCollection = new LyricsItemCollection(_options.Provider.Lyric.Config);
Expand All @@ -79,12 +79,7 @@ protected override async ValueTask<LyricsItemCollection> GenerateLyricAsync(obje

protected virtual void ValidateSongSearchResponse(SongSearchResponse response, LyricsProviderArgs args)
{
if (response.Code != 200)
{
throw new ErrorCodeException(ErrorCodes.TheReturnValueIsIllegal, response.ErrorMessage, args);
}

if (response.InnerData.SongItems.Count == 0)
if (response.TotalCount == 0)
{
throw new ErrorCodeException(ErrorCodes.NoMatchingSong, attachObj: args);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public KuWoLyricsProviderTests()
.FirstOrDefault(t => t.DownloaderName == InternalLyricsProviderNames.KuWo);
}

[Fact(Skip = "Not Working")]
[Fact]
[Trait("LyricsProvider ", "KuGou")]
public async Task DownloadAsync_Test()
{
Expand All @@ -26,7 +26,7 @@ public async Task DownloadAsync_Test()
lyric.IsPruneMusic.ShouldBeFalse();
}

[Fact(Skip = "Not Working")]
[Fact]
public async Task DownloadAsync_Source_Null_Test()
{
var lyric = await _kuwoLyricsProvider.DownloadAsync("Concerto for Piano and Orchestra No. 12 in A major, K414 - 1. Allegro",
Expand Down

0 comments on commit fea5e11

Please sign in to comment.