Date: 2014-10-11
Author: Fredrik Boulund
System: HP Microserver running Debian Linux (Debian 7.5 Wheezy)
TLDR: Short recipe to enable Bluetooth A2DP server that is always visible, with automatic bluetooth device pairing, and automatic pulseaudio module loading on Debian 7.5 wheezy.
Thanks to:
Joerg Schiller (https://gist.github.com/joergschiller)
Domen Puncer (https://gist.github.com/domenpuncer)
Daniel Hodgson (https://gist.github.com/Toasty27)
This might also be useful to have a look at: http://askubuntu.com/questions/2573/can-i-use-my-computer-as-an-a2dp-receiver
Note that I spent lots of time on trial and error for this to work, so I might have forgotten some important steps, YMMV. These instructions are mainly for myself to be able to redo everything again, should I ever need to.
All instructions assume that pulseaudio already works. Getting it to work was messy for me and I can't really remember how I did it. I use a USB soundcard that required a little fiddling. All commandlines below use #
and $
to signify root and regular prompt, respectively.
- First of all, install all bluetooth related packages via
apt-get
, e.g.:
# apt-get install bluetooth, bluez, bluez-alsa, bluez-gstreamer, bluez-tools, pulseaudio-module-bluetooth
It could be a good idea to toy around abit with hciconfig
, hcitool
, and perhaps bluetooth-agent
to see that you can manually connect a device and set the server's bluetooth device to discoverable etc.
Then we can start working to enable Bluetooth A2DP server, automatic bluetooth pairing and continous bluetooth visibility/discoverability, and so that pulseaudio loopback modules are automatically loaded and unloaded when connecting a device.
- Edit
/etc/bluetooth/audio.conf
to enable A2DP server abilities:
[General] Enable=Source,Sink,Media,Socket
Most other recipes I've seen only enable "Source" here, however the A2DP service never worked for me unless all these four were present. Make sure to restart the bluetooth device to reload the configuration:
# service bluetooth restart
- Make the computer discoverable:
# hciconfig hci0 piscan
This should be run occassionally (every 300 seconds, as this seems to be the maxlimit on "always visible" for Bluetooth devies):
# while true; do hciconfig hci0 piscan; sleep 300; done
Leave it running in tmux
or screen
window. Actually, being a bit paranoid about having my server's bluetooth device always visibile, I decided it might be a good idea to print the names of paired devices every now and then to see if I should blacklist some device (blacklist: hcitool block BDADDR
). My while loop now looks like this:
# while true; do clear; date; cat /var/lib/bluetooth/NN:NN:NN:NN:NN:NN/names; hciconfig hci0 piscan; sleep 300; done
This also uses date
to show the date and time when the commands were last run.
- Run
bluetooth-agent
to enable automatic pairing (this needs to keep running in a window, usescreen
ortmux
). NNNN is your desired PIN:
# bluetooth-agent NNNN
Leave it running in tmux
or screen
window. This could be in some kind of wrapper to restart it, should something happen with the bluetooth daemon (it stops when the daemon restarts for example).
- Download this brilliant Python script that automatically loads the required loopback module into pulseaudio so that audio is actually played via the soundcard sink (also attached to this gist):
https://gist.github.com/Toasty27/8406352#file-pulseaudio-auto-loopback-py
The script has some dependencies as well (I'm guessingpython-gi
,python-dbus
), but they were covered for me. This script needs to run as a regular user (at least on my system, because root cannot use pulseaudio) and it must be left running, i.e. usescreen
ortmux
. The manual way to do this would be something like this (after bluetooth device connected):
$ pactl list sources $ pactl load-module module-loopback source=N (N is the number of the source found when listing sources)
Then it magically starts playing. However, when you finish playing back audio the module must be unloaded:
$ pactl list short modules $ pactl unload-module NN (NN is the number of the loopback module that was loaded, should be last in the list of the previous command)
- Open an ssh connection in a
tmux
orscreen
session with the same user as the one running the Python script. This is ugly-hacky but if the user isn't logged in the sound will cut out a couple of seconds after connecting each time. I have no idea why this is the case, but after lots of testing I noticed it just works if you leave the user logged in. I think a smart way to go about this could be to have the terminal in this ssh connection actually run the Python script, so you don't need four tmux panes.
When everything is up an running there should be three panes in a tmux
(or screen
) session:
- A root prompt running
while true; do hciconfig hci0 piscan; sleep 300; done
, to continously make your device discoverable. - A root prompt running
bluetooth-agent NNNN
where NNNN is your PIN, to enable devices to connect using this PIN. - A user prompt running
pulseaudio-auto-loopback.py
, to load and unload the loopback module in pulseaudio whenever a device connects/disconnects. - A user prompt running
ssh localhost
, just sitting there being logged in (or use this to run the Python script).
It appears I had to run pactl load-module module-loopback source=bluez_source.XX_XX_XX_XX_XX_XX
at least once for it to work automatically later.
Hi, I don't know if it runs on Debian 8 Jessie or Raspbian as well. I guess it should but the only way to make sure is to try. Please report back if you tried it! :)