Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Directs audio in from Bluetooth device to all audio outputs on connect.
#This script was written for raspberry-pi-audio-reciever
#Project and can be found in it's original form at:
#My version of this script directs audio input from a
#bluetooth device to all availabe audio outputs (aka sinks)
name=$(sed 's/\"//g' <<< $NAME)
#exit if not a BT address
if [[ ! $name =~ ^([0-9A-F]{2}[:-]){5}([0-9A-F]{2})$ ]]; then exit 0; fi
bt_name=`grep Name /var/lib/bluetooth/*/$name/info | awk -F'=' '{print $2}'`
audio_source=bluez_source.$(sed 's/:/_/g' <<< $name)
action=$(expr "$ACTION" : "\([a-zA-Z]\+\).*")
logger "Action: $action"
if [ "$action" = "add" ]; then
audio_sinks=$(pactl list sinks short |cut -f 1)
for audio_sink in $audio_sinks; do
logger "[$(basename $0)] Bluetooth device is being added [$name] - $bt_name"
logger "[$(basename $0)] Patching $audio_source into ALSA sink #$audio_sink"
#hciconfig hci0 noscan
bluetoothctl << EOT
discoverable off
amixer cset numid=3 1
amixer set PCM 90%
#espeak -s 160 -k 1 "Device, $bt_name Connected"
/usr/local/bin/ "Device, $bt_name Connected"
amixer set PCM 100%
sleep 1
pactl set-sink-volume 0 65537
# loop back this source to the default sink
ID=$(pactl load-module module-loopback source=$audio_source sink=$audio_sink)
logger "[$(basename $0)] PulseAudio module-loopback returned handle [$handle]"
logger "$bt_name"
if [ "$action" = "remove" ]; then
logger "[$(basename $0)] Bluetooth device is being removed [$name] - $bt_name"
#hciconfig hci0 pscan
bluetoothctl << EOT
discoverable on
# remove any loopback modules assigned to this source
# only required for USB sound cards, which PulseAudio will not automatically remove
for ID in $(pactl list short modules | grep module-loopback | grep source=$audio_source | cut -f 1); do
logger "[$(basename $0)] Unloading module-loopback with handle [$ID]"
pactl unload-module $ID
sleep 5
amixer set PCM 90%
#espeak -s 160 -k 1 "Device, $bt_name Disconnected"
/usr/local/bin/ "Device, $bt_name Disconnected"
amixer set PCM 100%
# prevents any feedback loops caused by multiple module-loopbacks to sink(s)
audio_sinks=$(pactl listt sinks short |cut -f 1)
for audio_sink in $audio_sinks; do
while [[ $(pactl list modules short |grep module-loopback |grep source=bluez |grep sink=$audio_sink |cut -f 1| wc -l) -gt 1 ]]; do
EXCESS_MODULE="$(pactl list modules short |grep module-loopback |grep source=$audio_source |grep sink=$audio_sink |cut -f 1 |tail -n +2 |tail -n1)"
logger "[$(basename $0)] Multiple source to sink detected unloading module-loopback with handle [$EXCESS_MODULE]"
pactl unload-module $EXCESS_MODULE
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.