Làm cách nào để chạy tập lệnh khi thiết bị Bluetooth kết nối?


16

Tôi muốn khởi động trình phát nhạc của mình (Clementine) khi tai nghe bluetooth của tôi kết nối với máy tính của tôi. Làm cách nào để phát hiện thiết bị bluetooth kết nối để tôi có thể chạy tập lệnh để khởi động trình phát?

Câu trả lời:


12

Tôi không thích cách tiếp cận bỏ phiếu, vì vậy tôi đã thực hiện một số hoạt động đào trên bluez và DBus. Tôi đã kết thúc việc viết kịch bản sau đây:

#!/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()

Tất nhiên Bluez và PulseAudio hoạt động thông qua DBus bỏ phiếu. Miễn là tai nghe của bạn là bộ điều hợp mặc định, nó sẽ hoạt động tốt trong hầu hết các trường hợp. Đảm bảo bạn cũng kết nối PulseAudio với tai nghe nếu bạn muốn nghe điều gì đó. Cảm ơn bạn đã chia sẻ giải pháp của bạn :)
Takkat

thật tuyệt nếu bạn biết DEV_IDtrước khi kết nối .. nhưng nếu bạn muốn được thông báo về tất cả các sự kiện kết nối thì sao?
pstanton

4

Để khám phá kết nối Bluetooth được thiết lập thành công, chúng ta có thể chạy

sdptool browse xx:xx:xx:xx:xx:xx

Bằng cách này, kết nối SDB sẽ được kiểm tra kết nối đến địa chỉ MAC đã cho. Nó có thể mất thời gian đáng kể cho đến khi thời gian duyệt web bị lỗi như

Failed to connect to SDP server on 00:0C:78:4F:B6:B5: Host is down

Chúng tôi không biết mục đích chính xác của tập lệnh của bạn, nhưng rất có thể bạn muốn phát âm thanh qua Clementine khi tai nghe được kết nối.

Sau đó, chúng tôi có thể xem liệu có một bồn rửa âm thanh Bluetooth với

pacmd list-sinks | grep xx_xx_xx_xx_xx_xx

Nơi xx_xx_xx_xx_xx_xxlà địa chỉ MAC ( :cần phải được thay thế bằng _). Đầu ra sau đó sẽ cho bạn biết liệu có sẵn âm thanh Bluetooth hay không nếu không.

Xem câu trả lời này về cách chuyển âm thanh sang bồn rửa này.


Stream2ip

Với stream2ip, chúng ta có thể định nghĩa lệnh shell hoặc script để chạy sau khi kết nối được thiết lập. Ngoài ra còn có một tùy chọn để tự động khởi động trình phát phương tiện được hỗ trợ sau khi kết nối được thiết lập:

nhập mô tả hình ảnh ở đây

Stream2ip cũng sẽ cố gắng kết nối lại luồng phát lại đang chạy với thiết bị âm thanh Bluetooth trong trường hợp kết nối bị gián đoạn.


Cảm ơn câu trả lời của bạn. Bạn đang gợi ý rằng tôi nên thăm dò ý kiến sdptool browse <device-id>cho đến khi tôi nhận được mã trả về 0 và sau đó khởi động kịch bản của mình, phải không? Có cách nào để làm điều đó mà không bỏ phiếu?
Erigami

Sdptool chậm. Tôi sẽ đi cho pulseaudio. Bạn cần một vòng lặp vì chúng tôi không biết khi nào thiết bị của bạn ở đó.
Takkat

2

@Erigami Câu trả lời của bạn đã giúp rất nhiều nhưng để nó hoạt động tôi phải thực hiện một số thay đổi. Tôi đang sử dụng 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()

Tuy nhiên, nếu điều này không hoạt động thì sử dụng và giám sát hệ thống dbus.

dbus-monitor --system

d-feetcó thể được sử dụng hơn nữa. Nó là công cụ GUI để xem các đối tượng dbus.


1
Nếu bạn muốn cải thiện câu trả lời khác, vui lòng đề xuất chỉnh sửa cho câu trả lời và không tạo câu trả lời mới.
David foerster

1

Dưới đây là một ví dụ khác để giám sát tất cả các thiết bị Bluetooth. Nó không cần chỉ định một địa chỉ MAC cụ thể. Cách tiếp cận này làm cho cài đặt xinput liên tục ngay cả khi đăng nhập / thoát, tạm dừng / đánh thức và kết nối / ngắt kết nối thiết bị bluetooth của bạn.

Tôi có Bàn phím Bluetooth nhỏ gọn Thinkpad và tôi muốn chạy lệnh xinput bất cứ khi nào bàn phím được kết nối để điều chỉnh tốc độ của trackpoint. Dưới đây là các bước.

  1. Tải xuống mã từ Github bluetooth-ruunner . Các khoản tín dụng được trao cho đây , người đầu tiên viết bài này cho Raspberry Pi. Sửa đổi phần sau của mã để chạy comamnd tùy chỉnh của bạn.

    subprocess.call(['xinput', 'set-prop',
                     'ThinkPad Compact Bluetooth Keyboard with TrackPoint',
                     'Device Accel Constant Deceleration', '0.6'])

    Trong trường hợp của tôi, điều này tương đương với cuộc gọi từ thiết bị đầu cuối.

    $ xinput set-prop 'ThinkPad Compact Bluetooth Keyboard with TrackPoint' 'Device Accel Constant Deceleration' 0.6
  2. Lưu sửa đổi. Hãy thử chạy tập lệnh của bạn bằng cách

    $ python bluetooth-runner.py

    Kết nối và ngắt kết nối thiết bị Bluethooth của bạn. Bạn sẽ thấy thông báo tương ứng được in trên màn hình.

  3. Bây giờ, làm cho tập tin của bạn thực thi và sao chép nó trong một trong các thư mục trong của bạn $PATH, nói ~/bin/.

    $ chmod +x bluetooth-runner.py
    $ mkdir ~/bin # if you dont have it yet
    $ cp bluetooth-runner.py ~/bin
  4. Bây giờ, hãy đảm bảo bạn có thể chạy tập lệnh từ bất kỳ đâu trong thiết bị đầu cuối (đảm bảo tập lệnh nằm trong đường dẫn tìm kiếm của bạn).

  5. Bật lên Startup Applicationstừ menu ubfox. Thêm tập lệnh của bạn để khởi động.

    Thêm ứng dụng khởi động

  6. Bây giờ, chỉ còn một vấn đề nữa, tại thời điểm bạn đăng nhập, các tập lệnh có thể không bắt được sự kiện bluetooth đầu tiên . Điều này là do thiết bị bluetooth của bạn có thể được kết nối trước khi tập lệnh của bạn được khởi chạy ở chế độ nền.

    Để giải quyết điều này, hãy thêm lệnh tùy chỉnh của bạn trực tiếp vào Startup Applications. Trong trường hợp của tôi, đó là lệnh sau:

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

Và bây giờ bạn sẽ có thể thưởng thức thiết bị Bluetooth của mình với Ubuntu.


kịch bản python không theo dõi kết nối bluetooth.
Paulo Pedroso

0

Bạn viết "khi tai nghe của bạn kết nối với máy tính của bạn". Làm thế nào để nó làm điều đó, tự động? Khi bạn phải kích hoạt thủ công, bạn cũng có thể biến nó thành tập lệnh và sau đó chạy tập lệnh của mình sau khi kết nối được thiết lập. Đây là những gì tôi đã làm để đặt thiết bị đầu ra mặc định thành bộ thu bluetooth của mình (để tôi có thể thay đổi âm lượng bằng các phím cứng):

bluetooth-connect && pactl set-default-sink bluez_sink.0C_A6_94_9A_37_4D

Trường hợp bluetooth-connecttrông như thế này: https://github.com/sblask/dotfiles/blob/c39d37ad67947b58b4a079cb41ae6f9e4a081d8/.bin/bluetooth-connect.symlink Nó giả định mọi thứ đã được ghép nối và sẵn sàng để kết nối. Bạn tìm thấy địa chỉ MAC trong blueman hoặc bằng cách chạy pacmd list-sinks | grep -e 'name:' -e 'index'khi thiết bị bluetooth được kết nối. Bạn sẽ muốn chạy bluetooth-connect && your-script. your-scriptsẽ chỉ được chạy khi kết nối được thiết lập thành công.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.