
Now Playing on IRC
Back in the IRC days of the late 90s and early 2000s, chat was full of people sharing the songs they were playing on their media players.
I never quite understood how it worked. All I knew was that I had to install a plugin or script, and instantly the title of the MP3 I was listening to on Winamp would magically appear as text on IRC.
Recently, as I was rekindling my interest in IRC (like so many times over the last 20 years), the question “How did it actually work?” came flooding back. I decided it was time to solve this mystery, and what better way to learn than by building something.
I wanted to build an IRC bot that could report the music I was currently playing, ideally regardless of which player I used.
The Question
For me, this journey started with a bunch of questions:
- How does one process pull information from another process?
- Is that even possible?
- Wouldn’t there be a security risk?
My Assumptions
I remembered seeing and using DLL files. Winamp had a plugin architecture, and installing plugins essentially meant adding DLLs. But what are they and how do they work?
I wondered:
- Perhaps the IRC client loaded something directly into the player?
- Or maybe it read shared memory?
- Or was it something simpler, like parsing the window title of the music player?
- Or did it exploit some kind of security hole?
The point is, on Windows, this kind of integration felt messy and hacky. Each player had its own plugin API. Integration was tight, often in-process, and there was no standard way for one app to expose metadata to another. It worked, but it felt like magic.
The Linux Way
Fast forward to today. On Linux, the mechanism is much cleaner and more principled. Applications don’t spy on each other, they cooperate.
Linux provides D-Bus (Desktop Bus), a messaging middleware for inter-process communication. Processes can reveal which services and information they provide, and other processes can request that information.
For media players, there’s a standard called MPRIS (Media Player Remote Interfacing Specification). Media players can implement this interface to expose metadata such as:
- Track title
- Artist
- Album
- Playback position
All of this can be accessed through D-Bus by any process that requests it. Everything is typed, structured, and discoverable. No scraping or hacks needed.
The Click
The moment it clicked for me was when I started listing all the active D-Bus names. It felt like a new world opened up.
Commands like dbus-monitor or busctl made it easy to see what other processes are broadcasting.
For example, with the native busctl:
$ busctl --user get-property org.mpris.MediaPlayer2.qmmp /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player Metadata
a{sv} 6 "mpris:length" x 0 "mpris:trackid" o "/org/qmmp/MediaPlayer2/Track/1390591028" "xesam:artist" as 1 "J.Wilson 90" "xesam:genre" as 1 "Future Funk, City Pop, Nu Disco, Vaporwave, Anime Groove, Synthwave"
"xesam:title" s "It Hurts a Little" "xesam:url" s "http://s1.yumicoradio.net:8000/stream"
Or using the thin wrapper playerctl:
$ playerctl -p qmmp metadata --format '{{artist}} - {{title}}'
KORZ - Midnight talks
Seeing the title, artist, and album structured and typed felt almost too easy. The “magic” was suddenly gone, replaced by something elegant.
Bonus: You can use D-Bus to control your players too.
For example, to stop playback:
busctl –user call org.mpris.MediaPlayer2.qmmp /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player Stop
Turning it into an IRC Bot
Once I understood D-Bus, writing the bot became quite straightforward.
I knew I needed to:
- Subscribe to
org.mpris.MediaPlayer2.Player.Metadataon the D-Bus - Receive updates when the tracks changed
- Format it and send it back to IRC
It was event-driven, neat, and clean. Best of all, it worked across most media players that implement MPRIS. No rewriting logic for each player.
I didn’t need to install DLLs, write a new process to expose an API, or configure lifecycles just to pull metadata. Everything I needed was already there.
You can find my code at https://gist.github.com/davidchua/034899bbf87df17fb838cd1fca2e614a
Reflection
When it all finally clicked, it felt like closing a small loop from my childhood.
IRC played a big part in my early years and eventual progression into tech. Connecting with people all over the world through a modem, seeing the wonders of how these systems worked, fueled my curiosity and desire to understand everything I interacted with.
Now, being able to close the loop on one of the first amazing things I witnessed online, it felt strangely complete.