Ui improvements
This commit is contained in:
parent
5fcb6a4149
commit
56660fe0b5
4 changed files with 122 additions and 7 deletions
|
|
@ -4,7 +4,8 @@
|
||||||
AudioPlayer::AudioPlayer(QObject *parent)
|
AudioPlayer::AudioPlayer(QObject *parent)
|
||||||
: QObject(parent),
|
: QObject(parent),
|
||||||
mediaPlayer(new QMediaPlayer(this)),
|
mediaPlayer(new QMediaPlayer(this)),
|
||||||
audioOutput(new QAudioOutput(this))
|
audioOutput(new QAudioOutput(this)),
|
||||||
|
positionTimer(new QTimer(this))
|
||||||
{
|
{
|
||||||
// Set up audio output with default device
|
// Set up audio output with default device
|
||||||
mediaPlayer->setAudioOutput(audioOutput);
|
mediaPlayer->setAudioOutput(audioOutput);
|
||||||
|
|
@ -13,6 +14,14 @@ AudioPlayer::AudioPlayer(QObject *parent)
|
||||||
this, &AudioPlayer::handlePlaybackStateChanged);
|
this, &AudioPlayer::handlePlaybackStateChanged);
|
||||||
connect(mediaPlayer, &QMediaPlayer::mediaStatusChanged,
|
connect(mediaPlayer, &QMediaPlayer::mediaStatusChanged,
|
||||||
this, &AudioPlayer::handleMediaStatusChanged);
|
this, &AudioPlayer::handleMediaStatusChanged);
|
||||||
|
|
||||||
|
// Set up position timer for updating playback position
|
||||||
|
positionTimer->setInterval(500); // Update every 500ms
|
||||||
|
connect(positionTimer, &QTimer::timeout, [this]() {
|
||||||
|
if (isPlaying()) {
|
||||||
|
emit positionChanged(mediaPlayer->position());
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioPlayer::~AudioPlayer()
|
AudioPlayer::~AudioPlayer()
|
||||||
|
|
@ -28,11 +37,36 @@ void AudioPlayer::play(const QString &filePath)
|
||||||
|
|
||||||
mediaPlayer->setSource(QUrl::fromLocalFile(filePath));
|
mediaPlayer->setSource(QUrl::fromLocalFile(filePath));
|
||||||
mediaPlayer->play();
|
mediaPlayer->play();
|
||||||
|
|
||||||
|
// Start position timer
|
||||||
|
positionTimer->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioPlayer::play()
|
||||||
|
{
|
||||||
|
if (!isPlaying()) {
|
||||||
|
mediaPlayer->play();
|
||||||
|
positionTimer->start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioPlayer::pause()
|
||||||
|
{
|
||||||
|
if (isPlaying()) {
|
||||||
|
mediaPlayer->pause();
|
||||||
|
positionTimer->stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioPlayer::setPosition(int position)
|
||||||
|
{
|
||||||
|
mediaPlayer->setPosition(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioPlayer::stop()
|
void AudioPlayer::stop()
|
||||||
{
|
{
|
||||||
mediaPlayer->stop();
|
mediaPlayer->stop();
|
||||||
|
positionTimer->stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AudioPlayer::isPlaying() const
|
bool AudioPlayer::isPlaying() const
|
||||||
|
|
@ -69,7 +103,11 @@ void AudioPlayer::handleMediaStatusChanged(QMediaPlayer::MediaStatus status)
|
||||||
emit playbackFinished();
|
emit playbackFinished();
|
||||||
} else if (status == QMediaPlayer::LoadedMedia ||
|
} else if (status == QMediaPlayer::LoadedMedia ||
|
||||||
status == QMediaPlayer::BufferedMedia) {
|
status == QMediaPlayer::BufferedMedia) {
|
||||||
// Media loaded successfully
|
// Media loaded successfully, emit duration
|
||||||
|
int duration = mediaPlayer->duration();
|
||||||
|
if (duration > 0) {
|
||||||
|
emit durationChanged(duration);
|
||||||
|
}
|
||||||
} else if (status == QMediaPlayer::InvalidMedia) {
|
} else if (status == QMediaPlayer::InvalidMedia) {
|
||||||
emit playbackError(mediaPlayer->errorString());
|
emit playbackError(mediaPlayer->errorString());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QMediaDevices>
|
#include <QMediaDevices>
|
||||||
#include <QAudioDevice>
|
#include <QAudioDevice>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
class AudioPlayer : public QObject
|
class AudioPlayer : public QObject
|
||||||
{
|
{
|
||||||
|
|
@ -17,7 +18,10 @@ public:
|
||||||
~AudioPlayer();
|
~AudioPlayer();
|
||||||
|
|
||||||
void play(const QString &filePath);
|
void play(const QString &filePath);
|
||||||
|
void play();
|
||||||
void stop();
|
void stop();
|
||||||
|
void pause();
|
||||||
|
void setPosition(int position);
|
||||||
bool isPlaying() const;
|
bool isPlaying() const;
|
||||||
int duration() const;
|
int duration() const;
|
||||||
int position() const;
|
int position() const;
|
||||||
|
|
@ -26,6 +30,8 @@ signals:
|
||||||
void playbackStarted();
|
void playbackStarted();
|
||||||
void playbackFinished();
|
void playbackFinished();
|
||||||
void playbackError(const QString &error);
|
void playbackError(const QString &error);
|
||||||
|
void positionChanged(int position);
|
||||||
|
void durationChanged(int duration);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void handlePlaybackStateChanged(QMediaPlayer::PlaybackState state);
|
void handlePlaybackStateChanged(QMediaPlayer::PlaybackState state);
|
||||||
|
|
@ -34,6 +40,7 @@ private slots:
|
||||||
private:
|
private:
|
||||||
QMediaPlayer *mediaPlayer;
|
QMediaPlayer *mediaPlayer;
|
||||||
QAudioOutput *audioOutput;
|
QAudioOutput *audioOutput;
|
||||||
|
QTimer *positionTimer;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // AUDIOPLAYER_H
|
#endif // AUDIOPLAYER_H
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ MainWindow::MainWindow(QWidget *parent)
|
||||||
playbackTimer(new QTimer(this)),
|
playbackTimer(new QTimer(this)),
|
||||||
currentSongIndex(-1),
|
currentSongIndex(-1),
|
||||||
isPlaying(false),
|
isPlaying(false),
|
||||||
|
isPaused(false),
|
||||||
shuffleMode(false)
|
shuffleMode(false)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
@ -111,11 +112,42 @@ void MainWindow::saveSettings()
|
||||||
settings.setValue("vaeModelPath", vaeModelPath);
|
settings.setValue("vaeModelPath", vaeModelPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString MainWindow::formatTime(int milliseconds)
|
||||||
|
{
|
||||||
|
if (milliseconds < 0) return "0:00";
|
||||||
|
|
||||||
|
int seconds = milliseconds / 1000;
|
||||||
|
int minutes = seconds / 60;
|
||||||
|
seconds = seconds % 60;
|
||||||
|
|
||||||
|
return QString("%1:%2").arg(minutes).arg(seconds, 2, 10, QChar('0'));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::updatePosition(int position)
|
||||||
|
{
|
||||||
|
if (position < 0) return;
|
||||||
|
|
||||||
|
// Update slider and time labels
|
||||||
|
ui->positionSlider->setValue(position);
|
||||||
|
ui->elapsedTimeLabel->setText(formatTime(position));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::updateDuration(int duration)
|
||||||
|
{
|
||||||
|
if (duration <= 0) return;
|
||||||
|
|
||||||
|
// Set slider range and update duration label
|
||||||
|
ui->positionSlider->setRange(0, duration);
|
||||||
|
ui->durationLabel->setText(formatTime(duration));
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::updateControls()
|
void MainWindow::updateControls()
|
||||||
{
|
{
|
||||||
bool hasSongs = songModel->rowCount() > 0;
|
bool hasSongs = songModel->rowCount() > 0;
|
||||||
|
|
||||||
ui->playButton->setEnabled(hasSongs && !isPlaying);
|
// Play button is enabled when not playing, or can be used to resume when paused
|
||||||
|
ui->playButton->setEnabled(hasSongs && (!isPlaying || isPaused));
|
||||||
|
ui->pauseButton->setEnabled(isPlaying && !isPaused);
|
||||||
ui->skipButton->setEnabled(isPlaying);
|
ui->skipButton->setEnabled(isPlaying);
|
||||||
ui->stopButton->setEnabled(isPlaying);
|
ui->stopButton->setEnabled(isPlaying);
|
||||||
ui->addSongButton->setEnabled(true);
|
ui->addSongButton->setEnabled(true);
|
||||||
|
|
@ -125,9 +157,18 @@ void MainWindow::updateControls()
|
||||||
|
|
||||||
void MainWindow::on_playButton_clicked()
|
void MainWindow::on_playButton_clicked()
|
||||||
{
|
{
|
||||||
|
if (isPaused) {
|
||||||
|
// Resume playback
|
||||||
|
audioPlayer->play();
|
||||||
|
isPaused = false;
|
||||||
|
updateControls();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (isPlaying) {
|
if (isPlaying) {
|
||||||
audioPlayer->stop();
|
audioPlayer->stop();
|
||||||
isPlaying = false;
|
isPlaying = false;
|
||||||
|
isPaused = false;
|
||||||
updateControls();
|
updateControls();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -141,11 +182,22 @@ void MainWindow::on_playButton_clicked()
|
||||||
generateAndPlayNext();
|
generateAndPlayNext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_pauseButton_clicked()
|
||||||
|
{
|
||||||
|
if (isPlaying && !isPaused) {
|
||||||
|
// Pause playback
|
||||||
|
audioPlayer->pause();
|
||||||
|
isPaused = true;
|
||||||
|
updateControls();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::on_skipButton_clicked()
|
void MainWindow::on_skipButton_clicked()
|
||||||
{
|
{
|
||||||
if (isPlaying) {
|
if (isPlaying) {
|
||||||
// Stop current playback and move to next song
|
// Stop current playback and move to next song
|
||||||
audioPlayer->stop();
|
audioPlayer->stop();
|
||||||
|
isPaused = false;
|
||||||
playNextSong();
|
playNextSong();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -156,11 +208,20 @@ void MainWindow::on_stopButton_clicked()
|
||||||
// Stop current playback completely
|
// Stop current playback completely
|
||||||
audioPlayer->stop();
|
audioPlayer->stop();
|
||||||
isPlaying = false;
|
isPlaying = false;
|
||||||
|
isPaused = false;
|
||||||
ui->statusLabel->setText("Stopped");
|
ui->statusLabel->setText("Stopped");
|
||||||
updateControls();
|
updateControls();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_positionSlider_sliderMoved(int position)
|
||||||
|
{
|
||||||
|
if (isPlaying && audioPlayer->isPlaying()) {
|
||||||
|
// Seek to the new position when slider is moved
|
||||||
|
audioPlayer->setPosition(position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::on_shuffleButton_clicked()
|
void MainWindow::on_shuffleButton_clicked()
|
||||||
{
|
{
|
||||||
shuffleMode = ui->shuffleButton->isChecked();
|
shuffleMode = ui->shuffleButton->isChecked();
|
||||||
|
|
@ -258,10 +319,6 @@ void MainWindow::on_advancedSettingsButton_clicked()
|
||||||
jsonTemplateEdit->setMinimumHeight(200);
|
jsonTemplateEdit->setMinimumHeight(200);
|
||||||
jsonLayout->addWidget(jsonTemplateEdit);
|
jsonLayout->addWidget(jsonTemplateEdit);
|
||||||
|
|
||||||
QLabel *fieldsLabel = new QLabel("Available fields: caption, lyrics, instrumental, bpm, duration, keyscale, timesignature,\nvocal_language, seed, lm_temperature, lm_cfg_scale, lm_top_p, lm_top_k, lm_negative_prompt,\naudio_codes, inference_steps, guidance_scale, shift");
|
|
||||||
fieldsLabel->setWordWrap(true);
|
|
||||||
jsonLayout->addWidget(fieldsLabel);
|
|
||||||
|
|
||||||
tabWidget->addTab(jsonTab, "JSON Template");
|
tabWidget->addTab(jsonTab, "JSON Template");
|
||||||
|
|
||||||
// Path Settings tab
|
// Path Settings tab
|
||||||
|
|
@ -405,6 +462,10 @@ void MainWindow::songGenerated(const QString &filePath)
|
||||||
|
|
||||||
// Play the generated song
|
// Play the generated song
|
||||||
audioPlayer->play(filePath);
|
audioPlayer->play(filePath);
|
||||||
|
|
||||||
|
// Connect position and duration updates for the slider
|
||||||
|
connect(audioPlayer, &AudioPlayer::positionChanged, this, &MainWindow::updatePosition);
|
||||||
|
connect(audioPlayer, &AudioPlayer::durationChanged, this, &MainWindow::updateDuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::playNextSong()
|
void MainWindow::playNextSong()
|
||||||
|
|
@ -420,6 +481,7 @@ void MainWindow::playNextSong()
|
||||||
} else {
|
} else {
|
||||||
// No more songs
|
// No more songs
|
||||||
isPlaying = false;
|
isPlaying = false;
|
||||||
|
isPaused = false;
|
||||||
ui->statusLabel->setText("Finished playback");
|
ui->statusLabel->setText("Finished playback");
|
||||||
updateControls();
|
updateControls();
|
||||||
}
|
}
|
||||||
|
|
@ -453,6 +515,7 @@ void MainWindow::generationError(const QString &error)
|
||||||
dialog.exec();
|
dialog.exec();
|
||||||
|
|
||||||
isPlaying = false;
|
isPlaying = false;
|
||||||
|
isPaused = false;
|
||||||
updateControls();
|
updateControls();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,13 @@ public:
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void on_playButton_clicked();
|
void on_playButton_clicked();
|
||||||
|
void on_pauseButton_clicked();
|
||||||
void on_skipButton_clicked();
|
void on_skipButton_clicked();
|
||||||
void on_stopButton_clicked();
|
void on_stopButton_clicked();
|
||||||
void on_shuffleButton_clicked();
|
void on_shuffleButton_clicked();
|
||||||
|
void on_positionSlider_sliderMoved(int position);
|
||||||
|
void updatePosition(int position);
|
||||||
|
void updateDuration(int duration);
|
||||||
void on_addSongButton_clicked();
|
void on_addSongButton_clicked();
|
||||||
void on_editSongButton_clicked();
|
void on_editSongButton_clicked();
|
||||||
void on_removeSongButton_clicked();
|
void on_removeSongButton_clicked();
|
||||||
|
|
@ -44,8 +48,11 @@ private:
|
||||||
AceStepWorker *aceStepWorker;
|
AceStepWorker *aceStepWorker;
|
||||||
QTimer *playbackTimer;
|
QTimer *playbackTimer;
|
||||||
|
|
||||||
|
QString formatTime(int milliseconds);
|
||||||
|
|
||||||
int currentSongIndex;
|
int currentSongIndex;
|
||||||
bool isPlaying;
|
bool isPlaying;
|
||||||
|
bool isPaused;
|
||||||
bool shuffleMode;
|
bool shuffleMode;
|
||||||
QString jsonTemplate;
|
QString jsonTemplate;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue