Get track data from D-Bus
Sergey, 25 July 2017
An example of getting info about currently playing track from D-Bus using MPRIS. This code was used in AnnicomScrobbler.
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include <glib/gprintf.h>
#include <gio/gio.h>
#include <curl/curl.h>
struct song {
gchar *title;
gchar *artist;
gchar *genre;
};
void get_song(char* address, struct song *currsong) {
GDBusProxy *proxy;
GDBusConnection *conn;
GError *error = NULL;
GVariant *answer, *value;
GVariantIter *iter;
gchar *key;
conn = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &error);
g_assert_no_error(error);
proxy = g_dbus_proxy_new_sync(conn,
G_DBUS_PROXY_FLAGS_NONE,
NULL,
address,
"/org/mpris/MediaPlayer2",
"org.freedesktop.DBus.Properties",
NULL,
&error);
if(error != NULL) {
g_object_unref(proxy);
g_object_unref(conn);
return;
}
answer = g_dbus_proxy_call_sync(proxy,
"Get",
g_variant_new("(ss)",
"org.mpris.MediaPlayer2.Player",
"Metadata"),
G_DBUS_CALL_FLAGS_NONE,
-1,
NULL,
&error);
if((error != NULL) || (answer == NULL)) {
if(answer != NULL) {
g_variant_unref(answer);
}
g_object_unref(proxy);
g_object_unref(conn);
return;
}
GVariant *tmp;
g_variant_get(answer,"(v)", &tmp);
g_variant_get(tmp, "a{sv}", &iter);
while(g_variant_iter_loop(iter, "{sv}", &key, &value)) {
if(strncmp(key, "xesam:title", 11) == 0) {
g_variant_get(value, "s", &(currsong->title));
}
else if(strncmp(key, "xesam:genre", 11) == 0) {
if(g_variant_is_container(value)) {
g_variant_get_child(value, 0, "s", &(currsong->genre));
}
else {
g_variant_get(value, "s", &(currsong->genre));
}
}
else if(strncmp(key, "xesam:artist", 12) == 0) {
if(g_variant_is_container(value)) {
g_variant_get_child(value, 0, "s", &(currsong->artist));
}
else {
g_variant_get(value, "s", &(currsong->artist));
}
}
}
g_variant_unref(tmp);
g_variant_unref(answer);
g_object_unref(proxy);
g_object_unref(conn);
}
Usage:
get_song(currsong);
printf("song title: %s\ngenre: %s, artist: %s", currsong->title, currsong->genre, currsong->artist);