如何在蓝牙设备连接时运行脚本?
当我的蓝牙耳机连接到我的电脑时,我想启动我的音乐播放器(Clementine)。 如何检测连接的蓝牙设备,以便我可以运行脚本来启动播放器?
我不喜欢轮询方法,所以我对bluez和DBus进行了一些挖掘。 我最后编写了以下脚本:
#!/usr/bin/python import dbus from dbus.mainloop.glib import DBusGMainLoop import gobject import subprocess # ID of the device we care about DEV_ID = '00_1D_54_AB_DC_72' dbus_loop = DBusGMainLoop() bus = dbus.SystemBus(mainloop=dbus_loop) # Figure out the path to the headset man = bus.get_object('org.bluez', '/') iface = dbus.Interface(man, 'org.bluez.Manager') adapterPath = iface.DefaultAdapter() headset = bus.get_object('org.bluez', adapterPath + '/dev_' + DEV_ID) # ^^^ I'm not sure if that's kosher. But it works. def cb(iface=None, mbr=None, path=None): if ("org.bluez.Headset" == iface and path.find(DEV_ID) > -1): print 'iface: %s' % iface print 'mbr: %s' % mbr print 'path: %s' % path print "\n" print "matched" if mbr == "Connected": subprocess.call(["clementine", "--play"]) print 'conn' elif mbr == "Disconnected": subprocess.call(["clementine", "--stop"]) print 'dconn' headset.connect_to_signal("Connected", cb, interface_keyword='iface', member_keyword='mbr', path_keyword='path') headset.connect_to_signal("Disconnected", cb, interface_keyword='iface', member_keyword='mbr', path_keyword='path') loop = gobject.MainLoop() loop.run()
要发现成功建立的蓝牙连接,我们可以运行
sdptool browse xx:xx:xx:xx:xx:xx
通过这种方式,将测试SDB连接与给定MAC地址的连接。 可能需要相当长的时间才能浏览超时的错误
Failed to connect to SDP server on 00:0C:78:4F:B6:B5: Host is down
我们不知道您的脚本的确切用途,但很可能您希望在连接耳机时通过Clementine播放音频。
然后我们可以看看是否有蓝牙音频接收器
pacmd list-sinks | grep xx_xx_xx_xx_xx_xx
其中xx_xx_xx_xx_xx_xx
是MAC地址( :
需要用_
替换)。 然后输出将告诉您是否有可用的蓝牙音频接收器,如果没有则可以。
有关如何将音频切换到此接收器,请参阅此答案 。
Stream2ip
使用stream2ip,我们可以定义一个shell命令或在建立连接后运行的脚本。 建立连接后,还可以选择自动启动支持的媒体播放器:
如果连接中断,Stream2ip还会尝试将当前正在运行的播放流重新连接到蓝牙音频设备。
这是另一个监控所有蓝牙设备的示例。 它不需要指定特定的MAC地址。 即使在登录/退出,暂停/唤醒和连接/断开蓝牙设备时,此方法也会使xinput设置保持不变。
我有一个Thinkpad紧凑型蓝牙键盘,我希望每当连接键盘时运行xinput命令来调整跟踪点的速度。 这是步骤。
-
从Github bluetooth-ruunner下载代码。 在这里为Raspberry Pi首次写这篇文章的学分。 修改代码的以下部分以运行自定义comamnds。
subprocess.call(['xinput', 'set-prop', 'ThinkPad Compact Bluetooth Keyboard with TrackPoint', 'Device Accel Constant Deceleration', '0.6'])
在我的情况下,这相当于从终端呼叫。
$ xinput set-prop 'ThinkPad Compact Bluetooth Keyboard with TrackPoint' 'Device Accel Constant Deceleration' 0.6
-
保存修改。 尝试运行脚本
$ python bluetooth-runner.py
连接和断开Bluethooth设备。 您应该会在屏幕上看到相应的消息。
-
现在,让你的文件可执行并将其复制到
$PATH
一个目录中,比如~/bin/
。$ chmod +x bluetooth-runner.py $ mkdir ~/bin # if you dont have it yet $ cp bluetooth-runner.py ~/bin
-
现在,确保您可以从终端的任何位置运行脚本(确保它在您的搜索路径中)。
-
从ubuntu菜单
Startup Applications
。 将您的脚本添加到启动中。 -
现在,只剩下一个问题,在您登录时,脚本可能无法捕获第一个蓝牙事件。 这是因为您的蓝牙设备可能在脚本在后台初始化之前已连接。
要解决此问题,请直接在“
Startup Applications
添加自定义命令。 在我的例子中,它是以下命令:xinput set-prop 'ThinkPad Compact Bluetooth Keyboard with TrackPoint' 'Device Accel Constant Deceleration' 0.6
现在,您将能够使用Ubuntu享受您的蓝牙设备。
@Erigami你的回答很有帮助但是为了让它有效我会做一些改变。 我正在使用ubuntu 14.04。
#!/usr/bin/python import dbus from dbus.mainloop.glib import DBusGMainLoop import gobject import subprocess # ID of the device we care about DEV_ID = 'CC:C3:EA:A5:16:90'.replace(":", "_") dbus_loop = DBusGMainLoop() bus = dbus.SystemBus(mainloop=dbus_loop) # Figure out the path to the headset man = bus.get_object('org.bluez', '/') iface = dbus.Interface(man, 'org.bluez.Manager') adapterPath = iface.DefaultAdapter() print(adapterPath + '/dev_' + DEV_ID) headset = bus.get_object('org.bluez', adapterPath + '/dev_' + DEV_ID) # ^^^ I'm not sure if that's kosher. But it works. def cb(*args, **kwargs): is_connected = args[-1] if isinstance(is_connected, dbus.Boolean) and is_connected: print("Connected") elif isinstance(is_connected, dbus.Boolean) and not is_connected: print("Disconnected") headset.connect_to_signal("PropertyChanged", cb, interface_keyword='iface', member_keyword='mbr', path_keyword='path') loop = gobject.MainLoop() loop.run()
如果这不起作用,那么使用和监控系统dbus。
dbus-monitor --system
d-feet
可以进一步使用。 它是观看dbus对象的GUI工具。
你写“当你的耳机连接到你的电脑”。 它是如何自动完成的? 当您必须手动触发它时,您也可以将其设为脚本,然后在建立连接后运行脚本。 这就是我将默认输出设备设置为我的蓝牙接收器所做的操作(因此我可以使用硬件密钥更改音量):
bluetooth-connect && pactl set-default-sink bluez_sink.0C_A6_94_9A_37_4D
bluetooth-connect
看起来像这样: https : //github.com/sblask/dotfiles/blob/c39d37ad67947b358b4a079cb41ae6f9e4a081d8/.bin/bluetooth-connect.symlink它假设一切都已配对并准备连接。 您可以在blueman中找到MAC地址,也可以运行pacmd list-sinks | grep -e 'name:' -e 'index'
当蓝牙设备连接时, pacmd list-sinks | grep -e 'name:' -e 'index'
。 你想要运行bluetooth-connect && your-script
。 只有在成功建立连接后才会运行your-script
。