Linux · Bluetooth · PipeWire

Your headsets,
in conversation.

Turn a Linux computer or Raspberry Pi into a local intercom. Bring your own Bluetooth headsets, decide who can hear whom, and choose whether everyone talks at once or takes a turn.

No internet cloud dependency. Audio stays on your host and paired headsets.

01

Groups that make sense
Route conversations by team.

02

Two ways to talk
Open microphones or take turns.

03

Local by design
Your audio stays on the host.

Conversations with boundaries

Make room for the right voices.

Talk groups decide where each headset’s microphone goes. Build a shared workshop, separate crews, or overlapping circles with one headset in more than one group.

01 / MEMBERSHIP

Choose who’s in.

Assign paired headsets to one or more groups. When groups are configured, an unassigned headset is kept out of group routes.

OfficeAlex · Jules
WorkshopJules · Morgan
02 / ROUTING

Hear only your group.

A microphone reaches other headsets sharing at least one group—never its own headset. With no groups configured, the intercom stays all-to-all.

AlexJulesMorgan Jules bridges both groups

Taking turns? In half-duplex mode, each group has its own first-in, first-out queue. Separate groups can have a talker at the same time.

A small terminal, a clear picture

Keep the network in hand.

Open bt-intercom panel for the terminal control panel. Check Bluetooth connection and signal, confirm duplex audio is available, then manage groups and membership without editing config files.

  • TabSwitch between groups and headsets
  • ↑ ↓Select a group or member
  • nCreate a talk group
  • dRemove the selected group
  • SpaceToggle headset membership
  • EnterSave a new group name
  • EscCancel name entry or quit the panel

Changes save to your user config and a running intercom picks them up on its next routing update.

┌ bt-intercom | Headsets and talk groups ───────────────────────────────┐
Live headset status
HEADSETADDRESSBLUETOOTHDUPLEXSIGNAL
AlexAA:BB:CC:DD:EE:01connectedready−58 dBm
JulesAA:BB:CC:DD:EE:02connectedready−64 dBm
MorganAA:BB:CC:DD:EE:03connectedready−71 dBm
Talk groups [n add, d delete]

> Office

Workshop

Office [space toggle]

> [x] Alex (AA:BB:CC:DD:EE:01)

[x] Jules (AA:BB:CC:DD:EE:02)

[ ] Morgan (AA:BB:CC:DD:EE:03)

Illustrative terminal view; the control panel runs in your terminal, not in a separate app window.

See the setup in motion

From status to speaking.

Check headset transport, choose a transmit mode, and follow live routing as a talker takes and releases the floor.

bt-intercom / terminal tourILLUSTRATIVE SESSION

Play the terminal tour with the asciinema player, or download the asciicast recording.

$ bt-intercom --help
A Bluetooth headset intercom for Linux

Usage: bt-intercom [OPTIONS] <COMMAND>

Commands:
  scan         Scan for nearby Bluetooth devices
  pair         Pair, trust, and connect a headset
  remove       Remove a headset from the saved intercom network
  status       Show Bluetooth headset audio status
  run          Route configured headset microphones to one another
  completions  Generate shell completion definitions
  panel        Open the interactive terminal control panel
  help         Print this message or the help of the given subcommand(s)

Options:
      --verbose  Enable detailed diagnostics on stderr (unless RUST_LOG is set)
  -V, --version  
  -h, --help     Print help
$ bt-intercom status AA:BB:CC:DD:EE:01 AA:BB:CC:DD:EE:02
Alex (AA:BB:CC:DD:EE:01): duplex ready (1 microphone ports, 1 speaker ports)
  controller: hci0; HFP: true; A2DP: true
Jules (AA:BB:CC:DD:EE:02): duplex ready (1 microphone ports, 1 speaker ports)
  controller: hci1; HFP: true; A2DP: true
$ bt-intercom run AA:BB:CC:DD:EE:01 AA:BB:CC:DD:EE:02 \
  --mode half-duplex --ptt AA:BB:CC:DD:EE:01=auto \
  --ptt AA:BB:CC:DD:EE:02=auto --transport sco-a2dp --dashboard
INFO: Half-duplex: Hold play/pause to request the FIFO floor; release to cancel or relinquish. Double beep confirms a ready route.

[Dashboard redraw]
bt-intercom | half-duplex | muted | 0 owned active links
HEADSET NAME       ADDRESS             CONNECTED  DUPLEX  TX/RX LINKS  SIGNAL
Alex               AA:BB:CC:DD:EE:01  yes        yes      0/0          -58 dBm (strong)
Jules              AA:BB:CC:DD:EE:02  yes        yes      0/0          -66 dBm (good)

Links represent routing, not measured speech; RSSI is shown only if BlueZ reports it.

[Dashboard redraw]
bt-intercom | half-duplex | transmitting | 1 owned active links
HEADSET NAME       ADDRESS             CONNECTED  DUPLEX  TX/RX LINKS  SIGNAL
Alex               AA:BB:CC:DD:EE:01  yes        yes      1/0          -58 dBm (strong)
Jules              AA:BB:CC:DD:EE:02  yes        yes      0/1          -66 dBm (good)

Links represent routing, not measured speech; RSSI is shown only if BlueZ reports it.

[Dashboard redraw]
bt-intercom | half-duplex | muted | 0 owned active links
HEADSET NAME       ADDRESS             CONNECTED  DUPLEX  TX/RX LINKS  SIGNAL
Alex               AA:BB:CC:DD:EE:01  yes        yes      0/0          -58 dBm (strong)
Jules              AA:BB:CC:DD:EE:02  yes        yes      0/0          -66 dBm (good)

Links represent routing, not measured speech; RSSI is shown only if BlueZ reports it.
^C
$ 

Example addresses and representative output; not a recording of real Bluetooth hardware.

Ready to set up your intercom?

Bring your headsets together.

Read the setup guide

Requires Linux, BlueZ, PipeWire, WirePlumber, and Bluetooth Classic headsets with duplex audio. Browser playback is a demonstration; the intercom itself runs on your Linux host.