TTKMusicPlayer  4.1.3.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 {
117 
118  TTKSemaphoreLoop loop;
119  connect(m_networkRequest, SIGNAL(downLoadDataChanged(QString)), &loop, SLOT(quit()));
121  loop.exec();
122 
124  if(m_networkRequest->items().isEmpty())
125  {
127  }
128  else
129  {
131  }
132 }
133 
135 {
136  if(!m_player)
137  {
138  return;
139  }
140 
141  if(!m_info.m_songProps.isEmpty())
142  {
144  }
145 }
146 
148 {
149  if(!m_info.m_artistName.isEmpty())
150  {
151  MusicDownloadWidget *widget = new MusicDownloadWidget(this);
152  widget->initialize(m_info);
153  widget->show();
154  }
155 }
156 
158 {
159  if(!m_info.m_artistName.isEmpty())
160  {
162  item.m_name = m_info.m_songName;
163 
164  MusicSongSharingWidget widget(this);
166  widget.exec();
167  }
168 }
169 
171 {
172  if(!m_player)
173  {
174  return;
175  }
176 
177  if(m_analysis->isEmpty())
178  {
179  const QString &lrc = QString("<p style='font-weight:600;' align='center'>%1</p>").arg(tr("No lrc data file found"));
180  m_lrcLabel->setText(lrc);
181  return;
182  }
183 
184  const int index = m_analysis->currentIndex();
185  const qint64 time = m_analysis->findTime(index);
186 
187  if(time < position * TTK_DN_S2MS && time != -1)
188  {
189  QString lrc;
190  for(int i = 0; i < m_analysis->lineMax(); ++i)
191  {
192  if(i == m_analysis->lineMiddle())
193  {
194  lrc += QString("<p style='font-weight:700;' align='center'>");
195  }
196  else
197  {
198  lrc += QString("<p align='center'>");
199  }
200 
201  lrc += m_analysis->text(i);
202  lrc += QString("</p>");
203  }
204  m_lrcLabel->setText(lrc);
205  m_analysis->setCurrentIndex(index + 1);
206  }
207 }
208 
210 {
211  QWidget *widget = new QWidget(m_mainWindow);
212  widget->setStyleSheet(TTK::UI::ColorStyle03 + TTK::UI::FontStyle04);
213  QVBoxLayout *widgetLayout = new QVBoxLayout(widget);
214 
215  m_detectedMovie = new QMovie(":/toolSets/lb_radar", {}, widget);
216  QLabel *iconLabel = new QLabel(widget);
217  iconLabel->setFixedSize(200, 200);
218  QVBoxLayout *iconLabelLayout = new QVBoxLayout(iconLabel);
219  iconLabelLayout->setSpacing(0);
220  iconLabelLayout->setContentsMargins(0, 0, 0, 0);
221 
222  m_detectedButton = new QPushButton(widget);
224  m_detectedButton->setCursor(QCursor(Qt::PointingHandCursor));
225  m_detectedButton->setFixedSize(162, 162);
226 #ifdef Q_OS_UNIX
227  m_detectedButton->setFocusPolicy(Qt::NoFocus);
228 #endif
229 
230  iconLabelLayout->addWidget(m_detectedButton, 0, Qt::AlignCenter);
231  iconLabel->setMovie(m_detectedMovie);
232  iconLabel->setLayout(iconLabelLayout);
233  connect(m_detectedButton, SIGNAL(clicked()), SLOT(detectedButtonClicked()));
234 
235  m_detectedLabel = new QLabel(widget);
236  m_detectedLabel->setText(tr("Intelligent recognition of playing song"));
237 
238  QLabel *text = new QLabel(tr("Shortcut:") + " Shift + Ctrl + T", widget);
239  text->setStyleSheet(TTK::UI::FontStyle03);
240 
241  widgetLayout->addStretch(2);
242  widgetLayout->addWidget(iconLabel, 0, Qt::AlignCenter);
243  widgetLayout->addStretch(1);
244  widgetLayout->addWidget(m_detectedLabel, 0, Qt::AlignCenter);
245  widgetLayout->addStretch(1);
246  widgetLayout->addWidget(text, 0, Qt::AlignCenter);
247  widget->setLayout(widgetLayout);
248  //
249  m_mainWindow->addWidget(widget);
250  m_mainWindow->setCurrentWidget(widget);
251 }
252 
254 {
255  if(m_mainWindow->count() > 1)
256  {
257  delete m_lrcLabel;
258  delete m_mainWindow->widget(1);
259  }
260  else
261  {
262  m_player = new MusicCoreMPlayer(this);
263  m_analysis = new MusicLrcAnalysis(this);
264  m_analysis->setLineMax(11);
265  connect(m_player, SIGNAL(positionChanged(qint64)), SLOT(positionChanged(qint64)));
266  }
267  const MusicSongIdentifyData &songIdentify = m_networkRequest->items().front();
268 
269  QWidget *widget = new QWidget(m_mainWindow);
270  widget->setStyleSheet(TTK::UI::ColorStyle03 + TTK::UI::FontStyle04);
271  QVBoxLayout *widgetLayout = new QVBoxLayout(widget);
272  //
273  QWidget *infoWidget = new QWidget(widget);
274  QHBoxLayout *infoWidgetLayout = new QHBoxLayout(infoWidget);
275  infoWidgetLayout->setContentsMargins(0, 0, 0, 0);
276  infoWidgetLayout->setSpacing(25);
277 
278  QWidget *infoFuncWidget = new QWidget(infoWidget);
279  QGridLayout *infoFuncWidgetLayout = new QGridLayout(infoFuncWidget);
280  infoFuncWidgetLayout->setContentsMargins(0, 0, 0, 0);
281 
282  QLabel *textLabel = new QLabel(widget);
283  textLabel->setText(QString("%1 - %2").arg(songIdentify.m_artistName, songIdentify.m_songName));
284  textLabel->setAlignment(Qt::AlignCenter);
285  //
286  TTKSemaphoreLoop loop;
287  MusicAbstractQueryRequest *d = G_DOWNLOAD_QUERY_PTR->makeQueryRequest(this);
288  connect(d, SIGNAL(downLoadDataChanged(QString)), &loop, SLOT(quit()));
289  d->startToSearch(textLabel->text().trimmed());
290  loop.exec();
291 
292  if(!d->isEmpty())
293  {
294  for(const TTK::MusicSongInformation &info : d->items())
295  {
296  if(info.m_artistName.toLower().trimmed().contains(songIdentify.m_artistName.toLower().trimmed(), Qt::CaseInsensitive) &&
297  info.m_songName.toLower().trimmed().contains(songIdentify.m_songName.toLower().trimmed(), Qt::CaseInsensitive))
298  {
299  m_info = info;
300  break;
301  }
302  }
303  }
304  //
305  QLabel *iconLabel = new QLabel(widget);
306  iconLabel->setMinimumSize(280, 280);
307  if(!m_info.m_artistName.isEmpty())
308  {
309  const QString &name = ART_DIR_FULL + m_info.m_artistName + SKN_FILE;
310  if(!QFile::exists(name))
311  {
313  connect(d, SIGNAL(downLoadDataChanged(QString)), &loop, SLOT(quit()));
314  d->startToRequest();
315  loop.exec();
316  }
317  iconLabel->setPixmap(QPixmap(name).scaled(iconLabel->size()));
318  }
319  else
320  {
321  iconLabel->setPixmap(QPixmap(":/image/lb_default_art").scaled(iconLabel->size()));
322  }
323 
324  QPushButton *playButton = new QPushButton(infoFuncWidget);
325  QPushButton *loveButton = new QPushButton(infoFuncWidget);
326  QPushButton *downButton = new QPushButton(infoFuncWidget);
327  QPushButton *shareButton = new QPushButton(infoFuncWidget);
328 
329 #ifdef Q_OS_UNIX
330  playButton->setFocusPolicy(Qt::NoFocus);
331  loveButton->setFocusPolicy(Qt::NoFocus);
332  downButton->setFocusPolicy(Qt::NoFocus);
333  shareButton->setFocusPolicy(Qt::NoFocus);
334 #endif
335 
336  playButton->setFixedSize(25, 25);
337  loveButton->setFixedSize(25, 25);
338  downButton->setFixedSize(25, 25);
339  shareButton->setFixedSize(25, 25);
340 
341  playButton->setCursor(QCursor(Qt::PointingHandCursor));
342  loveButton->setCursor(QCursor(Qt::PointingHandCursor));
343  downButton->setCursor(QCursor(Qt::PointingHandCursor));
344  shareButton->setCursor(QCursor(Qt::PointingHandCursor));
345 
346  playButton->setStyleSheet(TTK::UI::SongsDetectPlayBtn);
347  loveButton->setStyleSheet(TTK::UI::SongsDetectUnloveBtn);
348  downButton->setStyleSheet(TTK::UI::SongsDetectDownloadBtn);
349  shareButton->setStyleSheet(TTK::UI::SongsDetectShareBtn);
350 
351  connect(playButton, SIGNAL(clicked()), SLOT(playSongClicked()));
352  connect(downButton, SIGNAL(clicked()), SLOT(showDownloadWidget()));
353  connect(shareButton, SIGNAL(clicked()), SLOT(showSongShareWidget()));
354 
355  infoFuncWidgetLayout->addWidget(textLabel, 0, 0, 1, 4);
356  infoFuncWidgetLayout->addWidget(iconLabel, 1, 0, 1, 4);
357  infoFuncWidgetLayout->addWidget(playButton, 2, 0, Qt::AlignCenter);
358  infoFuncWidgetLayout->addWidget(loveButton, 2, 1, Qt::AlignCenter);
359  infoFuncWidgetLayout->addWidget(downButton, 2, 2, Qt::AlignCenter);
360  infoFuncWidgetLayout->addWidget(shareButton, 2, 3, Qt::AlignCenter);
361  infoFuncWidget->setLayout(infoFuncWidgetLayout);
362  //
363  m_lrcLabel = new QLabel(widget);
364  m_lrcLabel->setMinimumWidth(280);
365 
366  if(!m_info.m_artistName.isEmpty())
367  {
369  if(!QFile::exists(name))
370  {
371  MusicAbstractDownLoadRequest *d = G_DOWNLOAD_QUERY_PTR->makeLrcRequest(m_info.m_lrcUrl, name, this);
372  connect(d, SIGNAL(downLoadDataChanged(QString)), &loop, SLOT(quit()));
373  d->startToRequest();
374  loop.exec();
375  }
376 
378 
380  if(!m_info.m_songProps.isEmpty())
381  {
383  }
384  }
385 
386  infoWidgetLayout->addWidget(infoFuncWidget);
387  infoWidgetLayout->addWidget(m_lrcLabel);
388  infoWidget->setLayout(infoWidgetLayout);
389  //
390  QPushButton *reDetect = new QPushButton(widget);
391  reDetect->setFixedSize(56, 56);
392  reDetect->setStyleSheet(TTK::UI::SongsRedetectBtn);
393  reDetect->setCursor(QCursor(Qt::PointingHandCursor));
394  connect(reDetect, SIGNAL(clicked()), SLOT(reDetectButtonClicked()));
395 
396  QLabel *text3Label = new QLabel(tr("Redetect"), widget);
397  text3Label->setStyleSheet(TTK::UI::FontStyle03);
398 
399  widgetLayout->addStretch(1);
400  widgetLayout->addWidget(infoWidget, 1, Qt::AlignCenter);
401  widgetLayout->addStretch(1);
402  widgetLayout->addWidget(reDetect, 0, Qt::AlignCenter);
403  widgetLayout->addWidget(text3Label, 0, Qt::AlignCenter);
404  widgetLayout->addStretch(1);
405  widget->setLayout(widgetLayout);
406  //
407  m_mainWindow->addWidget(widget);
408  m_mainWindow->setCurrentWidget(widget);
409 }
410 
412 {
413  if(m_mainWindow->count() > 1)
414  {
415  delete m_mainWindow->widget(1);
416  }
417 
418  QWidget *widget = new QWidget(m_mainWindow);
419  widget->setStyleSheet(TTK::UI::ColorStyle03 + TTK::UI::FontStyle04);
420  QVBoxLayout *widgetLayout = new QVBoxLayout(widget);
421 
422  QLabel *iconLabel = new QLabel(widget);
423  iconLabel->setPixmap(QPixmap(":/toolSets/lb_detect_error"));
424  QLabel *text1Label = new QLabel(tr("There are no recognized songs"), widget);
425  QLabel *text2Label = new QLabel(tr("Only playing songs can be recognized"), widget);
426  QLabel *text3Label = new QLabel(tr("Redetect"), widget);
427  text3Label->setStyleSheet(TTK::UI::FontStyle03);
428  //
429  QPushButton *reDetect = new QPushButton(widget);
430  reDetect->setFixedSize(56, 56);
431  reDetect->setStyleSheet(TTK::UI::SongsRedetectBtn);
432  reDetect->setCursor(QCursor(Qt::PointingHandCursor));
433  connect(reDetect, SIGNAL(clicked()), SLOT(reDetectButtonClicked()));
434 #ifdef Q_OS_UNIX
435  reDetect->setFocusPolicy(Qt::NoFocus);
436 #endif
437 
438  widgetLayout->addStretch(2);
439  widgetLayout->addWidget(iconLabel, 0, Qt::AlignCenter);
440  widgetLayout->addStretch(1);
441  widgetLayout->addWidget(text1Label, 0, Qt::AlignCenter);
442  widgetLayout->addStretch(1);
443  widgetLayout->addWidget(text2Label, 0, Qt::AlignCenter);
444  widgetLayout->addStretch(2);
445  widgetLayout->addWidget(reDetect, 0, Qt::AlignCenter);
446  widgetLayout->addWidget(text3Label, 0, Qt::AlignCenter);
447  widgetLayout->addStretch(1);
448  widget->setLayout(widgetLayout);
449  //
450  m_mainWindow->addWidget(widget);
451  m_mainWindow->setCurrentWidget(widget);
452 }
TTK_MODULE_EXPORT QString generateSongName(const QString &title, const QString &artist)
Definition: musicsong.cpp:105
int addWavHeader(const char *fileName) const
The class of the download widget.
void setMedia(Module type, const QString &url, int winId=-1)
void setLineMax(int max)
The class of the abstract download data.
void setCurrentIndex(int index)
int lineMax() const
static const QString FontStyle03
The class of the song share widget.
#define ART_DIR_FULL
Definition: musicobject.h:130
void initialize(Module type, const MusicSongSharingWidget::Item &data)
The class of the download the type of data.
static constexpr const char * SongsDetectShareBtn
The class of the audio recorder core.
MusicSongPropertyList m_songProps
Definition: musicobject.h:297
int exec(ProcessEventsFlags flags=AllEvents)
static constexpr const char * SongsDetectUnloveBtn
const MusicSongIdentifyDataList & items() const
The class of the song identify data item.
static void popup(const QString &text)
void initialize(const QString &name)
virtual void startToQueryResult(TTK::MusicSongInformation *info, int bitrate)
int lineMiddle() const
const char * name
Definition: http_parser.c:458
The class of the core lrc analysis.
#define TTK_RECORD_DATA_FILE
bool isEmpty() const
void startToRequest(const QString &path)
int currentIndex() const
QString text(int index) const
static constexpr const char * SongsDetectDownloadBtn
TTK_MODULE_EXPORT QString lrcDirPrefix()
static constexpr const char * SongsDetectStopBtn
MusicAudioRecorderModule * m_recordCore
State loadFromLrcFile(const QString &path)
qint64 findTime(int index) const
MusicIdentifySongRequest * m_networkRequest
static constexpr const char * SongsRedetectBtn
static const QString BackgroundStyle10
The class of the mplayer core.
static const QString FontStyle04
The class of the song identify query request.
static const QString ColorStyle03
Definition: musicuiobject.h:43
#define TTK_DN_S2MS
Definition: ttkglobal.h:281
TTK::MusicSongInformation m_info
virtual void startToRequest()=0
MusicIdentifySongWidget(QWidget *parent=nullptr)
#define G_DOWNLOAD_QUERY_PTR
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:62
const TTK::MusicSongInformationList & items() const
#define LRC_FILE
Definition: musicobject.h:65
The class of the semaphore event loop.
virtual void startToRequest() override
The class of the music song information.
Definition: musicobject.h:283
#define TTK_BN_128
Definition: ttkglobal.h:353