Last active
December 17, 2024 15:51
Enable bluetooth A2DP on Raspberry-PI via pulseaudio.
To install, edit /etc/udev/rules.d/99-input.rules and add the line:
SUBSYSTEM=="bluetooth", RUN+="/usr/lib/udev/bluetooth" Then save this script as /usr/lib/udev/bluetooth and set it executable.
Bluetooth devices must be linked first.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# This script is called by udev when you link a bluetooth device with your computer | |
# It's called to add or remove the device from pulseaudio | |
# | |
# | |
# Output to this file | |
LOGFILE="/var/log/bluetooth_dev" | |
# Name of the local sink in this computer | |
# You can get it by calling : pactl list short sinks | |
AUDIOSINK="alsa_output.platform-bcm2835_AUD0.0.analog-stereo" | |
# User used to execute pulseaudio, an active session must be open to avoid errors | |
USER="pi" | |
# Audio Output for raspberry-pi | |
# 0=auto, 1=headphones, 2=hdmi. | |
AUDIO_OUTPUT=1 | |
# If on, this computer is not discovearable when an audio device is connected | |
# 0=off, 1=on | |
ENABLE_BT_DISCOVER=1 | |
echo "For output see $LOGFILE" | |
## This function add the pulseaudio loopback interface from source to sink | |
## The source is set by the bluetooth mac address using XX_XX_XX_XX_XX_XX format. | |
## param: XX_XX_XX_XX_XX_XX | |
## return 0 on success | |
add_from_mac(){ | |
if [ -z "$1" ] # zero params | |
then | |
echo "Mac not found" >> $LOGFILE | |
else | |
mac=$1 # Mac is parameter-1 | |
# Setting source name | |
bluez_dev=bluez_source.$mac | |
echo "bluez source: $mac" >> $LOGFILE | |
# This script is called early, we just wait to be sure that pulseaudio discovered the device | |
sleep 1 | |
# Very that the source is present | |
CONFIRM=`sudo -u pi pactl list short | grep $bluez_dev` | |
if [ ! -z "$CONFIRM" ] | |
then | |
echo "Adding the loopback interface: $bluez_dev" >> $LOGFILE | |
echo "sudo -u $USER pactl load-module module-loopback source=$bluez_dev sink=$AUDIOSINK rate=44100 adjust_time=0" >> $LOGFILE | |
# This command route audio from bluetooth source to the local sink.. | |
# it's the main goal of this script | |
sudo -u $USER pactl load-module module-loopback source=$bluez_dev sink=$AUDIOSINK rate=44100 adjust_time=0 >> $LOGFILE | |
return $? | |
else | |
echo "Unable to find a bluetooth device compatible with pulsaudio using the following device: $bluez_dev" >> $LOGFILE | |
return -1 | |
fi | |
fi | |
} | |
## This function set volume to maximum and choose the right output | |
## return 0 on success | |
volume_max(){ | |
# Set the audio OUTPUT on raspberry pi | |
# amixer cset numid=3 <n> | |
# where n is 0=auto, 1=headphones, 2=hdmi. | |
amixer cset numid=3 $AUDIO_OUTPUT >> $LOGFILE | |
# Set volume level to 100 percent | |
amixer set Master 100% >> $LOGFILE | |
pacmd set-sink-volume 0 65537 >> $LOGFILE | |
return $? | |
} | |
## This function will detect the bluetooth mac address from input device and configure it. | |
## Lots of devices are seen as input devices. But Mac OS X is not detected as input | |
## return 0 on success | |
detect_mac_from_input(){ | |
ERRORCODE=-1 | |
echo "Detecting mac from input devices" >> $LOGFILE | |
for dev in $(find /sys/devices/virtual/input/ -name input*) | |
do | |
if [ -f "$dev/name" ] | |
then | |
mac=$(cat "$dev/name" | sed 's/:/_/g') | |
add_from_mac $mac | |
# Endfor if the command is successfull | |
ERRORCODE=$? | |
if [ $ERRORCODE -eq 0]; then | |
return 0 | |
fi | |
fi | |
done | |
# Error | |
return $ERRORCODE | |
} | |
## This function will detect the bt mac address from dev-path and configure it. | |
## Devpath is set by udev on device link | |
## return 0 on success | |
detect_mac_from_devpath(){ | |
ERRORCODE=-1 | |
if [ ! -z "$DEVPATH" ]; then | |
echo "Detecting mac from DEVPATH" >> $LOGFILE | |
for dev in $(find /sys$DEVPATH -name address) | |
do | |
mac=$(cat "$dev" | sed 's/:/_/g') | |
add_from_mac $mac | |
# Endfor if the command is successfull | |
ERRORCODE=$? | |
if [ $ERRORCODE -eq 0]; then | |
return 0 | |
fi | |
done | |
return $ERRORCODE; | |
else | |
echo "DEVPATH not set, wrong bluetooth device? " >> $LOGFILE | |
return -2 | |
fi | |
return $ERRORCODE | |
} | |
## Detecting if an action is set | |
if [ -z "$ACTION" ]; then | |
echo "The script must be called from udev." >> $LOGFILE | |
exit -1; | |
fi | |
## Getting the action | |
ACTION=$(expr "$ACTION" : "\([a-zA-Z]\+\).*") | |
# Switch case | |
case "$ACTION" in | |
"add") | |
# Turn off bluetooth discovery before connecting existing BT device to audio | |
if [ $ENABLE_BT_DISCOVER -eq 1]; then | |
echo "Stet computer as hidden" >> $LOGFILE | |
hciconfig hci0 noscan | |
fi | |
# Turn volume to max | |
volume_max | |
# Detect BT Mac Address from input devices | |
detect_mac_from_input | |
OK=$? | |
# Detect BT Mac address from device path on a bluetooth event | |
if [ $OK != 0 ]; then | |
if [ "$SUBSYSTEM" == "bluetooth" ]; then | |
detect_mac_from_devpath | |
OK=$? | |
fi | |
fi | |
# Check if the add was successfull, otherwise display all available sources | |
if [ $OK != 0 ]; then | |
echo "Your bluetooth device is not detected !" >> $LOGFILE | |
echo "Available sources are:" >> $LOGFILE | |
sudo -u $USER pactl list short sources >> $LOGFILE | |
else | |
echo "Device successfully added " >> $LOGFILE | |
fi | |
;; | |
"remove") | |
# Turn on bluetooth discovery if device disconnects | |
if [ $ENABLE_BT_DISCOVER -eq 1]; then | |
echo "Set computer as visible" >> $LOGFILE | |
sudo hciconfig hci0 piscan | |
fi | |
echo "Removed" >> $LOGFILE | |
;; | |
# | |
*) | |
echo "Unsuported action $action" >> $LOGFILE | |
;; | |
esac | |
echo "--" >> $LOGFILE |
My bluetooth device is not getting detected. Any hints how to solve this?
Unable to find a bluetooth device compatible with pulsaudio using the following device: bluez_source.XX_XX_XX_XX_XX
Your bluetooth device is not detected !
Available sources are:
0 alsa_output.platform-soc_audio.analog-stereo.monitor module-alsa-card.c s16le 2ch 44100Hz IDLE
--
@mschwarzer
I have same problem.
@malteos @00xBIT
This check is done by sudo -u $USER pactl list short sources
and under sudo
sources are not shown:
$ pactl list short sources
0 alsa_output.usb-Burr-Brown_from_TI_USB_Audio_DAC-00.analog-stereo.monitor
24 bluez_source.xx_xx_xx_xx_xx_xx.a2dp_source
$ sudo -u openhabian pactl list short sources
0 alsa_output.usb-Burr-Brown_from_TI_USB_Audio_DAC-00.analog-stereo.monitor
I haven't found solution for this problem, but I found out that audio is routing correctly without this script (probably newer pulseaudio or bluez is smarter). The only thing that I had to configure is setting default sink in /etc/pulse/client.conf
:
; default-sink = alsa_output.usb-Burr-Brown_from_TI_USB_Audio_DAC-00.analog-stereo
My setup:
Operating System: Raspbian GNU/Linux 9 (stretch)
Kernel: Linux 4.14.94-v7+
Package: pulseaudio
Version: 10.0-1+deb9u1
Package: bluez
Version: 5.43-2+rpt2+deb9u2
There is a nice up to date project that you can use instead: https://github.com/nicokaiser/rpi-audio-receiver
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks for this script!
I just put the script in my home directory with some changes since I'm not using pulseaudio. Its working, but the logfile isn't being created so I'm having a hard time troubleshooting. Does it have to run from /usr/lib/udev to make the log or something?