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