Playing Audio over Bluetooth on Rasbperry Pi (Using Bluealsa, Command Line)

In many situations (connecting remotely to the pi, programmatically playing audio), it is necessary to have command line interface (CLI) options that enable you setup and play audio via bluetooth. This post covers the process of connecting to a bluetooth device (speaker) and using the bluealsa library to play audio via command line. The post also includes a sample on how play audio over bluetooth devices  a Nodejs app using the sound-player nodejs library.

Step 1: Install Bluealsa

Bluealsa is a direct integration between the Bluez (an implementation of the Bluetooth protocol stack.) and the alsa sound library. Previously, this was done using PulseAudio. However bluez-alsa promises better ..

The current status quo is, that in order to stream audio from/to a Bluetooth device, one has to install PulseAudio, or use Bluez < 5. However, Bluez version 4 is considered to be deprecated, so the only reasonable way to achieve this goal is to install PulseAudio.

With this application (later named as BlueALSA), one can achieve the same goal as with PulseAudio, but with less dependencies and more bare-metal-like. BlueALSA registers all known Bluetooth audio profiles in Bluez, so in theory every Bluetooth device (with audio capabilities) can be connected. In order to access the audio stream, one has to connect to the ALSA PCM device called bluealsa. The device is based on the ALSA software PCM plugin.

To install bluez-also, use

sudo apt-get install bluealsa 

if interested in building bluealsa from source, please see the project github page.

Note: If you are running the recent version of the Raspberry Pi OS – Stretch, it already comes with bluealsa installed.

Step 2: Connect Your Bluetooth Device (Speaker, mic etc)

To do this, the linux bluetooth control CLI tool (bluetoothctl) is used to scan for devices (get MAC address), pair and then connect to them.

bluetoothctl  // start the bluetooth control tool

power on // turn on your Pi bluetooth interface if off

agent on // turn on the default bluetooth agent

scan on   // scan for all nearby bluetooth device. Your device should be discoverable and turned. Note your devices mac address

pair XX:XX:XX:XX:XX   // You should see pairing successful

connect XX:XX:XX:XX:XX // You should see connection successful

Step3: Play Audio.

Once step 2 is completed, your bluetooth device should now be available  to bluealsa as a virtual PCM device. What you need to know now is the right deviceid which can be passed as a parameter to sound libraries such as aplay, afplay, mpg321 etc. Your deviceid is given as:

bluealsa:HCI=hci0,DEV=XX:XX:XX:XX:XX:XX,PROFILE=a2dp

XX:XX:XX:XX:XX:XX represents your bluetooth device mac address.

To play an audio file using aplay, simply supply the device id

aplay -D bluealsa:HCI=hci0,DEV=XX:XX:XX:XX:XX:XX,PROFILE=a2dp /usr/share/sounds/alsa/Front_Center.wav

Similarly, to play an audio file using mpg321,

mpg321 -a bluealsa:HCI=hci0,DEV=XX:XX:XX:XX:XX:XX,PROFILE=a2dp /usr/share/sounds/alsa/Front_Center.wav

Note: Given your bluetooth device is a virtual device, it will not be listed when you run aplay -l or similar listing commands.

Bonus: Recording Audio

To record audio via your bluetooth device .. if it has a microphone is also fairly easy. Again, you update your device id parameter. However, rather than using a2dp as profile, you use sco.

 

arecord -D bluealsa:HCI=hci0,DEV=XX:XX:XX:XX:XX:XX,PROFILE=sco test.wav

(I have had some difficulty with audio recording where the recorded file just contain nothing ..:( … might be my headset)

A Nodejs Implementation

A simple example to play audio over bluetooth is using the sound-player nodejs library. Simply set the device parameter to your bluealsa virtual pcm deviceid.


var soundplayer = require("sound-player")
var options = {
filename: "preview.wav",
gain: 10,
debug: true,
player: 'aplay',
device: 'bluealsa:HCI=hci0,DEV=XX:XX:XX:XX:XX:XX,PROFILE=a2dp'
}

var player = new soundplayer(options)
player.play();

player.on('error', function(err) {
console.log('Error occurred:', err);
});

 

Final Note: Bluealsa and PulseAudio do not play well together.

You will have to completely uninstall PulseAudio and all its baggage in order to use bluealsa.

Due to BlueZ limitations, it seems, that it is not possible to use BlueALSA and PulseAudio to handle Bluetooth audio together. BlueZ can not handle more than one application which registers audio profile in the Bluetooth stack. However, it is possible to run BlueALSA and PulseAudio alongside, but Bluetooth support has to be disabled in the PulseAudio. Any Bluetooth related module has to be unloaded

However, from my tests, playing audio over bluetooth using bluealsa has been a  easier/faster to setup and more stable compared to using pulseaudio.

This post and the above code snippet was tested on a Raspberry Pi 3 running Stretch.

 

About Vykthur

Mobile and Web App Developer and Researcher. Passionate about learning, teaching, and recently - writing.
This entry was posted in Programming and tagged , , , , . Bookmark the permalink.
  • jimla

    Vykthur – can’t seem to find bluealsa – in debian package manager – lots of alsa packages though – any idea?

    • Vykthur

      I believe that should be sudo apt-get install bluealsa