diff --git a/src/manageaudioplayer.cpp b/src/manageaudioplayer.cpp index 2bba52c8..dec2672b 100644 --- a/src/manageaudioplayer.cpp +++ b/src/manageaudioplayer.cpp @@ -1,568 +1,577 @@ /* * Copyright 2016 Matthieu Gallien * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "manageaudioplayer.h" #include "mediaplaylist.h" #include ManageAudioPlayer::ManageAudioPlayer(QObject *parent) : QObject(parent) { } QPersistentModelIndex ManageAudioPlayer::currentTrack() const { return mCurrentTrack; } QAbstractItemModel *ManageAudioPlayer::playListModel() const { return mPlayListModel; } int ManageAudioPlayer::urlRole() const { return mUrlRole; } int ManageAudioPlayer::isPlayingRole() const { return mIsPlayingRole; } QUrl ManageAudioPlayer::playerSource() const { if (!mCurrentTrack.isValid()) { return QUrl(); } return mCurrentTrack.data(mUrlRole).toUrl(); } QMediaPlayer::MediaStatus ManageAudioPlayer::playerStatus() const { return mPlayerStatus; } int ManageAudioPlayer::playerPlaybackState() const { return mPlayerPlaybackState; } QMediaPlayer::Error ManageAudioPlayer::playerError() const { return mPlayerError; } int ManageAudioPlayer::audioDuration() const { return mAudioDuration; } bool ManageAudioPlayer::playerIsSeekable() const { return mPlayerIsSeekable; } int ManageAudioPlayer::playerPosition() const { return mPlayerPosition; } int ManageAudioPlayer::playControlPosition() const { return mPlayerPosition; } QVariantMap ManageAudioPlayer::persistentState() const { auto persistentStateValue = QVariantMap(); persistentStateValue[QStringLiteral("isPlaying")] = mPlayingState; persistentStateValue[QStringLiteral("playerPosition")] = mPlayerPosition; if (mCurrentTrack.isValid()) { persistentStateValue[QStringLiteral("audioPlayerCurrentTitle")] = mCurrentTrack.data(mTitleRole); persistentStateValue[QStringLiteral("audioPlayerCurrentArtistName")] = mCurrentTrack.data(mArtistNameRole); persistentStateValue[QStringLiteral("audioPlayerCurrentAlbumName")] = mCurrentTrack.data(mAlbumNameRole); } else { persistentStateValue[QStringLiteral("audioPlayerCurrentTitle")] = {}; persistentStateValue[QStringLiteral("audioPlayerCurrentArtistName")] = {}; persistentStateValue[QStringLiteral("audioPlayerCurrentAlbumName")] = {}; } return persistentStateValue; } int ManageAudioPlayer::playListPosition() const { if (mCurrentTrack.isValid()) { return mCurrentTrack.row(); } return 0; } int ManageAudioPlayer::titleRole() const { return mTitleRole; } int ManageAudioPlayer::artistNameRole() const { return mArtistNameRole; } int ManageAudioPlayer::albumNameRole() const { return mAlbumNameRole; } void ManageAudioPlayer::setCurrentTrack(const QPersistentModelIndex ¤tTrack) { mOldCurrentTrack = mCurrentTrack; mCurrentTrack = currentTrack; if (mCurrentTrack.isValid()) { restorePreviousState(); } mPlayerError = QMediaPlayer::NoError; if (mOldCurrentTrack != mCurrentTrack || mPlayingState) { Q_EMIT currentTrackChanged(); } switch (mPlayerPlaybackState) { case StoppedState: notifyPlayerSourceProperty(); break; case PlayingState: case PausedState: triggerStop(); if (mPlayingState && !mCurrentTrack.isValid()) { mPlayingState = false; } mSkippingCurrentTrack = true; break; } } void ManageAudioPlayer::setPlayListModel(QAbstractItemModel *aPlayListModel) { if (mPlayListModel == aPlayListModel) { return; } if (mPlayListModel) { disconnect(mPlayListModel, &QAbstractItemModel::dataChanged, this, &ManageAudioPlayer::tracksDataChanged); } mPlayListModel = aPlayListModel; if (mPlayListModel) { connect(mPlayListModel, &QAbstractItemModel::dataChanged, this, &ManageAudioPlayer::tracksDataChanged); } Q_EMIT playListModelChanged(); } void ManageAudioPlayer::setUrlRole(int value) { mUrlRole = value; Q_EMIT urlRoleChanged(); notifyPlayerSourceProperty(); restorePreviousState(); } void ManageAudioPlayer::setIsPlayingRole(int value) { if (mIsPlayingRole == value) { return; } mIsPlayingRole = value; Q_EMIT isPlayingRoleChanged(); } void ManageAudioPlayer::setPlayerStatus(QMediaPlayer::MediaStatus playerStatus) { if (mPlayerStatus == playerStatus) { return; } if (playerStatus < static_cast(QMediaPlayer::UnknownMediaStatus) || playerStatus > static_cast(QMediaPlayer::InvalidMedia)) { return; } mPlayerStatus = static_cast(playerStatus); Q_EMIT playerStatusChanged(); switch (mPlayerStatus) { case QMediaPlayer::NoMedia: break; case QMediaPlayer::LoadingMedia: break; case QMediaPlayer::LoadedMedia: if (mPlayingState) { triggerPlay(); } break; case QMediaPlayer::BufferingMedia: break; case QMediaPlayer::StalledMedia: break; case QMediaPlayer::BufferedMedia: break; case QMediaPlayer::EndOfMedia: break; case QMediaPlayer::InvalidMedia: triggerSkipNextTrack(); break; case QMediaPlayer::UnknownMediaStatus: break; } } void ManageAudioPlayer::setPlayerPlaybackState(int playerPlaybackState) { if (mPlayerPlaybackState == playerPlaybackState) { return; } if (playerPlaybackState < static_cast(StoppedState) || playerPlaybackState > static_cast(PausedState)) { return; } mPlayerPlaybackState = static_cast(playerPlaybackState); Q_EMIT playerPlaybackStateChanged(); if (!mSkippingCurrentTrack) { switch(mPlayerPlaybackState) { case StoppedState: if (mPlayerStatus == QMediaPlayer::EndOfMedia || mPlayerStatus == QMediaPlayer::InvalidMedia) { triggerSkipNextTrack(); } if (mPlayListModel && mCurrentTrack.isValid()) { mPlayListModel->setData(mCurrentTrack, MediaPlayList::NotPlaying, mIsPlayingRole); } break; case PlayingState: if (mPlayListModel && mCurrentTrack.isValid()) { mPlayListModel->setData(mCurrentTrack, MediaPlayList::IsPlaying, mIsPlayingRole); } break; case PausedState: if (mPlayListModel && mCurrentTrack.isValid()) { mPlayListModel->setData(mCurrentTrack, MediaPlayList::IsPaused, mIsPlayingRole); } break; } } else { switch(mPlayerPlaybackState) { case StoppedState: if (mCurrentTrack != mOldCurrentTrack) { notifyPlayerSourceProperty(); } mSkippingCurrentTrack = false; if (mPlayListModel && mOldCurrentTrack.isValid()) { mPlayListModel->setData(mOldCurrentTrack, MediaPlayList::NotPlaying, mIsPlayingRole); } break; case PlayingState: if (mPlayListModel && mCurrentTrack.isValid()) { mPlayListModel->setData(mCurrentTrack, MediaPlayList::IsPlaying, mIsPlayingRole); } break; case PausedState: if (mPlayListModel && mCurrentTrack.isValid()) { mPlayListModel->setData(mCurrentTrack, MediaPlayList::IsPaused, mIsPlayingRole); } break; } } } void ManageAudioPlayer::setPlayerError(QMediaPlayer::Error playerError) { if (mPlayerError == playerError) { return; } mPlayerError = playerError; Q_EMIT playerErrorChanged(); if (mPlayerError != QMediaPlayer::NoError) { auto currentSource = playerSource(); Q_EMIT sourceInError(currentSource, mPlayerError); if (currentSource.isLocalFile()) { Q_EMIT displayTrackError(currentSource.toLocalFile()); } else { Q_EMIT displayTrackError(currentSource.toString()); } } } +void ManageAudioPlayer::ensurePause() +{ + if (mPlayingState) { + mPlayingState = false; + triggerPause(); + } +} + void ManageAudioPlayer::ensurePlay() { if (!mPlayingState) { - playPause(); + mPlayingState = true; + triggerPlay(); } } void ManageAudioPlayer::playPause() { mPlayingState = !mPlayingState; switch (mPlayerStatus) { case QMediaPlayer::LoadedMedia: case QMediaPlayer::BufferingMedia: case QMediaPlayer::BufferedMedia: case QMediaPlayer::LoadingMedia: if (mPlayingState) { triggerPlay(); } else { triggerPause(); } break; case QMediaPlayer::EndOfMedia: if (mPlayerPlaybackState == PlayingState && !mPlayingState) { triggerPause(); } else if (mPlayerPlaybackState == PausedState && mPlayingState) { triggerPlay(); } break; case QMediaPlayer::NoMedia: case QMediaPlayer::StalledMedia: case QMediaPlayer::InvalidMedia: case QMediaPlayer::UnknownMediaStatus: break; } } void ManageAudioPlayer::setAudioDuration(int audioDuration) { if (mAudioDuration == audioDuration) { return; } mAudioDuration = audioDuration; Q_EMIT audioDurationChanged(); } void ManageAudioPlayer::setPlayerIsSeekable(bool playerIsSeekable) { if (mPlayerIsSeekable == playerIsSeekable) { return; } mPlayerIsSeekable = playerIsSeekable; Q_EMIT playerIsSeekableChanged(); } void ManageAudioPlayer::setPlayerPosition(int playerPosition) { if (mPlayerPosition == playerPosition) { return; } mPlayerPosition = playerPosition; Q_EMIT playerPositionChanged(); QTimer::singleShot(0, [this]() {Q_EMIT playControlPositionChanged();}); } void ManageAudioPlayer::setPlayControlPosition(int playerPosition) { Q_EMIT seek(playerPosition); } void ManageAudioPlayer::setPersistentState(const QVariantMap &persistentStateValue) { if (mPersistentState == persistentStateValue) { return; } mPersistentState = persistentStateValue; Q_EMIT persistentStateChanged(); if (mCurrentTrack.isValid()) { restorePreviousState(); } } void ManageAudioPlayer::playerSeek(int position) { Q_EMIT seek(position); } void ManageAudioPlayer::playListFinished() { mPlayingState = false; } void ManageAudioPlayer::tracksDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector &roles) { if (!mCurrentTrack.isValid()) { return; } if (mCurrentTrack.row() > bottomRight.row() || mCurrentTrack.row() < topLeft.row()) { return; } if (mCurrentTrack.column() > bottomRight.column() || mCurrentTrack.column() < topLeft.column()) { return; } if (roles.isEmpty()) { notifyPlayerSourceProperty(); restorePreviousState(); } else { for(auto oneRole : roles) { if (oneRole == mUrlRole) { notifyPlayerSourceProperty(); restorePreviousState(); } } } } void ManageAudioPlayer::setTitleRole(int titleRole) { if (mTitleRole == titleRole) { return; } mTitleRole = titleRole; Q_EMIT titleRoleChanged(); if (mCurrentTrack.isValid()) { restorePreviousState(); } } void ManageAudioPlayer::setArtistNameRole(int artistNameRole) { if (mArtistNameRole == artistNameRole) { return; } mArtistNameRole = artistNameRole; Q_EMIT artistNameRoleChanged(); if (mCurrentTrack.isValid()) { restorePreviousState(); } } void ManageAudioPlayer::setAlbumNameRole(int albumNameRole) { if (mAlbumNameRole == albumNameRole) { return; } mAlbumNameRole = albumNameRole; Q_EMIT albumNameRoleChanged(); if (mCurrentTrack.isValid()) { restorePreviousState(); } } void ManageAudioPlayer::notifyPlayerSourceProperty() { auto newUrlValue = mCurrentTrack.data(mUrlRole); if ((mCurrentTrack == mOldCurrentTrack && mOldPlayerSource == newUrlValue && mPlayingState) || mOldPlayerSource != newUrlValue) { Q_EMIT playerSourceChanged(); mOldPlayerSource = newUrlValue; } } void ManageAudioPlayer::triggerPlay() { QTimer::singleShot(0, [this]() {Q_EMIT playerPlay();}); } void ManageAudioPlayer::triggerPause() { QTimer::singleShot(0, [this]() {Q_EMIT playerPause();}); } void ManageAudioPlayer::triggerStop() { QTimer::singleShot(0, [this]() {Q_EMIT playerStop();}); } void ManageAudioPlayer::triggerSkipNextTrack() { QTimer::singleShot(0, [this]() {Q_EMIT skipNextTrack();}); } void ManageAudioPlayer::restorePreviousState() { if (mPersistentState.isEmpty()) { return; } auto itTitle = mPersistentState.find(QStringLiteral("audioPlayerCurrentTitle")); auto itArtistName = mPersistentState.find(QStringLiteral("audioPlayerCurrentArtistName")); auto itAlbumName = mPersistentState.find(QStringLiteral("audioPlayerCurrentAlbumName")); if (itTitle == mPersistentState.end() || itArtistName == mPersistentState.end() || itAlbumName == mPersistentState.end()) { return; } if (*itTitle != mCurrentTrack.data(mTitleRole) || *itArtistName != mCurrentTrack.data(mArtistNameRole) || *itAlbumName != mCurrentTrack.data(mAlbumNameRole)) { if (mCurrentTrack.isValid() && mCurrentTrack.data(mTitleRole).isValid() && mCurrentTrack.data(mArtistNameRole).isValid() && mCurrentTrack.data(mAlbumNameRole).isValid()) { mPersistentState.clear(); } return; } if (!mCurrentTrack.data(mUrlRole).toUrl().isValid()) { return; } auto isPlaying = mPersistentState.find(QStringLiteral("isPlaying")); if (isPlaying != mPersistentState.end() && mPlayingState != isPlaying->toBool()) { mPlayingState = isPlaying->toBool(); } auto playerPosition = mPersistentState.find(QStringLiteral("playerPosition")); if (playerPosition != mPersistentState.end()) { mPlayerPosition = playerPosition->toInt(); Q_EMIT seek(mPlayerPosition); } mPersistentState.clear(); } #include "moc_manageaudioplayer.cpp" diff --git a/src/manageaudioplayer.h b/src/manageaudioplayer.h index c32995fc..7e570d30 100644 --- a/src/manageaudioplayer.h +++ b/src/manageaudioplayer.h @@ -1,300 +1,302 @@ /* * Copyright 2016 Matthieu Gallien * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef MANAGEAUDIOPLAYER_H #define MANAGEAUDIOPLAYER_H #include #include #include #include #include class ManageAudioPlayer : public QObject { Q_OBJECT Q_PROPERTY(QPersistentModelIndex currentTrack READ currentTrack WRITE setCurrentTrack NOTIFY currentTrackChanged) Q_PROPERTY(QAbstractItemModel* playListModel READ playListModel WRITE setPlayListModel NOTIFY playListModelChanged) Q_PROPERTY(QUrl playerSource READ playerSource NOTIFY playerSourceChanged) Q_PROPERTY(int titleRole READ titleRole WRITE setTitleRole NOTIFY titleRoleChanged) Q_PROPERTY(int artistNameRole READ artistNameRole WRITE setArtistNameRole NOTIFY artistNameRoleChanged) Q_PROPERTY(int albumNameRole READ albumNameRole WRITE setAlbumNameRole NOTIFY albumNameRoleChanged) Q_PROPERTY(int urlRole READ urlRole WRITE setUrlRole NOTIFY urlRoleChanged) Q_PROPERTY(int isPlayingRole READ isPlayingRole WRITE setIsPlayingRole NOTIFY isPlayingRoleChanged) Q_PROPERTY(QMediaPlayer::MediaStatus playerStatus READ playerStatus WRITE setPlayerStatus NOTIFY playerStatusChanged) Q_PROPERTY(int playerPlaybackState READ playerPlaybackState WRITE setPlayerPlaybackState NOTIFY playerPlaybackStateChanged) Q_PROPERTY(QMediaPlayer::Error playerError READ playerError WRITE setPlayerError NOTIFY playerErrorChanged) Q_PROPERTY(int audioDuration READ audioDuration WRITE setAudioDuration NOTIFY audioDurationChanged) Q_PROPERTY(bool playerIsSeekable READ playerIsSeekable WRITE setPlayerIsSeekable NOTIFY playerIsSeekableChanged) Q_PROPERTY(int playerPosition READ playerPosition WRITE setPlayerPosition NOTIFY playerPositionChanged) Q_PROPERTY(int playControlPosition READ playControlPosition WRITE setPlayControlPosition NOTIFY playControlPositionChanged) Q_PROPERTY(QVariantMap persistentState READ persistentState WRITE setPersistentState NOTIFY persistentStateChanged) public: enum PlayerPlaybackState { PlayingState = 1, PausedState = 2, StoppedState = 0, }; Q_ENUM(PlayerPlaybackState) explicit ManageAudioPlayer(QObject *parent = nullptr); QPersistentModelIndex currentTrack() const; QAbstractItemModel* playListModel() const; int urlRole() const; int isPlayingRole() const; QUrl playerSource() const; QMediaPlayer::MediaStatus playerStatus() const; int playerPlaybackState() const; QMediaPlayer::Error playerError() const; int audioDuration() const; bool playerIsSeekable() const; int playerPosition() const; int playControlPosition() const; QVariantMap persistentState() const; int playListPosition() const; int titleRole() const; int artistNameRole() const; int albumNameRole() const; Q_SIGNALS: void currentTrackChanged(); void playListModelChanged(); void playerSourceChanged(); void urlRoleChanged(); void isPlayingRoleChanged(); void playerStatusChanged(); void playerPlaybackStateChanged(); void playerErrorChanged(); void playerPlay(); void playerPause(); void playerStop(); void skipNextTrack(); void audioDurationChanged(); void playerIsSeekableChanged(); void playerPositionChanged(); void playControlPositionChanged(); void persistentStateChanged(); void seek(int position); void titleRoleChanged(); void artistNameRoleChanged(); void albumNameRoleChanged(); void sourceInError(QUrl source, QMediaPlayer::Error playerError); void displayTrackError(const QString &fileName); public Q_SLOTS: void setCurrentTrack(const QPersistentModelIndex ¤tTrack); void setPlayListModel(QAbstractItemModel* aPlayListModel); void setUrlRole(int value); void setIsPlayingRole(int value); void setPlayerStatus(QMediaPlayer::MediaStatus playerStatus); void setPlayerPlaybackState(int playerPlaybackState); void setPlayerError(QMediaPlayer::Error playerError); + void ensurePause(); + void ensurePlay(); void playPause(); void setAudioDuration(int audioDuration); void setPlayerIsSeekable(bool playerIsSeekable); void setPlayerPosition(int playerPosition); void setPlayControlPosition(int playerPosition); void setPersistentState(const QVariantMap &persistentStateValue); void playerSeek(int position); void playListFinished(); void tracksDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector &roles); void setTitleRole(int titleRole); void setArtistNameRole(int artistNameRole); void setAlbumNameRole(int albumNameRole); private: void notifyPlayerSourceProperty(); void triggerPlay(); void triggerPause(); void triggerStop(); void triggerSkipNextTrack(); void restorePreviousState(); QPersistentModelIndex mCurrentTrack; QPersistentModelIndex mOldCurrentTrack; QAbstractItemModel *mPlayListModel = nullptr; int mTitleRole = Qt::DisplayRole; int mArtistNameRole = Qt::DisplayRole; int mAlbumNameRole = Qt::DisplayRole; int mUrlRole = Qt::DisplayRole; int mIsPlayingRole = Qt::DisplayRole; QVariant mOldPlayerSource; QMediaPlayer::MediaStatus mPlayerStatus = QMediaPlayer::NoMedia; PlayerPlaybackState mPlayerPlaybackState = StoppedState; QMediaPlayer::Error mPlayerError = QMediaPlayer::NoError; bool mPlayingState = false; bool mSkippingCurrentTrack = false; int mAudioDuration = 0; bool mPlayerIsSeekable = false; int mPlayerPosition = 0; QVariantMap mPersistentState; }; #endif // MANAGEAUDIOPLAYER_H diff --git a/src/mpris2/mediaplayer2player.cpp b/src/mpris2/mediaplayer2player.cpp index 8fca0169..9cb37127 100644 --- a/src/mpris2/mediaplayer2player.cpp +++ b/src/mpris2/mediaplayer2player.cpp @@ -1,412 +1,412 @@ /*************************************************************************** * Copyright 2014 Sujith Haridasan * * Copyright 2014 Ashish Madeti * * Copyright 2016 Matthieu Gallien * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * ***************************************************************************/ #include "mediaplayer2player.h" #include "mpris2.h" #include "mediaplaylist.h" #include "manageaudioplayer.h" #include "managemediaplayercontrol.h" #include "manageheaderbar.h" #include "audiowrapper.h" #include #include #include #include #include #include static const double MAX_RATE = 1.0; static const double MIN_RATE = 1.0; MediaPlayer2Player::MediaPlayer2Player(MediaPlayList *playListControler, ManageAudioPlayer *manageAudioPlayer, ManageMediaPlayerControl *manageMediaPlayerControl, ManageHeaderBar *manageHeaderBar, AudioWrapper *audioPlayer, QObject* parent) : QDBusAbstractAdaptor(parent), m_playListControler(playListControler), m_manageAudioPlayer(manageAudioPlayer), m_manageMediaPlayerControl(manageMediaPlayerControl), m_manageHeaderBar(manageHeaderBar), m_audioPlayer(audioPlayer) { if (!m_playListControler) { return; } connect(m_manageAudioPlayer, &ManageAudioPlayer::playerSourceChanged, this, &MediaPlayer2Player::playerSourceChanged, Qt::QueuedConnection); connect(m_manageMediaPlayerControl, &ManageMediaPlayerControl::playControlEnabledChanged, this, &MediaPlayer2Player::playControlEnabledChanged); connect(m_manageMediaPlayerControl, &ManageMediaPlayerControl::skipBackwardControlEnabledChanged, this, &MediaPlayer2Player::skipBackwardControlEnabledChanged); connect(m_manageMediaPlayerControl, &ManageMediaPlayerControl::skipForwardControlEnabledChanged, this, &MediaPlayer2Player::skipForwardControlEnabledChanged); connect(m_manageAudioPlayer, &ManageAudioPlayer::playerPlaybackStateChanged, this, &MediaPlayer2Player::playerPlaybackStateChanged); connect(m_manageAudioPlayer, &ManageAudioPlayer::playerIsSeekableChanged, this, &MediaPlayer2Player::playerIsSeekableChanged); connect(m_manageAudioPlayer, &ManageAudioPlayer::playerPositionChanged, this, &MediaPlayer2Player::audioPositionChanged); connect(m_manageAudioPlayer, &ManageAudioPlayer::audioDurationChanged, this, &MediaPlayer2Player::audioDurationChanged); connect(m_audioPlayer, &AudioWrapper::volumeChanged, this, &MediaPlayer2Player::playerVolumeChanged); m_volume = m_audioPlayer->volume(); signalPropertiesChange(QStringLiteral("Volume"), Volume()); m_mediaPlayerPresent = 1; } MediaPlayer2Player::~MediaPlayer2Player() = default; QString MediaPlayer2Player::PlaybackStatus() const { QString result; if (!m_playListControler) { result = QStringLiteral("Stopped"); return result; } if (m_manageAudioPlayer->playerPlaybackState() == ManageAudioPlayer::StoppedState) { result = QStringLiteral("Stopped"); } else if (m_manageAudioPlayer->playerPlaybackState() == ManageAudioPlayer::PlayingState) { result = QStringLiteral("Playing"); } else { result = QStringLiteral("Paused"); } return result; } bool MediaPlayer2Player::CanGoNext() const { return m_canGoNext; } void MediaPlayer2Player::Next() { emit next(); if (m_playListControler) { m_playListControler->skipNextTrack(); } } bool MediaPlayer2Player::CanGoPrevious() const { return m_canGoPrevious; } void MediaPlayer2Player::Previous() { emit previous(); if (m_playListControler) { m_playListControler->skipPreviousTrack(); } } bool MediaPlayer2Player::CanPause() const { return m_canPlay; } void MediaPlayer2Player::Pause() { if (m_playListControler) { - m_manageAudioPlayer->playerPause(); + m_manageAudioPlayer->ensurePause(); } } void MediaPlayer2Player::PlayPause() { emit playPause(); if (m_playListControler) { m_manageAudioPlayer->playPause(); } } void MediaPlayer2Player::Stop() { emit stop(); } bool MediaPlayer2Player::CanPlay() const { return m_canPlay; } void MediaPlayer2Player::Play() { if (m_playListControler) { m_manageAudioPlayer->playPause(); } } double MediaPlayer2Player::Volume() const { return m_volume; } void MediaPlayer2Player::setVolume(double volume) { m_volume= qBound(0.0, volume, 1.0); emit volumeChanged(m_volume); m_audioPlayer->setVolume(100 * m_volume); signalPropertiesChange(QStringLiteral("Volume"), Volume()); } QVariantMap MediaPlayer2Player::Metadata() const { return m_metadata; } qlonglong MediaPlayer2Player::Position() const { return m_position; } void MediaPlayer2Player::setPropertyPosition(int newPositionInMs) { m_position = qlonglong(newPositionInMs) * 1000; signalPropertiesChange(QStringLiteral("Position"), Position()); Q_EMIT Seeked(m_position); } double MediaPlayer2Player::Rate() const { return m_rate; } void MediaPlayer2Player::setRate(double newRate) { if (newRate == 0) { Pause(); } else { m_rate = qBound(MinimumRate(), newRate, MaximumRate()); emit rateChanged(m_rate); signalPropertiesChange(QStringLiteral("Rate"), Rate()); } } double MediaPlayer2Player::MinimumRate() const { return MIN_RATE; } double MediaPlayer2Player::MaximumRate() const { return MAX_RATE; } bool MediaPlayer2Player::CanSeek() const { return m_playerIsSeekableChanged; } bool MediaPlayer2Player::CanControl() const { return true; } void MediaPlayer2Player::Seek(qlonglong Offset) { if (mediaPlayerPresent()) { int offset = (m_position + Offset) / 1000; m_manageAudioPlayer->playerSeek(offset); } } void MediaPlayer2Player::emitSeeked(int pos) { emit Seeked(qlonglong(pos) * 1000); } void MediaPlayer2Player::SetPosition(const QDBusObjectPath &trackId, qlonglong pos) { if (trackId.path() == m_currentTrackId) { m_manageAudioPlayer->playerSeek(pos / 1000); } } void MediaPlayer2Player::OpenUri(const QString &uri) { Q_UNUSED(uri); } void MediaPlayer2Player::playerSourceChanged() { if (!m_playListControler) { return; } setCurrentTrack(m_manageAudioPlayer->playListPosition()); } void MediaPlayer2Player::playControlEnabledChanged() { if (!m_playListControler) { return; } m_canPlay = m_manageMediaPlayerControl->playControlEnabled(); signalPropertiesChange(QStringLiteral("CanPause"), CanPause()); signalPropertiesChange(QStringLiteral("CanPlay"), CanPlay()); emit canPauseChanged(); emit canPlayChanged(); } void MediaPlayer2Player::skipBackwardControlEnabledChanged() { if (!m_playListControler) { return; } m_canGoPrevious = m_manageMediaPlayerControl->skipBackwardControlEnabled(); signalPropertiesChange(QStringLiteral("CanGoPrevious"), CanGoPrevious()); emit canGoPreviousChanged(); } void MediaPlayer2Player::skipForwardControlEnabledChanged() { if (!m_playListControler) { return; } m_canGoNext = m_manageMediaPlayerControl->skipForwardControlEnabled(); signalPropertiesChange(QStringLiteral("CanGoNext"), CanGoNext()); emit canGoNextChanged(); } void MediaPlayer2Player::playerPlaybackStateChanged() { signalPropertiesChange(QStringLiteral("PlaybackStatus"), PlaybackStatus()); emit playbackStatusChanged(); playerIsSeekableChanged(); } void MediaPlayer2Player::playerIsSeekableChanged() { m_playerIsSeekableChanged = m_manageAudioPlayer->playerIsSeekable(); signalPropertiesChange(QStringLiteral("CanSeek"), CanSeek()); emit canSeekChanged(); } void MediaPlayer2Player::audioPositionChanged() { setPropertyPosition(m_manageAudioPlayer->playerPosition()); } void MediaPlayer2Player::audioDurationChanged() { m_metadata = getMetadataOfCurrentTrack(); signalPropertiesChange(QStringLiteral("Metadata"), Metadata()); skipBackwardControlEnabledChanged(); skipForwardControlEnabledChanged(); playerPlaybackStateChanged(); playerIsSeekableChanged(); setPropertyPosition(m_manageAudioPlayer->playerPosition()); } void MediaPlayer2Player::playerVolumeChanged() { setVolume(m_audioPlayer->volume() / 100.0); } int MediaPlayer2Player::currentTrack() const { return m_manageAudioPlayer->playListPosition(); } void MediaPlayer2Player::setCurrentTrack(int newTrackPosition) { m_currentTrack = m_manageAudioPlayer->playerSource().toString(); m_currentTrackId = QDBusObjectPath(QStringLiteral("/org/kde/elisa/playlist/") + QString::number(newTrackPosition)).path(); emit currentTrackChanged(); } QVariantMap MediaPlayer2Player::getMetadataOfCurrentTrack() { auto result = QVariantMap(); result[QStringLiteral("mpris:trackid")] = QVariant::fromValue(QDBusObjectPath(m_currentTrackId)); result[QStringLiteral("mpris:length")] = qlonglong(m_manageAudioPlayer->audioDuration()) * 1000; //convert milli-seconds into micro-seconds result[QStringLiteral("xesam:title")] = m_manageHeaderBar->title(); result[QStringLiteral("xesam:url")] = m_manageAudioPlayer->playerSource().toString(); result[QStringLiteral("xesam:album")] = m_manageHeaderBar->album(); result[QStringLiteral("xesam:artist")] = QStringList{m_manageHeaderBar->artist().toString()}; result[QStringLiteral("mpris:artUrl")] = m_manageHeaderBar->image().toString(); return result; } int MediaPlayer2Player::mediaPlayerPresent() const { return m_mediaPlayerPresent; } void MediaPlayer2Player::setMediaPlayerPresent(int status) { if (m_mediaPlayerPresent != status) { m_mediaPlayerPresent = status; emit mediaPlayerPresentChanged(); signalPropertiesChange(QStringLiteral("CanGoNext"), CanGoNext()); signalPropertiesChange(QStringLiteral("CanGoPrevious"), CanGoPrevious()); signalPropertiesChange(QStringLiteral("CanPause"), CanPause()); signalPropertiesChange(QStringLiteral("CanPlay"), CanPlay()); emit canGoNextChanged(); emit canGoPreviousChanged(); emit canPauseChanged(); emit canPlayChanged(); } } void MediaPlayer2Player::signalPropertiesChange(const QString &property, const QVariant &value) { QVariantMap properties; properties[property] = value; const int ifaceIndex = metaObject()->indexOfClassInfo("D-Bus Interface"); QDBusMessage msg = QDBusMessage::createSignal(QStringLiteral("/org/mpris/MediaPlayer2"), QStringLiteral("org.freedesktop.DBus.Properties"), QStringLiteral("PropertiesChanged")); msg << QLatin1String(metaObject()->classInfo(ifaceIndex).value()); msg << properties; msg << QStringList(); QDBusConnection::sessionBus().send(msg); } #include "moc_mediaplayer2player.cpp"