File indexing completed on 2025-03-23 04:34:33
0001 /** 0002 * SPDX-FileCopyrightText: 2018 Nicolas Fella <nicolas.fella@gmx.de> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 */ 0006 0007 #include "mprisremoteplayer.h" 0008 #include "mprisremoteplayermediaplayer2.h" 0009 #include "mprisremoteplayermediaplayer2player.h" 0010 #include "mprisremoteplugin.h" 0011 0012 #include <QDateTime> 0013 0014 #include <QUuid> 0015 #include <networkpacket.h> 0016 0017 MprisRemotePlayer::MprisRemotePlayer(QString id, MprisRemotePlugin *plugin) 0018 : QObject(plugin) 0019 , id(id) 0020 , m_playing(false) 0021 , m_canPlay(true) 0022 , m_canPause(true) 0023 , m_canGoPrevious(true) 0024 , m_canGoNext(true) 0025 , m_volume(50) 0026 , m_length(0) 0027 , m_lastPosition(0) 0028 , m_lastPositionTime() 0029 , m_title() 0030 , m_artist() 0031 , m_album() 0032 , m_canSeek(false) 0033 , m_dbusConnectionName(QStringLiteral("mpris_") + QUuid::createUuid().toString(QUuid::Id128)) 0034 , m_dbusConnection(QDBusConnection::connectToBus(QDBusConnection::SessionBus, m_dbusConnectionName)) 0035 { 0036 // Expose this player on the newly created connection. This allows multiple mpris services in the same Qt process 0037 new MprisRemotePlayerMediaPlayer2(this, plugin); 0038 new MprisRemotePlayerMediaPlayer2Player(this, plugin); 0039 0040 m_dbusConnection.registerObject(QStringLiteral("/org/mpris/MediaPlayer2"), this); 0041 // Make sure our service name is unique. Reuse the connection name for this. 0042 m_dbusConnection.registerService(QStringLiteral("org.mpris.MediaPlayer2.kdeconnect.") + m_dbusConnectionName); 0043 } 0044 0045 MprisRemotePlayer::~MprisRemotePlayer() 0046 { 0047 // Drop the DBus connection (it was only used for this class) 0048 QDBusConnection::disconnectFromBus(m_dbusConnectionName); 0049 } 0050 0051 void MprisRemotePlayer::parseNetworkPacket(const NetworkPacket &np) 0052 { 0053 bool trackInfoHasChanged = false; 0054 0055 // Track properties 0056 QString newTitle = np.get<QString>(QStringLiteral("title"), m_title); 0057 QString newArtist = np.get<QString>(QStringLiteral("artist"), m_artist); 0058 QString newAlbum = np.get<QString>(QStringLiteral("album"), m_album); 0059 int newLength = np.get<int>(QStringLiteral("length"), m_length); 0060 0061 // Check if they changed 0062 if (newTitle != m_title || newArtist != m_artist || newAlbum != m_album || newLength != m_length) { 0063 trackInfoHasChanged = true; 0064 m_title = newTitle; 0065 m_artist = newArtist; 0066 m_album = newAlbum; 0067 m_length = newLength; 0068 Q_EMIT trackInfoChanged(); 0069 } 0070 0071 // Check volume changes 0072 int newVolume = np.get<int>(QStringLiteral("volume"), m_volume); 0073 if (newVolume != m_volume) { 0074 m_volume = newVolume; 0075 Q_EMIT volumeChanged(); 0076 } 0077 0078 if (np.has(QStringLiteral("pos"))) { 0079 // Check position 0080 int newLastPosition = np.get<int>(QStringLiteral("pos"), m_lastPosition); 0081 int positionDiff = qAbs(position() - newLastPosition); 0082 m_lastPosition = newLastPosition; 0083 m_lastPositionTime = QDateTime::currentMSecsSinceEpoch(); 0084 0085 // Only consider it seeking if the position changed more than 1 second or the track has changed 0086 if (qAbs(positionDiff) >= 1000 || trackInfoHasChanged) { 0087 Q_EMIT positionChanged(); 0088 } 0089 } 0090 0091 // Check if we started/stopped playing 0092 bool newPlaying = np.get<bool>(QStringLiteral("isPlaying"), m_playing); 0093 if (newPlaying != m_playing) { 0094 m_playing = newPlaying; 0095 Q_EMIT playingChanged(); 0096 } 0097 0098 // Control properties 0099 bool newCanSeek = np.get<bool>(QStringLiteral("canSeek"), m_canSeek); 0100 bool newCanPlay = np.get<bool>(QStringLiteral("canPlay"), m_canPlay); 0101 bool newCanPause = np.get<bool>(QStringLiteral("canPause"), m_canPause); 0102 bool newCanGoPrevious = np.get<bool>(QStringLiteral("canGoPrevious"), m_canGoPrevious); 0103 bool newCanGoNext = np.get<bool>(QStringLiteral("canGoNext"), m_canGoNext); 0104 if (newCanSeek != m_canSeek || newCanPlay != m_canPlay || newCanPause != m_canPause || newCanGoPrevious != m_canGoPrevious || newCanGoNext != m_canGoNext) { 0105 m_canSeek = newCanSeek; 0106 m_canPlay = newCanPlay; 0107 m_canPause = newCanPause; 0108 m_canGoPrevious = newCanGoPrevious; 0109 m_canGoNext = newCanGoNext; 0110 Q_EMIT controlsChanged(); 0111 } 0112 } 0113 0114 long MprisRemotePlayer::position() const 0115 { 0116 if (m_playing) { 0117 return m_lastPosition + (QDateTime::currentMSecsSinceEpoch() - m_lastPositionTime); 0118 } else { 0119 return m_lastPosition; 0120 } 0121 } 0122 0123 void MprisRemotePlayer::setPosition(long position) 0124 { 0125 m_lastPosition = position; 0126 m_lastPositionTime = QDateTime::currentMSecsSinceEpoch(); 0127 } 0128 0129 int MprisRemotePlayer::volume() const 0130 { 0131 return m_volume; 0132 } 0133 0134 long int MprisRemotePlayer::length() const 0135 { 0136 return m_length; 0137 } 0138 0139 bool MprisRemotePlayer::playing() const 0140 { 0141 return m_playing; 0142 } 0143 0144 QString MprisRemotePlayer::title() const 0145 { 0146 return m_title; 0147 } 0148 0149 QString MprisRemotePlayer::artist() const 0150 { 0151 return m_artist; 0152 } 0153 0154 QString MprisRemotePlayer::album() const 0155 { 0156 return m_album; 0157 } 0158 0159 bool MprisRemotePlayer::canSeek() const 0160 { 0161 return m_canSeek; 0162 } 0163 0164 QString MprisRemotePlayer::identity() const 0165 { 0166 return id; 0167 } 0168 0169 bool MprisRemotePlayer::canPlay() const 0170 { 0171 return m_canPlay; 0172 } 0173 0174 bool MprisRemotePlayer::canPause() const 0175 { 0176 return m_canPause; 0177 } 0178 0179 bool MprisRemotePlayer::canGoPrevious() const 0180 { 0181 return m_canGoPrevious; 0182 } 0183 0184 bool MprisRemotePlayer::canGoNext() const 0185 { 0186 return m_canGoNext; 0187 } 0188 0189 QDBusConnection &MprisRemotePlayer::dbus() 0190 { 0191 return m_dbusConnection; 0192 } 0193 0194 #include "moc_mprisremoteplayer.cpp"