Bluetooth audio on a headless Raspberry Pi using BlueAlsa¶
Intro¶
How to connect a Bluetooth speaker or a pair of Bluetooth headphones to a Rapberry Pi using the command line. No PulseAudio required!
Tested on a Raspberry Pi 400 running freshly installed [1] Raspberry Pi OS Lite aka Rasbian GNU/Linux 10 (Buster). Report any issues on GitHub.
BlueAlsa [2] is a Bluetooth audio backend for ALSA. It bridges the gap between BlueZ 5 (the Bluetooth stack) and ALSA (the audio stack) without the need for PulseAudio (a fat sound server).
Note
These instructions don’t apply to Rasbian 11 as it doesn’t ship a BlueAlsa package.
Rasbian 12 should include bluez-alsa-utils
[3]; this page will be updated thereafter.
Command lines¶
A full terminal log is available here.
Note
The prompts have been removed for the best copy-pasting experience. You can highlight whole code blocks, no need to aim for corners!
Worried about “Pastejacking”? You can clone this website’s git repo and get hit by malicious build scripts instead or view this page’s raw reST source.
Adding the ‘pi’ user to the ‘bluetooth’ group¶
sudo usermod -G bluetooth -a pi && logout
Logout is needed for the change to take effect.
Installing and starting the BlueAlsa daemon¶
sudo apt update && sudo apt install bluealsa -y && \
sudo service bluealsa start
On Debian and derivatives the service will be enabled on startup by default.
Connecting a Bluetooth device¶
Warning
The code blocks in this section can not be copy-pasted.
Lines with commands to enter are emphasized.
The 00:00:00:00:00:00
and AA:BB:CC:DD:EE:FF
below stand for the MAC addresses of your Bluetooth controller and audio device, respectively. You’ll find them out soon.
Using bluetoothctl interactively¶
Automating bluetoothctl
is currently not covered in this article. I’ve listed some pointers here [6].
Start the bluetoothctl
shell. On Raspbian Lite Bluetooth is enabled out of the box and the agent is registered automatically.
pi@raspberrypi:~ $ bluetoothctl
Agent registered
[bluetooth]#
The last line shows the bluetoothctl
prompt; the following commands are executed in the bluetoothctl
shell.
Tip
Tab completion works here, no need to type the full address!
To discover your Bluetooth device’s MAC, turn scan on
. Make sure the device is in pairing mode!
[bluetooth]# scan on
Discovery started
[CHG] Controller 00:00:00:00:00:00 Discovering: yes
bluetoothctl
will keep spitting out scan results so you might want to turn scan off
after recognizing your device. Exiting bluetoothctl
will turn off scanning automatically, but we’re not there yet!
Next up: pairing, trusting and connecting. Trusting enables connecting automatically, including after reboot. Yet you need to connect manually for the first time.
[bluetooth]# pair AA:BB:CC:DD:EE:FF
Attempting to pair with AA:BB:CC:DD:EE:FF
[CHG] Device AA:BB:CC:DD:EE:FF Connected: yes
[CHG] Device AA:BB:CC:DD:EE:FF ServicesResolved: yes
[CHG] Device AA:BB:CC:DD:EE:FF Paired: yes
Pairing successful
[CHG] Device AA:BB:CC:DD:EE:FF ServicesResolved: no
[CHG] Device AA:BB:CC:DD:EE:FF Connected: no
[bluetooth]# trust AA:BB:CC:DD:EE:FF
[CHG] Device AA:BB:CC:DD:EE:FF Trusted: yes
Changing AA:BB:CC:DD:EE:FF trust succeeded
[bluetooth]# connect AA:BB:CC:DD:EE:FF
Attempting to connect to AA:BB:CC:DD:EE:FF
[CHG] Device AA:BB:CC:DD:EE:FF Connected: yes
Connection successful
The prompt changes to reflect connection status. Exit the bluetoothctl
shell with either ^D
or typing quit
.
[BT DEVICE NAME]# quit
Your Bluetooth device’s MAC address is needed in the next step, so let’s save it into a variable as follows:
pi@raspberrypi:~ $ MAC="AA:BB:CC:DD:EE:FF"
Playing audio¶
The following barebones system-wide config for bluealsa
defaults to using A2DP (ie. not sounding like a cheap handsfree); see the Gentoo Wiki article on Bluetooth headphones [4], the BlueALSA README [2] and the ALSA Wiki [5] for more information about configuration, listed here in order of thoroughness and relevance.
A simple multi-device asound.conf can be found here.
The following lines are indented with four spaces; the tab key doesn’t work as expected in here documents [7], but it does in your text editor.
Note
$MAC
is your Bluetooth device’s MAC address and is substituted automatically (as long as you did the previous section in the same shell). Feel free to copypaste!
sudo tee /etc/asound.conf <<EOF
defaults.bluealsa {
interface "hci0"
device "$MAC"
profile "a2dp"
}
EOF
All done. Test with aplay
:
Warning
Loud!
aplay -D bluealsa /usr/share/sounds/alsa/Front_Center.wav
The file should play without throwing any errors.
Example of streaming audio from YouTube using mpv¶
The youtube-dl
[8] version installed in tandem with mpv
is really old; the package from PyPI is used here instead.
sudo apt install -y python3-pip mpv && \
sudo apt purge -y youtube-dl && \
sudo pip3 install youtube-dl && \
mpv --no-video --audio-device=alsa/bluealsa ytdl://dQw4w9WgXcQ
mpv
can be configured to use BlueAlsa by default. Below is a simple system-wide mpv.conf
for audio-only Bluetooth usage; ~/.config/mpv/mpv.conf
is where per-user configuration resides. For more information, search for “Configuration files” in the mpv manual [9]. alsa/$PCM_NAME
(for example alsa/btheadset
) is used to refer to a spesific device.
sudo tee /etc/mpv/mpv.conf <<EOF
no-video
volume=50
audio-device=alsa/bluealsa
EOF
Disabling SAP (optional)¶
sudo mkdir /etc/systemd/system/bluetooth.service.d && \
cd /etc/systemd/system/bluetooth.service.d && \
sudo tee 01-disable-sap-plugin.conf <<EOF
[Service]
ExecStart=
ExecStart=/usr/lib/bluetooth/bluetoothd --noplugin=sap
EOF
sudo systemctl daemon-reload && \
sudo systemctl restart bluetooth.service
The empty ExecStart=
line is required for replacing the daemon’s start command and not just appending to it [10].
Reloading daemon configurations and restarting the bluetooth
service requires no reboot. [11]
Further reading¶
I have found the following resources useful. Feel free to look elsewhere, but be wary of everything assuming you have or need PulseAudio. To prevent link rot, I’ve made sure both the Internet Archive Wayback Machine and archive.today have a copy available as well as forked the repos/gists on GitHub.
See also the open GitHub issue “Add a mention on setting the sound device as default” for some discussion regarding ALSA defaults and fallbacks, as well as how to set a higher baud rate to fix sound stuttering.