Update current music player to have round spinning album art

This commit is contained in:
2025-11-19 21:39:36 -07:00
parent ec11876c2e
commit 58ecda86a9
16 changed files with 138 additions and 49 deletions

View File

@@ -1,42 +1,123 @@
#include "playerWindow.h"
#include <QVBoxLayout>
#include <QLabel>
#include <QPixmap>
#include <QPainter>
#include <QPainterPath>
#include <QFileInfo>
#include <QCloseEvent>
#include "src/data/cleanerScripts.h"
PlayerWindow::PlayerWindow(const AlbumData& item, QWidget* parent)
: QWidget(parent), item_(item)
{
this->setWindowTitle("Now Playing");
this->resize(300, 350);
this->resize(300, 370);
QVBoxLayout* layout = new QVBoxLayout(this);
// Album Art
QLabel* art = new QLabel;
QPixmap pix(item.imagePath);
art->setPixmap(pix.scaled(250, 250, Qt::KeepAspectRatio, Qt::SmoothTransformation));
art->setAlignment(Qt::AlignCenter);
layout->addWidget(art);
// --------------------------------------
// 1. CREATE ALBUM ART (CIRCULAR)
// --------------------------------------
artLabel_ = new QLabel;
artLabel_->setAlignment(Qt::AlignCenter);
layout->addWidget(artLabel_);
// Track Label (new)
QPixmap pix(item.imagePath);
// Scale, crop square
QPixmap scaled = pix.scaled(250, 250,
Qt::KeepAspectRatioByExpanding,
Qt::SmoothTransformation);
int side = qMin(scaled.width(), scaled.height());
QPixmap square = scaled.copy(
(scaled.width() - side) / 2,
(scaled.height() - side) / 2,
side,
side
);
// Mask to circle
discArt_ = QPixmap(side, side);
discArt_.fill(Qt::transparent);
{
QPainter p(&discArt_);
p.setRenderHint(QPainter::Antialiasing);
QPainterPath path;
path.addEllipse(0, 0, side, side);
p.setClipPath(path);
p.drawPixmap(0, 0, square);
}
artLabel_->setPixmap(discArt_);
// --------------------------------------
// 2. TRACK LABEL
// --------------------------------------
trackLabel_ = new QLabel("Track 1");
trackLabel_->setAlignment(Qt::AlignCenter);
trackLabel_->setStyleSheet("font-size: 14px; font-weight: 500;");
layout->addWidget(trackLabel_);
// Player setup
// --------------------------------------
// 3. SPINNING TIMER
// --------------------------------------
spinTimer_ = new QTimer(this);
spinTimer_->setInterval(16);
connect(spinTimer_, &QTimer::timeout, this, [this]() {
rotationAngle_ += 0.6;
int side = discArt_.width();
QPixmap frame(side, side);
frame.fill(Qt::transparent);
QPainter p(&frame);
p.setRenderHint(QPainter::Antialiasing);
p.setRenderHint(QPainter::SmoothPixmapTransform);
// rotate around center
p.translate(side / 2, side / 2);
p.rotate(rotationAngle_);
p.translate(-side / 2, -side / 2);
p.drawPixmap(0, 0, discArt_);
// If you eventually add overlay:
// p.resetTransform();
// p.drawPixmap(0, 0, overlayArt_);
artLabel_->setPixmap(frame);
});
// --------------------------------------
// 4. MEDIA PLAYER SETUP
// --------------------------------------
player_ = new QMediaPlayer(this);
audio_ = new QAudioOutput(this);
audio_ = new QAudioOutput(this);
player_->setAudioOutput(audio_);
connect(player_, &QMediaPlayer::mediaStatusChanged, this,
[this](QMediaPlayer::MediaStatus s){
[this](QMediaPlayer::MediaStatus s) {
if (s == QMediaPlayer::EndOfMedia) {
spinTimer_->stop();
playNext();
}
});
connect(player_, &QMediaPlayer::playbackStateChanged, this,
[this](QMediaPlayer::PlaybackState st) {
if (st == QMediaPlayer::PlayingState)
spinTimer_->start();
else
spinTimer_->stop();
});
// --------------------------------------
// 5. PLAY FIRST TRACK
// --------------------------------------
playNext();
}
@@ -49,14 +130,11 @@ void PlayerWindow::playNext()
QString filePath = item_.audioFiles[index_];
QString fileName = QFileInfo(filePath).fileName();
// Remove extension for cleaner title
QString title = cleanTrackTitle(fileName);
// Track number is index + 1
int trackNumber = index_ + 1;
trackLabel_->setText(QString("Track %1: %2").arg(trackNumber).arg(title));
trackLabel_->setText(
QString("Track %1: %2").arg(index_ + 1).arg(title)
);
player_->setSource(QUrl::fromLocalFile(filePath));
player_->play();
@@ -64,11 +142,11 @@ void PlayerWindow::playNext()
index_++;
}
// Stop the music when the window is closed
void PlayerWindow::closeEvent(QCloseEvent* event)
{
if (player_) {
player_->stop();
spinTimer_->stop();
}
QWidget::closeEvent(event); // still let Qt do its normal cleanup
QWidget::closeEvent(event);
}

View File

@@ -1,28 +1,37 @@
#pragma once
#include <QWidget>
#include <QLabel>
#include <QMediaPlayer>
#include <QAudioOutput>
#include <QTimer>
#include "src/data/albumInformation.h"
#include "src/data/cleanerScripts.h"
class PlayerWindow : public QWidget {
Q_OBJECT
QLabel* trackLabel_;
Q_OBJECT
public:
explicit PlayerWindow(const AlbumData& item, QWidget* parent = nullptr);
explicit PlayerWindow(const AlbumData& item, QWidget* parent = nullptr);
protected:
void closeEvent(QCloseEvent* event) override;
private slots:
void playNext();
private:
AlbumData item_;
int index_ = 0;
AlbumData item_;
int index_ = 0;
QMediaPlayer* player_;
QAudioOutput* audio_;
QMediaPlayer* player_;
QAudioOutput* audio_;
protected:
void closeEvent(QCloseEvent* event) override;
QLabel* artLabel_;
QLabel* trackLabel_;
QPixmap discArt_; // circular cropped album art
QPixmap overlayArt_; // optional overlay (not required)
qreal rotationAngle_ = 0;
QTimer* spinTimer_;
};