MPD with double wireless remote pulse bluetooth sink
I had the beautifully stupid idea of firing my mpd with a central hub that connects to multiple bluetooth devices all over my appartment.
o ------------ o o ------------------ o o ----------------- o
| MPD (Docker) | ---> | Pulse Server (RPi) | ---> | Bluetooth Speaker |
o ------------ o o ------------------ o o ----------------- o
MPD
The config for the mpd is fairly straight forward:
audio_output {
type "pulse"
name "PulseAudio Edifier Wohnraum"
server "192.168.178.48"
sink "bluez_sink.FC_E8_06_57_A9_8D.a2dp_sink"
}
The server
address is the address of the Raspberry Pi, which runs the pulseaudio server and the sink
is the audio device local to the Raspberry Pi. To find out what device you have to enter here just run pactl list short sinks
on the Pi and choose the right device (this will be explained later).
Pulse Server
This is the hard part, there will be problems and you have to debug a lot.
First of all configure a headless Raspberry Pi to run a pulseaudio server and bluetoothd. On Arch Linux for Arm I installed the following packages:
pacman -S pulseaudio-bluetooh bluez dbus bluez-tools
Make sure /etc/pulse/system.pa contains the following:
Create Systemd Unit files to run the pulseaudio server in system mode:
And enable it with systemctl enable pulseaudio.service
.
Now you have to create the pulse user: adduser -m pulse
and add it to the respective groups:
usermod -a -G bluetooth pulse # I haven't had this group, works anyway
usermod -a -G audio pulse
usermod -a -G pulse-access root
To allow it being configured by the buetoothd create the following file (the whole path might not preexist on your system): /etc/dbus-1/system.d/pulseaudio.conf
Adding the bluetooth device (headless)
You can either use the bt-device tool but I didn't do that. I can only explain how the procedure works with bluetoothctl:
[root@alarm]# bluetoothctl
Agent registered
[CHG] Controller B8:27:EB:3E:68:DC Pairable: yes
[bluetooth]# scan on
Discovery started
[CHG] Controller B8:27:EB:3E:68:DC Discovering: yes
[NEW] Device FC:E8:06:57:A9:8D EDIFIER R1380DB
[CHG] Device FC:E8:06:57:A9:8D TxPower: 4
[CHG] Device FC:E8:06:57:A9:8D UUIDs: 0000110d-0000-1000-8000-00805f9b34fb
[CHG] Device FC:E8:06:57:A9:8D UUIDs: 0000110b-0000-1000-8000-00805f9b34fb
[CHG] Device FC:E8:06:57:A9:8D UUIDs: 0000110e-0000-1000-8000-00805f9b34fb
[CHG] Device FC:E8:06:57:A9:8D UUIDs: 0000110f-0000-1000-8000-00805f9b34fb
[CHG] Device FC:E8:06:57:A9:8D RSSI: -70
[bluetooth]# devices
Device FC:E8:06:57:A9:8D EDIFIER R1380DB
[CHG] Device FC:E8:06:57:A9:8D RSSI: -78
[CHG] Device FC:E8:06:57:A9:8D RSSI: -69
[bluetooth]# pair FC:E8:06:57:A9:8D
Attempting to pair with FC:E8:06:57:A9:8D
[CHG] Device FC:E8:06:57:A9:8D Connected: yes
[CHG] Device FC:E8:06:57:A9:8D Bonded: yes
[CHG] Device FC:E8:06:57:A9:8D UUIDs: 00001101-0000-1000-8000-00805f9b34fb
[CHG] Device FC:E8:06:57:A9:8D UUIDs: 0000110b-0000-1000-8000-00805f9b34fb
[CHG] Device FC:E8:06:57:A9:8D UUIDs: 0000110c-0000-1000-8000-00805f9b34fb
[CHG] Device FC:E8:06:57:A9:8D UUIDs: 0000110d-0000-1000-8000-00805f9b34fb
[CHG] Device FC:E8:06:57:A9:8D UUIDs: 0000110e-0000-1000-8000-00805f9b34fb
[CHG] Device FC:E8:06:57:A9:8D UUIDs: 0000110f-0000-1000-8000-00805f9b34fb
[CHG] Device FC:E8:06:57:A9:8D UUIDs: 00001800-0000-1000-8000-00805f9b34fb
[CHG] Device FC:E8:06:57:A9:8D ServicesResolved: yes
[CHG] Device FC:E8:06:57:A9:8D Paired: yes
Pairing successful
[CHG] Device FC:E8:06:57:A9:8D ServicesResolved: no
[CHG] Device FC:E8:06:57:A9:8D Connected: no
[bluetooth]# trust FC:E8:06:57:A9:8D
[CHG] Device FC:E8:06:57:A9:8D Trusted: yes
Changing FC:E8:06:57:A9:8D trust succeeded
[bluetooth]# connect FC:E8:06:57:A9:8D
Attempting to connect to FC:E8:06:57:A9:8D
[CHG] Device FC:E8:06:57:A9:8D Connected: yes
[NEW] Endpoint /org/bluez/hci1/dev_FC_E8_06_57_A9_8D/sep5
[NEW] Endpoint /org/bluez/hci1/dev_FC_E8_06_57_A9_8D/sep1
[NEW] Transport /org/bluez/hci1/dev_FC_E8_06_57_A9_8D/sep1/fd0
Connection successful
[CHG] Transport /org/bluez/hci1/dev_FC_E8_06_57_A9_8D/sep1/fd0 State: active
[CHG] Transport /org/bluez/hci1/dev_FC_E8_06_57_A9_8D/sep1/fd0 Volume: 0x007f (127)
[CHG] Device FC:E8:06:57:A9:8D ServicesResolved: yes
[CHG] Transport /org/bluez/hci1/dev_FC_E8_06_57_A9_8D/sep1/fd0 State: idle
[CHG] Transport /org/bluez/hci1/dev_FC_E8_06_57_A9_8D/sep1/fd0 State: active
There are basically three commands that you have to run:
[bluetooth]# scan on
[bluetooth]# pair FC:E8:06:57:A9:8D
[bluetooth]# trust FC:E8:06:57:A9:8D
[bluetooth]# connect FC:E8:06:57:A9:8D
After that do a reboot. If you are lucky, everything should come up automatically and pactl list short sinks
displays something like this:
0 alsa_output.platform-bcm2835_audio.stereo-fallback module-alsa-card.c s16le 2ch 44100Hz SUSPENDED
1 bluez_sink.FC_E8_06_57_A9_8D.a2dp_sink module-bluez5-device.c s16le 2ch 44100Hz SUSPENDED
This is the device you need to enter in your mpd.conf
Debugging
Next to output in bluetoothctl
I'd recommend an open terminal with journalctl -f
running at all times.
The Raspberry Pi is the worst platform for playing with bluetooth. There is a long standing problem with RPI 2,3 and 4. When wifi is actively used as I'm doing here, the bluetooth audio will be distorted. Crackling audio resulting from adaptively down- and uprading the codec.
Therefore you have to use an USB bluetooth dongle.
But that's not the only problem. Even with an USB dongle you might suffer interruptions. You should try changing the power supply, if the audio suddenly stops playing after 5-15 minutes and your journal looks something like this:
Oct 11 11:46:28 alarm kernel: Bluetooth: hci1: Opcode 0x c52 failed: -110
Oct 11 11:46:28 alarm kernel: Bluetooth: hci1: command 0x0c52 tx timeout
Oct 11 11:46:25 alarm kernel: Bluetooth: hci1: Opcode 0x c13 failed: -110
Oct 11 11:46:25 alarm kernel: Bluetooth: hci1: command 0x0c13 tx timeout
Oct 11 11:46:23 alarm kernel: Bluetooth: hci1: Opcode 0x c52 failed: -110
Oct 11 11:46:23 alarm kernel: Bluetooth: hci1: command 0x0c52 tx timeout