feat: Completed the QQ music lyrics downloader.

完成了 QQ 音乐歌词下载器。
This commit is contained in:
real-zony 2021-05-09 22:43:05 +08:00
parent 9fe8e1e56c
commit bad38ef34c
3 changed files with 86 additions and 5 deletions

View File

@ -22,7 +22,7 @@ namespace ZonyLrcTools.Cli.Infrastructure.Lyric.KuGou
throw new System.NotImplementedException(); throw new System.NotImplementedException();
} }
protected override ValueTask<LyricItemCollection> GenerateLyricAsync(byte[] data) protected override ValueTask<LyricItemCollection> GenerateLyricAsync(byte[] data, LyricDownloaderArgs args)
{ {
throw new System.NotImplementedException(); throw new System.NotImplementedException();
} }

View File

@ -0,0 +1,33 @@
using Newtonsoft.Json;
namespace ZonyLrcTools.Cli.Infrastructure.Lyric.QQMusic.JsonModel
{
public class GetLyricRequest
{
[JsonProperty("nobase64")] public int IsNoBase64Encoding { get; set; }
[JsonProperty("songmid")] public string SongId { get; set; }
[JsonProperty("platform")] public string ClientPlatform { get; set; }
[JsonProperty("inCharset")] public string InCharset { get; set; }
[JsonProperty("outCharset")] public string OutCharset { get; set; }
[JsonProperty("g_tk")] public int Gtk { get; set; }
protected GetLyricRequest()
{
}
public GetLyricRequest(string songId)
{
IsNoBase64Encoding = 1;
SongId = songId;
ClientPlatform = "yqq";
InCharset = "utf8";
OutCharset = "utf-8";
Gtk = 5381;
}
}
}

View File

@ -1,4 +1,10 @@
using System;
using System.Linq;
using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Web;
using Newtonsoft.Json.Linq;
using ZonyLrcTools.Cli.Infrastructure.Exceptions;
using ZonyLrcTools.Cli.Infrastructure.Lyric.QQMusic.JsonModel; using ZonyLrcTools.Cli.Infrastructure.Lyric.QQMusic.JsonModel;
using ZonyLrcTools.Cli.Infrastructure.Network; using ZonyLrcTools.Cli.Infrastructure.Network;
@ -12,6 +18,9 @@ namespace ZonyLrcTools.Cli.Infrastructure.Lyric.QQMusic
private readonly ILyricItemCollectionFactory _lyricItemCollectionFactory; private readonly ILyricItemCollectionFactory _lyricItemCollectionFactory;
private const string QQSearchMusicUrl = @"https://c.y.qq.com/soso/fcgi-bin/client_search_cp"; private const string QQSearchMusicUrl = @"https://c.y.qq.com/soso/fcgi-bin/client_search_cp";
private const string QQGetLyricUrl = @"https://c.y.qq.com/lyric/fcgi-bin/fcg_query_lyric_new.fcg";
private const string QQMusicRequestReferer = @"https://y.qq.com/";
public QQLyricDownloader(IWarpHttpClient warpHttpClient, public QQLyricDownloader(IWarpHttpClient warpHttpClient,
ILyricItemCollectionFactory lyricItemCollectionFactory) ILyricItemCollectionFactory lyricItemCollectionFactory)
@ -22,15 +31,54 @@ namespace ZonyLrcTools.Cli.Infrastructure.Lyric.QQMusic
protected override async ValueTask<byte[]> DownloadDataAsync(LyricDownloaderArgs args) protected override async ValueTask<byte[]> DownloadDataAsync(LyricDownloaderArgs args)
{ {
var searchResult = await _warpHttpClient.PostAsync<SongSearchResponse>( var searchResult = await _warpHttpClient.GetAsync<SongSearchResponse>(
QQSearchMusicUrl, QQSearchMusicUrl,
new SongSearchRequest(args.SongName, args.Artist)); new SongSearchRequest(args.SongName, args.Artist));
throw new System.NotImplementedException();
ValidateSongSearchResponse(searchResult, args);
var lyricJsonString = await _warpHttpClient.GetAsync(QQGetLyricUrl,
new GetLyricRequest(searchResult.Data.Song.SongItems.FirstOrDefault()?.SongId),
op => op.Headers.Referrer = new Uri(QQMusicRequestReferer));
return Encoding.UTF8.GetBytes(lyricJsonString);
} }
protected override ValueTask<LyricItemCollection> GenerateLyricAsync(byte[] data) protected override async ValueTask<LyricItemCollection> GenerateLyricAsync(byte[] data, LyricDownloaderArgs args)
{ {
throw new System.NotImplementedException(); await ValueTask.CompletedTask;
var lyricJsonString = Encoding.UTF8.GetString(data);
lyricJsonString = lyricJsonString.Replace(@"MusicJsonCallback(", string.Empty).TrimEnd(')');
if (lyricJsonString.Contains("\"code\":-1901"))
{
throw new ErrorCodeException(ErrorCodes.NoMatchingSong, attachObj: args);
}
if (lyricJsonString.Contains("此歌曲为没有填词的纯音乐,请您欣赏"))
{
return _lyricItemCollectionFactory.Build(null);
}
var lyricJsonObj = JObject.Parse(lyricJsonString);
var sourceLyric = HttpUtility.HtmlDecode(HttpUtility.HtmlDecode(lyricJsonObj.SelectToken("$.lyric").Value<string>()));
var translateLyric = HttpUtility.HtmlDecode(HttpUtility.HtmlDecode(lyricJsonObj.SelectToken("$.trans").Value<string>()));
return _lyricItemCollectionFactory.Build(sourceLyric, translateLyric);
}
protected virtual void ValidateSongSearchResponse(SongSearchResponse response, LyricDownloaderArgs args)
{
if (response is not {StatusCode: 0} || response.Data.Song.SongItems == null)
{
throw new ErrorCodeException(ErrorCodes.TheReturnValueIsIllegal, attachObj: args);
}
if (response.Data.Song.SongItems.Count <= 0)
{
throw new ErrorCodeException(ErrorCodes.NoMatchingSong, attachObj: args);
}
} }
} }
} }