是否可以“重载”dbus Get Properties命令?

时间:2017-01-07 19:54:58

标签: bluetooth raspberry-pi3 dbus audio-player

我正在尝试使用我的覆盆子pi为我的汽车设置蓝牙音频。我从手机播放音乐和设置2个GPIO按钮,使用DBus消息向前或向后移动曲目。我想有一个屏幕显示当前播放的歌曲,但我遇到了障碍。

使用dbus我可以发出以下命令:

  

dbus-send --system --type = method_call --print-reply --dest = org.bluez / org / bluez / hci0 / dev_DC_41_5F_17_4C_79 / player0 org.freedesktop.DBus.Properties.Get string:org.bluez .MediaPlayer1 string:Track

返回此“变体”

variant       array [
     dict entry(
        string "Item"
        variant                object path "/org/bluez/hci0/dev_DC_41_5F_17_4C_79/player0/NowPlaying/item751498629074736430"
     )
     dict entry(
        string "Album"
        variant                string "Horse Of A Different Color"
     )
     dict entry(
        string "TrackNumber"
        variant                uint32 1
     )
     dict entry(
        string "Genre"
        variant                string "Country"
     )
     dict entry(
        string "Duration"
        variant                uint32 173061
     )
     dict entry(
        string "NumberOfTracks"
        variant                uint32 50
     )
     dict entry(
        string "Title"
        variant                string "Drinkin' 'Bout You"
     )
     dict entry(
        string "Artist"
        variant                string "Big & Rich"
     )
  ]

我想做的是只返回歌曲的标题。我尝试输入'Title'这个词而不是'Track',同时在命令'string:Title'的末尾添加另一个运算符,希望它能缩小信息范围。但我没有运气。

任何人都可以了解我如何才能展示标题吗? 感谢

1 个答案:

答案 0 :(得分:1)

我不确定是否有办法在程序外读取变体。如果没有,您将需要构建一个小程序来实现您想要的目标。

变体是一个容器,您寻找的信息在此变体中。您的变体类型为{sv},这意味着它是一个字典{key,value},其中键是字符串,值是变体(v)。

以下C代码将解析变体(使用GLib GDBus api):

/* Call the method that will return your variant dictionary */
GVariant *returnValue = MethodCallThatWillReturnTheDictionary();

/* This will be used to iterate through the dict */
GVariantIter *iter_dict; 

/* These two will be used to store the key and value pair in the dict */
const gchar *key;
GVariant value;

/* Init the iterator */
g_variant_get(returnValue, "a{sv}", &iter_dict);

/* Iterate through the dict */
while(g_variant_iter_loop(iter_dict, "{&sv}", &key, &value)){

    /* Each time we iterate, check if the key is "Title" */
    if( ! strcmp(key, "Title")){

        /* You now know that the Title is inside the "value" variant
           We still have to extract it */

        int title_length /* This will receive the Title length */
        const gchar *yourTitle = g_variant_get_string(value, &title_length);

    }
}
g_variant_iter_free(iter_dict); /* We don't need it anymore */

您可以在此处获取有关变体的更多信息:

https://developer.gnome.org/glib/stable/glib-GVariant.html

在这里:

https://developer.gnome.org/glib/stable/gvariant-format-strings.html

如果您不确定DBus和GDBus(DBus的GLib绑定),您可以在下面的链接中阅读更多内容,寻找低级和高级D-Bus支持。在您的情况下,您将需要GDBusConnection和GDBusProxy:

创建与总线的连接,然后使用您在dbus-send中使用的名称,路径和接口名称构建代理。然后使用我给你的代码示例来提取标题。

https://developer.gnome.org/gio/stable/