Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save daks/9d16fa26c38d270792d445ffe690bdce to your computer and use it in GitHub Desktop.

Select an option

Save daks/9d16fa26c38d270792d445ffe690bdce to your computer and use it in GitHub Desktop.

Turn your Linux box into a Bluetooth audio endpoint (quick guide)

This short article shows a simple PipeWire + BlueZ setup to let a Linux machine act as a Bluetooth audio endpoint — for example, to play audio from your phone to a USB headset attached to the Linux box. The commands below are the minimal steps: install the packages, enable services, verify PipeWire is running, pair/connect from the phone, and optionally select the USB headset as the default sink.


Tested environment

The steps in this guide were validated on the following setup:

  • Raspberry Pi 4 Model B
  • 2025-05-13-raspios-bookworm-arm64-lite
  • pipewire 1.2.7, bluez 5.66, wireplumber 0.4.13, pulseaudio-utils 16.1

1) Install required packages

Install BlueZ (Bluetooth stack), PipeWire (audio server), WirePlumber (session manager) and the PulseAudio-compatibility layer so old tools still work:

sudo apt update
sudo apt install bluez wireplumber pipewire libspa-0.2-bluetooth pipewire-pulse pipewire-audio-client-libraries pulseaudio-utils

Note: package names may vary on non-Debian systems. On some distros you may need extra packages (ofono/hsphfpd) for advanced headset profiles (HFP).


2) Enable Bluetooth and PipeWire services

Enable the system Bluetooth service and the user PipeWire services (run as your regular user):

sudo systemctl enable --now bluetooth
systemctl --user daemon-reload
systemctl --user enable --now pipewire pipewire-pulse wireplumber

If you want the user services to keep running even when you're not logged in, enable linger for your account:

# If you need services to run outside an active login session
sudo loginctl enable-linger $(whoami)

enable-linger makes systemd start your user services at boot and keeps them available between sessions.


3) Quick checks to confirm PipeWire is up

Use these commands to inspect PipeWire and the compatibility layer:

# low-level PipeWire info (either will show useful debug info)
pw-cli info all || pw-cli dump

# higher-level PipeWire CLI
wpctl status

# PulseAudio-compat checks (shows servers/sinks)
pactl info
pactl list sinks short

wpctl status gives a friendly summary of devices/sinks/sources; pactl is useful because many apps or scripts still expect PulseAudio tools.


4) Pair and connect from your phone (using bluetoothctl)

Run bluetoothctl and execute these commands inside its REPL to make the Linux box discoverable and pairable, then pair/connect from the phone:

bluetoothctl
# inside the bluetoothctl prompt:
power on
agent on
default-agent
scan on
# On your phone: discover and attempt pairing. When you see the MAC:
pair XX:XX:XX:XX:XX:XX
trust XX:XX:XX:XX:XX:XX
connect XX:XX:XX:XX:XX:XX
# when done:
quit

trust marks the device trusted so it can reconnect automatically. Replace XX:... with the MAC address shown while scanning.


5) Choose output (set your USB headset as default sink)

List sinks and set the default sink by name (use the sink name from pactl list short sinks):

pactl list short sinks            # show available sinks
pactl set-default-sink <SINK_NAME>  # set the chosen sink as default

This makes incoming Bluetooth audio (or any system audio) play through the selected device (e.g., the USB headset plugged into the Linux box).


6) Troubleshooting & tips

  • If pw-cli / wpctl complain about connection refused, ensure your user PipeWire services are running (systemctl --user status pipewire wireplumber).
  • If Bluetooth audio connects but microphone (HFP) doesn't work: HFP support is more involved and may require ofono or hsphfpd integration; A2DP (high-quality playback only) is usually simpler and works out of the box.
  • If you see Host is down or pactl not found, ensure PipeWire and the PulseAudio compatibility layer are installed and running, and that your user PATH includes /usr/bin.
  • If audio is routed to the wrong device when a USB headset is plugged in, use pactl to list sinks and then pactl set-default-sink to pick the correct one.
  • For persistent service behavior across reboots and no active login, loginctl enable-linger $(whoami) is handy but consider security/ownership implications on multiuser systems.

Summary

  1. Install BlueZ + PipeWire + WirePlumber.
  2. Enable the Bluetooth system service and the user PipeWire services.
  3. Verify PipeWire is running with pw-cli / wpctl and pactl.
  4. Pair and connect using bluetoothctl.
  5. Set the USB headset as the default sink with pactl if needed.

This setup converts your Linux box into a convenient Bluetooth audio endpoint so you can play audio from your phone (or other devices) through speakers or a USB headset attached to the Linux machine. If you want, I can expand this into a step-by-step script with checks and helpful messages.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment