TTKMusicPlayer  4.2.0.0
TTKMusicPlayer imitates Kugou UI, the music player uses of qmmp core library based on Qt for windows and linux
musicidentifysongwidget.cpp
Go to the documentation of this file.
8 #include "musicdownloadwidget.h"
9 #include "musiccoremplayer.h"
10 #include "musiclrcanalysis.h"
11 #include "musictoastlabel.h"
12 #include "musicsong.h"
13 
14 #include <QMovie>
15 #include <QShortcut>
16 
18  : QWidget(parent),
19  m_lrcLabel(nullptr),
20  m_player(nullptr),
21  m_analysis(nullptr)
22 {
23  QHBoxLayout *layout = new QHBoxLayout(this);
24  layout->setSpacing(0);
25  layout->setContentsMargins(0, 0, 0, 0);
26 
27  m_mainWindow = new QStackedWidget(this);
28  m_mainWindow->setObjectName("MainWindow");
29  m_mainWindow->setStyleSheet(QString("#%1{ %2 }").arg(m_mainWindow->objectName(), TTK::UI::BackgroundStyle10));
30  layout->addWidget(m_mainWindow);
31  setLayout(layout);
32 
33  m_timer = new QTimer(this);
34  m_timer->setInterval(10 * TTK_DN_S2MS);
35  connect(m_timer, SIGNAL(timeout()), SLOT(detectedTimeOut()));
36 
39 
40  QShortcut *cut = new QShortcut(Qt::SHIFT + Qt::CTRL + Qt::Key_T, this);
41  connect(cut, SIGNAL(activated()), SLOT(detectedButtonClicked()));
42 
44  m_detectedButton->setEnabled(false);
45 }
46 
48 {
49  delete m_timer;
50  delete m_player;
51  delete m_analysis;
52  delete m_recordCore;
53  delete m_networkRequest;
54  delete m_detectedButton;
55  delete m_detectedLabel;
56  delete m_detectedMovie;
57  delete m_mainWindow;
58 }
59 
61 {
63  {
64  m_detectedButton->setEnabled(true);
65  }
66  else
67  {
68  MusicToastLabel::popup(tr("Config init error"));
69  }
70 }
71 
73 {
74  if(!m_detectedButton->isEnabled())
75  {
76  return;
77  }
78 
80 
82  {
84  if(m_recordCore->error())
85  {
86  MusicToastLabel::popup(tr("Audio init error"));
87  return;
88  }
89 
90  m_detectedMovie->start();
91  m_timer->start();
93  m_detectedLabel->setText(tr("Recognizing playing song"));
94  }
95  else
96  {
98  m_detectedMovie->stop();
99  m_timer->stop();
101  m_detectedLabel->setText(tr("Intelligent recognition of playing song"));
102  }
103 }
104 
106 {
107  m_mainWindow->setCurrentIndex(0);
108  if(m_player)
109  {
110  m_player->stop();
111  }
112 }
113 
115 {
116  const QString &path = TTK_RECORD_DATA_FILE;
118 
119  TTKEventLoop loop;
120  connect(m_networkRequest, SIGNAL(downLoadDataChanged(QString)), &loop, SLOT(quit()));
122  loop.exec();
123 
125  if(m_networkRequest->items().isEmpty())
126  {
128  }
129  else
130  {
132  }
133 }
134 
136 {
137  if(!m_player)
138  {
139  return;
140  }
141 
142  if(!m_info.m_songProps.isEmpty())
143  {
145  }
146 }
147 
149 {
150  if(!m_info.m_artistName.isEmpty())
151  {
152  MusicDownloadWidget *widget = new MusicDownloadWidget(this);
153  widget->initialize(m_info);
154  widget->show();
155  }
156 }
157 
159 {
160  if(!m_info.m_artistName.isEmpty())
161  {
163  item.m_name = m_info.m_songName;
164 
165  MusicSongSharingWidget widget(this);
167  widget.exec();
168  }
169 }
170 
172 {
173  if(!m_player)
174  {
175  return;
176  }
177 
178  if(m_analysis->isEmpty())
179  {
180  const QString &lrc = QString("<p style='font-weight:600;' align='center'>%1</p>").arg(tr("No lrc data file found"));
181  m_lrcLabel->setText(lrc);
182  return;
183  }
184 
185  const int index = m_analysis->currentIndex();
186  const qint64 time = m_analysis->findTime(index);
187 
188  if(time < position * TTK_DN_S2MS && time != -1)
189  {
190  QString lrc;
191  for(int i = 0; i < m_analysis->lineMax(); ++i)
192  {
193  if(i == m_analysis->lineMiddle())
194  {
195  lrc += QString("<p style='font-weight:700;' align='center'>");
196  }
197  else
198  {
199  lrc += QString("<p align='center'>");
200  }
201 
202  lrc += m_analysis->text(i);
203  lrc += QString("</p>");
204  }
205  m_lrcLabel->setText(lrc);
206  m_analysis->setCurrentIndex(index + 1);
207  }
208 }
209 
211 {
212  QWidget *widget = new QWidget(m_mainWindow);
213  widget->setStyleSheet(TTK::UI::ColorStyle03 + TTK::UI::FontStyle04);
214  QVBoxLayout *widgetLayout = new QVBoxLayout(widget);
215 
216  m_detectedMovie = new QMovie(":/toolSets/lb_radar", {}, widget);
217  QLabel *iconLabel = new QLabel(widget);
218  iconLabel->setFixedSize(200, 200);
219  QVBoxLayout *iconLabelLayout = new QVBoxLayout(iconLabel);
220  iconLabelLayout->setSpacing(0);
221  iconLabelLayout->setContentsMargins(0, 0, 0, 0);
222 
223  m_detectedButton = new QPushButton(widget);
225  m_detectedButton->setCursor(QCursor(Qt::PointingHandCursor));
226  m_detectedButton->setFixedSize(162, 162);
227 #ifdef Q_OS_UNIX
228  m_detectedButton->setFocusPolicy(Qt::NoFocus);
229 #endif
230 
231  iconLabelLayout->addWidget(m_detectedButton, 0, Qt::AlignCenter);
232  iconLabel->setMovie(m_detectedMovie);
233  iconLabel->setLayout(iconLabelLayout);
234  connect(m_detectedButton, SIGNAL(clicked()), SLOT(detectedButtonClicked()));
235 
236  m_detectedLabel = new QLabel(widget);
237  m_detectedLabel->setText(tr("Intelligent recognition of playing song"));
238 
239  QLabel *text = new QLabel(tr("Shortcut:") + " Shift + Ctrl + T", widget);
240  text->setStyleSheet(TTK::UI::FontStyle03);
241 
242  widgetLayout->addStretch(2);
243  widgetLayout->addWidget(iconLabel, 0, Qt::AlignCenter);
244  widgetLayout->addStretch(1);
245  widgetLayout->addWidget(m_detectedLabel, 0, Qt::AlignCenter);
246  widgetLayout->addStretch(1);
247  widgetLayout->addWidget(text, 0, Qt::AlignCenter);
248  widget->setLayout(widgetLayout);
249  //
250  m_mainWindow->addWidget(widget);
251  m_mainWindow->setCurrentWidget(widget);
252 }
253 
255 {
256  if(m_mainWindow->count() > 1)
257  {
258  delete m_lrcLabel;
259  delete m_mainWindow->widget(1);
260  }
261  else
262  {
263  m_player = new MusicCoreMPlayer(this);
264  m_analysis = new MusicLrcAnalysis(this);
265  m_analysis->setLineMax(11);
266  connect(m_player, SIGNAL(positionChanged(qint64)), SLOT(positionChanged(qint64)));
267  }
268  const MusicSongIdentifyData &songIdentify = m_networkRequest->items().front();
269 
270  QWidget *widget = new QWidget(m_mainWindow);
271  widget->setStyleSheet(TTK::UI::ColorStyle03 + TTK::UI::FontStyle04);
272  QVBoxLayout *widgetLayout = new QVBoxLayout(widget);
273  //
274  QWidget *infoWidget = new QWidget(widget);
275  QHBoxLayout *infoWidgetLayout = new QHBoxLayout(infoWidget);
276  infoWidgetLayout->setContentsMargins(0, 0, 0, 0);
277  infoWidgetLayout->setSpacing(25);
278 
279  QWidget *infoFuncWidget = new QWidget(infoWidget);
280  QGridLayout *infoFuncWidgetLayout = new QGridLayout(infoFuncWidget);
281  infoFuncWidgetLayout->setContentsMargins(0, 0, 0, 0);
282 
283  QLabel *textLabel = new QLabel(widget);
284  textLabel->setText(QString("%1 - %2").arg(songIdentify.m_artistName, songIdentify.m_songName));
285  textLabel->setAlignment(Qt::AlignCenter);
286  //
287  TTKEventLoop loop;
288  MusicAbstractQueryRequest *d = G_DOWNLOAD_QUERY_PTR->makeQueryRequest(this);
289  connect(d, SIGNAL(downLoadDataChanged(QString)), &loop, SLOT(quit()));
290  d->startToSearch(textLabel->text().trimmed());
291  loop.exec();
292 
293  if(!d->isEmpty())
294  {
295  for(const TTK::MusicSongInformation &info : d->items())
296  {
297  if(info.m_artistName.trimmed().contains(songIdentify.m_artistName.trimmed(), Qt::CaseInsensitive) &&
298  info.m_songName.trimmed().contains(songIdentify.m_songName.trimmed(), Qt::CaseInsensitive))
299  {
300  m_info = info;
301  break;
302  }
303  }
304  }
305  //
306  QLabel *iconLabel = new QLabel(widget);
307  iconLabel->setMinimumSize(280, 280);
308  if(!m_info.m_artistName.isEmpty())
309  {
310  const QString &name = ART_DIR_FULL + m_info.m_artistName + SKN_FILE;
311  if(!QFile::exists(name))
312  {
314  connect(d, SIGNAL(downLoadDataChanged(QString)), &loop, SLOT(quit()));
315  d->startToRequest();
316  loop.exec();
317  }
318  iconLabel->setPixmap(QPixmap(name).scaled(iconLabel->size()));
319  }
320  else
321  {
322  iconLabel->setPixmap(QPixmap(":/image/lb_default_art").scaled(iconLabel->size()));
323  }
324 
325  QPushButton *playButton = new QPushButton(infoFuncWidget);
326  QPushButton *loveButton = new QPushButton(infoFuncWidget);
327  QPushButton *downButton = new QPushButton(infoFuncWidget);
328  QPushButton *shareButton = new QPushButton(infoFuncWidget);
329 
330 #ifdef Q_OS_UNIX
331  playButton->setFocusPolicy(Qt::NoFocus);
332  loveButton->setFocusPolicy(Qt::NoFocus);
333  downButton->setFocusPolicy(Qt::NoFocus);
334  shareButton->setFocusPolicy(Qt::NoFocus);
335 #endif
336 
337  playButton->setFixedSize(25, 25);
338  loveButton->setFixedSize(25, 25);
339  downButton->setFixedSize(25, 25);
340  shareButton->setFixedSize(25, 25);
341 
342  playButton->setCursor(QCursor(Qt::PointingHandCursor));
343  loveButton->setCursor(QCursor(Qt::PointingHandCursor));
344  downButton->setCursor(QCursor(Qt::PointingHandCursor));
345  shareButton->setCursor(QCursor(Qt::PointingHandCursor));
346 
347  playButton->setStyleSheet(TTK::UI::SongsDetectPlayBtn);
348  loveButton->setStyleSheet(TTK::UI::SongsDetectUnloveBtn);
349  downButton->setStyleSheet(TTK::UI::SongsDetectDownloadBtn);
350  shareButton->setStyleSheet(TTK::UI::SongsDetectShareBtn);
351 
352  connect(playButton, SIGNAL(clicked()), SLOT(playSongClicked()));
353  connect(downButton, SIGNAL(clicked()), SLOT(showDownloadWidget()));
354  connect(shareButton, SIGNAL(clicked()), SLOT(showSongShareWidget()));
355 
356  infoFuncWidgetLayout->addWidget(textLabel, 0, 0, 1, 4);
357  infoFuncWidgetLayout->addWidget(iconLabel, 1, 0, 1, 4);
358  infoFuncWidgetLayout->addWidget(playButton, 2, 0, Qt::AlignCenter);
359  infoFuncWidgetLayout->addWidget(loveButton, 2, 1, Qt::AlignCenter);
360  infoFuncWidgetLayout->addWidget(downButton, 2, 2, Qt::AlignCenter);
361  infoFuncWidgetLayout->addWidget(shareButton, 2, 3, Qt::AlignCenter);
362  infoFuncWidget->setLayout(infoFuncWidgetLayout);
363  //
364  m_lrcLabel = new QLabel(widget);
365  m_lrcLabel->setMinimumWidth(280);
366 
367  if(!m_info.m_artistName.isEmpty())
368  {
370  if(!QFile::exists(path))
371  {
372  MusicAbstractDownLoadRequest *d = G_DOWNLOAD_QUERY_PTR->makeLrcRequest(m_info.m_lrcUrl, path, this);
373  connect(d, SIGNAL(downLoadDataChanged(QString)), &loop, SLOT(quit()));
374  d->startToRequest();
375  loop.exec();
376  }
377 
378  m_analysis->loadFromFile(path);
379 
381  if(!m_info.m_songProps.isEmpty())
382  {
384  }
385  }
386 
387  infoWidgetLayout->addWidget(infoFuncWidget);
388  infoWidgetLayout->addWidget(m_lrcLabel);
389  infoWidget->setLayout(infoWidgetLayout);
390  //
391  QPushButton *reDetect = new QPushButton(widget);
392  reDetect->setFixedSize(56, 56);
393  reDetect->setStyleSheet(TTK::UI::SongsRedetectBtn);
394  reDetect->setCursor(QCursor(Qt::PointingHandCursor));
395  connect(reDetect, SIGNAL(clicked()), SLOT(reDetectButtonClicked()));
396 
397  QLabel *text3Label = new QLabel(tr("Redetect"), widget);
398  text3Label->setStyleSheet(TTK::UI::FontStyle03);
399 
400  widgetLayout->addStretch(1);
401  widgetLayout->addWidget(infoWidget, 1, Qt::AlignCenter);
402  widgetLayout->addStretch(1);
403  widgetLayout->addWidget(reDetect, 0, Qt::AlignCenter);
404  widgetLayout->addWidget(text3Label, 0, Qt::AlignCenter);
405  widgetLayout->addStretch(1);
406  widget->setLayout(widgetLayout);
407  //
408  m_mainWindow->addWidget(widget);
409  m_mainWindow->setCurrentWidget(widget);
410 }
411 
413 {
414  if(m_mainWindow->count() > 1)
415  {
416  delete m_mainWindow->widget(1);
417  }
418 
419  QWidget *widget = new QWidget(m_mainWindow);
420  widget->setStyleSheet(TTK::UI::ColorStyle03 + TTK::UI::FontStyle04);
421  QVBoxLayout *widgetLayout = new QVBoxLayout(widget);
422 
423  QLabel *iconLabel = new QLabel(widget);
424  iconLabel->setPixmap(QPixmap(":/toolSets/lb_detect_error"));
425  QLabel *text1Label = new QLabel(tr("There are no recognized songs"), widget);
426  QLabel *text2Label = new QLabel(tr("Only playing songs can be recognized"), widget);
427  QLabel *text3Label = new QLabel(tr("Redetect"), widget);
428  text3Label->setStyleSheet(TTK::UI::FontStyle03);
429  //
430  QPushButton *reDetect = new QPushButton(widget);
431  reDetect->setFixedSize(56, 56);
432  reDetect->setStyleSheet(TTK::UI::SongsRedetectBtn);
433  reDetect->setCursor(QCursor(Qt::PointingHandCursor));
434  connect(reDetect, SIGNAL(clicked()), SLOT(reDetectButtonClicked()));
435 #ifdef Q_OS_UNIX
436  reDetect->setFocusPolicy(Qt::NoFocus);
437 #endif
438 
439  widgetLayout->addStretch(2);
440  widgetLayout->addWidget(iconLabel, 0, Qt::AlignCenter);
441  widgetLayout->addStretch(1);
442  widgetLayout->addWidget(text1Label, 0, Qt::AlignCenter);
443  widgetLayout->addStretch(1);
444  widgetLayout->addWidget(text2Label, 0, Qt::AlignCenter);
445  widgetLayout->addStretch(2);
446  widgetLayout->addWidget(reDetect, 0, Qt::AlignCenter);
447  widgetLayout->addWidget(text3Label, 0, Qt::AlignCenter);
448  widgetLayout->addStretch(1);
449  widget->setLayout(widgetLayout);
450  //
451  m_mainWindow->addWidget(widget);
452  m_mainWindow->setCurrentWidget(widget);
453 }
const TTK::MusicSongInformationList & items() const noexcept
int addWavHeader(const char *fileName) const
The class of the download widget.
void setMedia(Module type, const QString &url, int winId=-1)
int lineMax() const noexcept
The class of the abstract download data.
void setLineMax(int max) noexcept
static const QString FontStyle03
The class of the song share widget.
#define ART_DIR_FULL
Definition: musicobject.h:142
virtual void startToRequest(const QString &path) overridefinal
void initialize(Module type, const MusicSongSharingWidget::Item &data)
The class of the download the type of data.
static constexpr const char * SongsDetectShareBtn
int exec(ProcessEventsFlags flags=AllEvents)
The class of the audio recorder core.
MusicSongPropertyList m_songProps
Definition: musicobject.h:309
static constexpr const char * SongsDetectUnloveBtn
The class of the ttk event loop.
Definition: ttkeventloop.h:29
The class of the song identify data item.
void setCurrentIndex(int index) noexcept
#define qPrintable(s)
Definition: ttkqtglobal.h:35
static void popup(const QString &text)
void initialize(const QString &name)
int currentIndex() const noexcept
virtual void startToQueryResult(TTK::MusicSongInformation *info, int bitrate)
const char * name
Definition: http_parser.c:458
The class of the core lrc analysis.
#define TTK_RECORD_DATA_FILE
QString text(int index) const
static constexpr const char * SongsDetectDownloadBtn
TTK_MODULE_EXPORT QString lrcDirPrefix()
static constexpr const char * SongsDetectStopBtn
MusicAudioRecorderModule * m_recordCore
qint64 findTime(int index) const
int lineMiddle() const noexcept
static constexpr const char * SongsRedetectBtn
static const QString BackgroundStyle10
The class of the mplayer core.
static const QString FontStyle04
const MusicSongIdentifyDataList & items() const noexcept
static const QString ColorStyle03
Definition: musicuiobject.h:43
#define TTK_DN_S2MS
Definition: ttkglobal.h:355
TTK::MusicSongInformation m_info
virtual void startToRequest()=0
MusicIdentifySongWidget(QWidget *parent=nullptr)
State loadFromFile(const QString &path)
#define G_DOWNLOAD_QUERY_PTR
bool isEmpty() const noexcept
The class of the xf song identify query request.
virtual void startToSearch(const QString &value)=0
The class of the abstract query download data from net.
static constexpr const char * SongsDetectPlayBtn
void positionChanged(qint64 position)
static constexpr const char * SongsDetectStartBtn
#define SKN_FILE
Definition: musicobject.h:69
#define LRC_FILE
Definition: musicobject.h:76
virtual void startToRequest() override
TTK_MODULE_EXPORT QString generateSongName(const QString &title, const QString &artist) noexcept
Definition: musicsong.cpp:105
The class of the music song information.
Definition: musicobject.h:295
MusicXFIdentifyRequest * m_networkRequest
#define TTK_BN_128
Definition: ttkglobal.h:428