Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

Is there a way to set the Bluetooth in Ubuntu to autoconnect to devices it is paired to when it is turned on. Furthermore, is there a way to automatically change the sound output to a Bluetooth headset on connection?

share|improve this question
add comment

2 Answers 2

up vote 9 down vote accepted
+50

Pulseaudio >= 1.0

By editing the /etc/pulse/default.pa we can load the pulseaudio module module-switch-on-connect to autoconnect to an audio sink as soon as it is presented to the pulseaudio sound server. We need to insert the following line

load-module module-switch-on-connect

Previous versions of pulseaudio

Bluetooth devices are recognized in PulseAudio as soon as they are present. However connection needs to be made manually in audio settings. There is a GUI that allows one-click connection to BT devices (stream2ip).

Edit: From version 0.2.5 stream2ip allows auto-connecting to Bluetooth devices.

Edit: you can set up your bluez device as default device (e.g. by using pactl or in the config settings) with fallback to internal audio if no bluetooth device is present.

Edit: Here is a quick and dirty Python script to give you an idea on how to do the job:

#!/usr/bin/env python
#-*- coding: utf-8 -*-
#
# bt-autoconnect
# Autoconnects Bluetooth Devices to PulseAudio
# (c) Takkat Nebuk
# Licence: GPLv3
# usage:
# bt-autoconnect <MAC> <timeout>

import subprocess
import time
import sys
import string

cli_options = sys.argv

def main():
    MAC = cli_options[1]
    timeout = cli_options[2]
    PMAC = string.replace(MAC,':','_') # PA don't know ':', needs '_'
    pa_args = ['pacmd set-default-sink bluez_sink.' + PMAC]
    bt_args = ['sdptool browse ' + MAC]
    err = False
    while err == False:
        if subprocess.call(bt_args, shell=True) == 0:
            err = subprocess.call(pa_args, shell=True)
        time.sleep(int(timeout))
    exit()

if __name__ == "__main__":
    main()

Just copy this script and save it as bt-autoconnect.py. Make the script executable or run it from command line (recommended) by cd /script/directory and then type:

python bt-autoconnect.py [MAC] [timeout]

Replace MAC by the MAC of your Bluetooth device (e.g. 00:0C:78:4F:B6:B5) and set a desired timeout (e.g. 10) in seconds when the script looks for the device. This script will then listen to the given MAC every timeout seconds for a Bluetooth device and connects it to PulseAudio if present. The script will run forever until it's being killed or the virtual terminal was closed.

Sometimes PulseAudio seems not to be aware of the device being present again after it has been switched out. With some hope pulseaudio -k makes it reappear.

Not fancy, no GUI but at least in my settings it worked o.k..

Edit for those interested: bt-autoconnect with GUI for convenient setup is released. Please file bugs or suggestions there. Thank you for testing.

share|improve this answer
3  
You don't need to post a comment to add additional information. You can instead just edit it into you original answer and have it all in one place. –  Chris Wilson Oct 20 '10 at 12:37
add comment

Unfortunately, I have only now seen the answer from Takkat, It seems to be the better way than mine.

I guess this might still be relevant for Pulseaudio < 1.0. It doesn't use polling, but listens to Bluetooth events on dbus:

#!/usr/bin/python

# based on monitor-bluetooth
# Changes by Domen Puncer <domen@cba.si>

import gobject
import dbus
import dbus.mainloop.glib
import os


# we want this event: {AudioSource.PropertyChanged} [/org/bluez/16797/hci0/dev_00_24_7E_51_F7_52] State = playing
# and when that happens: pactl load-module module-loopback source=bluez_source.00_24_7E_51_F7_52 sink=alsa_output.pci-0000_00_1b.0.analog-stereo
def property_changed(name, value, path, interface):
    iface = interface[interface.rfind(".") + 1:]
    val = str(value)
    print "{%s.PropertyChanged} [%s] %s = %s" % (iface, path, name, val)
    if iface == "AudioSource" and name == "State" and val == "playing":
        bt_addr = "_".join(path.split('/')[-1].split('_')[1:])
        cmd = "pactl load-module module-loopback source=bluez_source.%s sink=alsa_output.pci-0000_00_1b.0.analog-stereo" % bt_addr
        os.system(cmd)


def object_signal(value, path, interface, member):
    iface = interface[interface.rfind(".") + 1:]
    val = str(value)
    print "{%s.%s} [%s] Path = %s" % (iface, member, path, val)

if __name__ == '__main__':
    dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)

    bus = dbus.SystemBus()

    bus.add_signal_receiver(property_changed, bus_name="org.bluez", signal_name = "PropertyChanged", path_keyword="path", interface_keyword="interface")

    mainloop = gobject.MainLoop()
    mainloop.run()
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.