NOTE: Skip all of the BS, and go to the Summary if you don't need all the verbiage!
Any of you that have followed my misadventures on Stack Exchange will know that I have struggled off-and-on for years trying to get my Raspberry Pi OS 'Lite' to play audio over Bluetooth. This frustration came to a head recently during a dialog with the RPi staff on GitHub. This was (and is) a simple case of corporate irresponsibility! I got more than a little fed up with the nonsense from some of the Raspberry Pi maintainers. It wasn't an abusive exchange - but it was pointed. Pointed enough that I was "banned" from their GitHub site - apparently "for life". Wow!... This is one thin-skinned bunch of assholes!
And Raspberry Pi is not like other open-source projects - this organization makes a tidy profit from the sale of devices, and supporting their industrial customer base. Consequently, they have an obligation to support the items they sell! Imagine that you have a profitable business selling Raspberry Pi hardware. You should realize that part and parcel of that business is producing and maintaining a certain amount of software. But then you allow some of your employees to lord it over users/customers. IMO, their attitude is all wrong! Unlike many other open source projects, Raspberry Pi provides nothing for free! To close this brouhaha: I'm sick and tired of arses who refuse to support their own software product because they deem it to be niche. <END OF RANT>
... So a bit of time has passed since that episode. As I reported a few days afterwards (in an earlier revision of this recipe), I managed to get pipewire
, wireplumber
(and assorted other dependencies) working! Yes... I was actually able to play music on an old 'JBL Flip5' BT speaker through my Raspberry Pi 3A+ "Lite" system!
Recently, I have managed to extend this success with Bluetooth:
- Completed a fresh installation (documented herein) of
pipewire
(ver '0.3.65') on the latest RPi OS Lite (July 4, 2024) 'bookworm' on an RPi 3A+ - Have Bluetooth audio working on a RPi Zero 2W 'bookworm' using
bluez-alsa
- Most recently, have upgraded
pipewire
to ver. 1.2.1 on RPi Zero 2W 'bookworm' using Debian'sbookworm-backports
I'll cover this in the sequel below.
of
pipewire
installation on RPi 3A+ under 'bookworm'
NOTE: (see DETAILS below for more information)
For those of you who want to get right down to business, following is a SUMMARY of the DETAILED procedures that follow:
$ bluetoothctl
[bluetooth]# help <prints a brief command summary>
[bluetooth]# power on
[bluetooth]# pairable on
[bluetooth]# scan on
<< scanning begins, wait until your device (speaker, headphones) shows up, and then: >>
[bluetooth]# scan off
[bluetooth]# trust <device id; e.g. B8:F6:53:9B:1A:97>
[bluetooth]# pair <device id; e.g. B8:F6:53:9B:1A:97>
[bluetooth]# quit
$ sudo apt install pipewire libspa-0.2-bluetooth
$ sudo vim /etc/systemd/system/getty.target.wants/getty@tty1.service
FROM:
[Service]
ExecStart=-/sbin/agetty -o '-p -- \\u' --noclear - $TERM
TO:
[Service]
ExecStart=
ExecStart=-/sbin/agetty --autologin pi --noclear %I $TERM
Start with a fresh install of 'bookworm Lite'. I decided to start from scratch mainly to convince myself that I had not inadvertently installed or configured something that might have influenced the outcome; i.e. my thinking is that accidental success is worse than failure! Here are the detailed steps I followed:
Before beginning the pipewire
installation, I used the bluetoothctl
package to:
- scan & discover my 'JBL Flip5' BT speaker
- "trust" & "pair" the Flip5 with the RPi3A BT controller
As I've written previously, using bluetoothctl
is a grubby effort that seems (to me) a rather hit-or-miss exercise. It seems the most awkward part is getting the speaker to show up during the "scan". I also had some troubles getting the "trust" established as there were repeated "Device B8:F6:53:9B:1A:97 not available" errors after the speaker was discovered during the "scan". In general, here's how I undertook the bluetoothctl
rain dance:
$ bluetoothctl
Agent registered
[CHG] Controller B8:27:EB:F3:8A:58 Pairable: yes
[bluetooth]# help
# "help" lists a command summary
[bluetooth]# power on
Changing power on succeeded
[bluetooth]# pairable on
Changing pairable on succeeded
[bluetooth]# scan on
Discovery started
[CHG] Controller B8:27:EB:F3:8A:58 Discovering: yes
[NEW] Device 78:B8:B3:5A:49:CA 78-B8-B3-5A-49-CA
[NEW] Device 22:A2:77:3A:65:3B 22-A2-77-3A-65-3B
...
# blah, blah, blah; on and on and on... eventually, with some luck, you hit "paydirt"
...
[NEW] Device B8:F6:53:9B:1A:97 JBL Flip 5
...
[bluetooth]# scan off
Discovery stopped
...
[bluetooth]# trust B8:F6:53:9B:1A:97
[CHG] Device B8:F6:53:9B:1A:97 Trusted: yes
Changing B8:F6:53:9B:1A:97 trust succeeded
[bluetooth]# pair B8:F6:53:9B:1A:97
Attempting to pair with B8:F6:53:9B:1A:97
[CHG] Device B8:F6:53:9B:1A:97 Connected: yes
[CHG] Device B8:F6:53:9B:1A:97 Bonded: yes
[CHG] Device B8:F6:53:9B:1A:97 UUIDs: 00001101-0000-1000-8000-00805f9b34fb
[CHG] Device B8:F6:53:9B:1A:97 UUIDs: 0000110b-0000-1000-8000-00805f9b34fb
[CHG] Device B8:F6:53:9B:1A:97 UUIDs: 0000110c-0000-1000-8000-00805f9b34fb
[CHG] Device B8:F6:53:9B:1A:97 UUIDs: 0000110e-0000-1000-8000-00805f9b34fb
[CHG] Device B8:F6:53:9B:1A:97 ServicesResolved: yes
[CHG] Device B8:F6:53:9B:1A:97 Paired: yes
Pairing successful
...
# this is (AFAIK) as far as you can go w/ `bluetoothctl`, so next command is "quit"
...
[bluetooth]# quit
-
The
pipewire
installation is straightforward. Theapt install
pulls in all but one of the required dependencies:$ sudo apt update ... $ sudo apt install pipewire Reading package lists... Done Building dependency tree... Done Reading state information... Done The following additional packages will be installed: libasyncns0 libavahi-client3 liblilv-0-0 liblua5.3-0 libmp3lame0 libmpg123-0 libopus0 libpipewire-0.3-0 libpipewire-0.3-common libpipewire-0.3-modules libpulse0 libserd-0-0 libsndfile1 libsord-0-0 libspa-0.2-modules libsratom-0-0 libvorbisenc2 libwebrtc-audio-processing1 libwireplumber-0.4-0 libx11-xcb1 pipewire-bin pipewire-pulse rtkit wireplumber Suggested packages: opus-tools pulseaudio serdi sordi libspa-0.2-bluetooth pulseaudio-utils wireplumber-doc The following NEW packages will be installed: libasyncns0 libavahi-client3 liblilv-0-0 liblua5.3-0 libmp3lame0 libmpg123-0 libopus0 libpipewire-0.3-0 libpipewire-0.3-common libpipewire-0.3-modules libpulse0 libserd-0-0 libsndfile1 libsord-0-0 libspa-0.2-modules libsratom-0-0 libvorbisenc2 libwebrtc-audio-processing1 libwireplumber-0.4-0 libx11-xcb1 pipewire pipewire-bin pipewire-pulse rtkit wireplumber 0 upgraded, 25 newly installed, 0 to remove and 0 not upgraded. Need to get 3,871 kB of archives. After this operation, 19.5 MB of additional disk space will be used. Do you want to continue? [Y/n] Y ... $
-
Next, install two of the suggested packages:
libspa-0.2-bluetooth
andwireplumber-doc
(onlylibspa-0.2-bluetooth
is required):$ sudo apt install libspa-0.2-bluetooth wireplumber-doc Reading package lists... Done Building dependency tree... Done Reading state information... Done The following additional packages will be installed: libfreeaptx0 liblc3-0 libldacbt-abr2 libldacbt-enc2 libsbc1 The following NEW packages will be installed: libfreeaptx0 liblc3-0 libldacbt-abr2 libldacbt-enc2 libsbc1 libspa-0.2-bluetooth wireplumber-doc 0 upgraded, 7 newly installed, 0 to remove and 0 not upgraded. Need to get 3,474 kB of archives. After this operation, 8,040 kB of additional disk space will be used. Do you want to continue? [Y/n] Y ... $
-
Check the versions of
pipewire
&wireplumber
- here's what I got on July 21, 2024:$ pipewire --version pipewire Compiled with libpipewire 0.3.65 Linked with libpipewire 0.3.65 $ wireplumber --version wireplumber Compiled with libwireplumber 0.4.13 Linked with libwireplumber 0.4.13
-
A player is needed; I installed
mpg123
:$ sudo apt install mpg123 Reading package lists... Done Building dependency tree... Done Reading state information... Done The following additional packages will be installed: libaudio2 libice6 libjack-jackd2-0 libopenal-data libopenal1 libout123-0 libportaudio2 libsm6 libsndio7.0 libsyn123-0 libxt6 x11-common Suggested packages: nas jackd2 sndiod jackd oss-compat oss4-base pulseaudio The following NEW packages will be installed: libaudio2 libice6 libjack-jackd2-0 libopenal-data libopenal1 libout123-0 libportaudio2 libsm6 libsndio7.0 libsyn123-0 libxt6 mpg123 x11-common 0 upgraded, 13 newly installed, 0 to remove and 0 not upgraded. Need to get 1,906 kB of archives. After this operation, 5,411 kB of additional disk space will be used. Do you want to continue? [Y/n] Y ... $
-
Let's
reboot
to get everything re-started, and then check oursystemd bluetooth.service
:$ sudo reboot ... $ systemctl status bluetooth.service ● bluetooth.service - Bluetooth service Loaded: loaded (/lib/systemd/system/bluetooth.service; enabled; preset: enabled) Active: active (running) since Sun 2024-07-21 20:17:57 UTC; 11min ago Docs: man:bluetoothd(8) Main PID: 569 (bluetoothd) Status: "Running" Tasks: 1 (limit: 174) CPU: 202ms CGroup: /system.slice/bluetooth.service └─569 /usr/libexec/bluetooth/bluetoothd Jul 21 20:28:34 rpi3a bluetoothd[569]: Endpoint registered: sender=:1.20 path=/MediaEndpoint/A2DPSource/aptx_ll_1 Jul 21 20:28:34 rpi3a bluetoothd[569]: Endpoint registered: sender=:1.20 path=/MediaEndpoint/A2DPSource/aptx_ll_0 Jul 21 20:28:34 rpi3a bluetoothd[569]: Endpoint registered: sender=:1.20 path=/MediaEndpoint/A2DPSource/aptx_ll_duplex_1 Jul 21 20:28:34 rpi3a bluetoothd[569]: Endpoint registered: sender=:1.20 path=/MediaEndpoint/A2DPSource/aptx_ll_duplex_0 Jul 21 20:28:34 rpi3a bluetoothd[569]: Endpoint registered: sender=:1.20 path=/MediaEndpoint/A2DPSource/faststream Jul 21 20:28:34 rpi3a bluetoothd[569]: Endpoint registered: sender=:1.20 path=/MediaEndpoint/A2DPSource/faststream_duplex Jul 21 20:28:34 rpi3a bluetoothd[569]: Endpoint registered: sender=:1.20 path=/MediaEndpoint/A2DPSink/opus_05 Jul 21 20:28:34 rpi3a bluetoothd[569]: Endpoint registered: sender=:1.20 path=/MediaEndpoint/A2DPSource/opus_05 Jul 21 20:28:34 rpi3a bluetoothd[569]: Endpoint registered: sender=:1.20 path=/MediaEndpoint/A2DPSink/opus_05_duplex Jul 21 20:28:34 rpi3a bluetoothd[569]: Endpoint registered: sender=:1.20 path=/MediaEndpoint/A2DPSource/opus_05_duplex
-
No complaints from
systemd
... will wonders never cease? Let's try to play some sounds:$ $ nohup mpg123 --loop -1 rainstorm.mp3 & [1] 835 $ nohup: ignoring input and appending output to 'nohup.out' # YES! We have the sound of 'rainstorm.mp3' coming from the speaker!
-
Let's check the
pipewire.service
and thewireplumber.service
:#NOTE: the '--user' option $ systemctl --user status pipewire ● pipewire.service - PipeWire Multimedia Service Loaded: loaded (/usr/lib/systemd/user/pipewire.service; enabled; preset: enabled) Active: active (running) since Sun 2024-07-21 22:40:34 UTC; 5h 44min ago TriggeredBy: ● pipewire.socket Main PID: 723 (pipewire) Tasks: 3 (limit: 174) CPU: 52.651s CGroup: /user.slice/user-1000.slice/user@1000.service/session.slice/pipewire.service └─723 /usr/bin/pipewire Jul 21 22:40:35 rpi3a pipewire[723]: mod.rt: RTKit error: org.freedesktop.DBus.Error.AccessDenied Jul 21 22:40:35 rpi3a pipewire[723]: mod.rt: could not make thread 780 realtime using RTKit: Permission denied Jul 21 22:40:35 rpi3a pipewire[723]: spa.v4l2: '/dev/video14' VIDIOC_ENUM_FRAMEINTERVALS: Inappropriate ioctl for device Jul 21 22:40:35 rpi3a pipewire[723]: spa.v4l2: '/dev/video15' VIDIOC_ENUM_FRAMEINTERVALS: Inappropriate ioctl for device Jul 21 22:40:35 rpi3a pipewire[723]: spa.v4l2: '/dev/video21' VIDIOC_ENUM_FRAMEINTERVALS: Inappropriate ioctl for device Jul 21 22:40:35 rpi3a pipewire[723]: spa.v4l2: '/dev/video22' VIDIOC_ENUM_FRAMEINTERVALS: Inappropriate ioctl for device Jul 21 22:40:35 rpi3a pipewire[723]: spa.v4l2: '/dev/video14' VIDIOC_ENUM_FRAMEINTERVALS: Inappropriate ioctl for device Jul 21 22:40:35 rpi3a pipewire[723]: spa.v4l2: '/dev/video15' VIDIOC_ENUM_FRAMEINTERVALS: Inappropriate ioctl for device Jul 21 22:40:35 rpi3a pipewire[723]: spa.v4l2: '/dev/video21' VIDIOC_ENUM_FRAMEINTERVALS: Inappropriate ioctl for device Jul 21 22:40:35 rpi3a pipewire[723]: spa.v4l2: '/dev/video22' VIDIOC_ENUM_FRAMEINTERVALS: Inappropriate ioctl for device $ systemctl --user status wireplumber ● wireplumber.service - Multimedia Service Session Manager Loaded: loaded (/usr/lib/systemd/user/wireplumber.service; enabled; preset: enabled) Active: active (running) since Mon 2024-07-22 04:28:56 UTC; 41s ago Main PID: 717 (wireplumber) Tasks: 5 (limit: 174) CPU: 1.264s CGroup: /user.slice/user-1000.slice/user@1000.service/session.slice/wireplumber.service └─717 /usr/bin/wireplumber Jul 22 04:28:56 rpi3a wireplumber[717]: Can't find org.freedesktop.portal.Desktop. Is xdg-desktop-portal running? Jul 22 04:28:56 rpi3a wireplumber[717]: RTKit error: org.freedesktop.DBus.Error.AccessDenied Jul 22 04:28:56 rpi3a wireplumber[717]: could not set nice-level to -11: Permission denied Jul 22 04:28:56 rpi3a wireplumber[717]: SPA handle 'api.libcamera.enum.manager' could not be loaded; is it installed? Jul 22 04:28:56 rpi3a wireplumber[717]: PipeWire's libcamera SPA missing or broken. libcamera not supported. Jul 22 04:28:56 rpi3a wireplumber[717]: RTKit error: org.freedesktop.DBus.Error.AccessDenied Jul 22 04:28:56 rpi3a wireplumber[717]: could not make thread 757 realtime using RTKit: Permission denied Jul 22 04:28:57 rpi3a wireplumber[717]: Trying to use legacy bluez5 API for LE Audio - only A2DP will be supported. Please upgrade bluez5. Jul 22 04:28:57 rpi3a wireplumber[717]: <WpSiAudioAdapter:0x5580d0e060> Object activation aborted: proxy destroyed Jul 22 04:28:57 rpi3a wireplumber[717]: <WpSiAudioAdapter:0x5580d0e060> failed to activate item: Object activation aborted: proxy destroyed
And so it seems that neither the
pipewire
norwireplumber
services are "happy". I currently have no idea what to do about that... but am very pleased that the BT audio seems to work quite well in spite of it!
pipewire
and wireplumber
are under a systemd
service file that runs in userland. The long and the short of that is that when the user who started these services logs off - they stop working - the audio "goes away". That may be inconvenient at times. Fortunately, there is a way around this problem: keep your user (presumably user pi
) logged in under getty
. Fortunately, this is fairly straightforward - or even unnecessary if you're happy stopping BT audio when you log off.
If you want to make this change, here's one way to do it:
N.B. : There are several ways to modify service files in systemd. I am aware some consider it "bad form" to edit the "main file" directly, but that is how I'm going to do it here.
$ sudo vim /etc/systemd/system/getty.target.wants/getty@tty1.service
[Service]
...
ExecStart=-/sbin/agetty -o '-p -- \\u' --noclear - $TERM
[Service]
...
# ExecStart=-/sbin/agetty -o '-p -- \\u' --noclear - $TERM
ExecStart=
ExecStart=-/sbin/agetty --autologin pi --noclear %I $TERM
The above changes simply add an autologin
for user pi
(or the user you've selected to run pipewire
). After the reboot
you can check that user pi
has been logged in on tty1
:
$ who
pi tty1 1970-01-10 21:45
pi pts/0 -3386239902218585523 (192.168.1.209)
Once you see your user listed on tty1
, you may logout
if you wish, and your music will continue to play!
If you're considering your options for a Bluetooth audio setup, the most important thing to consider wrt bluez-alsa
(as described in this recipe) is that it's not available as-is in apt
package format. IOW, what we cover here requires you download the source files, and build (compile & install) bluez-alsa
.
This is not as difficult as it may sound! But it's probably a bit more challenging than installing pipewire
. Here's a rough outline on how to approach this:
- Visit the
bluez-alsa
GitHub site, and review the README file. - Review the build and installation file
- Review the wiki for build and installation details
The bluez-alsa wiki contains most of the step-by-step details needed to download the source, build it on your RPi and install it there. The authors of bluez-alsa
have also created a Discussions tab on their GitHub site as a vehicle for technical support. You should peruse and search existing Q&A before you ask new questions, but the support here is truly amazing!
I'll defer on more details at this time. I did manage to successfully install bluez-alsa
on my RPi Zero 2W running under 'bookworm Lite'. This installation worked well (but not flawlessly) for about 3 months. Compared to pipewire
, bluez-alsa
is a much more lightweight software solution. I even built (compiled) bluez-alsa
on the Zero 2W!
In an effort to overcome the occasional glitch in BT audio on my Zero 2W running bluez-alsa
, I decided to try the 'bookworm-backport' of pipewire
. I re-installed the latest release of 'bookworm', and added bookworm-backports
to /etc/apt/sources.list
. I'm not going to delve into the details of that installation here as this recipe has already become too wordy for my tastes; I'll put this in a new recipe, and add a link here when it's completed.