From 280036d3eb7992df05e7e0ba5c3e726539c5f211 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20M=C3=A9ndez?= Date: Sat, 25 Nov 2023 15:45:00 -0600 Subject: [PATCH] Refactor working, some details missing --- audiosource.h | 2 +- audiosourcecoordinator.cpp | 51 ++++- audiosourcecoordinator.h | 4 +- audiosourcefile.cpp | 97 +++++++++- audiosourcefile.h | 7 + main.cpp | 2 +- mainwindow.cpp | 12 +- mainwindow.h | 4 + playerview.cpp | 371 ++++++++----------------------------- playerview.h | 82 ++++---- util.cpp | 10 + util.h | 2 + 12 files changed, 283 insertions(+), 361 deletions(-) diff --git a/audiosource.h b/audiosource.h index 2790a75..d26c00e 100644 --- a/audiosource.h +++ b/audiosource.h @@ -14,7 +14,7 @@ class AudioSource : public QObject signals: void playbackStateChanged(MediaPlayer::PlaybackState state); void positionChanged(qint64 progress); - void dataEmitted(const QByteArray& data); + void dataEmitted(const QByteArray& data, QAudioFormat format); void metadataChanged(QMediaMetaData metadata); void durationChanged(qint64 duration); void eqEnabledChanged(bool enabled); diff --git a/audiosourcecoordinator.cpp b/audiosourcecoordinator.cpp index b36009b..72a9b75 100644 --- a/audiosourcecoordinator.cpp +++ b/audiosourcecoordinator.cpp @@ -1,4 +1,5 @@ #include "audiosourcecoordinator.h" +#include "audiosourcefile.h" AudioSourceCoordinator::AudioSourceCoordinator(QObject *parent, PlayerView *playerView) : QObject{parent} @@ -6,10 +7,6 @@ AudioSourceCoordinator::AudioSourceCoordinator(QObject *parent, PlayerView *play system_audio = new SystemAudioControl(this); view = playerView; - // TODO instantiate sources - // TODO setSource - - /* view->setVolume(system_audio->getVolume()); connect(system_audio, &SystemAudioControl::volumeChanged, view, &PlayerView::setVolume); connect(view, &PlayerView::volumeChanged, this, &AudioSourceCoordinator::setVolume); @@ -17,18 +14,45 @@ AudioSourceCoordinator::AudioSourceCoordinator(QObject *parent, PlayerView *play view->setBalance(system_audio->getBalance()); connect(system_audio, &SystemAudioControl::balanceChanged, view, &PlayerView::setBalance); connect(view, &PlayerView::balanceChanged, this, &AudioSourceCoordinator::setBalance); - */ + } void AudioSourceCoordinator::setSource(int source) { // TODO - // deactivate old source - // disconnect slots + if(currentSource >= 0) { + // deactivate old source + sources[currentSource]->deactivate(); + + // disconnect slots + } + + currentSource = source; // connect slots to new source - // activate new source + connect(view, &PlayerView::positionChanged, sources[currentSource], &AudioSource::handleSeek); + connect(view, &PlayerView::previousClicked, sources[currentSource], &AudioSource::handlePrevious); + connect(view, &PlayerView::playClicked, sources[currentSource], &AudioSource::handlePlay); + connect(view, &PlayerView::pauseClicked, sources[currentSource], &AudioSource::handlePause); + connect(view, &PlayerView::stopClicked, sources[currentSource], &AudioSource::handleStop); + connect(view, &PlayerView::nextClicked, sources[currentSource], &AudioSource::handleNext); + connect(view, &PlayerView::openClicked, sources[currentSource], &AudioSource::handleOpen); + connect(view, &PlayerView::shuffleClicked, sources[currentSource], &AudioSource::handleShuffle); + connect(view, &PlayerView::repeatClicked, sources[currentSource], &AudioSource::handleRepeat); - this->currentSource = source; + connect(sources[currentSource], &AudioSource::playbackStateChanged, view, &PlayerView::setPlaybackState); + connect(sources[currentSource], &AudioSource::positionChanged, view, &PlayerView::setPosition); + connect(sources[currentSource], &AudioSource::dataEmitted, view, &PlayerView::setSpectrumData); + connect(sources[currentSource], &AudioSource::metadataChanged, view, &PlayerView::setMetadata); + connect(sources[currentSource], &AudioSource::durationChanged, view, &PlayerView::setDuration); + connect(sources[currentSource], &AudioSource::eqEnabledChanged, view, &PlayerView::setEqEnabled); + connect(sources[currentSource], &AudioSource::plEnabledChanged, view, &PlayerView::setPlEnabled); + connect(sources[currentSource], &AudioSource::shuffleEnabledChanged, view, &PlayerView::setShuffleEnabled); + connect(sources[currentSource], &AudioSource::repeatEnabledChanged, view, &PlayerView::setRepeatEnabled); + connect(sources[currentSource], &AudioSource::messageSet, view, &PlayerView::setMessage); + connect(sources[currentSource], &AudioSource::messageClear, view, &PlayerView::clearMessage); + + // activate new source + sources[currentSource]->activate(); } void AudioSourceCoordinator::setVolume(int volume) @@ -40,3 +64,12 @@ void AudioSourceCoordinator::setBalance(int balance) { system_audio->setBalance(balance); } + +void AudioSourceCoordinator::addSource(AudioSource *source, bool activate) +{ + // Instantiate sources + sources.append(source); + if(activate) { + setSource(sources.length() - 1); + } +} diff --git a/audiosourcecoordinator.h b/audiosourcecoordinator.h index 60d3f2b..e57288b 100644 --- a/audiosourcecoordinator.h +++ b/audiosourcecoordinator.h @@ -12,6 +12,8 @@ class AudioSourceCoordinator : public QObject public: explicit AudioSourceCoordinator(QObject *parent = nullptr, PlayerView *playerView = nullptr); + void addSource(AudioSource *source, bool activate = false); + signals: void sourceChanged(int source); @@ -22,7 +24,7 @@ public slots: private: QList sources; - int currentSource = 0; + int currentSource = -1; SystemAudioControl *system_audio = nullptr; PlayerView *view = nullptr; diff --git a/audiosourcefile.cpp b/audiosourcefile.cpp index a8df10a..80af838 100644 --- a/audiosourcefile.cpp +++ b/audiosourcefile.cpp @@ -1,5 +1,6 @@ #include #include +#include #include "audiosourcefile.h" #include "util.h" @@ -22,23 +23,23 @@ AudioSourceFile::AudioSourceFile(QObject *parent, PlaylistModel *playlistModel) m_playlist = m_playlistModel->playlist(); connect(m_playlist, &QMediaPlaylist::currentIndexChanged, this, - &PlayerView::playlistPositionChanged); + &AudioSourceFile::handlePlaylistPositionChanged); connect(m_playlist, &QMediaPlaylist::mediaAboutToBeRemoved, this, - &PlayerView::playlistMediaRemoved); + &AudioSourceFile::handlePlaylistMediaRemoved); connect(m_player, &MediaPlayer::playbackStateChanged, this, &AudioSourceFile::playbackStateChanged); // Emit data for spectrum analyzer - connect(m_player, &MediaPlayer::newData, this, &AudioSourceFile::dataEmitted); + connect(m_player, &MediaPlayer::newData, this, &AudioSourceFile::handleSpectrumData); } void AudioSourceFile::activate() { emit playbackStateChanged(m_player->playbackState()); - emit positionChanged(0); - // emit metadataChanged(...) TODO get current playlist file meta - // emit durationChanged(...) + emit positionChanged(m_player->position()); + emit metadataChanged(m_player->metaData()); + emit durationChanged(m_player->duration()); emit eqEnabledChanged(false); emit plEnabledChanged(true); emit shuffleEnabledChanged(shuffleEnabled); @@ -184,3 +185,87 @@ void AudioSourceFile::setStatusInfo(const QString &info) else emit messageClear(); } + +void AudioSourceFile::handlePlaylistPositionChanged(int) +{ + m_player->setSource(m_playlist->currentQueueMedia()); + + if (shouldBePlaying) { + m_player->play(); + } +} + +void AudioSourceFile::handlePlaylistMediaRemoved(int from, int to) +{ + // Stop only if currently playing file was removed + int playingIndex = m_playlist->currentIndex(); + if(playingIndex >= from && playingIndex <= to) { + shouldBePlaying = false; + m_player->stop(); + m_player->clearSource(); + } +} + +void AudioSourceFile::jump(const QModelIndex &index) +{ + if (index.isValid()) { + m_playlist->setCurrentIndex(index.row()); + shouldBePlaying = true; + m_player->play(); + } +} + +void AudioSourceFile::open() +{ + + /* + QList urls; + urls << QUrl::fromLocalFile(QStandardPaths::standardLocations(QStandardPaths::HomeLocation).first()) + << QUrl::fromLocalFile(QStandardPaths::standardLocations(QStandardPaths::DownloadLocation).first()) + << QUrl::fromLocalFile(QStandardPaths::standardLocations(QStandardPaths::MusicLocation).first()); + + + QFileDialog fileDialog(this); + QString filters = audioFileFilters().join(" "); + fileDialog.setNameFilter("Audio (" + filters + ")"); + fileDialog.setAcceptMode(QFileDialog::AcceptOpen); + fileDialog.setFileMode(QFileDialog::ExistingFiles); + fileDialog.setWindowTitle(tr("Open Files")); + fileDialog.setDirectory(QStandardPaths::standardLocations(QStandardPaths::MusicLocation) + .value(0, QDir::homePath())); + fileDialog.setOption(QFileDialog::ReadOnly, true); + fileDialog.setOption(QFileDialog::DontUseNativeDialog, true); + fileDialog.setViewMode(QFileDialog::Detail); + fileDialog.setSidebarUrls(urls); + +#ifdef IS_EMBEDDED + fileDialog.setWindowState(Qt::WindowFullScreen); +#endif + + if (fileDialog.exec() == QDialog::Accepted) + addToPlaylist(fileDialog.selectedUrls()); +*/ +} + +void AudioSourceFile::addToPlaylist(const QList &urls) +{ + const int previousMediaCount = m_playlist->mediaCount(); + for (auto &url : urls) { + if (isPlaylist(url)) + m_playlist->load(url); + else + m_playlist->addMedia(url); + } + if (m_playlist->mediaCount() > previousMediaCount) { + // Start playing only if not already playing + if(m_player->playbackState() == MediaPlayer::PlaybackState::StoppedState) { + auto index = m_playlistModel->index(previousMediaCount, 0); + jump(index); + } + } +} + +void AudioSourceFile::handleSpectrumData(const QByteArray& data) +{ + emit dataEmitted(data, m_player->format()); +} diff --git a/audiosourcefile.h b/audiosourcefile.h index b0bfab1..2d61d54 100644 --- a/audiosourcefile.h +++ b/audiosourcefile.h @@ -31,11 +31,18 @@ public slots: void jump(const QModelIndex &index); + void open(); + void addToPlaylist(const QList &urls); + private slots: void handleMetaDataChanged(); void handleMediaStatusChanged(MediaPlayer::MediaStatus status); void handleBufferingProgress(float progress); void handleMediaError(); + void handlePlaylistPositionChanged(int); + void handlePlaylistMediaRemoved(int, int); + void handleSpectrumData(const QByteArray& data); + private: MediaPlayer *m_player = nullptr; diff --git a/main.cpp b/main.cpp index e276c8f..ec26748 100644 --- a/main.cpp +++ b/main.cpp @@ -32,7 +32,7 @@ int main(int argc, char *argv[]) QList urls; for (auto &a : parser.positionalArguments()) urls.append(QUrl::fromUserInput(a, QDir::currentPath())); - window.player->addToPlaylist(urls); + //window.player->addToPlaylist(urls); } #ifdef IS_EMBEDDED diff --git a/mainwindow.cpp b/mainwindow.cpp index 2451d4c..478dc74 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -37,13 +37,17 @@ MainWindow::MainWindow(QWidget *parent) playlist = new PlaylistView(this, m_playlistModel); playlist->setAttribute(Qt::WidgetAttribute::WA_StyledBackground, true); + coordinator = new AudioSourceCoordinator(this, player); + fileSource = new AudioSourceFile(this, m_playlistModel); + coordinator->addSource(fileSource, true); + controlButtons = new ControlButtonsWidget(this); // Connect events connect(player, &PlayerView::showPlaylistClicked, this, &MainWindow::showPlaylist); connect(playlist, &PlaylistView::showPlayerClicked, this, &MainWindow::showPlayer); - connect(playlist, &PlaylistView::songSelected, player, &PlayerView::jump); - connect(playlist, &PlaylistView::addSelectedFilesClicked, player, &PlayerView::addToPlaylist); + connect(playlist, &PlaylistView::songSelected, fileSource, &AudioSourceFile::jump); + connect(playlist, &PlaylistView::addSelectedFilesClicked, fileSource, &AudioSourceFile::addToPlaylist); connect(controlButtons, &ControlButtonsWidget::playClicked, player, &PlayerView::playClicked); connect(controlButtons, &ControlButtonsWidget::pauseClicked, player, &PlayerView::pauseClicked); @@ -51,8 +55,8 @@ MainWindow::MainWindow(QWidget *parent) connect(controlButtons, &ControlButtonsWidget::nextClicked, player, &PlayerView::nextClicked); connect(controlButtons, &ControlButtonsWidget::previousClicked, player, &PlayerView::previousClicked); connect(controlButtons, &ControlButtonsWidget::openClicked, player, &PlayerView::showPlaylistClicked); - connect(controlButtons, &ControlButtonsWidget::repeatClicked, player, &PlayerView::repeatButtonClicked); - connect(controlButtons, &ControlButtonsWidget::shuffleClicked, player, &PlayerView::shuffleButtonClicked); + //TOSO connect(controlButtons, &ControlButtonsWidget::repeatClicked, player, &PlayerView::repeatButtonClicked); + //TODO connect(controlButtons, &ControlButtonsWidget::shuffleClicked, player, &PlayerView::shuffleButtonClicked); connect(controlButtons, &ControlButtonsWidget::logoClicked, this, &MainWindow::showShutdownModal); // Prepare player main view diff --git a/mainwindow.h b/mainwindow.h index a6c832d..1cc4434 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -4,6 +4,8 @@ #include #include #include +#include "audiosourcecoordinator.h" +#include "audiosourcefile.h" #include "controlbuttonswidget.h" #include "playerview.h" #include "playlistview.h" @@ -22,6 +24,8 @@ class MainWindow : public QMainWindow PlayerView *player; ControlButtonsWidget *controlButtons; PlaylistView *playlist; + AudioSourceCoordinator *coordinator; + AudioSourceFile *fileSource; public slots: void showPlayer(); diff --git a/playerview.cpp b/playerview.cpp index 52deeb7..fe4f000 100644 --- a/playerview.cpp +++ b/playerview.cpp @@ -2,7 +2,6 @@ #include "ui_playerview.h" #include "playlistmodel.h" -#include "qmediaplaylist.h" #include "scale.h" #include "util.h" @@ -25,68 +24,41 @@ PlayerView::PlayerView(QWidget *parent, PlaylistModel *playlistModel) : // Load custom fonts QFontDatabase::addApplicationFont(":/assets/bignumbers.ttf"); - m_system_audio = new SystemAudioControl(this); - // Setup UI ui->setupUi(this); scale(); - //! [create-objs] - m_player = new MediaPlayer(this); + // Setup spectrum analyzer spectrum = new SpectrumWidget(this); - //! [create-objs] - connect(m_player, &MediaPlayer::durationChanged, this, &PlayerView::durationChanged); - connect(m_player, &MediaPlayer::positionChanged, this, &PlayerView::positionChanged); - connect(m_player, QOverload<>::of(&MediaPlayer::metaDataChanged), this, - &PlayerView::metaDataChanged); - connect(m_player, &MediaPlayer::mediaStatusChanged, this, &PlayerView::statusChanged); - connect(m_player, &MediaPlayer::bufferProgressChanged, this, &PlayerView::bufferingProgress); - connect(m_player, &MediaPlayer::errorChanged, this, &PlayerView::displayErrorMessage); - - m_playlistModel = playlistModel; - m_playlist = m_playlistModel->playlist(); - //! [2] - connect(m_playlist, &QMediaPlaylist::currentIndexChanged, this, - &PlayerView::playlistPositionChanged); - connect(m_playlist, &QMediaPlaylist::mediaAboutToBeRemoved, this, - &PlayerView::playlistMediaRemoved); // duration slider and label - ui->posBar->setRange(0, m_player->duration()); - connect(ui->posBar, &QSlider::sliderMoved, this, &PlayerView::seek); + ui->posBar->setRange(0, 0); + connect(ui->posBar, &QSlider::sliderMoved, this, &PlayerView::positionChanged); // Set volume slider ui->volumeSlider->setRange(0, 100); - this->setVolumeSlider(m_system_audio->getVolume()); - connect(m_system_audio, &SystemAudioControl::volumeChanged, this, &PlayerView::setVolumeSlider); + connect(ui->volumeSlider, &QSlider::valueChanged, this, &PlayerView::volumeChanged); // Set Balance Slider ui->balanceSlider->setRange(-100, 100); - this->setBalanceSlider(m_system_audio->getBalance()); - connect(m_system_audio, &SystemAudioControl::balanceChanged, this, &PlayerView::setBalanceSlider); + connect(ui->balanceSlider, &QSlider::valueChanged, this, &PlayerView::handleBalanceChanged); // Reset time counter ui->progressTimeLabel->setText(""); // Set play status icon - setPlaybackState(m_player->playbackState()); + setPlaybackState(MediaPlayer::StoppedState); - connect(ui->volumeSlider, &QSlider::valueChanged, this, &PlayerView::volumeChanged); - connect(ui->balanceSlider, &QSlider::valueChanged, this, &PlayerView::balanceChanged); + connect(ui->playlistButton, &QCheckBox::clicked, this, &PlayerView::plClicked); connect(ui->playlistButton, &QCheckBox::clicked, this, &PlayerView::showPlaylistClicked); - connect(m_player, &MediaPlayer::playbackStateChanged, this, &PlayerView::setPlaybackState); - //connect(m_player, &MediaPlayer::volumeChanged, this, &PlayerView::setVolumeSlider); - // Setup spectrum widget - connect(m_player, &MediaPlayer::newData, this, &PlayerView::handleSpectrumData); QVBoxLayout *spectrumLayout = new QVBoxLayout; spectrumLayout->addWidget(spectrum); spectrumLayout->setContentsMargins(0, 0, 0, 0); spectrumLayout->setSpacing(0); ui->spectrumContainer->setLayout(spectrumLayout); - metaDataChanged(); } PlayerView::~PlayerView() @@ -179,70 +151,34 @@ void PlayerView::scale() ui->spectrumContainer->setGeometry(scGeo.x()*UI_SCALE, scGeo.y()*UI_SCALE, scGeo.width()*UI_SCALE, scGeo.height()*UI_SCALE); } -void PlayerView::open() -{ - - QList urls; - urls << QUrl::fromLocalFile(QStandardPaths::standardLocations(QStandardPaths::HomeLocation).first()) - << QUrl::fromLocalFile(QStandardPaths::standardLocations(QStandardPaths::DownloadLocation).first()) - << QUrl::fromLocalFile(QStandardPaths::standardLocations(QStandardPaths::MusicLocation).first()); - - - QFileDialog fileDialog(this); - QString filters = audioFileFilters().join(" "); - fileDialog.setNameFilter("Audio (" + filters + ")"); - fileDialog.setAcceptMode(QFileDialog::AcceptOpen); - fileDialog.setFileMode(QFileDialog::ExistingFiles); - fileDialog.setWindowTitle(tr("Open Files")); - fileDialog.setDirectory(QStandardPaths::standardLocations(QStandardPaths::MusicLocation) - .value(0, QDir::homePath())); - fileDialog.setOption(QFileDialog::ReadOnly, true); - fileDialog.setOption(QFileDialog::DontUseNativeDialog, true); - fileDialog.setViewMode(QFileDialog::Detail); - fileDialog.setSidebarUrls(urls); - - #ifdef IS_EMBEDDED - fileDialog.setWindowState(Qt::WindowFullScreen); - #endif - - if (fileDialog.exec() == QDialog::Accepted) - addToPlaylist(fileDialog.selectedUrls()); -} - -static bool isPlaylist(const QUrl &url) // Check for ".m3u" playlists. -{ - if (!url.isLocalFile()) - return false; - const QFileInfo fileInfo(url.toLocalFile()); - return fileInfo.exists() - && !fileInfo.suffix().compare(QLatin1String("m3u"), Qt::CaseInsensitive); -} - -void PlayerView::addToPlaylist(const QList &urls) +void PlayerView::setPlaybackState(MediaPlayer::PlaybackState state) { - const int previousMediaCount = m_playlist->mediaCount(); - for (auto &url : urls) { - if (isPlaylist(url)) - m_playlist->load(url); - else - m_playlist->addMedia(url); - } - if (m_playlist->mediaCount() > previousMediaCount) { - // Start playing only if not already playing - if(m_player->playbackState() == MediaPlayer::PlaybackState::StoppedState) { - auto index = m_playlistModel->index(previousMediaCount, 0); - jump(index); - } + QString imageSrc; + switch(state) { + case MediaPlayer::StoppedState: + if(spectrum) spectrum->stop(); + imageSrc = ":/assets/status_stopped.png"; + break; + case MediaPlayer::PlayingState: + if(spectrum) spectrum->play(); + imageSrc = ":/assets/status_playing.png"; + break; + case MediaPlayer::PausedState: + if(spectrum) spectrum->pause(); + imageSrc = ":/assets/status_paused.png"; + break; } -} -void PlayerView::durationChanged(qint64 duration) -{ - m_duration = duration / 1000; - ui->posBar->setMaximum(duration); + // Set play status icon + QPixmap image; + image.load(imageSrc); + QGraphicsScene *scene = new QGraphicsScene(this); + scene->addPixmap(image); + scene->setSceneRect(image.rect()); + ui->playStatusIcon->setScene(scene); } -void PlayerView::positionChanged(qint64 progress) +void PlayerView::setPosition(qint64 progress) { if (!ui->posBar->isSliderDown()) ui->posBar->setValue(progress); @@ -250,17 +186,20 @@ void PlayerView::positionChanged(qint64 progress) updateDurationInfo(progress / 1000); } -void PlayerView::metaDataChanged() +void PlayerView::setSpectrumData(const QByteArray& data, QAudioFormat format) { - auto metaData = m_player->metaData(); + spectrum->setData(data, format); +} +void PlayerView::setMetadata(QMediaMetaData metadata) +{ // Generate track info string - QString artist = metaData.value(QMediaMetaData::AlbumArtist).toString().toUpper(); - QString album = metaData.value(QMediaMetaData::AlbumTitle).toString().toUpper(); - QString title = metaData.value(QMediaMetaData::Title).toString().toUpper(); + QString artist = metadata.value(QMediaMetaData::AlbumArtist).toString().toUpper(); + QString album = metadata.value(QMediaMetaData::AlbumTitle).toString().toUpper(); + QString title = metadata.value(QMediaMetaData::Title).toString().toUpper(); // Calculate duration - qint64 ms = metaData.value(QMediaMetaData::Duration).toLongLong(); + qint64 ms = metadata.value(QMediaMetaData::Duration).toLongLong(); qint64 duration = ms/1000; QTime totalTime((duration / 3600) % 60, (duration / 60) % 60, duration % 60, (duration * 1000) % 1000); @@ -276,180 +215,66 @@ void PlayerView::metaDataChanged() setTrackInfo(trackInfo); // Set kbps - int bitrate = metaData.value(QMediaMetaData::AudioBitRate).toInt()/1000; + int bitrate = metadata.value(QMediaMetaData::AudioBitRate).toInt()/1000; ui->kbpsValueLabel->setText(bitrate > 0 ? QString::number(bitrate) : ""); // Set kHz - int khz = metaData.value(QMediaMetaData::AudioCodec).toInt()/1000; + int khz = metadata.value(QMediaMetaData::AudioCodec).toInt()/1000; ui->khzValueLabel->setText(khz > 0 ? QString::number(khz) : ""); } -void PlayerView::previousClicked() -{ - // Go to previous track if we are within the first 5 seconds of playback - // Otherwise, seek to the beginning. - if (m_player->position() <= 5000) { - handlePrevious(); - } else { - m_player->setPosition(0); - } -} - -void PlayerView::nextClicked() -{ - handleNext(); -} - -void PlayerView::playClicked() -{ - shouldBePlaying = true; - m_player->play(); -} - -void PlayerView::pauseClicked() -{ - shouldBePlaying = false; - m_player->pause(); -} - -void PlayerView::stopClicked() -{ - shouldBePlaying = false; - m_player->stop(); -} - -void PlayerView::repeatButtonClicked(bool checked) -{ - repeatEnabled = checked; - QMediaPlaylist::PlaybackMode mode = QMediaPlaylist::PlaybackMode::Sequential; - if(repeatEnabled) mode = QMediaPlaylist::PlaybackMode::Loop; - m_playlist->setPlaybackMode(mode); -} - -void PlayerView::shuffleButtonClicked(bool checked) -{ - shuffleEnabled = checked; - m_playlist->setShuffle(shuffleEnabled); -} - -void PlayerView::jump(const QModelIndex &index) -{ - if (index.isValid()) { - m_playlist->setCurrentIndex(index.row()); - shouldBePlaying = true; - m_player->play(); - } -} - -void PlayerView::playlistPositionChanged(int) +void PlayerView::setDuration(qint64 duration) { - m_player->setSource(m_playlist->currentQueueMedia()); - - if (shouldBePlaying) { - m_player->play(); - } + m_duration = duration / 1000; + ui->posBar->setMaximum(duration); } -void PlayerView::playlistMediaRemoved(int from, int to) +void PlayerView::setVolume(int volume) { - // Stop only if currently playing file was removed - int playingIndex = m_playlist->currentIndex(); - if(playingIndex >= from && playingIndex <= to) { - shouldBePlaying = false; - m_player->stop(); - m_player->clearSource(); - } + ui->volumeSlider->setValue(volume); } -void PlayerView::seek(int mseconds) +void PlayerView::setBalance(int balance) { - m_player->setPosition(mseconds); + ui->balanceSlider->setValue(balance); } -void PlayerView::statusChanged(MediaPlayer::MediaStatus status) +void PlayerView::setEqEnabled(bool enabled) { - handleCursor(status); - - // handle status message - switch (status) { - case MediaPlayer::NoMedia: - case MediaPlayer::LoadedMedia: - setStatusInfo(QString()); - break; - case MediaPlayer::LoadingMedia: - setStatusInfo(tr("Loading...")); - break; - case MediaPlayer::BufferingMedia: - case MediaPlayer::BufferedMedia: - setStatusInfo(tr("Buffering %1%").arg(qRound(m_player->bufferProgress() * 100.))); - break; - case MediaPlayer::StalledMedia: - setStatusInfo(tr("Stalled %1%").arg(qRound(m_player->bufferProgress() * 100.))); - break; - case MediaPlayer::EndOfMedia: - QApplication::alert(this); - handleNext(); - break; - case MediaPlayer::InvalidMedia: - displayErrorMessage(); - break; - } + eqEnabled = enabled; + ui->eqButton->setChecked(eqEnabled); } -void PlayerView::handleCursor(MediaPlayer::MediaStatus status) +void PlayerView::setPlEnabled(bool enabled) { -#ifndef QT_NO_CURSOR - if (status == MediaPlayer::LoadingMedia || status == MediaPlayer::BufferingMedia - || status == MediaPlayer::StalledMedia) - setCursor(QCursor(Qt::BusyCursor)); - else - unsetCursor(); -#endif + plEnabled = enabled; + ui->playlistButton->setChecked(plEnabled); } -void PlayerView::bufferingProgress(float progress) +void PlayerView::setShuffleEnabled(bool enabled) { - if (m_player->mediaStatus() == MediaPlayer::StalledMedia) - setStatusInfo(tr("Stalled %1%").arg(qRound(progress * 100.))); - else - setStatusInfo(tr("Buffering %1%").arg(qRound(progress * 100.))); + shuffleEnabled = enabled; + // TODO set controlbuttonswidget shuffle button state } -void PlayerView::handleSpectrumData(const QByteArray& data) +void PlayerView::setRepeatEnabled(bool enabled) { - spectrum->setData(data, m_player->format()); + repeatEnabled = enabled; + // TODO set controlbuttonswidget repeat button state } - -void PlayerView::setTrackInfo(const QString &info) +void PlayerView::setMessage(QString message, qint64 timeout) { - m_trackInfo = info; - - ui->songInfoLabel->setText(info); - - if (!m_statusInfo.isEmpty()) - setWindowTitle(QString("%1 | %2").arg(m_trackInfo, m_statusInfo)); - else - setWindowTitle(m_trackInfo); + //ui->songInfoLabel->setText(message); + // TODO timeout } -void PlayerView::setStatusInfo(const QString &info) +void PlayerView::clearMessage() { - m_statusInfo = info; - - if (!m_statusInfo.isEmpty()) - setWindowTitle(QString("%1 | %2").arg(m_trackInfo, m_statusInfo)); - else - setWindowTitle(m_trackInfo); + ui->songInfoLabel->setText(m_trackInfo); } -void PlayerView::displayErrorMessage() -{ - if (m_player->error() == MediaPlayer::NoError) - return; - setStatusInfo(m_player->errorString()); - qDebug() << m_player->errorString(); -} +///////////// void PlayerView::updateDurationInfo(qint64 currentInfo) { @@ -464,22 +289,19 @@ void PlayerView::updateDurationInfo(qint64 currentInfo) ui->progressTimeLabel->setText(tDisplayStr); } -void PlayerView::setVolumeSlider(int volume) +void PlayerView::setTrackInfo(const QString &info) { - ui->volumeSlider->setValue(volume); -} + m_trackInfo = info; -void PlayerView::setBalanceSlider(int balance) -{ - ui->balanceSlider->setValue(balance); -} + ui->songInfoLabel->setText(info); -void PlayerView::volumeChanged() -{ - m_system_audio->setVolume(ui->volumeSlider->value()); + if (!m_statusInfo.isEmpty()) + setWindowTitle(QString("%1 | %2").arg(m_trackInfo, m_statusInfo)); + else + setWindowTitle(m_trackInfo); } -void PlayerView::balanceChanged() +void PlayerView::handleBalanceChanged() { // Snap slider to the center if it falls near to it int val = ui->balanceSlider->value(); @@ -487,48 +309,5 @@ void PlayerView::balanceChanged() val = 0; ui->balanceSlider->setValue(val); } - m_system_audio->setBalance(val); -} - -void PlayerView::handlePrevious() -{ - // If is first item in playlist, do nothing - // That's handled by QMediaPlaylist - m_playlist->previous(); -} - -void PlayerView::handleNext() -{ - // If is last item in playlist: - // If repeat enabled, go to first - // If not, do nothing - // That's handled by QMediaPlaylist - m_playlist->next(); -} - -void PlayerView::setPlaybackState(MediaPlayer::PlaybackState state) -{ - QString imageSrc; - switch(state) { - case MediaPlayer::StoppedState: - if(spectrum) spectrum->stop(); - imageSrc = ":/assets/status_stopped.png"; - break; - case MediaPlayer::PlayingState: - if(spectrum) spectrum->play(); - imageSrc = ":/assets/status_playing.png"; - break; - case MediaPlayer::PausedState: - if(spectrum) spectrum->pause(); - imageSrc = ":/assets/status_paused.png"; - break; - } - - // Set play status icon - QPixmap image; - image.load(imageSrc); - QGraphicsScene *scene = new QGraphicsScene(this); - scene->addPixmap(image); - scene->setSceneRect(image.rect()); - ui->playStatusIcon->setScene(scene); + emit balanceChanged(val); } diff --git a/playerview.h b/playerview.h index 6718e28..f8b7fa4 100644 --- a/playerview.h +++ b/playerview.h @@ -1,11 +1,9 @@ #ifndef PLAYERVIEW_H #define PLAYERVIEW_H -#include "qmediaplaylist.h" #include "playlistmodel.h" #include "mediaplayer.h" #include "spectrumwidget.h" -#include "systemaudiocontrol.h" #include #include @@ -34,64 +32,62 @@ class PlayerView : public QWidget ~PlayerView(); public slots: - void setVolumeSlider(int volume); - void setBalanceSlider(int balance); - void jump(const QModelIndex &index); - void open(); - void addToPlaylist(const QList &urls); + void setPlaybackState(MediaPlayer::PlaybackState state); + void setPosition(qint64 progress); + void setSpectrumData(const QByteArray& data, QAudioFormat format); + void setMetadata(QMediaMetaData metadata); + void setDuration(qint64 duration); + void setVolume(int volume); + void setBalance(int balance); + void setEqEnabled(bool enabled); + void setPlEnabled(bool enabled); + void setShuffleEnabled(bool enabled); + void setRepeatEnabled(bool enabled); + void setMessage(QString message, qint64 timeout); + void clearMessage(); +signals: + void volumeChanged(int volume); + void balanceChanged(int balance); + void positionChanged(qint64 progress); + void eqClicked(); + void plClicked(); void previousClicked(); - void nextClicked(); void playClicked(); void pauseClicked(); void stopClicked(); - void repeatButtonClicked(bool checked); - void shuffleButtonClicked(bool checked); - -private slots: - void durationChanged(qint64 duration); - void positionChanged(qint64 progress); - void metaDataChanged(); - - void seek(int mseconds); - void playlistPositionChanged(int); - void playlistMediaRemoved(int, int); - - void statusChanged(MediaPlayer::MediaStatus status); - void bufferingProgress(float progress); - void handleSpectrumData(const QByteArray& data); - - void displayErrorMessage(); - -signals: - void showPlaylistClicked(); + void nextClicked(); + void openClicked(); + void shuffleClicked(); + void repeatClicked(); + void menuClicked(); private: Ui::PlayerView *ui; void scale(); SpectrumWidget *spectrum = nullptr; - void setTrackInfo(const QString &info); - void setStatusInfo(const QString &info); - void setPlaybackState(MediaPlayer::PlaybackState state); - void handleCursor(MediaPlayer::MediaStatus status); - void updateDurationInfo(qint64 currentInfo); - void volumeChanged(); - void balanceChanged(); - void handlePrevious(); - void handleNext(); - MediaPlayer *m_player = nullptr; - QMediaPlaylist *m_playlist = nullptr; - SystemAudioControl *m_system_audio = nullptr; - - PlaylistModel *m_playlistModel = nullptr; QString m_trackInfo; QString m_statusInfo; qint64 m_duration; + bool plEnabled = false; + bool eqEnabled = false; bool shuffleEnabled = false; bool repeatEnabled = false; - bool shouldBePlaying = false; + + void updateDurationInfo(qint64 currentInfo); + void setTrackInfo(const QString &info); + +private slots: + void handleBalanceChanged(); + + ////////// + + +signals: + void showPlaylistClicked(); + }; #endif // PLAYERVIEW_H diff --git a/util.cpp b/util.cpp index 8f2e2c6..4a8ed3e 100644 --- a/util.cpp +++ b/util.cpp @@ -1,5 +1,6 @@ #include "util.h" #include "qdatetime.h" +#include "qfileinfo.h" #include #include @@ -89,3 +90,12 @@ bool isAudioFile(QString path) return false; } + +bool isPlaylist(const QUrl &url) +{ + if (!url.isLocalFile()) + return false; + const QFileInfo fileInfo(url.toLocalFile()); + return fileInfo.exists() + && !fileInfo.suffix().compare(QLatin1String("m3u"), Qt::CaseInsensitive); +} diff --git a/util.h b/util.h index 8791346..099456e 100644 --- a/util.h +++ b/util.h @@ -12,4 +12,6 @@ QStringList audioFileFilters(); bool isAudioFile(QString path); +bool isPlaylist(const QUrl &url); // Check for ".m3u" playlists. + #endif // UTIL_H