Changing sound output of application to use Bluetooth headphoes
So with Tiling window manager(XMonad) I don’t have a systray setup. By that, I don’t have any tray applet widgets. One of the disadvantage of that is that when I have firefox or any application which plays sound by default it uses my laptop speaker.
When I connect my Bose QC II it doesn’t change the audio automatically to it. Up until now I used to close and then reopen Firefox or any application that still played the audio using my Laptop’s speakers.
More recently when I was dabbling with multiple Desktop Environments(XFCE, Gnome, KDE, LXDE) I noticed the same behavior. Was expecting DE’s to handle this behavior rather seamlessly but I noticed that I had to change to my bluetooth through the systray applet. This got me thinking that there should be a way for me to achieve this through commandline.
Enter commandline
First we need to get the list of audio sinks available:
$ pactl list sinks short
0 alsa_output.pci-0000_00_1f.3.analog-stereo module-alsa-card.c s16le 2ch 48000Hz SUSPENDED
3 bluez_sink.28_11_A5_71_61_49.a2dp_sink module-bluez5-device.c s16le 2ch 44100Hz SUSPENDED
4 alsa_output.pci-0000_01_00.1.hdmi-stereo module-alsa-card.c s16le 2ch 44100Hz SUSPENDED
Hopefully it is obvious from the output that 3(in my case) is what we want as sink for my bluetooth headphones.
If you want a more verbose list you could use pacmd
$ pacmd list-sinks
The above command spits a lot more info along with the product name(in case you have multiple Bluetooth devices and want to narrow down on the right one.
If you want to change the default output sink you could just type this command in
pacmd set-default-sink 1
But in my case I wanted to change the stream for firefox to my Bose headphones.
$ pacmd list-sink-inputs
1 sink input(s) available.
index: 0
driver: <protocol-native.c>
flags: START_CORKED
state: CORKED
sink: 3 <bluez_sink.28_11_A5_71_61_49.a2dp_sink>
volume: front-left: 65536 / 100% / 0.00 dB, front-right: 65536 / 100% / 0.00 dB
balance 0.00
muted: no
current latency: 154.69 ms
requested latency: 45.32 ms
sample spec: float32le 2ch 48000Hz
channel map: front-left,front-right
Stereo
resample method: speex-float-1
module: 12
client: 100 <Firefox>
properties:
media.name = "AudioStream"
application.name = "Firefox"
native-protocol.peer = "UNIX socket client"
native-protocol.version = "34"
application.process.id = "1531"
application.process.user = "ruminator"
application.process.host = "archpad"
application.process.binary = "firefox"
application.language = "en_US.UTF-8"
window.x11.display = ":0"
application.process.machine_id = "b0cbd25c457647ca86dadf6e87280db1"
application.process.session_id = "1"
application.icon_name = "firefox"
module-stream-restore.id = "sink-input-by-application-name:Firefox"
From above you can see that the sink input index is 0 for Firefox. To move the stream to bluetooth headphones, we need to run
pacmd move-sink-input 0 3
In the above command 0
is the index of the input stream and 3
index of the sink, which is the Bose headphones.
Voila, now my input stream is routed to the headphones without having to restart any application.