TTKMusicPlayer  4.3.0.0
TTKMusicPlayer imitates Kugou UI, the music player uses of qmmp core library based on Qt for windows and linux
musickwqueryinterface.cpp
Go to the documentation of this file.
3 
5 
6 static constexpr const char *KW_SONG_PATH_V1_URL = "eVZwd0d3aGhUSmNoNHBHZTFFYldyOGZjY0trcldsMlphUWtNL0thR3AyTjRkU0xyZGJuSlBGQTBueURhaDM3bTVrNUE5S0I5dWpjcWRHeTNaanJPUXc1YkNOQm9pNlJrbVFFTWI3YVdpcFFWS2tUSGNoSk5RUDl3WDhSZlZaUzd2TnRpaDBTS0psbVE0Tmk5YlJHQXdtY2tGaGlERmU4RnFXSGVZdWFWeGo4dUFpbm4zWUJTemlFYVhkREM0Q0pSNytUK05VYlBVcUdVRnhLSUJ3TXg3ZEc2UzBxVGVMOFZqdnJJN1E9PQ==";
7 static constexpr const char *KW_SONG_PATH_V2_URL = "VlpjeWIxQkZNbDdkNHA3eUFRMHVnNmVVanpITWJ6MEp1T1ZraElNc2JXaGIvVytMcmFNZVFKNEQ2UXRrcHZyV2dXTjJqQT09";
8 static constexpr const char *KW_SONG_PATH_V2_DATA_URL = "NUVnZE5SbWFmNHRGemdTeHd6RHlwYjF2TllaR1R5TkNKRUt6NWpxcDVEcW9JdkREN0QzRmNGOVM0R0lQK29wTTZwaHBHa3FkR3dWbEx6M3ZHVnZBM1NseWF1eUoyN0wwZmQwT3BJaXFzbWcraDlISnAyVnN0VTdGT3ZxZWlicVFGcjFkYWc3QlJ0czlGdFVrTW1WeTd3U1c1S0wwQjRrNDM0S0EySU9pOVg4QmVYSW5GUUIwWWcwMlM5Sng2YVIvYmpYL0xib2NnRlFLV3A2aXBJMWxEalNMNVpnPQ==";
9 static constexpr const char *KW_SONG_PATH_V3_URL = "UElteEluQm8zUnRXTERvMkkwYTVhNitEUG9rRVA0Wk80VFFOb3dKL1ZsNldLc1RDVFJQZ3llaTN1MXhzL3NSM3ovaVhTTld5L1NpTE9hdTlBM3NuNjBQbWpOTT0=";
10 static constexpr const char *KW_ALBUM_COVER_URL = "NkhRaDluWTFxV2wvTEl6ZkszRmRUa1MvS0JlQUl6MDJVUkpqcjFnYzJ4djZ0b0xmcjhzZHJnV0xscW89";
11 static constexpr const char *KW_ARTIST_COVER_URL = "YW4xU3FFQnprWG11R0J5QjVGREFHdy9Yd0w3dEZZcFJIWm5FMXQ5QkJJN0EzQTd4TnBwR1BQZ0d5Qzg9";
12 
13 void ReqKWInterface::makeRequestRawHeader(QNetworkRequest *request) noexcept
14 {
15  TTK::setSslConfiguration(request);
16  TTK::setUserAgentHeader(request);
18 }
19 
20 QString ReqKWInterface::makeSongArtist(const QString &name)
21 {
22  return TTK::String::charactersReplace(name).replace("&", ";").replace("+", ";");
23 }
24 
25 QString ReqKWInterface::makeSongArtist(const QString &in, const QString &name)
26 {
27  const QString &artistName = TTK::String::charactersReplace(name);
28  return in.isEmpty() ? artistName : (in + ";" + artistName);
29 }
30 
31 QString ReqKWInterface::makeArtistPixmapUrl(const QString &url)
32 {
33  return TTK::Algorithm::mdII(KW_ARTIST_COVER_URL, false) + url.section('/', 1);
34 }
35 
36 QString ReqKWInterface::makeCoverPixmapUrl(const QString &url, const QString &id)
37 {
38  if(url.isEmpty() && !id.isEmpty())
39  {
40  return TTK::Algorithm::mdII(KW_ALBUM_COVER_INFO_URL, false).arg(id);
41  }
42  else if(!TTK::String::isNetworkUrl(url))
43  {
44  return TTK::Algorithm::mdII(KW_ALBUM_COVER_URL, false) + url.section('/', 1);
45  }
46  else
47  {
48  return url;
49  }
50 }
51 
52 static void parseSongPropertyV1(TTK::MusicSongInformation *info, const QString &suffix, const QString &format, int bitrate)
53 {
54  for(const TTK::MusicSongProperty &prop : qAsConst(info->m_songProps))
55  {
56  if(prop.m_bitrate == bitrate)
57  {
58  return;
59  }
60  }
61 
62  TTK_INFO_STREAM("parse song" << bitrate << "kbps property in v1 module");
63 
64  QString quality;
65  if((format.contains("MP3128") || format.contains("128kmp3")) && bitrate == TTK_BN_128)
66  {
67  quality = "128kmp3";
68  }
69  else if((format.contains("MP3192") || format.contains("192kmp3")) && bitrate == TTK_BN_192)
70  {
71  quality = "192kmp3";
72  }
73  else if((format.contains("MP3H") || format.contains("320kmp3")) && bitrate == TTK_BN_320)
74  {
75  quality = "320kmp3";
76  }
77  else if((format.contains("FLAC") || format.contains("2000kflac")) && bitrate == TTK_BN_1000)
78  {
79  quality = "2000kflac";
80  }
81  else
82  {
83  return;
84  }
85 
86  QNetworkRequest request;
87  request.setUrl(TTK::Algorithm::mdII(KW_SONG_PATH_V1_URL, false).arg(info->m_songId, quality));
89 
90  const QByteArray &bytes = TTK::syncNetworkQueryForGet(&request);
91  if(bytes.isEmpty())
92  {
93  return;
94  }
95 
96  QJsonParseError ok;
97  const QJsonDocument &json = QJsonDocument::fromJson(bytes, &ok);
99  {
100  QVariantMap value = json.toVariant().toMap();
101  if(value["code"].toInt() == 200 && value.contains("data"))
102  {
103  value = value["data"].toMap();
104  if(value.isEmpty())
105  {
106  return;
107  }
108 
109  const QString &format = value["format"].toString();
110  if(format == suffix)
111  {
113  prop.m_url = value["url"].toString();
114  prop.m_size = TTK_DEFAULT_STR;
115  prop.m_format = suffix;
116  prop.m_bitrate = bitrate;
117  info->m_songProps.append(prop);
118  }
119  }
120  }
121 }
122 
123 static void parseSongPropertyV2(TTK::MusicSongInformation *info, const QString &suffix, const QString &format, int bitrate)
124 {
125  for(const TTK::MusicSongProperty &prop : qAsConst(info->m_songProps))
126  {
127  if(prop.m_bitrate == bitrate)
128  {
129  return;
130  }
131  }
132 
133  TTK_INFO_STREAM("parse song" << bitrate << "kbps property in v2 module");
134 
135  QString quality;
136  if((format.contains("MP3128") || format.contains("128kmp3")) && bitrate == TTK_BN_128)
137  {
138  quality = "128kmp3";
139  }
140  else if((format.contains("MP3192") || format.contains("192kmp3")) && bitrate == TTK_BN_192)
141  {
142  quality = "192kmp3";
143  }
144  else if((format.contains("MP3H") || format.contains("320kmp3")) && bitrate == TTK_BN_320)
145  {
146  quality = "320kmp3";
147  }
148  else if((format.contains("FLAC") || format.contains("2000kflac")) && bitrate == TTK_BN_1000)
149  {
150  quality = "2000kflac";
151  }
152  else
153  {
154  return;
155  }
156 
157  QAlgorithm::Des des;
158  const QString &parameter = des.encrypt(TTK::Algorithm::mdII(KW_SONG_PATH_V2_DATA_URL, false).arg(quality).toUtf8(),
159  TTK::Algorithm::mdII("OGlVTjJWOEdlMkkzSkZIeg==", MDII_SHR_KEY, false).toUtf8());
160  QNetworkRequest request;
161  request.setUrl(TTK::Algorithm::mdII(KW_SONG_PATH_V2_URL, false).arg(parameter, info->m_songId));
163 
164  const QByteArray &bytes = TTK::syncNetworkQueryForGet(&request);
165  if(bytes.isEmpty())
166  {
167  return;
168  }
169 
170  if(!bytes.contains("res not found"))
171  {
172  const QString text(bytes);
173  static TTKRegularExpression regx(".*url=(.*)\r\nsig=");
174 
175  if(regx.match(text) != -1)
176  {
178  prop.m_url = regx.captured(1);
179  prop.m_size = TTK_DEFAULT_STR;
180  prop.m_format = suffix;
181  prop.m_bitrate = bitrate;
182 
183  if(prop.isEmpty() || info->m_songProps.contains(prop))
184  {
185  return;
186  }
187 
188  info->m_songProps.append(prop);
189  }
190  }
191 }
192 
193 static void parseSongPropertyV3(TTK::MusicSongInformation *info, const QString &suffix, const QString &format, int bitrate)
194 {
195  for(const TTK::MusicSongProperty &prop : qAsConst(info->m_songProps))
196  {
197  if(prop.m_bitrate == bitrate)
198  {
199  return;
200  }
201  }
202 
203  TTK_INFO_STREAM("parse song" << bitrate << "kbps property in v3 module");
204 
205  QString quality;
206  if((format.contains("MP3128") || format.contains("128kmp3")) && bitrate == TTK_BN_128)
207  {
208  quality = "128k";
209  }
210  else if((format.contains("MP3192") || format.contains("192kmp3")) && bitrate == TTK_BN_192)
211  {
212  quality = "192k";
213  }
214  else if((format.contains("MP3H") || format.contains("320kmp3")) && bitrate == TTK_BN_320)
215  {
216  quality = "320k";
217  }
218  else if((format.contains("FLAC") || format.contains("2000kflac")) && bitrate == TTK_BN_1000)
219  {
220  quality = "lossless";
221  }
222  else
223  {
224  return;
225  }
226 
227  QNetworkRequest request;
228  request.setUrl(TTK::Algorithm::mdII(KW_SONG_PATH_V3_URL, false).arg(info->m_songId, quality));
230 
231  const QByteArray &bytes = TTK::syncNetworkQueryForGet(&request);
232  if(bytes.isEmpty())
233  {
234  return;
235  }
236 
237  QJsonParseError ok;
238  const QJsonDocument &json = QJsonDocument::fromJson(bytes, &ok);
240  {
241  QVariantMap value = json.toVariant().toMap();
242  if(value["code"].toInt() == 200 && value.contains("data"))
243  {
244  value = value["data"].toMap();
245  if(value.isEmpty())
246  {
247  return;
248  }
249 
251  prop.m_url = value["url"].toString();
252  prop.m_size = value["size"].toString();
253  prop.m_format = suffix;
254  prop.m_bitrate = bitrate;
255  info->m_songProps.append(prop);
256  }
257  }
258 }
259 
260 static void parseSongPropertyUnity(TTK::MusicSongInformation *info, const QString &format, int bitrate)
261 {
262  for(const TTK::MusicSongProperty &prop : qAsConst(info->m_songProps))
263  {
264  if(prop.m_bitrate == bitrate)
265  {
266  return;
267  }
268  }
269 
270  TTK_INFO_STREAM("parse song" << bitrate << "kbps property in unity module");
271 
272  if(((format.contains("MP3128") || format.contains("128kmp3")) && bitrate == TTK_BN_128) ||
273  ((format.contains("MP3H") || format.contains("320kmp3")) && bitrate == TTK_BN_320) ||
274  ((format.contains("FLAC") || format.contains("2000kflac")) && bitrate == TTK_BN_1000))
275  {
277  }
278 }
279 
280 static void parseSongProperty(TTK::MusicSongInformation *info, const QString &suffix, const QString &format, int bitrate)
281 {
283  {
284  parseSongPropertyUnity(info, format, bitrate);
285  parseSongPropertyV1(info, suffix, format, bitrate);
286  parseSongPropertyV2(info, suffix, format, bitrate);
287  parseSongPropertyV3(info, suffix, format, bitrate);
288  }
289  else
290  {
291  parseSongPropertyV1(info, suffix, format, bitrate);
292  parseSongPropertyV2(info, suffix, format, bitrate);
293  parseSongPropertyV3(info, suffix, format, bitrate);
294  parseSongPropertyUnity(info, format, bitrate);
295  }
296 }
297 
299 {
300  if(info->m_songId.isEmpty())
301  {
302  return;
303  }
304 
305  if(info->m_formatProps.isEmpty())
306  {
307  parseSongProperty(info, MP3_FILE_SUFFIX, "128kmp3", TTK_BN_128);
308  return;
309  }
310 
311  if(bitrate == TTK_BN_0)
312  {
317  }
318  else
319  {
320  parseSongProperty(info, bitrate > TTK_BN_320 ? FLAC_FILE_SUFFIX : MP3_FILE_SUFFIX, info->m_formatProps, bitrate);
321  }
322 }
323 
325 {
326  info->m_formatProps = format;
327 }
TTK_MODULE_EXPORT QString charactersReplace(const QString &value)
TTK_MODULE_EXPORT void setUserAgentHeader(QNetworkRequest *request, const QByteArray &data={}) noexcept
QString captured(int index) const
TTK_MODULE_EXPORT void setSslConfiguration(QNetworkRequest *request, QSslSocket::PeerVerifyMode mode=QSslSocket::VerifyNone) noexcept
#define TTK_DEFAULT_STR
Definition: ttkglobal.h:276
static void parseSongPropertyV1(TTK::MusicSongInformation *info, const QString &suffix, const QString &format, int bitrate)
static constexpr const char * KW_SONG_PATH_V1_URL
QVariant toVariant() const
The class of the music song property.
Definition: musicobject.h:242
static QJsonDocument fromJson(const QByteArray &json, QJsonParseError *error=0)
static constexpr const char * KW_ARTIST_COVER_URL
static constexpr const char * KW_SONG_PATH_V2_DATA_URL
static constexpr const char * KW_ALBUM_COVER_INFO_URL
MusicSongPropertyList m_songProps
Definition: musicobject.h:314
QString makeCoverPixmapUrl(const QString &url, const QString &id)
QByteArray encrypt(const QByteArray &in, const QByteArray &key)
Definition: deswrapper.cpp:349
TTK_MODULE_EXPORT QByteArray syncNetworkQueryForGet(QNetworkRequest *request)
#define TTK_BN_1000
Definition: ttkglobal.h:434
#define MP3_FILE_SUFFIX
Definition: musicobject.h:58
static void parseSongPropertyV2(TTK::MusicSongInformation *info, const QString &suffix, const QString &format, int bitrate)
static void parseSongProperty(TTK::MusicSongInformation *info, const QString &suffix, const QString &format, int bitrate)
ParseError error
static void parseSongPropertyV3(TTK::MusicSongInformation *info, const QString &suffix, const QString &format, int bitrate)
#define qAsConst
Definition: ttkqtglobal.h:57
const char * name
Definition: http_parser.c:458
TTK_MODULE_EXPORT bool isNetworkUrl(const QString &path) noexcept
TTK_MODULE_EXPORT QString suffix(const QString &name)
static constexpr const char * KW_SONG_PATH_V2_URL
#define TTK_INFO_STREAM(msg)
Definition: ttklogger.h:74
The class of the des wrapper.
Definition: deswrapper.h:34
static void parseSongPropertyUnity(TTK::MusicSongInformation *info, const QString &format, int bitrate)
bool isEmpty() const noexcept
Definition: musicobject.h:255
TTK_MODULE_EXPORT void setContentTypeHeader(QNetworkRequest *request, const QByteArray &data={}) noexcept
#define TTK_BN_0
Definition: ttkglobal.h:424
#define TTK_BN_320
Definition: ttkglobal.h:431
QString makeArtistPixmapUrl(const QString &url)
static constexpr const char * QUERY_KW_INTERFACE
QString makeSongArtist(const QString &name)
static constexpr const char * KW_ALBUM_COVER_URL
The class of the regular expression.
void makeRequestRawHeader(QNetworkRequest *request) noexcept
int match(const QString &str, int pos=0)
#define TTK_BN_192
Definition: ttkglobal.h:429
#define FLAC_FILE_SUFFIX
Definition: musicobject.h:60
void parseFromSongProperty(TTK::MusicSongInformation *info, const QString &type, const QString &id, int bitrate)
static constexpr const char * MDII_SHR_KEY
TTK_MODULE_EXPORT QString mdII(const QString &data, bool encode)
void parseFromSongProperty(TTK::MusicSongInformation *info, int bitrate)
The class of the music song information.
Definition: musicobject.h:300
#define TTK_BN_128
Definition: ttkglobal.h:428
#define G_SETTING_PTR
static constexpr const char * KW_SONG_PATH_V3_URL