mirror of https://github.com/KDE/kasts.git
[KMediaSession] Only send MRPIS2 positionChanged signal on seek
Stop spamming the DBus with positionChanged signals if playback is progressing at the nominal playback rate. This brings the implementation in line with the MPRIS2 player spec. The previous implementation was causing android battery drain issues with KDEConnect constantly updating the position (and player details) on the notification widget. This implementation will still send the current playback position every 10 seconds to ensure that clients that don't implement the standard properly or did not receive previous messages, will still get regularly updated. This also fixes correct signaling of playback rate changes over DBus.
This commit is contained in:
parent
52e074e266
commit
eac74ecbbb
|
@ -224,12 +224,12 @@ qreal AudioManager::playbackRate() const
|
|||
|
||||
qreal AudioManager::minimumPlaybackRate() const
|
||||
{
|
||||
return MIN_RATE;
|
||||
return d->m_player.minimumPlaybackRate();
|
||||
}
|
||||
|
||||
qreal AudioManager::maximumPlaybackRate() const
|
||||
{
|
||||
return MAX_RATE;
|
||||
return d->m_player.maximumPlaybackRate();
|
||||
}
|
||||
|
||||
bool AudioManager::isStreaming() const
|
||||
|
|
|
@ -51,8 +51,6 @@ class AudioManager : public QObject
|
|||
Q_PROPERTY(bool isStreaming READ isStreaming NOTIFY isStreamingChanged)
|
||||
|
||||
public:
|
||||
const double MAX_RATE = 1.0;
|
||||
const double MIN_RATE = 2.5;
|
||||
const qint64 SKIP_TRACK_END = 15000;
|
||||
|
||||
static AudioManager &instance()
|
||||
|
|
|
@ -193,6 +193,18 @@ qreal KMediaSession::playbackRate() const
|
|||
return 1.0;
|
||||
}
|
||||
|
||||
qreal KMediaSession::minimumPlaybackRate() const
|
||||
{
|
||||
qCDebug(KMediaSessionLog) << "KMediaSession::minimumPlayBackRate()";
|
||||
return MIN_RATE;
|
||||
}
|
||||
|
||||
qreal KMediaSession::maximumPlaybackRate() const
|
||||
{
|
||||
qCDebug(KMediaSessionLog) << "KMediaSession::maximumPlayBackRate()";
|
||||
return MAX_RATE;
|
||||
}
|
||||
|
||||
KMediaSession::Error KMediaSession::error() const
|
||||
{
|
||||
qCDebug(KMediaSessionLog) << "KMediaSession::error()";
|
||||
|
@ -404,6 +416,7 @@ void KMediaSession::setPosition(qint64 position)
|
|||
d->m_player->setPosition(position);
|
||||
QTimer::singleShot(0, this, [this, position]() {
|
||||
Q_EMIT positionChanged(position);
|
||||
Q_EMIT positionJumped(position);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -412,7 +425,11 @@ void KMediaSession::setPlaybackRate(qreal rate)
|
|||
{
|
||||
qCDebug(KMediaSessionLog) << "KMediaSession::setPlaybackRate(" << rate << ")";
|
||||
if (d->m_player) {
|
||||
d->m_player->setPlaybackRate(rate);
|
||||
qreal clippedRate = rate > MAX_RATE ? MAX_RATE : (rate < MIN_RATE ? MIN_RATE : rate);
|
||||
d->m_player->setPlaybackRate(clippedRate);
|
||||
QTimer::singleShot(0, this, [this, clippedRate]() {
|
||||
Q_EMIT playbackRateChanged(clippedRate);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -49,6 +49,9 @@ class KMEDIASESSION_EXPORT KMediaSession : public QObject
|
|||
Q_PROPERTY(bool canGoPrevious READ canGoPrevious WRITE setCanGoPrevious NOTIFY canGoPreviousChanged)
|
||||
|
||||
public:
|
||||
const double MAX_RATE = 3.0;
|
||||
const double MIN_RATE = 0.1;
|
||||
|
||||
enum MediaBackends {
|
||||
Qt = 0,
|
||||
Vlc = 1,
|
||||
|
@ -103,6 +106,8 @@ public:
|
|||
[[nodiscard]] KMediaSession::MediaStatus mediaStatus() const;
|
||||
[[nodiscard]] KMediaSession::PlaybackState playbackState() const;
|
||||
[[nodiscard]] qreal playbackRate() const;
|
||||
[[nodiscard]] qreal minimumPlaybackRate() const;
|
||||
[[nodiscard]] qreal maximumPlaybackRate() const;
|
||||
[[nodiscard]] KMediaSession::Error error() const;
|
||||
[[nodiscard]] qint64 duration() const;
|
||||
[[nodiscard]] qint64 position() const;
|
||||
|
@ -130,7 +135,8 @@ Q_SIGNALS:
|
|||
void playbackRateChanged(qreal rate);
|
||||
void errorChanged(KMediaSession::Error error);
|
||||
void durationChanged(qint64 duration);
|
||||
void positionChanged(qint64 position);
|
||||
void positionChanged(qint64 position); // emitted constantly while playing
|
||||
void positionJumped(qint64 position); // emitted only if position jumps after explicit seek operation
|
||||
void seekableChanged(bool seekable);
|
||||
|
||||
void metaDataChanged(MetaData *metadata);
|
||||
|
|
|
@ -34,7 +34,6 @@ MediaPlayer2Player::MediaPlayer2Player(KMediaSession *audioPlayer, bool showProg
|
|||
connect(m_audioPlayer, &KMediaSession::sourceChanged, this, &MediaPlayer2Player::setSource);
|
||||
|
||||
// Signals from KMediaSession which are directly forwarded
|
||||
connect(m_audioPlayer, &KMediaSession::playbackRateChanged, this, &MediaPlayer2Player::rateChanged);
|
||||
// TODO: implement this in KMediaSession, such that it can be forwarded
|
||||
// connect(m_audioPlayer, &KMediaSession::minimumRateChanged,
|
||||
// this, &MediaPlayer2Player::mimimumRateChanged);
|
||||
|
@ -44,8 +43,9 @@ MediaPlayer2Player::MediaPlayer2Player(KMediaSession *audioPlayer, bool showProg
|
|||
|
||||
// Signals which are semi-wrapped signals from KMediaSession
|
||||
connect(m_audioPlayer, &KMediaSession::playbackStateChanged, this, &MediaPlayer2Player::playerPlaybackStateChanged);
|
||||
connect(m_audioPlayer, &KMediaSession::playbackRateChanged, this, &MediaPlayer2Player::playerPlaybackRateChanged);
|
||||
connect(m_audioPlayer, &KMediaSession::volumeChanged, this, &MediaPlayer2Player::playerVolumeChanged);
|
||||
connect(m_audioPlayer, &KMediaSession::positionChanged, this, &MediaPlayer2Player::playerSeeked); // Implement Seeked signal
|
||||
connect(m_audioPlayer, &KMediaSession::positionJumped, this, &MediaPlayer2Player::playerSeeked); // Implement Seeked signal
|
||||
|
||||
connect(m_audioPlayer, &KMediaSession::canPlayChanged, this, &MediaPlayer2Player::playerCanPlayChanged);
|
||||
connect(m_audioPlayer, &KMediaSession::canPauseChanged, this, &MediaPlayer2Player::playerCanPauseChanged);
|
||||
|
@ -252,6 +252,24 @@ double MediaPlayer2Player::Rate() const
|
|||
return 1.0;
|
||||
}
|
||||
|
||||
double MediaPlayer2Player::MinimumRate() const
|
||||
{
|
||||
qCDebug(Mpris2Log) << "MediaPlayer2Player::MinimumRate()";
|
||||
if (m_audioPlayer)
|
||||
return m_audioPlayer->minimumPlaybackRate();
|
||||
else
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
double MediaPlayer2Player::MaximumRate() const
|
||||
{
|
||||
qCDebug(Mpris2Log) << "MediaPlayer2Player::MaximumRate()";
|
||||
if (m_audioPlayer)
|
||||
return m_audioPlayer->maximumPlaybackRate();
|
||||
else
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
void MediaPlayer2Player::setRate(double newRate)
|
||||
{
|
||||
qCDebug(Mpris2Log) << "MediaPlayer2Player::setRate(" << newRate << ")";
|
||||
|
@ -311,6 +329,13 @@ void MediaPlayer2Player::playerPlaybackStateChanged()
|
|||
Q_EMIT playbackStatusChanged();
|
||||
}
|
||||
|
||||
void MediaPlayer2Player::playerPlaybackRateChanged()
|
||||
{
|
||||
qCDebug(Mpris2Log) << "MediaPlayer2Player::playerPlaybackRateChanged()";
|
||||
signalPropertiesChange(QStringLiteral("Rate"), Rate());
|
||||
// Q_EMIT rateChanged(Rate());
|
||||
}
|
||||
|
||||
void MediaPlayer2Player::playerSeeked(qint64 position)
|
||||
{
|
||||
qCDebug(Mpris2Log) << "MediaPlayer2Player::playerSeeked(" << position << ")";
|
||||
|
@ -323,6 +348,16 @@ void MediaPlayer2Player::audioPositionChanged()
|
|||
// for progress indicator on taskbar
|
||||
if (m_audioPlayer)
|
||||
setPropertyPosition(static_cast<int>(m_audioPlayer->position()));
|
||||
|
||||
// Occasionally send updated position through MPRIS to make sure that
|
||||
// audio position is still correct if playing without seeking for a long
|
||||
// time. This will also guarantee correct playback position if the MPRIS
|
||||
// client does not support non-standard playback rates
|
||||
qlonglong position = Position();
|
||||
if (abs(position - m_lastSentPosition) > 10000000) { // every 10 seconds
|
||||
m_lastSentPosition = position;
|
||||
Q_EMIT Seeked(position);
|
||||
}
|
||||
}
|
||||
|
||||
void MediaPlayer2Player::audioDurationChanged()
|
||||
|
|
|
@ -24,6 +24,8 @@ class MediaPlayer2Player : public QDBusAbstractAdaptor
|
|||
|
||||
Q_PROPERTY(QString PlaybackStatus READ PlaybackStatus NOTIFY playbackStatusChanged)
|
||||
Q_PROPERTY(double Rate READ Rate WRITE setRate NOTIFY rateChanged)
|
||||
Q_PROPERTY(double MinimumRate READ MinimumRate NOTIFY minimumRateChanged)
|
||||
Q_PROPERTY(double MaximumRate READ MaximumRate NOTIFY maximumRateChanged)
|
||||
Q_PROPERTY(QVariantMap Metadata READ Metadata NOTIFY playbackStatusChanged)
|
||||
Q_PROPERTY(double Volume READ Volume WRITE setVolume NOTIFY volumeChanged)
|
||||
Q_PROPERTY(qlonglong Position READ Position WRITE setPropertyPosition NOTIFY playbackStatusChanged)
|
||||
|
@ -40,6 +42,8 @@ public:
|
|||
|
||||
QString PlaybackStatus() const;
|
||||
double Rate() const;
|
||||
double MinimumRate() const;
|
||||
double MaximumRate() const;
|
||||
QVariantMap Metadata() const;
|
||||
double Volume() const;
|
||||
qlonglong Position() const;
|
||||
|
@ -56,6 +60,8 @@ Q_SIGNALS:
|
|||
void Seeked(qlonglong Position);
|
||||
|
||||
void rateChanged(double newRate);
|
||||
void minimumRateChanged(double minRate);
|
||||
void maximumRateChanged(double maxRate);
|
||||
void volumeChanged(double newVol);
|
||||
void playbackStatusChanged();
|
||||
void canGoNextChanged();
|
||||
|
@ -84,8 +90,8 @@ public Q_SLOTS:
|
|||
void OpenUri(const QString &uri);
|
||||
|
||||
private Q_SLOTS:
|
||||
|
||||
void playerPlaybackStateChanged();
|
||||
void playerPlaybackRateChanged();
|
||||
void playerSeeked(qint64 position);
|
||||
void playerVolumeChanged();
|
||||
void playerCanGoNextChanged();
|
||||
|
@ -118,4 +124,5 @@ private:
|
|||
int mPreviousProgressPosition = 0;
|
||||
bool mShowProgressOnTaskBar = true;
|
||||
qlonglong m_position = 0;
|
||||
qlonglong m_lastSentPosition = 0;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue