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


16

当我的蓝牙耳机连接到计算机时,我想启动音乐播放器(Clementine)。如何检测蓝牙设备的连接,以便可以运行脚本启动播放器?

Answers:


12

我不喜欢轮询方法,所以我在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()

当然,Bluez和PulseAudio通过轮询DBus进行操作。只要您的耳机是默认适配器,在大多数情况下都可以正常工作。如果您想听到一些声音,请确保还将PulseAudio连接到耳机。感谢您分享您的解决方案:)
塔卡特(Takkat),2012年

如果您知道DEV_ID连接之前的知识,那就太好了。但是,如果您想收到所有连接事件的通知,该怎么办?
pstanton '17

4

要发现成功建立的蓝牙连接,我们可以运行

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_xxMAC地址在哪里(:需要替换为_)。然后,输出将告诉您是否有可用的蓝牙音频接收器,或者没有。

有关如何将音频切换到此接收器的信息,请参见此答案


Stream2ip

使用stream2ip,我们可以定义建立连接后要运行的shell命令或脚本。建立连接后,还有一个选项可以自动启动受支持的媒体播放器:

在此处输入图片说明

万一连接中断,Stream2ip还将尝试将当前正在运行的播放流重新连接到蓝牙音频设备。


感谢您的回答。您建议我进行轮询,sdptool browse <device-id>直到返回代码为0,然后启动脚本,对吗?有没有一种方法可以不进行轮询?
折纸2012年

sdptool很慢。我去买pulseaudio。您需要循环,因为我们不知道您的设备何时在那儿。
塔卡特2012年

2

@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工具。


1
如果您想改善其他答案,请提出修改建议,不要创建新答案。
大卫·佛斯特

1

这是另一个监视所有蓝牙设备的示例。不需要指定特定的MAC地址。即使登录/注销,挂起/唤醒以及连接/断开蓝牙设备,此方法也可以使xinput设置保持不变。

我有一个Thinkpad紧凑型蓝牙键盘,并且希望在连接键盘时运行xinput命令来调整跟踪点的速度。步骤如下。

  1. 从Github bluetooth-ruunner下载代码。给予学分在这里谁先写到这了树莓派。修改代码的以下部分以运行您的自定义命令。

    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. 火起来的Startup Applications从Ubuntu菜单。将脚本添加到启动中。

    添加启动应用程序

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

    要解决此问题,请直接在中添加您的自定义命令Startup Applications。就我而言,它是以下命令:

     xinput set-prop 'ThinkPad Compact Bluetooth Keyboard with TrackPoint' 'Device Accel Constant Deceleration' 0.6

现在,您将能够在Ubuntu上享受您的蓝牙设备。


python脚本不监视蓝牙连接。
Paulo Pedroso

0

您输入“当耳机连接到计算机时”。它是如何自动做到的?当您必须手动触发它时,最好将其设为脚本,然后在建立连接后运行脚本。这是我将默认输出设备设置为蓝牙接收器的操作(因此我可以使用硬件键更改音量):

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'在连接蓝牙设备时通过运行找到MAC地址。您将要运行bluetooth-connect && your-scriptyour-script仅在成功建立连接后运行。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.