Output to a Bluetooth Speaker from the Terminal


Here's a way to switch audio output to a bluetooth speaker using terminal tools.

On Pop_OS, I have a utility called bluetoothctl that facilitates communication with bluetooth devices.

This utility opens its own repl when typing bluetoothctl:

❯ bluetoothctl
Agent registered

From inside this repl, we can see our host device and its ability to connect to other devices.

[bluetooth]# show
Controller 70:A6:CC:3B:B4:E6 (public)
	Name: pop-os
	Alias: pop-os
	Class: 0x006c010c
	Powered: yes
	Discoverable: no
	DiscoverableTimeout: 0x000000b4
	Pairable: no
	UUID: A/V Remote Control        (0000110e-0000-1000-8000-00805f9b34fb)
	UUID: Handsfree Audio Gateway   (0000111f-0000-1000-8000-00805f9b34fb)
	UUID: PnP Information           (00001200-0000-1000-8000-00805f9b34fb)
	UUID: Audio Sink                (0000110b-0000-1000-8000-00805f9b34fb)
	UUID: Audio Source              (0000110a-0000-1000-8000-00805f9b34fb)
	UUID: A/V Remote Control Target (0000110c-0000-1000-8000-00805f9b34fb)
	UUID: Generic Access Profile    (00001800-0000-1000-8000-00805f9b34fb)
	UUID: Generic Attribute Profile (00001801-0000-1000-8000-00805f9b34fb)
	UUID: Device Information        (0000180a-0000-1000-8000-00805f9b34fb)
	UUID: Handsfree                 (0000111e-0000-1000-8000-00805f9b34fb)
	Modalias: usb:v1D6Bp0246d0540
	Discovering: no
	Roles: central
	Roles: peripheral
Advertising Features:
	ActiveInstances: 0x00 (0)
	SupportedInstances: 0x0c (12)
	SupportedIncludes: tx-power
	SupportedIncludes: appearance
	SupportedIncludes: local-name
	SupportedSecondaryChannels: 1M
	SupportedSecondaryChannels: 2M
	SupportedSecondaryChannels: Coded

Importantly, we see Pairable: no. We need to allow our host computer to pair with other devices. Let's switch that on:

[bluetooth]# pairable on
Changing pairable on succeeded

Next, let's see what devices are around us. Let's turn on scan mode:

[bluetooth]# scan on
Discovery started

Now we can list available devices. Once I turn on the bluetooth speaker I want to connect to, it's showing up as a [NEW] device:

[bluetooth]# devices
...
[NEW] Device B1:1F:25:16:95:95 Y-CD-146

To interface with this device, we need to address it by its hardware MAC address. Let's pair:

[bluetooth]# pair B1:1F:25:16:95:95
Attempting to pair with B1:1F:25:16:95:95
[CHG] Device B1:1F:25:16:95:95 Connected: yes
[CHG] Device B1:1F:25:16:95:95 UUIDs: 0000110b-0000-1000-8000-00805f9b34fb
[CHG] Device B1:1F:25:16:95:95 UUIDs: 0000110e-0000-1000-8000-00805f9b34fb
[CHG] Device B1:1F:25:16:95:95 UUIDs: 0000111e-0000-1000-8000-00805f9b34fb
[CHG] Device B1:1F:25:16:95:95 ServicesResolved: yes
[CHG] Device B1:1F:25:16:95:95 Paired: yes
Pairing successful

It worked. We can list devices that we're paired with:

[bluetooth]# paired-devices
Device B1:1F:25:16:95:95 Y-CD-146

Let's turn off the device scanning, since we've found what we want:

[bluetooth]# scan off
Discovery stopped

Pairing only says that we trust a device for later. Now we need to connect to it in order to add it to our available audio devices.

Before we do that, we can see what our current audio output is by using pactl (Pipewire Audio Control) in another terminal:

❯ pactl get-default-sink
alsa_output.pci-0000_00_1f.3.analog-stereo

Then we can see other audio outputs. Previous to connecting, we can see that only the built-in computer audio device is available. The bluetooth speaker is not yet available:

❯ pactl list short sinks
64	alsa_output.pci-0000_00_1f.3.analog-stereo	PipeWire	s32le 2ch 48000Hz	RUNNING

Let's connect back in bluetoothctl:

[bluetooth]# connect B1:1F:25:16:95:95
Attempting to connect to B1:1F:25:16:95:95
[CHG] Device B1:1F:25:16:95:95 Connected: yes
Connection successful
[CHG] Device B1:1F:25:16:95:95 ServicesResolved: yes

Now out in the terminal, we have another audio output device -- the bluetooth device, seen by a reference to the MAC address:

❯ pactl list short sinks
64	alsa_output.pci-0000_00_1f.3.analog-stereo	PipeWire	s32le 2ch 48000Hz	RUNNING
632	bluez_output.B1_1F_25_16_95_95.1	PipeWire	s16le 2ch 48000Hz	SUSPENDED

To change to output audio to that device, run:

❯ pactl set-default-sink bluez_output.B1_1F_25_16_95_95.1

Now, play some audio, and you'll be tub thumping in no time.

Terminal tools are beautiful. We get exact commands for toggling, scanning, pairing, connecting and switching audio output.