Skip to content

Instantly share code, notes, and snippets.

@egelev
Last active March 19, 2024 09:32
Star You must be signed in to star a gist
Save egelev/2e6b57d5a8ba62cf6df6fff2878c3fd4 to your computer and use it in GitHub Desktop.
Connect bluetooth headphones on Ubuntu 18.04
#!/usr/bin/env bash
function get_headphones_index() {
echo $(pacmd list-cards | grep bluez_card -B1 | grep index | awk '{print $2}')
}
function get_headphones_mac_address() {
local temp=$(pacmd list-cards | grep bluez_card -C20 | grep 'device.string' | cut -d' ' -f 3)
temp="${temp%\"}"
temp="${temp#\"}"
echo "${temp}"
}
function _control_bluethoot_headphones() {
local op=${1}
local hp_mac=${2}
echo -e "${op} ${hp_mac}\n quit" | bluetoothctl
}
function disconnect_bluetooth_headphones() {
local hp_mac=${1}
_control_bluethoot_headphones "disconnect" ${hp_mac}
}
function connect_bluetooth_headphones() {
local hp_mac=${1}
_control_bluethoot_headphones "connect" ${hp_mac}
}
function _set_headphones_profile() {
local profile=${1}
pacmd set-card-profile $(get_headphones_index) ${profile}
}
function set_headphones_profile_a2dp_sink() {
_set_headphones_profile "a2dp_sink"
echo "Bluethoot headphones a2dp_sink"
}
function set_headphones_profile_off() {
_set_headphones_profile "off"
echo "Bluethoot headphones profile off"
}
function main() {
local hp_mac=$(get_headphones_mac_address)
set_headphones_profile_off
sleep 2s
disconnect_bluetooth_headphones ${hp_mac}
sleep 6s
connect_bluetooth_headphones ${hp_mac}
sleep 3s
set_headphones_profile_a2dp_sink
}
main
@egelev
Copy link
Author

egelev commented Jan 11, 2020

This works perfectly for my WH-1000XM3's on Linux Mint 19.1. Thank you so much!

I don't know much about bluetooth, but was wondering if you could also help me with another problem; namely not being able to get the mic working on the A2DP sink profile. From a small amount of research, this appears to be because the A2DP profile is unidirectional, and thus cannot submit mic sound.

Solution to this is to use the HSP/HFP profile, however, this produces terrible sound quality and static noise. Do you have any solutions to this? What are my options?

Hi. I am glad this little script helped you. I am sorry but the "A2DP" is unidirectional and it doesn't support a mic. It is not really convenient to switch to 'HSP/HFP' when you need to have a call so I just got a separate low-cost USB mic. And to be honest I had a couple of complaints that the other side can't hear me well through my WH-1000XM2's mics.

@fospald
Copy link

fospald commented Mar 6, 2020

It is unbelievable that such basic functionality like bluetooth audio connection still does not work properly in Ubuntu 18.04.
Works this way with my WH-1000XM3 headphone but still annoying. Sometimes also audio gets out of sync and I have to switch to None and then A2DP again. Please leave a comment if there is a proper solution.
Edit: Compiling and installing bluez-5.52 does fix the issue for me: https://askubuntu.com/questions/1139404/sony-noise-cancelling-headphones-wh-1000xm2-3-and-bluetooth-initial-autoconnec

@egelev
Copy link
Author

egelev commented Mar 6, 2020

It is unbelievable that such basic functionality like bluetooth audio connection still does not work properly in Ubuntu 18.04.
Works this way with my WH-1000XM3 headphone but still annoying. Sometimes also audio gets out of sync and I have to switch to None and then A2DP again. Please leave a comment if there is a proper solution.
Edit: Compiling and installing bluez-5.52 does fix the issue for me: https://askubuntu.com/questions/1139404/sony-noise-cancelling-headphones-wh-1000xm2-3-and-bluetooth-initial-autoconnec

Hi @fospald.

I was pretty annoyed too. It really wonders me how some people are able to communicate with a rover on 225 million kilometers (the average distance to Mars) and the most popular open-source OS can not handle 10m Bluetooth audio connection :D.
However, I have to admit that the guys from Canonical are doing a good job. I recently installed Ubuntu 18.04.4 which was released on 12 Feb 2020 and my headphones work properly now. According to the release notes they have provided a fix for this particular issue.

I regularly use Sony WH-1000XM2 and Boltune ANC 2019 and they both work properly. I haven't experienced the sync audio problems you mentioned so I'm not able to share any experience here. However, setting the profile to 'None' and then back to 'A2DP' can be done with the helper functions of this script.

All the best :).

@vegrex
Copy link

vegrex commented May 25, 2020

Thanks! Using ATH-M50xBT headphones I had to extend that last sleep with one second because it could not get the index in 3s.

@jonpolak
Copy link

I have the opposite problem, I have a mono headset, which connects as A2DP by default... would love if the default was HSP.

@heyakyra
Copy link

heyakyra commented Jun 24, 2020

Seems many have had this issue: https://github.com/valderman/bt-reload-headphones

I have the opposite problem, I have a mono headset, which connects as A2DP by default... would love if the default was HSP.

This is the problem I'm also having in Fedora 32. I'm assuming that's because the underlying issue has not been addressed, merely the default connection has changed to anger the other half of users which depend on using their microphones.

I wasn't able to find a discussion about this on the bluez (linux-bluetooth) developers mailing list, but maybe someone else will have better luck: https://marc.info/?l=linux-bluetooth

Or wants to subscribe and raise the issue:
http://vger.kernel.org/vger-lists.html#linux-bluetooth

@jangroth
Copy link

Thanks for this script!

For my Bose QuietComfort 35 Wireless & on Ubuntu 20.04, I had to bump the sleep time between connect and set_profile to 6s. Works great then!

@mikeyjk
Copy link

mikeyjk commented Sep 3, 2020

This is amazing, thank you
Maybe pop up a way to donate you a coffee!

@egelev
Copy link
Author

egelev commented Sep 27, 2020 via email

@ryandward
Copy link

ryandward commented Sep 27, 2020

Hey Egelev,

I wanted to congratulate you on your awesome code. I looked through it a bit after I made this comment, and decided my comment was silly. Your fix worked until I rebooted my Gnome on Arch box. I eventually just gave up and switched to xfce and it just works now.

This whole thing has kind of showed me the holes there are in the current Gnome environment.

@Miuler
Copy link

Miuler commented Sep 28, 2020

Gracias, con este script porfin logre hacer funcionar mi WH-1000XM4!

@drakakisgeo
Copy link

Strangely I get this in Xubuntu 18

"connect_bluetooth_headphones.sh: 3: connect_bluetooth_headphones.sh: Syntax error: "(" unexpected"

Any idea why?

@egelev
Copy link
Author

egelev commented Oct 23, 2020

Strangely I get this in Xubuntu 18

"connect_bluetooth_headphones.sh: 3: connect_bluetooth_headphones.sh: Syntax error: "(" unexpected"

Any idea why?

Hi @drakakisgeo.
This is unexpected behavior. Is your default interpreter bash?
Can you please share the output from
$ bash --version

I use GNU bash, version 4.4.20(1)-release (x86_64-pc-linux-gnu).

@drakakisgeo
Copy link

drakakisgeo commented Oct 24, 2020

GNU bash, version 4.4.20(1)-release (x86_64-pc-linux-gnu) is what I get.

But also SHELL=/usr/bin/zsh so I ran it with bash. Thanks! Let's hope that will fix my issue :-)

@nikogamulin
Copy link

I tried to run the script in order to fix the configuration for Bose QC35 headphones. The script resets the Bluetooth module but nevertheless I can't get stereo quality. By default, the option Headset Head Unit (HSP/HFP) is selected. If I select High Fidelity Playback (A2DP Sink), nothing happens. I would appreciate if anyone suggested a way to fix the issue.

@fervic
Copy link

fervic commented Dec 10, 2020

Gracias, con este script porfin logre hacer funcionar mi WH-1000XM4!

@Miuler te funcionan como HSP/HFP? Es decir el micrófono también? Tengo el mismo headset y sólo me lo reconoce como A2DP.

Does it work with the HSP/HFP profile? Is it recognized as an input device? I have the exact same model of headset and it is only recognized as A2DP in my case.

@egelev
Copy link
Author

egelev commented Dec 10, 2020

Gracias, con este script porfin logre hacer funcionar mi WH-1000XM4!

@Miuler te funcionan como HSP/HFP? Es decir el micrófono también? Tengo el mismo headset y sólo me lo reconoce como A2DP.

Does it work with the HSP/HFP profile? Is it recognized as an input device? I have the exact same model of headset and it is only recognized as A2DP in my case.

The problem might be the Bluetooth profile and how the Sony Headphones present themselves to the Ubuntu system. Have a look here :).

@dgketchum
Copy link

Nice script. Many thanks!

@leka0024
Copy link

leka0024 commented Jan 13, 2021

No matter what I do (the order of turning headphone pairing on and turning bluetooth on, or leaving bluetooth off, etc.), I get the following messages in Ubuntu 20.04 when I run the script:

You need to specify a profile by its name.
Bluethoot headphones profile off
Agent registered
[bluetooth]# disconnect 
Missing device address argument
[bluetooth]#  quit
Agent registered
[bluetooth]# connect 
Missing dev argument
[bluetooth]#  quit
You need to specify a profile by its name.
Bluethoot headphones a2dp_sink

The headphones are Sony MDR-ZX780DC and they work just fine on iphone. (I did turn iphone bluetooth off)

Does anyone have any suggestion?

@egelev
Copy link
Author

egelev commented Jan 24, 2021

No matter what I do (the order of turning headphone pairing on and turning bluetooth on, or leaving bluetooth off, etc.), I get the following messages in Ubuntu 20.04 when I run the script:

You need to specify a profile by its name.
Bluethoot headphones profile off
Agent registered
[bluetooth]# disconnect 
Missing device address argument
[bluetooth]#  quit
Agent registered
[bluetooth]# connect 
Missing dev argument
[bluetooth]#  quit
You need to specify a profile by its name.
Bluethoot headphones a2dp_sink

The headphones are Sony MDR-ZX780DC and they work just fine on iphone. (I did turn iphone bluetooth off)

Does anyone have any suggestion?

Hello @leka0024.
Can you please provide the output of the following command: pacmd list-cards | grep bluez_card -B1 -A50 ?
If it is OK, it would be helpful to execute it twice:

  • when the headphones are not connected
  • when you connect them through the Ubuntu UI (don't pay attention to the profile - HSP/HFP or A2DP)

Thank you.

@leka0024
Copy link

leka0024 commented Jan 24, 2021

Hello @leka0024.
Can you please provide the output of the following command: pacmd list-cards | grep bluez_card -B1 -A50 ?
If it is OK, it would be helpful to execute it twice:

* when the headphones are not connected

* when you connect them through the Ubuntu UI (don't pay attention to the profile - HSP/HFP or A2DP)

Thank you.

Hi @egelev ,

Nothing returns with the pipe'd command you suggest. If I just run pacmd list-cards I get this info:

1 card(s) available.
    index: 0
	name: <alsa_card.pci-0000_00_1f.3-platform-skl_hda_dsp_generic>
	driver: <module-alsa-card.c>
	owner module: 23
	properties:
		alsa.card = "0"
		alsa.card_name = "sof-hda-dsp"
		alsa.long_card_name = "LENOVO-82HS-IdeaPadFlex514ITL05-LNVNB161216"
		alsa.driver_name = "snd_soc_skl_hda_dsp"
		device.bus_path = "pci-0000:00:1f.3-platform-skl_hda_dsp_generic"
		sysfs.path = "/devices/pci0000:00/0000:00:1f.3/skl_hda_dsp_generic/sound/card0"
		device.bus = "pci"
		device.vendor.id = "8086"
		device.vendor.name = "Intel Corporation"
		device.product.id = "a0c8"
		device.string = "0"
		device.description = "sof-hda-dsp"
		module-udev-detect.discovered = "1"
		device.icon_name = "audio-card-pci"

Is that helpful?

When I have turned Bluetooth on in the Ubuntu settings, it can never see my headphones (turned on, in pairing mode, and iphone bluetooth off), so I don't believe it has ever "connected".

Thanks for any suggestions!

@egelev
Copy link
Author

egelev commented Jan 25, 2021

Hi, @leka0024. Thank you for the info. Unfortunately, it looks like this is another issue. This script only changes the profile from HSP/HFP to A2DP once the headphones are successfully connected. I am sorry, it looks like some sort of incompatibility issue.

@rs-development
Copy link

Does someone has the problem that the Headset Mode is working but on A2DP no sound can be heard? It was workings since i upgraded to 20.xx but since one week or so i have problems again. Removing and Repairing does sometimes fix the issue.

WH-1000XM3, newest firmware.

@jrobinson-vs
Copy link

i am unable to as well on Linux Mint 20.1

@darrentmorgan
Copy link

Does someone has the problem that the Headset Mode is working but on A2DP no sound can be heard? It was workings since i upgraded to 20.xx but since one week or so i have problems again. Removing and Repairing does sometimes fix the issue.

WH-1000XM3, newest firmware.

This may or may not resolve your issue. I've found that on first connect it will not work with the headphones. I've had the Sony WH-1000xm3 and xm4's. My current simple fix is to connect the headphones, disconnect them and reconnect. Then click on the speaker icon and choose the applications tab and select the sound output to be the headphones. This is not a great work around, but it's the best that I've been able to come up with.

I've tested this on Ubuntu, mint and Mx Linux.

@marcelarie
Copy link

Does this work with Pipewire ?

@jmarshallh
Copy link

thank you so much !
worked for me on Linux Mint 20.2 Cinnamon and Sony WH-1000XM3 headset .
happy new year !

@italomunozj
Copy link

Hi Emil. I happened to find your script just today ... and I love it!, very useful. Thank you! ( :

@egelev
Copy link
Author

egelev commented Dec 8, 2022

Hi Emil. I happened to find your script just today ... and I love it!, very useful. Thank you! ( :

I'm glad it is still useful :).

@pavdwest
Copy link

pavdwest commented Dec 19, 2022

Thank you very much for this - worked perfectly out of the box with my Bose QCII Headset on Ubuntu 22.04.

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