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

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

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

答案1

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

答案2

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

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

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

在此处输入图片描述

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

答案3

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

答案4

你写“当你的耳机连接到你的电脑时”。它是如何自动做到这一点的?当你必须手动触发它时,你不妨将其制作成脚本,然后在建立连接后运行你的脚本。这是我将默认输出设备设置为我的蓝牙接收器所做的(这样我就可以用硬件键更改音量):

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'在蓝牙设备连接时运行。您可能希望运行bluetooth-connect && your-scriptyour-script只有在成功建立连接后才会运行。

相关内容