from PyQt6.QtCore import QObject, QTimer, pyqtSlot as Slot
from PyQt6.QtDBus import QDBusConnection, QDBusInterface, QDBusMessage, QDBusVariant, QDBusReply
class MPRISMonitor(QObject):
def __init__(self):
super().__init__()
self.updateTimer: QTimer = QTimer()
self.updateTimer.timeout.connect(self.updatePosition)
self.session = QDBusConnection.sessionBus()
self.playerList: list[str] = self.getPlayers()
self.playerInterface: QDBusInterface | None = None
self.connectedService: str = ""
if len(self.playerList) > 0:
self.playerInterface = MPRISMonitor.getPlayerInterface(self.playerList[0])
self.session.connect(
self.connectedService,
"/org/mpris/MediaPlayer2",
"org.freedesktop.DBus.Properties",
"PropertiesChanged",
self.handlePropertiesChanged
)
self.metadata: dict = {}
self.state: str = ""
self.position: int = 0
self.updateTimer.start(5000)
def getPlayers(self) -> list[str]:
"""Return a list of all active MPRIS player service names."""
reply = self.session.interface().registeredServiceNames()
mediaPlayers: list[str] = []
for s in str(reply.value()).split("\', \'"):
if s.startswith("org.mpris.MediaPlayer2."):
mediaPlayers.append(s)
return mediaPlayers
@staticmethod
def getPlayerInterface(serviceName: str):
"""Get a DBus interface for a given player."""
return QDBusInterface(
serviceName,
"/org/mpris/MediaPlayer2",
"org.freedesktop.DBus.Properties",
QDBusConnection.sessionBus()
)
def getMetadata(self):
msg: QDBusMessage = self.playerInterface.call("Get", "org.mpris.MediaPlayer2.Player", "Metadata")
if msg.arguments():
self.metadata = msg.arguments()[0].variant()
return self.metadata
def getState(self):
msg = self.playerInterface.call("Get", "org.mpris.MediaPlayer2.Player", "PlaybackStatus")
if msg.arguments():
return msg.arguments()[0].variant()
return None
def getPosition(self):
if self.playerInterface is None: return 0
msg = self.playerInterface.call("Get", "org.mpris.MediaPlayer2.Player", "Position")
if type(msg.arguments()[0]) is int:
return msg.arguments()[0] / 1000000 # µs → s
print(type(msg.arguments()))
return 0
@Slot(QDBusMessage)
def handlePropertiesChanged(self, msg: QDBusMessage):
args = msg.arguments()
if len(args) < 2:
return
changed = args[1] # dict of changed properties
if not isinstance(changed, dict):
return
if "Metadata" in changed:
cMetadata = changed["Metadata"]
if cMetadata != self.metadata:
self.metadata = cMetadata
if "PlaybackStatus" in changed:
cState = changed["PlaybackStatus"]
if cState != self.state:
print(f"▶️ Playback state: {cState}")
self.state = cState
print("Change detected! TBI")
def updatePosition(self):
pos = self.getPosition()
if abs(pos - self.position) > 2:
print(f"⏱️ Position: {pos:.1f}s")
self.position = pos
Comments
0 B
|0 👍
/0 👎
0 B
|👍
/👎