ฉันจะเรียกใช้สคริปต์เมื่ออุปกรณ์ Bluetooth เชื่อมต่อได้อย่างไร


16

ฉันต้องการเริ่มเครื่องเล่นเพลง (Clementine) เมื่อชุดหูฟังบลูทู ธ ของฉันเชื่อมต่อกับคอมพิวเตอร์ ฉันจะตรวจสอบการเชื่อมต่ออุปกรณ์บลูทู ธ เพื่อให้ฉันสามารถเรียกใช้สคริปต์เพื่อเริ่มเล่นได้อย่างไร

คำตอบ:


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

ดีมากถ้าคุณรู้DEV_IDก่อนการเชื่อมต่อ .. แต่ถ้าคุณต้องการที่จะได้รับการแจ้งเตือนจากเหตุการณ์การเชื่อมต่อทั้งหมด?
pstanton

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 เมื่อเชื่อมต่อชุดหูฟัง

จากนั้นเราก็จะเห็นว่ามีอ่างเสียง Bluetooth ด้วยหรือไม่

pacmd list-sinks | grep xx_xx_xx_xx_xx_xx

ที่อยู่xx_xx_xx_xx_xx_xxMAC อยู่ที่ไหน( :ต้องถูกแทนที่ด้วย_) ผลลัพธ์จะแจ้งให้คุณทราบว่ามีอ่างเสียง Bluetooth หรือไม่ถ้าไม่มี

ดู คำตอบนี้เกี่ยวกับวิธีการสลับเสียงไปยังอ่างล้างจานนี้


Stream2ip

กับ stream2ipเราสามารถกำหนดคำสั่งเชลล์หรือสคริปต์เพื่อเรียกใช้หลังจากสร้างการเชื่อมต่อ นอกจากนี้ยังมีตัวเลือกในการเริ่มต้นเครื่องเล่นสื่อที่รองรับโดยอัตโนมัติหลังจากสร้างการเชื่อมต่อ:

ป้อนคำอธิบายรูปภาพที่นี่

Stream2ip จะพยายามเชื่อมต่อสตรีมการเล่นที่กำลังเรียกใช้ไปยังอุปกรณ์เสียง Bluetooth ในกรณีที่การเชื่อมต่อถูกขัดจังหวะ


ขอบคุณสำหรับคำตอบ. คุณกำลังแนะนำว่าฉันควรสำรวจด้วยsdptool browse <device-id>จนกว่าฉันจะได้รับรหัสส่งคืน 0 จากนั้นเริ่มต้นสคริปต์ของฉันใช่ไหม มีวิธีทำโดยไม่มีการเลือกตั้งหรือไม่
Erigami

Sdptool ช้า ฉันจะไปสำหรับ pulseaudio คุณต้องวนซ้ำเพราะเราไม่รู้ว่าเมื่อไหร่ที่อุปกรณ์ของคุณอยู่ที่นั่น
Takkat

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สามารถนำมาใช้เพิ่มเติม เป็นเครื่องมือ GUI เพื่อดูวัตถุ dbus


1
หากคุณต้องการปรับปรุงคำตอบอื่น ๆ โปรดแนะนำการแก้ไขและไม่สร้างคำตอบใหม่
David Foerster

1

นี่เป็นอีกตัวอย่างสำหรับการตรวจสอบอุปกรณ์บลูทู ธ ทั้งหมด ไม่จำเป็นต้องระบุที่อยู่ MAC เฉพาะ วิธีนี้ทำให้การตั้งค่า xinput ยังคงอยู่แม้ว่าจะเข้าสู่ระบบ / ออกระงับ / ปลุกและเชื่อมต่อ / เลิกเชื่อมต่ออุปกรณ์บลูทู ธ ของคุณ

ฉันมีคีย์บอร์ด Bluetooth ขนาดกะทัดรัดของ Thinkpad และฉันต้องการเรียกใช้คำสั่ง xinput ทุกครั้งที่เชื่อมต่อแป้นพิมพ์เพื่อปรับความเร็วของ trackpoint นี่คือขั้นตอน

  1. รหัสดาวน์โหลดจาก Github บลูทู ธ 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. เปิดไฟStartup Applicationsจากเมนูอูบุนตู เพิ่มสคริปต์ของคุณเพื่อเริ่มต้น

    เพิ่มแอปพลิเคชั่นเริ่มต้น

  6. ตอนนี้เหลือเพียงปัญหาเดียวในขณะที่คุณลงชื่อเข้าใช้สคริปต์อาจไม่ได้รับความสนใจอันดับแรกเหตุการณ์บลูทู ธนี่เป็นเพราะอุปกรณ์บลูทู ธ ของคุณอาจเชื่อมต่อก่อนที่สคริปต์ของคุณจะเริ่มต้นในพื้นหลัง

    Startup Applicationsเพื่อแก้ปัญหานี้เพิ่มคำสั่งที่กำหนดเองของคุณโดยตรงใน ในกรณีของฉันมันเป็นคำสั่งดังต่อไปนี้:

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

และตอนนี้คุณจะสามารถเพลิดเพลินไปกับอุปกรณ์บลูทู ธ ของคุณด้วย Ubuntu


สคริปต์ python ไม่ได้ตรวจสอบการเชื่อมต่อบลูทู ธ
เปาโลเป

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ทุกอย่างจะถือว่าเป็นคู่และพร้อมที่จะเชื่อมต่อ คุณค้นหาที่อยู่ MAC ใน blueman หรือโดยการเรียกใช้pacmd list-sinks | grep -e 'name:' -e 'index'เมื่ออุปกรณ์บลูทู ธ เชื่อมต่อ bluetooth-connect && your-scriptคุณต้องการเรียกใช้ your-scriptจะทำงานเมื่อการเชื่อมต่อสำเร็จ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.