TTKMusicPlayer  4.1.3.0
TTKMusicPlayer imitates Kugou UI, the music player uses of qmmp core library based on Qt for windows and linux
musickgqueryinterface.cpp
Go to the documentation of this file.
3 
4 static constexpr const char *KG_UA_URL = "cGhYNDZVdmNaVG5KZk50NVFvcUJyYWVQdmdNTkFTMmM=";
5 
6 void ReqKGInterface::makeRequestRawHeader(QNetworkRequest *request)
7 {
8  request->setRawHeader("User-Agent", TTK::Algorithm::mdII(KG_UA_URL, MDII_UA_KEY, false).toUtf8());
11 }
12 
13 QString ReqKGInterface::makeSongArtist(const QString &name)
14 {
15  return TTK::String::charactersReplace(name).replace("+", ";");
16 }
17 
19 {
20  if(info->m_songId.isEmpty())
21  {
22  return;
23  }
24 
25  QNetworkRequest request;
26  request.setUrl(TTK::Algorithm::mdII(KG_SONG_INFO_URL, false).arg(info->m_songId));
28 
29  const QByteArray &bytes = TTK::syncNetworkQueryForGet(&request);
30  if(bytes.isEmpty())
31  {
32  return;
33  }
34 
35  QJson::Parser json;
36  bool ok = false;
37  const QVariant &data = json.parse(bytes, &ok);
38  if(ok)
39  {
40  QVariantMap value = data.toMap();
41  if(value["errcode"].toInt() == 0 && value.contains("data"))
42  {
43  value = value["data"].toMap();
44  info->m_songName = TTK::String::charactersReplace(value["songname"].toString());
45  info->m_artistId = value["singerid"].toString();
46  info->m_artistName = ReqKGInterface::makeSongArtist(value["singername"].toString());
47  info->m_coverUrl = value["imgurl"].toString().replace("{size}", "480");
48  info->m_lrcUrl = TTK::Algorithm::mdII(KG_SONG_LRC_URL, false).arg(value["songname"].toString(), info->m_songId).arg(value["duration"].toInt() * TTK_DN_S2MS);
49  }
50  }
51 }
52 
54 {
55  if(album.isEmpty())
56  {
57  return;
58  }
59 
61  parseFromSongAlbumInfo(&item, info->m_songId, album);
62 
63  info->m_albumId = item.m_id;
64  info->m_albumName = item.m_name;
65 }
66 
67 void ReqKGInterface::parseFromSongAlbumInfo(MusicResultDataItem *item, const QString &hash, const QString &album)
68 {
69  if(hash.isEmpty() || album.isEmpty())
70  {
71  return;
72  }
73 
74  QNetworkRequest request;
75  request.setUrl(TTK::Algorithm::mdII(KG_ALBUM_INFO_URL, false).arg(hash, album));
77 
78  const QByteArray &bytes = TTK::syncNetworkQueryForGet(&request);
79  if(bytes.isEmpty())
80  {
81  return;
82  }
83 
84  QJson::Parser json;
85  bool ok = false;
86  const QVariant &data = json.parse(bytes, &ok);
87  if(ok)
88  {
89  QVariantMap value = data.toMap();
90  if(value["error_code"].toInt() == 0 && value.contains("data"))
91  {
92  QVariantList datas = value["data"].toList();
93  for(const QVariant &var : qAsConst(datas))
94  {
95  if(var.isNull())
96  {
97  continue;
98  }
99 
100  for(const QVariant &al : var.toList())
101  {
102  if(al.isNull())
103  {
104  continue;
105  }
106 
107  value = al.toMap();
108  item->m_id = value["album_id"].toString();
109  item->m_name = TTK::String::charactersReplace(value["album_name"].toString());
110  item->m_description = value["publish_company"].toString();
111  item->m_time = value["publish_date"].toString();
112  item->m_category = value["language"].toString();
113  break;
114  }
115  }
116  }
117  }
118 }
119 
120 static void parseSongPropertyV1(TTK::MusicSongInformation *info, const QString &hash, int bitrate)
121 {
122  for(const TTK::MusicSongProperty &prop : qAsConst(info->m_songProps))
123  {
124  if(prop.m_bitrate == bitrate)
125  {
126  return;
127  }
128  }
129 
130  TTK_INFO_STREAM("parse song" << bitrate << "kbps property in v1 module");
131 
132  const QByteArray &key = TTK::Algorithm::md5(QString("%1kgcloudv2").arg(hash).toUtf8());
133 
134  QNetworkRequest request;
135  request.setUrl(TTK::Algorithm::mdII(KG_SONG_PATH_V1_URL, false).arg(hash, key.constData()));
137 
138  const QByteArray &bytes = TTK::syncNetworkQueryForGet(&request);
139  if(!bytes.isEmpty())
140  {
141  QJson::Parser json;
142  bool ok = false;
143  const QVariant &data = json.parse(bytes, &ok);
144  if(ok)
145  {
146  const QVariantMap &value = data.toMap();
147  if(value.contains("status") && value["status"].toInt() == 1)
148  {
150  prop.m_url = value["url"].toString();
151  prop.m_size = TTK::Number::sizeByteToLabel(value["fileSize"].toInt());
152  prop.m_format = value["extName"].toString();
153  prop.m_bitrate = bitrate;
154  info->m_songProps.append(prop);
155  }
156  }
157  }
158 }
159 
160 static void parseSongPropertyV2(TTK::MusicSongInformation *info, const QString &hash, int bitrate)
161 {
162  for(const TTK::MusicSongProperty &prop : qAsConst(info->m_songProps))
163  {
164  if(prop.m_bitrate == bitrate)
165  {
166  return;
167  }
168  }
169 
170  TTK_INFO_STREAM("parse song" << bitrate << "kbps property in v2 module");
171 
172  const QString &mid = TTK::Algorithm::mdII("Wk51dktMOHJXUTdmM1VsVUVXTFM5RTlYQ05laDE0Z2lZMzFPL1M1VUJSaHd1N0kwRDQxdkpWVFJPZTQ9", false);
173  const QString &sign = TTK::Algorithm::mdII("SVhlNmFTaWpqdVhYVTAwaHh4QllwRkFGSmJpY0VSZUhXQmQrV2Q4WHo0eXVCWm1zK1p0RkVRPT0=", false);
174  const QString &user = "0";
175  const QByteArray &key = TTK::Algorithm::md5((hash + sign + mid + user).toUtf8());
176 
177  QNetworkRequest request;
178  request.setUrl(TTK::Algorithm::mdII(KG_SONG_PATH_V2_URL, false).arg(mid, hash, user, key.constData()));
179  request.setRawHeader("x-router", TTK::Algorithm::mdII("MTJnUGtpL0hqWXhZQmlCNE9hVzVyREF0QXZmeVBNNVc=", false).toUtf8());
181 
182  const QByteArray &bytes = TTK::syncNetworkQueryForGet(&request);
183  if(!bytes.isEmpty())
184  {
185  QJson::Parser json;
186  bool ok = false;
187  const QVariant &data = json.parse(bytes, &ok);
188  if(ok)
189  {
190  const QVariantMap &value = data.toMap();
191  if(value.contains("status") && value["status"].toInt() == 1)
192  {
193  const QVariantList &datas = value["url"].toList();
194  if(!datas.isEmpty())
195  {
197  prop.m_url = datas.front().toString();
198  prop.m_size = TTK::Number::sizeByteToLabel(value["fileSize"].toInt());
199  prop.m_format = value["extName"].toString();
200  prop.m_bitrate = bitrate;
201  info->m_songProps.append(prop);
202  }
203  }
204  }
205  }
206 }
207 
208 static void parseSongPropertyV3(TTK::MusicSongInformation *info, const QString &module, QString &id, int bitrate)
209 {
210  const qint64 time = TTKDateTime::currentTimestamp();
211  const QByteArray &key = TTK::Algorithm::md5(TTK::Algorithm::mdII(KG_SONG_PATH_V3_DATA_URL, false).arg(time).arg(module).toUtf8());
212 
213  QNetworkRequest request;
214  request.setUrl(TTK::Algorithm::mdII(KG_SONG_PATH_V3_URL, false).arg(time).arg(module, key.constData()));
216 
217  const QByteArray &bytes = TTK::syncNetworkQueryForGet(&request);
218  if(!bytes.isEmpty())
219  {
220  QJson::Parser json;
221  bool ok = false;
222  const QVariant &data = json.parse(bytes, &ok);
223  if(ok)
224  {
225  QVariantMap value = data.toMap();
226  if(value.contains("data") && value["err_code"].toInt() == 0)
227  {
228  value = value["data"].toMap();
229  id = value["encode_album_audio_id"].toString();
230 
231  const int rate = value["bitrate"].toInt();
232  const QString &url = value["play_url"].toString();
233 
234  if(rate == bitrate && !url.isEmpty())
235  {
237  prop.m_url = url;
238  prop.m_size = TTK::Number::sizeByteToLabel(value["filesize"].toInt());
239  prop.m_format = bitrate > TTK_BN_320 ? FLAC_FILE_SUFFIX : MP3_FILE_SUFFIX;;
240  prop.m_bitrate = bitrate;
241  info->m_songProps.append(prop);
242  }
243  }
244  }
245  }
246 }
247 
248 static void parseSongPropertyV3(TTK::MusicSongInformation *info, const QString &hash, int bitrate)
249 {
250  for(const TTK::MusicSongProperty &prop : qAsConst(info->m_songProps))
251  {
252  if(prop.m_bitrate == bitrate)
253  {
254  return;
255  }
256  }
257 
258  TTK_INFO_STREAM("parse song" << bitrate << "kbps property in v3 module");
259 
260  QString id;
261  parseSongPropertyV3(info, "hash=" + hash, id, bitrate);
262  parseSongPropertyV3(info, "encode_album_audio_id=" + id, id, bitrate);
263 }
264 
265 static void parseSongPropertyV4(TTK::MusicSongInformation *info, const QString &hash, int bitrate)
266 {
267  for(const TTK::MusicSongProperty &prop : qAsConst(info->m_songProps))
268  {
269  if(prop.m_bitrate == bitrate)
270  {
271  return;
272  }
273  }
274 
275  TTK_INFO_STREAM("parse song" << bitrate << "kbps property in v4 module");
276 
277  if(bitrate == TTK_BN_128 || bitrate == TTK_BN_320 || bitrate == TTK_BN_1000)
278  {
280  }
281 }
282 
283 static void parseSongProperty(TTK::MusicSongInformation *info, const QString &hash, int bitrate)
284 {
285  if(hash.isEmpty())
286  {
287  return;
288  }
289 
290  parseSongPropertyV1(info, hash, bitrate);
291  parseSongPropertyV2(info, hash, bitrate);
292  parseSongPropertyV3(info, hash, bitrate);
293  parseSongPropertyV4(info, hash, bitrate);
294 }
295 
297 {
298  const QStringList &formats = info->m_formatProps.split("|");
299  if(info->m_formatProps.isEmpty() || formats.count() < 4)
300  {
301  parseSongProperty(info, info->m_songId, TTK_BN_128);
302  return;
303  }
304 
305  if(bitrate == TTK_BN_0)
306  {
307  parseSongProperty(info, formats[0], TTK_BN_128);
308  parseSongProperty(info, formats[1], TTK_BN_192);
309  parseSongProperty(info, formats[2], TTK_BN_320);
310  parseSongProperty(info, formats[3], TTK_BN_1000);
311  }
312  else
313  {
314  int index = 0;
315  switch(bitrate)
316  {
317  case TTK_BN_128: index = 0; break;
318  case TTK_BN_192: index = 1; break;
319  case TTK_BN_320: index = 2; break;
320  case TTK_BN_1000: index = 3; break;
321  }
322 
323  parseSongProperty(info, formats[index], bitrate);
324  }
325 }
326 
328 {
329  info->m_formatProps = key["hash"].toString() + "|" + key["128hash"].toString() + "|" + key["320hash"].toString() + "|" + key["sqhash"].toString();
330 }
TTK_MODULE_EXPORT QString charactersReplace(const QString &value)
static void parseSongPropertyV2(TTK::MusicSongInformation *info, const QString &hash, int bitrate)
TTK_MODULE_EXPORT QByteArray md5(const QByteArray &data)
The class of the search result data item.
static constexpr const char * KG_SONG_INFO_URL
static qint64 currentTimestamp() noexcept
Definition: ttktime.cpp:249
The class of the music song property.
Definition: musicobject.h:225
static constexpr const char * QUERY_KG_INTERFACE
static constexpr wchar_t key[]
static constexpr const char * KG_SONG_PATH_V3_URL
TTK_MODULE_EXPORT void setSslConfiguration(QNetworkRequest *request, QSslSocket::PeerVerifyMode mode=QSslSocket::VerifyNone)
MusicSongPropertyList m_songProps
Definition: musicobject.h:297
QString makeSongArtist(const QString &name)
TTK_MODULE_EXPORT QString sizeByteToLabel(qint64 size)
TTK_MODULE_EXPORT QByteArray syncNetworkQueryForGet(QNetworkRequest *request)
#define TTK_BN_1000
Definition: ttkglobal.h:359
static constexpr const char * KG_SONG_PATH_V3_DATA_URL
void makeRequestRawHeader(QNetworkRequest *request)
#define MP3_FILE_SUFFIX
Definition: musicobject.h:51
static constexpr const char * MDII_UA_KEY
#define qAsConst
Definition: ttkqtglobal.h:51
const char * name
Definition: http_parser.c:458
static void parseSongProperty(TTK::MusicSongInformation *info, const QString &hash, int bitrate)
#define TTK_INFO_STREAM(msg)
Definition: ttklogger.h:68
static void parseSongPropertyV1(TTK::MusicSongInformation *info, const QString &hash, int bitrate)
static constexpr const char * KG_SONG_LRC_URL
static void parseSongPropertyV4(TTK::MusicSongInformation *info, const QString &hash, int bitrate)
#define TTK_BN_0
Definition: ttkglobal.h:349
#define TTK_BN_320
Definition: ttkglobal.h:356
QVariant parse(QIODevice *io, bool *ok=0)
Read JSON string from the I/O Device and converts it to a QVariant object.
Definition: parser.cpp:69
TTK_MODULE_EXPORT void makeContentTypeHeader(QNetworkRequest *request, const QByteArray &data={})
#define TTK_DN_S2MS
Definition: ttkglobal.h:281
static constexpr const char * KG_SONG_PATH_V2_URL
TTK_MODULE_EXPORT QString toString(Record type)
static constexpr const char * KG_ALBUM_INFO_URL
void parseFromSongAlbumLrc(TTK::MusicSongInformation *info)
Main class used to convert JSON data to QVariant objects.
Definition: parser.h:40
void parseFromSongAlbumInfo(TTK::MusicSongInformation *info, const QString &album)
#define TTK_BN_192
Definition: ttkglobal.h:354
#define FLAC_FILE_SUFFIX
Definition: musicobject.h:53
void parseFromSongProperty(TTK::MusicSongInformation *info, const QString &type, const QString &id, int bitrate)
void parseFromSongProperty(TTK::MusicSongInformation *info, int bitrate)
TTK_MODULE_EXPORT QString mdII(const QString &data, bool encode)
static void parseSongPropertyV3(TTK::MusicSongInformation *info, const QString &module, QString &id, int bitrate)
static constexpr const char * KG_SONG_PATH_V1_URL
The class of the music song information.
Definition: musicobject.h:283
static constexpr const char * KG_UA_URL
#define TTK_BN_128
Definition: ttkglobal.h:353