Created
February 16, 2026 15:49
-
-
Save stpettersens/075908c8b8e73cd165a471f7258080ea to your computer and use it in GitHub Desktop.
Simple program that prints the current playing song from Rhythmbox.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import std.conv; | |
| import std.file; | |
| import std.stdio; | |
| import std.string; | |
| import std.process; | |
| import core.time; | |
| import core.thread; | |
| import core.sys.posix.unistd; // getlogin | |
| void create_working_dir() { | |
| string dir = "/tmp/rb"; | |
| if (!exists(dir)) { | |
| string user = fromStringz(getlogin()).idup; | |
| executeShell(format("doas -u %s mkdir -p %s", user, dir)); | |
| } | |
| } | |
| void kill_get_song_loop(string pid_file) { | |
| if (exists(pid_file)) { | |
| auto f = File(pid_file, "r"); | |
| string pid = strip(f.readln()); | |
| executeShell(format("kill %s", pid)); | |
| remove(pid_file); | |
| } | |
| } | |
| void print_song(string playing_file) { | |
| if (exists(playing_file)) { | |
| auto f = File(playing_file, "r"); | |
| string song = strip(f.readln()); | |
| writeln(song); | |
| return; | |
| } | |
| writeln("..."); | |
| } | |
| void spawn_get_song_loop() { | |
| string pid_file = "/tmp/rb/pid"; | |
| string playing_file = "/tmp/rb/playing"; | |
| bool rb_running = false; | |
| auto processes = executeShell("pgrep rhythmbox | xargs printf '%d,'"); | |
| string[] pids = chop(strip(processes.output)).split(","); | |
| foreach (pid; pids) { | |
| uint p = to!uint(pid); | |
| if (p != 0) rb_running = true; | |
| break; | |
| } | |
| if (rb_running && !exists(pid_file)) { | |
| auto pid = spawnProcess("rb_get_song"); | |
| auto fo = File(pid_file, "w"); | |
| fo.write(pid.processID.to!string); | |
| fo.flush(); | |
| Thread.sleep(5.seconds); | |
| } | |
| else if (!rb_running) { | |
| if (exists(playing_file)) { | |
| remove(playing_file); | |
| } | |
| kill_get_song_loop(pid_file); | |
| } | |
| print_song(playing_file); | |
| } | |
| int main() { | |
| create_working_dir(); | |
| spawn_get_song_loop(); | |
| return 0; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env python3 | |
| # This Python program will get the current song from Rhythmbox. | |
| # It should be invoked as a process by now_playing. | |
| import dbus | |
| import dbus.mainloop.glib | |
| from gi.repository import GLib | |
| playing_file = '/tmp/rb/playing' | |
| _artist = '' | |
| def dump_playing_file(): | |
| with open(playing_file, 'w') as f: | |
| f.write('...') | |
| if __name__ == "__main__": | |
| dump_playing_file() | |
| dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) | |
| bus = dbus.SessionBus() | |
| player = bus.get_object("org.mpris.MediaPlayer2.rhythmbox", "/org/mpris/MediaPlayer2") | |
| iface = dbus.Interface(player, "org.freedesktop.DBus.Properties") | |
| def on_metadata_changed(interface, changed_props, invalidated_props): | |
| if "Metadata" in changed_props: | |
| meta = changed_props["Metadata"] | |
| artist = meta.get(dbus.String("xesam:artist"), "") | |
| title = meta.get(dbus.String("xesam:title"), "") | |
| global _artist | |
| _artist = str(artist).split(".String('")[1] | |
| _artist = _artist.split("'")[0] | |
| try: | |
| if _artist != "": | |
| with open(playing_file, 'w') as f: | |
| f.write(f'{_artist} - {title}') | |
| except: | |
| pass | |
| iface.connect_to_signal("PropertiesChanged", on_metadata_changed) | |
| GLib.MainLoop().run() |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This program will be rewritten to support any player (including Chromium browsers for YouTube) which supports MPRIS.