From 32f01b03bdbce5624874413246c08d042998468b Mon Sep 17 00:00:00 2001 From: Bart De Vries Date: Tue, 13 Apr 2021 20:51:00 +0200 Subject: [PATCH] Enable next button in Player This functionality has safeguards built in, including a canGoNext property. This can be extended with streaming playing in the future. --- src/audiomanager.cpp | 39 ++++++++++++++++++++++++++++++++++++++ src/audiomanager.h | 10 ++++++++++ src/enclosure.cpp | 5 +++++ src/enclosure.h | 4 ++-- src/qml/PlayerControls.qml | 3 ++- 5 files changed, 58 insertions(+), 3 deletions(-) diff --git a/src/audiomanager.cpp b/src/audiomanager.cpp index 65e7bfd4..17e27409 100644 --- a/src/audiomanager.cpp +++ b/src/audiomanager.cpp @@ -164,6 +164,7 @@ QMediaPlayer::MediaStatus AudioManager::status() const void AudioManager::setEntry(Entry* entry) { if (entry != nullptr) { + // TODO: here is a good spot to check if the previous track was (nearly) finished, so it can be removed if needed qDebug() << "Going to change source"; d->m_lockPositionSaving = true; d->m_entry = entry; @@ -210,6 +211,7 @@ void AudioManager::setEntry(Entry* entry) Q_EMIT canPauseChanged(); Q_EMIT canSkipForwardChanged(); Q_EMIT canSkipBackwardChanged(); + Q_EMIT canGoNextChanged(); d->m_isSeekable = true; Q_EMIT seekableChanged(true); } else { @@ -218,6 +220,7 @@ void AudioManager::setEntry(Entry* entry) Q_EMIT canPauseChanged(); Q_EMIT canSkipForwardChanged(); Q_EMIT canSkipBackwardChanged(); + Q_EMIT canGoNextChanged(); d->m_isSeekable = false; Q_EMIT seekableChanged(false); } @@ -319,9 +322,45 @@ void AudioManager::skipBackward() seek(std::max((qint64)0, (position() - SKIP_STEP))); } +bool AudioManager::canGoNext() const +{ + int index = DataManager::instance().getQueue().indexOf(d->m_entry->id()); + if (index >= 0) { + // check if there is a next track + if (index < DataManager::instance().getQueue().count()-1) { + Entry* next_entry = DataManager::instance().getEntry(DataManager::instance().getQueue()[index+1]); + if (next_entry->enclosure()) { + if (next_entry->enclosure()->status() == Enclosure::Downloaded) { + return true; + } + } + } + } + return false; +} + +void AudioManager::next() +{ + QMediaPlayer::State currentState = playbackState(); + // TODO: needs to be more complicated; what if track has not been downloaded and streaming is not allowed; probably needs a canGoNext routine + // go to next track in playlist + int index = DataManager::instance().getQueue().indexOf(d->m_entry->id()); + if (canGoNext()) { + setEntry(DataManager::instance().getEntry(DataManager::instance().getQueue()[index+1])); + if (currentState == QMediaPlayer::PlayingState) play(); + } else { + setEntry(nullptr); + } +} + void AudioManager::mediaStatusChanged() { qDebug() << "AudioManager::mediaStatusChanged" << d->m_player.mediaStatus(); + + // File has reached the end and has stopped + if (d->m_player.mediaStatus() == QMediaPlayer::EndOfMedia) { + + } } void AudioManager::playerStateChanged() diff --git a/src/audiomanager.h b/src/audiomanager.h index 595f5f69..6d72c549 100644 --- a/src/audiomanager.h +++ b/src/audiomanager.h @@ -81,6 +81,10 @@ class AudioManager : public QObject READ seekable NOTIFY seekableChanged) + Q_PROPERTY(bool canGoNext + READ canGoNext + NOTIFY canGoNextChanged) + public: explicit AudioManager(QObject *parent = nullptr); @@ -129,6 +133,8 @@ public: [[nodiscard]] bool canSkipBackward() const; + [[nodiscard]] bool canGoNext() const; + Q_SIGNALS: void playerOpenChanged(bool state); @@ -169,6 +175,8 @@ Q_SIGNALS: void canSkipBackwardChanged(); + void canGoNextChanged(); + public Q_SLOTS: void setEntry(Entry* entry); @@ -199,6 +207,8 @@ public Q_SLOTS: void skipForward(); + void next(); + private Q_SLOTS: void mediaStatusChanged(); diff --git a/src/enclosure.cpp b/src/enclosure.cpp index dc5dacb1..2e300265 100644 --- a/src/enclosure.cpp +++ b/src/enclosure.cpp @@ -130,6 +130,11 @@ QString Enclosure::path() const return Fetcher::instance().enclosurePath(m_url); } +Enclosure::Status Enclosure::status() const +{ + return m_status; +} + qint64 Enclosure::playPosition() const{ return m_playposition; } diff --git a/src/enclosure.h b/src/enclosure.h index b2e9ae56..4da38bf0 100644 --- a/src/enclosure.h +++ b/src/enclosure.h @@ -23,7 +23,7 @@ class Enclosure : public QObject Q_PROPERTY(QString title MEMBER m_title CONSTANT) Q_PROPERTY(QString type MEMBER m_type CONSTANT) Q_PROPERTY(QString url MEMBER m_url CONSTANT) - Q_PROPERTY(Status status MEMBER m_status NOTIFY statusChanged) + Q_PROPERTY(Status status READ status NOTIFY statusChanged) Q_PROPERTY(double downloadProgress MEMBER m_downloadProgress NOTIFY downloadProgressChanged) Q_PROPERTY(QString path READ path CONSTANT) Q_PROPERTY(qint64 playPosition READ playPosition WRITE setPlayPosition NOTIFY playPositionChanged) @@ -43,8 +43,8 @@ public: Q_INVOKABLE void deleteFile(); QString path() const; + Status status() const; qint64 playPosition() const; - void setPlayPosition(const qint64 &position); Q_SIGNALS: diff --git a/src/qml/PlayerControls.qml b/src/qml/PlayerControls.qml index d9801b7e..7d124abf 100644 --- a/src/qml/PlayerControls.qml +++ b/src/qml/PlayerControls.qml @@ -199,7 +199,8 @@ Kirigami.Page { icon.width: parent.buttonsize flat: true Layout.alignment: Qt.AlignHCenter - onClicked: console.log("Next track to be implemented") + onClicked: audio.next() + enabled: audio.canGoNext } } }