如何在蓝牙设备连接时运行脚本?

当我的蓝牙耳机连接到我的电脑时,我想启动我的音乐播放器(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命令来调整跟踪点的速度。 这是步骤。

  1. 从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 
  2. 保存修改。 尝试运行脚本

     $ python bluetooth-runner.py 

    连接和断开Bluethooth设备。 您应该会在屏幕上看到相应的消息。

  3. 现在,让你的文件可执行并将其复制到$PATH一个目录中,比如~/bin/

     $ chmod +x bluetooth-runner.py $ mkdir ~/bin # if you dont have it yet $ cp bluetooth-runner.py ~/bin 
  4. 现在,确保您可以从终端的任何位置运行脚本(确保它在您的搜索路径中)。

  5. 从ubuntu菜单Startup Applications 。 将您的脚本添加到启动中。

    添加启动应用程序

  6. 现在,只剩下一个问题,在您登录时,脚本可能无法捕获第一个蓝牙事件。 这是因为您的蓝牙设备可能在脚本在后台初始化之前已连接。

    要解决此问题,请直接在“ 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