使用d-bus在C.H.I.P上用bluez 5.43改变音量

时间:2017-01-13 22:29:12

标签: dbus bluez

我是d-bus和bluez的新手。我有一个CHIP模块,作为BT扬声器运行。我跟着这个:

https://github.com/hadess/CHIP-bluetooth-speaker

以及以下链接中的说明以获得iPhone音量:

https://github.com/hadess/CHIP-bluetooth-speaker/issues/8

我希望能够从我的iphone和模块中改变扬声器的音量 - 所以我猜猜dbus命令是可行的。

我使用以下方式成功连接并与iPhone断开连接:

dbus-send --system --print-reply --dest=org.bluez /org/bluez/hci0/dev_A0_D7_95_A9_88_91 org.bluez.Device1.Disconnect

d-feet对我说明如何操作非常有用。但是,我不知道如何播放/暂停/ volumeUp / volumeDown。这里的文档:

https://kernel.googlesource.com/pub/scm/bluetooth/bluez/+/5.43/doc/media-api.txt

解释了如何进行播放/暂停,但我无法让它发挥作用。我试过了:

dbus-send --system --print-reply --dest=org.bluez /org/bluez/hci0/dev_A0_D7_95_A9_88_91 org.bluez.MediaPlayer1.Pause

dbus-send --system --print-reply --dest=org.bluez /org/bluez/hci0/dev_A0_D7_95_A9_88_91/Player1 org.bluez.MediaPlayer1.Pause

出现同样的错误:

Error org.freedesktop.DBus.Error.UnknownMethod: Method "Pause" with signature "" on interface "org.bluez.MediaPlayer1" doesn't exist

我完全不清楚如何更改音量(mediacontrol1中的VolumeUp和VolumeDown命令如图所示弃用)。

有人可以帮忙吗?

更新

在康斯坦丁发表评论之后(谢谢),我想再澄清一下。

使用d-feet,我可以获得设备的以下信息:

enter image description here

我应该能够看到" MediaTransport1"和/或" MediaControl1"列表中的界面条目?

当我调用device1的内省时,我得到:

'<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"\n"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">\n<node><interface name="org.freedesktop.DBus.Introspectable"><method name="Introspect"><arg name="xml" type="s" direction="out"/>\n</method></interface><interface name="org.bluez.Device1"><method name="Disconnect"></method><method name="Connect"></method><method name="ConnectProfile"><arg name="UUID" type="s" direction="in"/>\n</method><method name="DisconnectProfile"><arg name="UUID" type="s" direction="in"/>\n</method><method name="Pair"></method><method name="CancelPairing"></method><property name="Address" type="s" access="read"></property><property name="Name" type="s" access="read"></property><property name="Alias" type="s" access="readwrite"></property><property name="Class" type="u" access="read"></property><property name="Appearance" type="q" access="read"></property><property name="Icon" type="s" access="read"></property><property name="Paired" type="b" access="read"></property><property name="Trusted" type="b" access="readwrite"></property><property name="Blocked" type="b" access="readwrite"></property><property name="LegacyPairing" type="b" access="read"></property><property name="RSSI" type="n" access="read"></property><property name="Connected" type="b" access="read"></property><property name="UUIDs" type="as" access="read"></property><property name="Modalias" type="s" access="read"></property><property name="Adapter" type="o" access="read"></property></interface><interface name="org.freedesktop.DBus.Properties"><method name="Get"><arg name="interface" type="s" direction="in"/>\n<arg name="name" type="s" direction="in"/>\n<arg name="value" type="v" direction="out"/>\n</method><method name="Set"><arg name="interface" type="s" direction="in"/>\n<arg name="name" type="s" direction="in"/>\n<arg name="value" type="v" direction="in"/>\n</method><method name="GetAll"><arg name="interface" type="s" direction="in"/>\n<arg name="properties" type="a{sv}" direction="out"/>\n</method><signal name="PropertiesChanged"><arg name="interface" type="s"/>\n<arg name="changed_properties" type="a{sv}"/>\n<arg name="invalidated_properties" type="as"/>\n</signal>\n</interface></node>'

哪个没有关于音量,传输控制等的详细信息。这是否意味着我的bluez设置是不允许的?

最终,我想让这一切都在Python中工作,所以,Constantin,如果你能继续得到你的支持,python代码的一些例子也会很棒。

更新2

好的,所以在使用Bluez v5.23的Rpi V3上尝试这个,我得到:

pi@raspberrypi:~ $ qdbus --system org.bluez /org/bluez/hci0/dev_A0_D7_95_A9_88_91
method QString org.freedesktop.DBus.Introspectable.Introspect()
property read QDBusObjectPath org.bluez.Device1.Adapter
property read QString org.bluez.Device1.Address
property readwrite QString org.bluez.Device1.Alias
property read ushort org.bluez.Device1.Appearance
property readwrite bool org.bluez.Device1.Blocked
property read uint org.bluez.Device1.Class
property read bool org.bluez.Device1.Connected
property read QString org.bluez.Device1.Icon
property read bool org.bluez.Device1.LegacyPairing
property read QString org.bluez.Device1.Modalias
property read QString org.bluez.Device1.Name
property read bool org.bluez.Device1.Paired
property read short org.bluez.Device1.RSSI
property readwrite bool org.bluez.Device1.Trusted
property read QStringList org.bluez.Device1.UUIDs
method void org.bluez.Device1.CancelPairing()
method void org.bluez.Device1.Connect()
method void org.bluez.Device1.ConnectProfile(QString UUID)
method void org.bluez.Device1.Disconnect()
method void org.bluez.Device1.DisconnectProfile(QString UUID)
method void org.bluez.Device1.Pair()
method QDBusVariant org.freedesktop.DBus.Properties.Get(QString interface, QString name)
method QVariantMap org.freedesktop.DBus.Properties.GetAll(QString interface)
signal void org.freedesktop.DBus.Properties.PropertiesChanged(QString interface, QVariantMap changed_properties
method void org.freedesktop.DBus.Properties.Set(QString interface, QString name, QDBusVariant value)
property read bool org.bluez.MediaControl1.Connected
method void org.bluez.MediaControl1.FastForward()
method void org.bluez.MediaControl1.Next()
method void org.bluez.MediaControl1.Pause()
method void org.bluez.MediaControl1.Play()
method void org.bluez.MediaControl1.Previous()
method void org.bluez.MediaControl1.Rewind()
method void org.bluez.MediaControl1.Stop()
method void org.bluez.MediaControl1.VolumeDown()
method void org.bluez.MediaControl1.VolumeUp()

...所以显示了MediaControl1。

问题是,是由于Bluez的不同版本还是不同的平台?响应dbus命令也是有点慢(我不期待)。有时它几乎是立即的,其他时间可能需要1-2秒。这是预期的吗?

1 个答案:

答案 0 :(得分:3)

首先,在将“Player1”添加到对象路径时,你是以正确的方式,文档明确指出:

Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/playerX

但是,您是如何找到“Player1”的?这不能是一个随机数,你会发现你必须通过内省你的设备(带有dev_XX_XX的对象路径......)附加到mac地址的确切字符串,通常是在xml标签中''

现在关于你的错误,我知道文档声明Pause方法没有参数,尽管文档可能不是最新的? 了解dbus方法的一个简单方法是分析内省: 您可以使用以下命令检索内省(您应该在hci0之后更新路径以匹配您的对象路径):

dbus-send --system --print-reply --dest=org.bluez /org/bluez/hci0 org.freedesktop.DBus.Introspectable.Introspect

举个例子,从内省中提取以下内容:

<method name="GetAll"><arg name="interface" type="s" direction="in"/><arg name="properties" type="a{sv}" direction="out"/>

从中我了解到GetAll方法将接口名称作为参数(direction in,type s)作为字符串,并返回字符串,其中字符串(键)映射到变体(值)(方向输出,键入a {SV})

您可以自省设备并确保找到“Player1”节点标签吗?然后反省Player1并确保Pause方法不带任何参数。

要更改音量,我想您应该使用接口org.bluez.MediaTransport1 中的“音量”属性(查看media-api.txt文件的末尾)

最后,你打算在程序中包含这些操作吗?如果是,我建议使用适当语言的dbus绑定(C,Glib,Python,C#...)。我可以为您提供有关如何在程序中与bluez交互的更多文档。

<强>更新

您的rpi(5.23)上的版本已经过时并使用了一个现已弃用的API(请参阅org.bluez.MediaControl1界面在此处到处都有[已弃用] https://git.kernel.org/cgit/bluetooth/bluez.git/tree/doc/media-api.txt

通过查看文档,在内省设备时,您应该看不到任何接口。如果您内省/ org / bluez / hci0(参考指定的对象路径),则应出现 org.bluez.Media1

Service     org.bluez
Interface   org.bluez.Media1
Object path [variable prefix]/{hci0,hci1,...}

当内省玩家时,org.bluez.MediaPlayer1会出现:

Service     org.bluez (Controller role)
Interface   org.bluez.MediaPlayer1
Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/playerX

虽然在你的情况下,我在你的内省中看不到任何与“playerX”相关的内容,而这是首先需要修复的问题。

要通过蓝牙传输声音,您希望将A2DP协议与Linux一起用作“源”并将扬声器用作“接收器”。此功能(音频流)可能需要PulseAudio。尝试将最新版本的pulseaudio添加到您的系统中(您可能希望从源代码编译)。有关详情,请参阅此处:https://www.freedesktop.org/wiki/Software/PulseAudio/Documentation/User/Bluetooth/

也许您的rpi使用bluez4和pulseaudio配置为自动连接。这可以解释为什么你可以在rpi上看到接口。

还有Arch Wiki可以帮助您排除故障:https://wiki.archlinux.org/index.php/Bluetooth_headset#Headset_via_Bluez5.2FPulseAudio

在我查找信息时,我找到了这个网站:http://www.lightofdawn.org/wiki/wiki.cgi/BluezA2DP

它描述了如何使用bluez api使其适用于A2DP。本教程是为bluez4编写的,作者最后讨论了bluez5的兼容性。

我无法准确说出你需要做什么动作以及你需要做什么,虽然你在google搜索“bluez a2dp python”时会找到大量的文档和教程(就像reddit上的这个,仔细阅读他的评论)他的代码文件的顶部):https://www.reddit.com/r/Python/comments/1f1xkt/use_python_to_turn_your_bluetooth_laptop_into_a/

我的猜测是你需要扫描(org.bluez.Adapter1),注册端点(org.bluez.Media1),配对(并且可能连接?使用org.bluez.Device1)并获取文件描述符写作(org.bluez.MediaTransport1)

在做其他任何事情之前,你需要看到使用d-feet的接口!一旦你使用了d-feet,你可以参考这个要点来获得一个简单的python示例来执行扫描:https://gist.github.com/CynaCons/8eb02540f87af5594fac489a9dca32c1

我还在github gist上传了一个高级版本。