树莓派 + Bluez + A2DP + AVRCP
Posted
技术标签:
【中文标题】树莓派 + Bluez + A2DP + AVRCP【英文标题】:Raspberry Pi + Bluez + A2DP + AVRCP 【发布时间】:2019-02-12 05:49:00 【问题描述】:在过去的 2 天里,我一直在寻找一种方法来通过我的 Raspiberry pi 无头扬声器控制我的 iPhone 上的媒体播放。
我已经使用以下教程成功设置了 pi: Headless A2DP Audio Streaming on Raspbian Stretch 现在我正在寻找一种方法来控制我的树莓派音频流的播放。
我一直在研究 MediaTransport1、MediaPlayer1、MediaControl1,但不幸的是我没有成功。
给你几个我已经执行的试验和错误的例子:
为:
dbus-send --system --print-reply --dest=org.bluez /org/bluez/hci0/dev_C8_85_50_B1_C8_6B org.bluez.MediaPlayer1.Pause
我收到了:
Error org.freedesktop.DBus.Error.UnknownMethod: Method "Pause" with signature "" on interface "org.bluez.MediaPlayer1" doesn't exist
为
qdbus --system org.bluez /org/bluez/hci0/dev_C8_85_50_B1_C8_6B/fd0 org.freedesktop.DBus.Properties.Set org.bluez.MediaTransport1 Volume 127
我收到了
Error: org.freedesktop.DBus.Error.InvalidSignature
Invalid signature for 'Volume'
另外,我发现了一个播放器,我认为我可以用它来构建我自己的脚本作为示例Here,但我遇到了一个错误:
pi@raspberrypi:~/blueutils $ python simpleplayer.py
Available commands:
PropertiesChanged(interface, properties)
help(cmd)
Use python syntax to pass arguments to available methods.
E.g.: PropertiesChanged('Metadata' : 'Title': 'My title', 'Album': 'my album' )
>>> <Interface <ProxyObject wrapping <dbus._dbus.SystemBus (system) at 0xb61968d0> :1.13 /org/bluez/hci0 at 0xb619db70> implementing 'org.bluez.Media1' at 0xb619dc50>
Traceback (most recent call last):
File "simpleplayer.py", line 197, in <module>
media.RegisterPlayer(dbus.ObjectPath(path), player.properties)
File "/usr/lib/python2.7/dist-packages/dbus/proxies.py", line 70, in __call__
return self._proxy_method(*args, **keywords)
File "/usr/lib/python2.7/dist-packages/dbus/proxies.py", line 145, in __call__
**keywords)
File "/usr/lib/python2.7/dist-packages/dbus/connection.py", line 651, in call_blocking
message, timeout)
dbus.exceptions.DBusException: org.bluez.Error.NotSupported: Operation is not supported
当我反省时
dbus-send --system --print-reply --dest=org.bluez /org/bluez/hci0 org.freedesktop.DBus.Introspectable.Introspect
我明白他的:
<node>
<interface name="org.freedesktop.DBus.Introspectable">
<method name="Introspect">
<arg name="xml" type="s" direction="out"/>
</method>
</interface>
<interface name="org.bluez.Adapter1">
<method name="StartDiscovery"></method>
<method name="SetDiscoveryFilter">
<arg name="properties" type="asv" direction="in"/>
</method>
<method name="StopDiscovery"></method>
<method name="RemoveDevice">
<arg name="device" type="o" direction="in"/>
</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="Powered" type="b" access="readwrite"></property>
<property name="Discoverable" type="b" access="readwrite"></property>
<property name="DiscoverableTimeout" type="u" access="readwrite"></property>]
<property name="Pairable" type="b" access="readwrite"></property>
<property name="PairableTimeout" type="u" access="readwrite"></property>
<property name="Discovering" type="b" access="read"></property>
<property name="UUIDs" type="as" access="read"></property>
<property name="Modalias" type="s" access="read"></property>
</interface>
<interface name="org.freedesktop.DBus.Properties">
<method name="Get">
<arg name="interface" type="s" direction="in"/>
<arg name="name" type="s" direction="in"/>
<arg name="value" type="v" direction="out"/>
</method>
<method name="Set">
<arg name="interface" type="s" direction="in"/>
<arg name="name" type="s" direction="in"/>
<arg name="value" type="v" direction="in"/>
</method>
<method name="GetAll">
<arg name="interface" type="s" direction="in"/>
<arg name="properties" type="asv" direction="out"/>
</method>
<signal name="PropertiesChanged">
<arg name="interface" type="s"/>
<arg name="changed_properties" type="asv"/>
<arg name="invalidated_properties" type="as"/>
</signal>
</interface>
<interface name="org.bluez.GattManager1">
<method name="RegisterApplication">
<arg name="application" type="o" direction="in"/>
<arg name="options" type="asv" direction="in"/>
</method>
<method name="UnregisterApplication">
<arg name="application" type="o" direction="in"/>
</method>
</interface>
<interface name="org.bluez.Media1">
<method name="RegisterEndpoint">
<arg name="endpoint" type="o" direction="in"/>
<arg name="properties" type="asv" direction="in"/>
</method>
<method name="UnregisterEndpoint">
<arg name="endpoint" type="o" direction="in"/>
</method>
<method name="RegisterPlayer">
<arg name="player" type="o" direction="in"/>
<arg name="properties" type="asv" direction="in"/>
</method>
<method name="UnregisterPlayer">
<arg name="player" type="o" direction="in"/>
</method>
</interface>
<node name="dev_40_9C_28_07_63_DD"/>
<node name="dev_C8_85_50_B1_C8_6B"/>
</node>
谁能帮我解决这个问题,或者有人知道使用树莓派控制手机上音乐播放的程序吗?
问候。
更新 1: 非常感谢@Parthiban,它运行良好。
另外,我不得不说我按照此处的教程将 bluez 版本重新安装到 5.50:Install bluez on the Raspberry Pi 因为我看不到 /playerX(在我的情况下为 0)。在我编译源代码之前,我做了一些额外的工作(不确定它是否相关,但它没有伤害),我添加了.auto_connect = true
所示的 avrcp 配置文件:
Here
希望这对可能遇到我的问题的每个人都有帮助
【问题讨论】:
【参考方案1】:您需要指定签名来设置音量,如下所示,
dbus-send --system --print-reply --type=method_call --dest='org.bluez' '/org/bluez/hci0/dev_C8_85_50_B1_C8_6B/fd0' org.freedesktop.DBus.Properties.Set string:"org.bluez.MediaTransport1" string:"Volume" variant:uint16:127
这是因为,正如dbus specification 中提到的,在使用 set 时需要指定三个参数,
-
接口名称
属性名称
作为变量的属性值
对于暂停方法,使用“org.freedesktop.DBus.Introspectable.Introspect
”探索设备的“org.bluez.MediaPlayer1
”界面。您用来访问“暂停”方法的对象路径是错误的。如here所述,您需要使用“[variable prefix]/hci0,hci1,.../dev_XX_XX_XX_XX_XX_XX/playerX
”。
所以在你的情况下,应该是,
dbus-send --system --print-reply --type=method_call --dest='org.bluez' '/org/bluez/hci0/dev_C8_85_50_B1_C8_6B/playerX' org.bluez.MediaPlayer1.Pause
需要将 playerX 替换为您的设备播放器的位置(您可以从 Introspect 中获取或观看“InterfaceAdded”信号。
【讨论】:
感谢您的回答,Pause 命令有效,但是当我尝试设置音量级别时,出现以下错误:dbus-send --system --print-reply --type=method_call --dest='org.bluez' '/org/bluez/hci0/dev_C8_85_50_B1_C8_6B/fd0' org.freedesktop.DBus.Properties.Set string:"org.bluez.MediaTransport1" string:"Volume" uint16:127' ' Error org.freedesktop.DBus.Error.UnknownMethod: Method "Set" with signature "ssq" on interface "org.freedesktop.DBus.Properties" doesn't exist
@ady_e_n:我不确定为什么“设置”方法在这里不可用。检查对象路径“/org/bluez/hci0/dev_C8_85_50_B1_C8_6B/fd0”中的“Introspect”。如果不存在,则尝试使用“/org/bluez/hci0/dev_C8_85_50_B1_C8_6B”。我不确定 MediaTransport 接口是如何组织的层次结构。
我已经这样做了:photos.app.goo.gl/jdgh6RiLTVQNNRR98 方法接缝在那里:</method><method name="Set"><arg name="interface" type="s" direction="in"/> <arg name="name" type="s" direction="in"/> <arg name="value" type="v" direction="in"/>
它只是返回一个错误
@ady_e_n:知道了:试试这个dbus-send --system --print-reply --type=method_call --dest='org.bluez' '/org/bluez/hci0/dev_C8_85_50_B1_C8_6B/fd0' org.freedesktop.DBus.Properties.Set string:"org.bluez.MediaTransport1" string:"Volume" variant:uint16:127
@ady_e_n:已更新答案以供将来参考!以上是关于树莓派 + Bluez + A2DP + AVRCP的主要内容,如果未能解决你的问题,请参考以下文章