回答:
私はポーリングのアプローチが好きではなかったので、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()
DEV_ID
接続前のことを知っていれば素晴らしいことですが、すべての接続イベントを通知したい場合はどうでしょうか?
正常に確立されたBluetooth接続を検出するには、次を実行します。
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
スクリプトの正確な目的はわかりませんが、ほとんどの場合、ヘッドセットが接続されているときにクレメンタイン経由でオーディオを再生したいと考えています。
その後、Bluetoothオーディオシンクが
pacmd list-sinks | grep xx_xx_xx_xx_xx_xx
xx_xx_xx_xx_xx_xx
MACアドレスはどこにありますか(:
で置き換える必要があります_
)。出力には、使用可能なBluetoothオーディオシンクがあるかどうかが表示されます。
オーディオをこのシンクに切り替える方法については、この回答を参照してください。
stream2ip我々は、シェルコマンドまたは接続が確立された後に実行するスクリプトを定義することができます。接続が確立された後に、サポートされているメディアプレーヤーを自動的に開始するオプションもあります。
Stream2ipは、接続が中断された場合に、現在実行中の再生ストリームをBluetoothオーディオデバイスに再接続しようとします。
sdptool browse <device-id>
0のリターンコードを取得してからスクリプトを開始するまで、ポーリングする必要があることを提案していますか?ポーリングなしでそれを行う方法はありますか?
@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デバイスを監視する別の例を次に示します。特定のMACアドレスを指定する必要はありません。このアプローチにより、Bluetoothデバイスのログイン/アウト、サスペンド/ウェイク、および接続/切断時でもxinput設定が維持されます。
ThinkpadのコンパクトなBluetoothキーボードを使用しており、キーボードが接続されていてトラックポイントの速度を調整するたびにxinputコマンドを実行したい。手順は次のとおりです。
Github bluetooth-ruunnerからコードをダウンロードします。Raspberry Pi用に最初にこれを書いた人に与えられたクレジット。コードの次のセクションを変更して、カスタムコマンドを実行します。
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
変更を保存します。スクリプトを実行してみてください
$ python bluetooth-runner.py
Bluethoothデバイスを接続および切断します。画面に対応するメッセージが印刷されます。
今、あなたのファイルを実行可能にしますし、あなたの中のディレクトリの一つにそれをコピーし$PATH
、言います~/bin/
。
$ chmod +x bluetooth-runner.py
$ mkdir ~/bin # if you dont have it yet
$ cp bluetooth-runner.py ~/bin
ここで、端末のどこからでもスクリプトを実行できることを確認します(検索パスにあることを確認してください)。
アップ火災Startup Applications
Ubuntuのメニューから。スクリプトをスタートアップに追加します。
これで、ログイン時の問題が1つだけ残りました。スクリプトは、最初の bluetoothイベントをキャッチできません。これは、スクリプトがバックグラウンドで初期化される前に、Bluetoothデバイスが接続される可能性があるためです。
これを解決するには、カスタムコマンドをに直接追加しますStartup Applications
。私の場合、次のコマンドです。
xinput set-prop 'ThinkPad Compact Bluetooth Keyboard with TrackPoint' 'Device Accel Constant Deceleration' 0.6
これで、UbuntuでBluetoothデバイスを楽しむことができます。
「ヘッドセットがコンピューターに接続するとき」と書きます。それはどうやって自動的に行われますか?手動でトリガーする必要がある場合は、それをスクリプトにして、接続が確立された後にスクリプトを実行することもできます。これは、デフォルトの出力デバイスをbluetoothレシーバーに設定するためにしたことです(ハードウェアキーで音量を変更できます)。
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デバイスが接続されているときに実行します。実行したいでしょうbluetooth-connect && your-script
。your-script
接続が正常に確立されたときにのみ実行されます。