mirror of
https://github.com/real-zony/ZonyLrcToolsX.git
synced 2025-07-01 20:30:41 +00:00
85 lines
3.6 KiB
C#
85 lines
3.6 KiB
C#
using System;
|
|
using System.Linq;
|
|
using System.Text;
|
|
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.Network;
|
|
|
|
namespace ZonyLrcTools.Cli.Infrastructure.Lyric.QQMusic
|
|
{
|
|
public class QQLyricDownloader : LyricDownloader
|
|
{
|
|
public override string DownloaderName => InternalLyricDownloaderNames.QQ;
|
|
|
|
private readonly IWarpHttpClient _warpHttpClient;
|
|
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/splcloud/fcgi-bin/smartbox_new.fcg";
|
|
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,
|
|
ILyricItemCollectionFactory lyricItemCollectionFactory)
|
|
{
|
|
_warpHttpClient = warpHttpClient;
|
|
_lyricItemCollectionFactory = lyricItemCollectionFactory;
|
|
}
|
|
|
|
protected override async ValueTask<byte[]> DownloadDataAsync(LyricDownloaderArgs args)
|
|
{
|
|
var searchResult = await _warpHttpClient.GetAsync<SongSearchResponse>(
|
|
QQSearchMusicUrl,
|
|
new SongSearchRequest(args.SongName, args.Artist));
|
|
|
|
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 async ValueTask<LyricItemCollection> GenerateLyricAsync(byte[] data, LyricDownloaderArgs args)
|
|
{
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
} |