-
-
Save OndraZizka/2724d353f695dacd73a50883dfdf0fc6 to your computer and use it in GitHub Desktop.
#!/bin/bash | |
#### Restart Bluetooth | |
if [ "$1" == "resetBT" ] ; then | |
sudo rfkill block bluetooth && sleep 0.1 && sudo rfkill unblock bluetooth; | |
exit; | |
fi; | |
#### Toggle listen/speak | |
if [ "$1" == "" -o "$1" == "toggle" ] ; then | |
LINE=`pacmd list-sinks | grep '\(name:\|alias\)' | grep -B1 F5A | head -1` | |
if [ "$LINE" == "" ] ; then echo "F5A headset not found."; $0 reset; sleep 2; exit; fi | |
SINK_NAME="bluez_sink.00_19_5D_25_6F_6C.a2dp_sink" | |
if $(echo "$LINE" | grep $SINK_NAME &> /dev/null) ; then | |
echo "Detected quality sound output, that means we can't speak; switch that." | |
$0 speak; | |
else | |
echo "Quality sound not found, switch to the good sound." | |
$0 listen; | |
fi | |
fi | |
#### Change the output to F5A | |
if [ "$1" == "listen" ] ; then | |
LINE=`pacmd list-sinks | grep '\(name:\|alias\)' | grep -B1 F5A | head -1` | |
if [ "$LINE" == "" ] ; then echo "F5A phones not found."; $0 reset; sleep 2; exit; fi | |
# name: <bluez_sink.00_19_5D_25_6F_6C.headset_head_unit> | |
## Get what's between <...> | |
SINK_NAME=`echo "$LINE" | tr '>' '<' | cut -d'<' -f2`; | |
## The above gives an ID according to the active profile. | |
## To set manually: | |
#SINK_NAME="bluez_sink.00_19_5D_25_6F_6C.headset_head_unit" | |
#SINK_NAME="bluez_sink.00_19_5D_25_6F_6C.a2dp_sink" | |
## Switch the output to that. | |
echo "Switching audio output to $SINK_NAME"; | |
pacmd set-default-sink "$SINK_NAME" | |
#### Change profile to quality output + no mic. From `pacmd list-cards`: | |
CARD="bluez_card.00_19_5D_25_6F_6C" | |
PROFILE="a2dp_sink" | |
echo "Switching audio profile to $PROFILE"; | |
pacmd set-card-profile $CARD $PROFILE | |
exit; | |
fi; | |
#### Input | |
if [ "$1" == "speak" ] ; then | |
## Change profile to crappy output + mic. From `pacmd list-cards`: | |
CARD="bluez_card.00_19_5D_25_6F_6C" | |
pacmd set-card-profile $CARD headset_head_unit | |
LINE=`pacmd list-sources | grep '\(name:\|alias\)' | grep -B1 F5A | head -1` | |
if [ "$LINE" == "" ] ; then echo "F5A mic not found."; $0 reset; sleep 2; exit; fi | |
SOURCE_NAME=`echo "$LINE" | tr '>' '<' | cut -d'<' -f2`; | |
#SOURCE_NAME="bluez_source.00_19_5D_25_6F_6C.headset_head_unit" | |
#SOURCE_NAME="bluez_sink.00_19_5D_25_6F_6C.a2dp_sink.monitor" | |
echo "Switching audio input to $SOURCE_NAME"; | |
pacmd set-default-source "$SOURCE_NAME" || echo 'Try `pacmd list-sources`.'; | |
fi; | |
#### Resources: | |
## Why this is needed | |
# https://jimshaver.net/2015/03/31/going-a2dp-only-on-linux/ | |
## My original question | |
# https://askubuntu.com/questions/1004712/audio-profile-changes-automatically-to-hsp-bad-quality-when-i-change-input-to/1009156#1009156 | |
## Script to monitor plugged earphones and switch when unplugged (Ubuntu does that, but nice script): | |
# https://github.com/freundTech/linux-helper-scripts/blob/master/padevswitch/padevswitch |
Thats great! It Works perfectly with My PLT Focus! Thx!
Thank you very much for this effort. I wonder how can it work on Windows? when I use my bluetooth headphones there I can talk and listen with good quality.
really great, thanks. Bose headsets were giving headache with this. Regards!
worked like a charm
this looks like exactly what I need for my Mpow M5 headset. It works a treat in Ubuntu, but am now trying to get it to work in Manjaro KDE.
However, I'm getting "line 30: command not found"
Am a 'cut and paster' with code, so very limited understanding. My guess is that I've misunderstood the blanks I need to fill for my device.
My only initial change to the code was BLUETOOTH_DEVICE="Mpow M5"
Do I need to make other changes?
Thanks for script, i've modified it a little bit to have more universal usage.
Awesome, thank you.
My only initial change to the code was BLUETOOTH_DEVICE="Mpow M5"
Do I need to make other changes?
I don't think so, that's it.
Hey I am new here. Can anyone please tell me what to do with the script? How to use it?
Thank you for this script. It works nicely as expected! I suggest to use it together with a toggle button, e.g.,
#!/usr/bin/env python
''' switchHeadphones.py
Tkinter toggle button to switch microphone On/Off using a script
Modification of the solution proposed in
https://www.daniweb.com/posts/jump/1909448
for the Mic On/Off script from
https://gist.github.com/OndraZizka/2724d353f695dacd73a50883dfdf0fc6
'''
# Define the path for the script below, e.g.,
script = "./switchHeadphones.sh"
try:
# Python2
import Tkinter as tk
except ImportError:
# Python3
import tkinter as tk
import os
__author__ = "Weslley S Pereira"
__email__ = "[email protected]"
def toggle(tog=[0]):
'''
a list default argument has a fixed address
'''
tog[0] = not tog[0]
if tog[0]:
os.system(script+' speak')
t_btn.config(text='Switch Mic Off')
else:
os.system(script+' listen')
t_btn.config(text='Switch Mic On')
root = tk.Tk()
root.title('Headphone ')
t_btn = tk.Button(text='Switch Mic On', width=15, command=toggle)
t_btn.pack(pady=5)
root.mainloop()
Thanks!
I think this should become a repo by it's own. There're nice improvements to be done to be more generic and w/ toggle functionality @OndraZizka what do you think?
Thank you for this script. It works nicely as expected! I suggest to use it together with a toggle button, e.g.,
#! /usr/bin/python ''' switchHeadphones.py Tkinter toggle button to switch microphone On/Off using a script Modification of the solution proposed in https://www.daniweb.com/posts/jump/1909448 for the Mic On/Off script from https://gist.github.com/OndraZizka/2724d353f695dacd73a50883dfdf0fc6 ''' # Define the path for the script below, e.g., script = "./switchHeadphones.sh" try: # Python2 import Tkinter as tk except ImportError: # Python3 import tkinter as tk import os __author__ = "Weslley S Pereira" __email__ = "[email protected]" def toggle(tog=[0]): ''' a list default argument has a fixed address ''' tog[0] = not tog[0] if tog[0]: os.system(script+' speak') t_btn.config(text='Switch Mic Off') else: os.system(script+' listen') t_btn.config(text='Switch Mic On') root = tk.Tk() root.title('Headphone ') t_btn = tk.Button(text='Switch Mic On', width=15, command=toggle) t_btn.pack(pady=5) root.mainloop()
I don't know how to run this, I'm new to linux. Can someone please help me out ?
@weslleyspereira @vvillschneider
Usage:
- First, you may need to change the permissions of the original Shell script
switchHeadphones.sh
:
chmod +x switchHeadphones.sh
- Then, after connecting your headphones, execute the script Python I suggested as follows:
python <my_script.py> &
- Make sure the variable
script
holds the correct path for the original Shell scriptswitchHeadphones.sh
.
Usage:
1. First, you may need to change the permissions of the original Shell script `switchHeadphones.sh`: `chmod +x switchHeadphones.sh` 2. Then, after connecting your headphones, execute the script Python I suggested as follows: `python <my_script.py> &` 3. Make sure the variable `script` holds the correct path for the original Shell script `switchHeadphones.sh`.
@weslleyspereira, i tried running the above command of your's on ubuntu terminal , the chmod +x switchHeadphones.sh
ran perfectly, but later the command python switchHeadphones.py
gives me the following error:
File "switchHeadphones.py", line 9 if [ "${1}" == "reset" ] ; then ^ SyntaxError: invalid syntax
i renamed the file from .sh to .py as i could'nt run it
i have saved the file in my /home path. can you please help me out ? it would really mean a lot, thanks ^.^
Hi!
- Did you configure the Shell script
switchHeadphones.sh
? In case not, you should. You can do as suggested in the Shell script:
-- Runpacmd list-sinks | grep '\(name:\|alias\)'
and fill with value from alias of your Bluetooth device - The error you showed relates to the @artem328's script. Try running
./switchHeadphones.sh speak
then./switchHeadphones.sh listen
in your terminal and see if everything works. My Python script is only an interface for this nice Shell script.
@thedopepirate you shouldn't rename the .sh to .py
The sh is the script that toggles bt audio. You can use it alone. The py is a GUI that shows a toggle button and it calls the sh under the hood
Thanks !
Hi!
I was looking for a solution to use the mic of my headphones with A2DP mode (in Ubuntu 20.04). I kind of understand that this is technically impossible. Is that correct?!
Then, I understand that I need to switch to HSP/HFP mode if I'd like to use the mic. However, sound quality is terrible...
This code seems to allow to toggle between the 2 modes. I don't understand if it toggles automatically (for example when muting/unmuting in Skype, Teams, or whatever)? Some folks propose to add a toggle button, so I guess the switching is done manually? Is that different from the Sound Input & Output Device Chooser Gnome extension? See a screenshot here: https://ibb.co/s3gjtsH.
Hi!
I was looking for a solution to use the mic of my headphones with A2DP mode (in Ubuntu 20.04). I kind of understand that this is technically impossible. Is that correct?!
Then, I understand that I need to switch to HSP/HFP mode if I'd like to use the mic. However, sound quality is terrible...
As far as I know, it is currently impossible to obtain both good quality mic and phones in Ubuntu.
This code seems to allow to toggle between the 2 modes. I don't understand if it toggles automatically (for example when muting/unmuting in Skype, Teams, or whatever)? Some folks propose to add a toggle button, so I guess the switching is done manually?
The code allows you to toggle between the modes although it is not automatic.
Is that different from the Sound Input & Output Device Chooser Gnome extension? See a screenshot here: https://ibb.co/s3gjtsH.
I've just installed the plugin you suggested, and could not get the menu for changing the output mode like in the screenshot (Ubuntu 18.04.5). Did you have a good experience with that? Anyway, the toggle button I proposed in the Python script works quite fast, which is desirable during a conversation. But sure, it is just a homemade tweak I did to complement the original script.
Thanks for your reply.
You said it is currently impossible in Ubuntu. Do you mean it works fine in Windows?
Did you check in the configurations of the extension if there is something to switch on? Maybe your Gnome shell version is too old (< 3.14)? Maybe it only works in Ubuntu 20.04...
Maybe you also need this other Gnome extension in order to make it works: Bluetooth quick connect. I've both installed.
My understanding is that this bash script added to your Python script allow to toggle between the modes in one click while I need 3 clicks with the Gnome extension. I'm willing to try it. Is there any risk to run the bash script (I don't want to break any system file on my PC)? Do you need to run your Python script each time you start a conversation? Do you think your button could appear to the top bar each time I connect my headphones, so the button is always available?
Thanks for your reply.
You said it is currently impossible in Ubuntu. Do you mean it works fine in Windows?
No... I didn't test it on Windows, but it works fine in my iOS
Did you check in the configurations of the extension if there is something to switch on? Maybe your Gnome shell version is too old (< 3.14)? Maybe it only works in Ubuntu 20.04...
Maybe you also need this other Gnome extension in order to make it works: Bluetooth quick connect. I've both installed.
I checked the configurations and I found nothing I could do. Maybe Ubuntu 20.04 solves it, I don't know. I also tried the Gnome extension, it didn't solve the problem.
My understanding is that this bash script added to your Python script allow to toggle between the modes in one click while I need 3 clicks with the Gnome extension. I'm willing to try it. Is there any risk to run the bash script (I don't want to break any system file on my PC)? Do you need to run your Python script each time you start a conversation? Do you think your button could appear to the top bar each time I connect my headphones, so the button is always available?
Yes, they both work. I don't think there is any risk. The scripts just change the mic/phone configurations.
Yes, every time we need to run this script. It was just an exercise to test the switcher. I am pretty sure there is a way to put the button on the top bar, you just need to improve ii :)
Would it be possible to link this script to .bashrc so it immediately launches every time the device gets connected?
Possible? I think so. The question is how to do it in a clean way.
I just googled "run script when bluetooth device plugged in Linux" and found this: https://askubuntu.com/questions/138522/how-do-i-run-a-script-when-a-bluetooth-device-connects. Maybe it helps.
Maybe you could use the same variable BLUETOOTH_DEVICE
from @artem328's comment.
Hi!
1. Did you configure the Shell script `switchHeadphones.sh`? In case not, you should. You can do as suggested in the Shell script: -- Run `pacmd list-sinks | grep '\(name:\|alias\)'` and fill with value from alias of your Bluetooth device 2. The error you showed relates to the @artem328's script. Try running `./switchHeadphones.sh speak` then `./switchHeadphones.sh listen` in your terminal and see if everything works. My Python script is only an interface for this nice Shell script.
When I run ./switchHeadphones.sh speak
, I get the message F5A headset not found.
How do I fix this?
Hello! I wrote small Golang systray app for this: https://github.com/dethlex/headset-switcher. It still in development, but it works.
I am using the script from @artem328
Maybe someone can help me find the variables I need for this script to work, and where to add them to the script -- for instance, the name of the headset.
I get this error:
headset not found
It is a BOSE QC35 II
On line 4 I have:
BLUETOOTH_DEVICE="BOSE QC35 II"
but I get the above error message, and the headphones disconnect.
EDIT: The correct name is "Bose QC35 II" and then it works like a charm.
Thanks for script!!
details from blueman:
60:AB:D2:45:5D:47 public Bose QC35 II Bose QC35 II 0x240418 0x0000 audio-card yes yes no no yes 00000000-deca-fade-deca-deafdecacaff Proprietary 00001101-0000-1000-8000-00805f9b34fb Serial Port 00001108-0000-1000-8000-00805f9b34fb Headset 0000110b-0000-1000-8000-00805f9b34fb Audio Sink 0000110c-0000-1000-8000-00805f9b34fb Remote Control Target 0000110d-0000-1000-8000-00805f9b34fb Advanced Audio 0000110e-0000-1000-8000-00805f9b34fb Remote Control 0000111e-0000-1000-8000-00805f9b34fb Handsfree 0000112f-0000-1000-8000-00805f9b34fb Phonebook Access (PBAP) - PSE 00001200-0000-1000-8000-00805f9b34fb PnP Information 81c2e72a-0591-443e-a1ff-05f988593351 Proprietary 931c7e8a-540f-4686-b798-e8df0a2ad9f7 Proprietary f8d1fbe4-7966-4334-8024-ff96c9330e15 Proprietary bluetooth:v009Ep4020d0436 /org/bluez/hci0
Kubuntu 20.04
EDIT: The name of device is case-sensitive. The correct name is "Bose QC35 II" and then it works like a charm.
Thanks for script!!
Hi all, I am glad that there has been quite a lot of activity around my humble script :)
I personally moved to a device with BlueTooth 5, so I can't work on this anymore.
@tvaillantdeguelis wrote a good summary - BlueTooth 4 was not capable of supporting a microphone at a decent quality, unless there were workarounds supported by both the drivers and the device, like setting up 2 BT connections. I could not make that work on Linux.
@Fuzzphorescent I ran into the same problem today.
You might have found a solution for your problem by now, but I hope someone else with similar problem finds this useful
Original script searches ( greps) for F5A keyword from list of connected devices (sinks to be accurate) , well your device might have different name like mine. So, that's why you got that error.
The script given by artem328 worked like a charm for me along with toggle button. So try it out
@JustinFrost47 I never did figure it out but now having read your answer, it seems so obvious what the problem was. Looks like I hadn't skimmed the code back then to find out what prompted the error message.
I've since moved to a newer machine running Windows 10 (which is posing its own set of BT-related challenges). I'm now inspired to dust off the old laptop and give it another go for an undeserved sense of accomplishment. Thanks for the help, cheers.
Thanks for script, i've modified it a little bit to have more universal usage.