Bluetoothヘッドセットがコンピューターに接続したときに、音楽プレーヤー(Clementine)を起動したいのですが。 Bluetoothデバイスの接続を検出して、スクリプトを実行してプレーヤーを起動するにはどうすればよいですか?
私はポーリングのアプローチが好きではなかったので、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()
正常に確立された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オーディオシンクがあるかどうかが表示されます。
オーディオをこのシンクに切り替える方法については、 this answer を参照してください。
stream2ipを使用すると、接続が確立された後に実行するシェルコマンドまたはスクリプトを定義できます。接続の確立後に、サポートされているメディアプレーヤーを自動的に開始するオプションもあります。
Stream2ipは、接続が中断された場合に、現在実行中の再生ストリームをBluetoothオーディオデバイスに再接続しようとします。
すべてのBluetoothデバイスを監視する別の例を次に示します。特定のMACアドレスを指定する必要はありません。このアプローチにより、Bluetoothデバイスのログイン/アウト、サスペンド/ウェイク、および接続/切断時でもxinput設定が維持されます。
ThinkpadコンパクトBluetoothキーボードを使用しています。キーボードを接続してトラックポイントの速度を調整するたびにxinputコマンドを実行したいと思います。手順は次のとおりです。
Github bluetooth-ruunner からコードをダウンロードします。 ここ Raspberry Piの最初の作成者に与えられたクレジット。 Modifyコードの次のセクションを変更して、カスタムコマンドを実行します。
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
ここで、端末のどこからでもスクリプトを実行できることを確認してください(検索パスにあることを確認してください)。
UbuntuメニューからStartup Applications
を起動します。スクリプトをスタートアップに追加します。
これで、ログイン時に問題が1つだけ残ります。スクリプトは、非常に最初のbluetoothイベントをキャッチしない可能性があります。これは、バックグラウンドでスクリプトが初期化される前に、Bluetoothデバイスが接続される可能性があるためです。
これを解決するには、Startup Applications
にカスタムコマンドを直接追加します。私の場合、次のコマンドです。
xinput set-prop 'ThinkPad Compact Bluetooth Keyboard with TrackPoint' 'Device Accel Constant Deceleration' 0.6
これで、UbuntuでBluetoothデバイスを楽しむことができるようになります。
@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レシーバーに設定するためにしたことです(ハードウェアキーで音量を変更できます)。
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で見つけるか、bluetoothデバイスが接続されているときにpacmd list-sinks | grep -e 'name:' -e 'index'
を実行します。 bluetooth-connect && your-script
を実行します。 your-script
は、接続が正常に確立されたときにのみ実行されます。