D-BUS: Wie man seinen Videoplayer fernsteuert

Mysterium D-BUS, heute werfen wir ein bisschen Licht ins Dunkel 🙂

D-BUS: Wie man seinen Videoplayer fernsteuert

Ihr ahnt es sicher, der Sprachassistent aka Carola ist die Ursache fĂŒr diese Forschungen 😉 NatĂŒrlich wollte ich auch so schon immer wissen, wofĂŒr der D-BUS eigentlich da ist und wie man den benutzen kann, da lag es nahe sich mal mit dem Thema zu befassen.

Der D-BUS

Der D-Bus ist ein genormter, aber flexibler, Kommunikationskanal fĂŒr Programme, mit dessen Hilfe, Daten ausgetauscht und Funktionen in einem Programm von außen angestoßen werden können. Dazu bietet das Programm, das von außen gesteuert werden möchte, eine Schnittstelle via D-BUS Interface an.

Wer das alles auf Eurem Desktop tut und was da so alles angeboten wird, können wir mit dem QDBUSViewer sehen:

Serviceslist im DBUSViewer

Diese Dienste sind nur dort zu finden, wenn das Programm das Sie anbietet auch lÀuft. Es ist also keine statische Liste, die sich in irgendeiner Datei befindet, sondern live und dynamisch.

Wenn man diese Liste durchsieht, stĂ¶ĂŸt man z.b. auf den Desktopmanager „Cinnamon“, den „Pulseaudio-Server“, „Firefox“ und jede Menge andere Programme und Serverdienste, die etwas anbieten. Am Beispiel von Celluloid schauen wir uns mal an, was wir da machen können, denn Celluloid ist der vorkonfigurierte Videoplayer fĂŒr unseren Sprachassistenten:

Das MediaPlayerInterface von Celluloid

Blau hinterlegt sieht man den Servicenamen: org.mpris.MediaPlayer2.io.github.celluloid_player.Celluloid.instance-1

„org.mpris.MediaPlayer2“ indiziert ein MediaPlayer2 Interface, welches genormte Funktionen zur VerfĂŒgung stellt. Das bedeutet, daß alle Services, die so anfangen, das gleiche Interface bieten, also auf die gleiche Art angesprochen werden können. Man muß also keine Fernsteuerung nur fĂŒr Celluloid bauen, sondern man baut eine Fernsteuerung fĂŒr alle MediaApps 🙂

Ok, wir haben unseren Startpunkt fĂŒr den Service gefunden, und wenden uns der rechten Seite zu:

Den Objekten

Die Bezeichnungen „Objekte“,“Methoden“ und „Eigenschaften“ kommen nicht ganz umsonst daher, denn es sind alles Begriffe aus der Objekt-Orientierten-Programmierung(OOP). Ein „Objekt“ bietet „Methoden“ an, die auf das Objekt angewendet werden können und die objekteigenen Daten behandeln, in welcher Form auch immer ( Lesen, Schreiben, Ändern, usw. ) . Dazu bietet das Objekt „Interfaces“ (Schnittstellen) an, das sind vereinfacht ausgedrĂŒckt, bekannte Listen von Methoden und Eigenschaften. Über wiederum genormte Basismethoden eines Objekts, kann man diese Interfaces auslesen und bestimmen, was man mit dem Objekt eigentlich machen kann.

Das Interface „org.freedesktop.DBus.Properties“

Das wohl meist verbreitete Interface dĂŒrfte org.freedesktop.DBus.Properties sein. Dies bietet die Methoden „Get“,“GetAll“ und „Set“ an. Was ein „Signal“ ist und wofĂŒr man das verwendet, kommt weiter unten, da es fĂŒr uns nicht relevant ist.

Mit der Methode „Get“ kann ich einen Wert aus dem Objekt auslesen, mit „Set“ einen Wert ĂŒberschreiben.

Damit wir damit etwas tun können, brauchen wir entweder ein Bibliothek fĂŒr unsere Lieblingsprogrammiersprache, oder wir benutzen zu Anschauungszwecken den Konsolen Befehl: dbus-send

Beispiel

dbus-send \
–session \
–print-reply \
–type=method_call \
–dest=ZIELSERVICE \
OBJEKTPFAD \
INTERFACE.METHODE \
DATEN1 DATEN2 DATEN3DATENX

„–session“ bedeutet, der Service ist in der Desktopsession beheimatet , die Alternative wĂ€re „–system“

„–print-reply“ bedeutet, daß wir sehen wollen, was der Aufruf zurĂŒck gibt, was im Fall von „Get“ sehr wichtig ist, sonst sieht man nĂ€mlich nichts 😉 Bei Set oder einem anderen Methodenaufruf mĂŒssen wir das nicht zwangslĂ€ufig sehen.

„–type=method_call“ , meint, wir rufen eine Methode auf. Hier mĂŒĂŸte man etwas anderes angeben, wenn es um ein Signal geht. „method_call“ ist auch der Default, daher könnte man es auch weglassen.

„–dest=ZIELSERVICEZielservice ist natĂŒrlich der Service, den wir ansprechen wollen. In unserem Fall also „org.mpris.MediaPlayer2.io.github.celluloid_player.Celluloid.instance-1

Der OBJEKTPFAD ist der Name des Objekts ( aka. Klassenname ). Da es als URL geschrieben ist, bezeichnen es die Schöpfer auch als Path oder Pfad. FĂŒr uns wĂ€re das /org/mpris/MediaPlayer2 .

Die INTERFACE.METHODE ist was wir ausfĂŒhren wollen, hier Get. Es muß aber genau angegeben werden, aus welchem Interface man welche Methode anspricht. Das macht man, in dem die Methode mit einem „.“ an den Interfacenamen angefĂŒgt wird. Also: org.freedesktop.DBus.Properties.Get

Dann kommen noch die Information die Get braucht : Name des Interfaces und Eigenschaft, die man abfragen möchte. Diese Daten werden zwar als Texte angegeben, sind aber in Zielprogramm ggf. keine Zeichenketten. Daher muß man einen Type mit angeben. Das wird bei Set nachher deutlicher.

Am Ende sieht das Ganze so aus:

dbus-send –session \
–print-reply \
–type=method_call \
–dest=org.mpris.MediaPlayer2.io.github.celluloid_player.Celluloid.instance-1 \
/org/mpris/MediaPlayer2 \
org.freedesktop.DBus.Properties.Get \
string:‘org.mpris.MediaPlayer2.Player‚ \
string:‘Volume

Ich möchte also mit dem Befehl die Eigenschaft(Property) LautstĂ€rke(Volume) aus dem Interface  „org.mpris.MediaPlayer2.Player“ haben.

In der Praxis

In der Konsole sieht das dann so aus:

[eve ~]$ dbus-send –session –print-reply –type=method_call –dest=org.mpris.MediaPlayer2.io.github.celluloid_player.Celluloid.instance-1 /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Get string:’org.mpris.MediaPlayer2.Player‘ string:’Volume‘
method return time=1641987861.200759 sender=:1.256 -> destination=:1.267 serial=81 reply_serial=2
variant double 1
[eve ~]$

Der graue Teil ist fĂŒr Euch uninteressant.

variant double 1“ ist das Ergebnis der Anfrage. „Double“ bezeichnet hier eine doppeltgenaue Fließkommazahl. Ihr braucht Euch nur merken, daß es Bruchzahlen sind, im Gegensatz zu „Integer“ was Ganzzahlen wĂ€ren. Jetzt eine Eigenart der Amis, die das normiert haben : Anstatt Komma, benutzen die einen Punkt. „0,5“ ist dann also „0.5“

Jetzt steht oben aber nur „1“, was in Wirklichkeit aber „1.00“ meint. Bei ganzen Zahlen, werden die Nachkommastellen einfach nicht angezeigt. Nun mĂŒssen wir speziell fĂŒr dies Interface noch wissen, das die LautstĂ€rke Werte von 0… x % haben kann. „1“ meint hier jetzt also „100%“ .

Spannenderweise kann man mit Set die LautstĂ€rke auch auf ĂŒber 100% setzen, was der Player auch mitmacht, aber z.b. ĂŒber sein Interface nicht geht 😀

Setzen wir doch mal die LautstÀrke auf 50% und lesen dies dann aus:

[eve ~]$ dbus-send –session –print-reply –type=method_call –dest=org.mpris.MediaPlayer2.io.github.celluloid_player.Celluloid.instance-1 /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Set string:’org.mpris.MediaPlayer2.Player‘ string:’Volume‘ variant:double:0.5
method return time=1641988564.513863 sender=:1.256 -> destination=:1.268 serial=83 reply_serial=2
[eve ~]$ dbus-send –session –print-reply –type=method_call –dest=org.mpris.MediaPlayer2.io.github.celluloid_player.Celluloid.instance-1 /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Get string:’org.mpris.MediaPlayer2.Player‘ string:’Volume‘
method return time=1641988571.005362 sender=:1.256 -> destination=:1.269 serial=87 reply_serial=2
variant double 0.5

Hat also geklappt. Jetzt ist das Setzen der LaustÀrke nicht das Einzige was man damit machen kann:

[eve ~]$ dbus-send –session –print-reply –type=method_call –dest=org.mpris.MediaPlayer2.io.github.celluloid_player.Celluloid.instance-1 /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Get string:’org.mpris.MediaPlayer2.Player‘ string:‘PlaybackStatus
method return time=1641988850.220984 sender=:1.256 -> destination=:1.270 serial=88 reply_serial=2
variant string „Paused“

Der Medienplayer ist also angehalten. Wie man in der Übersicht sieht:

können wir die Position im Film setzen (SetPosition), die Wiedergabegeschwindigkeit setzen (Rate), Vor- und ZurĂŒckspulen(Seek), den Player anweisen eine andere Datei zu spielen ( OpenUri ) und vieles mehr.

Die Wiedergabefunktionen sind im Interface „org.mpris.MediaPlayer2.Player“ untergebracht, deswegen sehen die Beispiele unten anders aus, als unsere Anweisungen fĂŒr die LautstĂ€rkekontrolle.

Ein paar nĂŒtzliche Beispiele

Die Wiedergabe starten oder fortsetzen:

dbus-send –session –type=method_call –print-reply –dest=org.mpris.MediaPlayer2.io.github.celluloid_player.Celluloid.instance-1 /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Play

Die Wiedergabe pausieren

dbus-send –session –type=method_call –print-reply –dest=org.mpris.MediaPlayer2.io.github.celluloid_player.Celluloid.instance-1 /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Pause

Die Wiedergabe beenden ( was bei NetFlix zu einem kuriosen Umstand fĂŒhrt 😀 )

dbus-send –session –type=method_call –print-reply –dest=org.mpris.MediaPlayer2.io.github.celluloid_player.Celluloid.instance-1 /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Stop

In der Wiedergabeliste ein Video weiterspringen:

dbus-send –session –type=method_call –print-reply –dest=org.mpris.MediaPlayer2.io.github.celluloid_player.Celluloid.instance-1 /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Next

In der Wiedergabeliste ein Video zurĂŒckspringen:

dbus-send –session –type=method_call –print-reply –dest=org.mpris.MediaPlayer2.io.github.celluloid_player.Celluloid.instance-1 /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Previous

Wiedergabe fortsetzen oder pausieren, ist abhÀngig vom PlayStatus:

dbus-send –session –type=method_call –print-reply –dest=org.mpris.MediaPlayer2.io.github.celluloid_player.Celluloid.instance-1 /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.PlayPause

Mit dem DBUSViewer könnt Ihr direkt ausprobieren, was in der Anwendung mit Eurem Befehl ausgelöst wird. Ein Doppelklick auf Play reicht da schon. Bei Eigenschaften muß man die rechte Maustaste klicken und dann Get oder Set aufrufen.

Was sind Signale?

Signale sind ein Weg, wie ich beachrichtigt werde, wenn sich im Programme ( Objekt ) etwas Àndert.

Bleiben wir mal bei einer Videoplayerfernsteuerung.In diesem Kontext sollte die Fernsteuerung anzeigen, wo sich der Film gerade befindet, wie laut der Player eingestellt ist usw. . Damit das Programm das kann, melde ich ein Signal bei dem Service (Player) an und sage so, daß ich Updates zu dem Status X haben möchte.

Jeder der KDE Connect schon einmal als Fernsteuerung benutzt hat, kennt das Feature.

Das funktioniert natĂŒrlich nur bei laufenden Programmen, weswegen man das in der Konsole so nicht zeigen kann. DafĂŒr gibt es den DBUS-Monitor, der zeigt Euch so etwas an:

Beispiel:

$ dbus-monitor
method call time=1641989991.978864 sender=:1.93 -> destination=org.mpris.MediaPlayer2.io.github.celluloid_player.Celluloid.instance-1 serial=325 path=/org/mpris/MediaPlayer2; interface=org.freedesktop.DBus.Properties; member=Get
string „org.mpris.MediaPlayer2.Player“
string „CanSeek“
method return time=1641989991.979023 sender=:1.274 -> destination=:1.93 serial=72 reply_serial=325
variant boolean true
method call time=1641989991.979110 sender=:1.93 -> destination=org.mpris.MediaPlayer2.io.github.celluloid_player.Celluloid.instance-1 serial=326 path=/org/mpris/MediaPlayer2; interface=org.freedesktop.DBus.Properties; member=Get
string „org.mpris.MediaPlayer2.Player“
string „Position“
error time=1641989991.979292 sender=:1.274 -> destination=:1.93 error_name=org.gtk.GDBus.UnmappedGError.Quark._celluloid_2dmpris_2derror_2dquark.Code1 reply_serial=326
string „Failed to get value of unknown property „Position““
signal time=1641989992.711142 sender=:1.274 -> destination=(null destination) serial=74 path=/org/mpris/MediaPlayer2; interface=org.freedesktop.DBus.Properties; member=PropertiesChanged
string „org.mpris.MediaPlayer2.Player“
array [
dict entry(
string „Volume“
variant double 0.5
)
]
array [
]
method call time=1641989992.711327 sender=:1.93 -> destination=org.mpris.MediaPlayer2.io.github.celluloid_player.Celluloid.instance-1 serial=327 path=/org/mpris/MediaPlayer2; interface=org.freedesktop.DBus.Properties; member=Get
string „org.mpris.MediaPlayer2.Player“
string „CanSeek“
method return time=1641989992.741618 sender=:1.274 -> destination=:1.93 serial=75 reply_serial=327
variant boolean true
method call time=1641989992.741806 sender=:1.93 -> destination=org.mpris.MediaPlayer2.io.github.celluloid_player.Celluloid.instance-1 serial=328 path=/org/mpris/MediaPlayer2; interface=org.freedesktop.DBus.Properties; member=Get
string „org.mpris.MediaPlayer2.Player“
string „Position“
error time=1641989992.741967 sender=:1.274 -> destination=:1.93 error_name=org.gtk.GDBus.UnmappedGError.Quark._celluloid_2dmpris_2derror_2dquark.Code1 reply_serial=328
string „Failed to get value of unknown property „Position““

Ja, da geht was ab auf dem D-BUS, nicht wundern wenn Ihr ĂŒberwĂ€ltigt seid. Aber mit dieser kleinen EinfĂŒhrung kann man viel mehr davon verstehen, als Ihr jetzt vielleicht noch glaubt.

Beispiel oben:

signal time=1641989992.711142 sender=:1.274 -> destination=(null destination) serial=74 path=/org/mpris/MediaPlayer2; interface=org.freedesktop.DBus.Properties; member=PropertiesChanged
string „org.mpris.MediaPlayer2.Player
array [
dict entry(
string „Volume
variant double 0.5
)
]
array [
]

Der Sender ist die ID des Prozesses, der die Nachricht losgeschickt hat. „PropertiesChanged“ meint „Eigenschaft geĂ€ndert“. Der Rest dĂŒrfte fĂŒr Euch jetzt kein Problem mehr sein 😉

Linux am Dienstag: Nachlese 6.4.2021

Ein Linux am Dienstag Treffen ist wieder vorbei. FĂŒr all diejenigen, die nicht daran teilnehmen konnten, wir konnten wieder das ein oder andere Nutzerproblem lösen.

Linux am Dienstag: Nachlese 6.4.2021

Nacharbeiten von Fedora u.a. Upgrades

Wenn nach einem Distro-Upgrade von Fedora z.B. auf 33 mal einiges nicht gehen sollte, dann erinnert Euch an diesen Befehl: sudo restorecon -R -v /*

Er setzt alle SELinux Kontexte wieder auf die richtigen Werte. Wie ich am eigenen Laptop erfahren mußte,wird dies wohl nicht so automatisch gemacht, wie man sich das vorstellen wĂŒrde. Mehr dazu in diesem Blog-Artikel von 2015:

Probleme mit SELinux reparieren

Wake-on-Lan

Wie funktioniert eigentlich Wake-On-Lan? Die Frage fĂŒhrte selbstverstĂ€ndlich gleich zur nĂ€chsten Frage: „Was ist das fĂŒr eine komische Zahlenfolge da?“ und dies fĂŒhrte zu unserem gestrigen Schwerpunktthema: „Wie werden eigentlich Daten im Netz transportiert?„. Stichpunkte waren ARP, Traceroute, Netzwerkrauschen, Switche, Router und natĂŒrlich die Ursache aller VortrĂ€ge Wake-on-Lan und was man damit machen kann.

Facebook – 533 Millionen DatensĂ€tze aufgetaucht

Facebook: 533 Millionen DatensÀtze erbeutet

Allerdings gibt es eine erweiterte Anekdote:

Follow-Up: Scammer failen an Ostern per SMS

Herr Kelber, seines Zeichens oberster deutscher DatenschĂŒtzer, brachte die beiden obigen Meldungen zusammen, auch wenn diese vermutlich nicht zusammenhĂ€ngen, denn auch Telefone, die nicht im Facebooksystem waren, bekamen diese SMS auch zugeschickt.

Ich nehme daher an, daß einfach alle Nummernblöcke deutscher Mobilfunkanbieter periodisch vollgespammt wurden. Da man das ĂŒber normale Handies so nicht machen kann, werden dort auslĂ€ndische S7 Anbieter involviert sein, die in Massen SMS in die Welt spammen. Die diversen Polizeidirektionen Deutschlands warnen dann auch schon seit Mitte Januar in Presseveröffentlichungen vor dieser Welle.

„USA. DHS got new smartphones with signal after the solarwind hacks.“

Die Mitarbeiter von Homeland-Security bekommen neue Smartphones, diesmal mit Signal als Messanger, nachdem die US Behörden ja durch den Hack bei der Solarwinds Firewall, Besuch von auslÀndischen Hackern bekommen hatten. Ob die allerdings damit so richtig froh werden kann bezweifelt werden, da Signal jetzt eine Bezahlfunktion bekommt: https://signal.org/blog/help-us-test-payments-in-signal/

Ein prominentes deutsches IT-Verschwörungsblog meinte daraus bereits das Ende von Signal ableiten zu können, weil wenn die mit Krypto-Geld hantieren wollen, Blockchains dafĂŒr einbauen und Nutzerdaten „in die Cloud hochladen“ und den frĂŒher immer publizierten Sourcecode seit ĂŒber einem Jahr nicht mehr bereitstellen, dann kann das nur das Ende bedeuten. Tja.. mir egal, wir nutzen Matrix 🙂

Fedora wird nicht auf 33 aktualisiert

Wie uns gestern berichtet wurde, aktualisierte Packagekit auf mehrfache Anweisung den PC nicht von Fedora 32 auf Fedora 33. Hier nochmal die Anleitung, wie man Fedora als Rootuser von Hand auf die neue Distro umstellt:

„screen“ starten

rpm –import /etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-33-$(uname -i)
dnf clean all;dnf -y upgrade;
dnf –allowerasing –releasever=33 –setopt=deltarpm=false distro-sync

Alles bestĂ€tigen was gefragt wird und ab damit 🙂

Screen setzt man ein, falls die Desktopsession mitten im Update sterben sollte. Durch Screen lĂ€uft das Update im Hintergrund weiter und man kann sich dann einfach per Terminal und „screen -r“ wieder in die Terminalsession einklinken. Vorteile hat das Update von Hand natĂŒrlich auch: man sieht endlich wie weit es schon fortgeschritten ist.