Skip to content

Instantly share code, notes, and snippets.

@kingster
Last active May 3, 2022 01:09
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save kingster/3784fa2f0de1f5ce4418 to your computer and use it in GitHub Desktop.
Save kingster/3784fa2f0de1f5ce4418 to your computer and use it in GitHub Desktop.
Raspberry PI Bluetooth Audio Player
### BEGIN INIT INFO
# Provides: bluetooth-agent
# Required-Start: $remote_fs $syslog bluetooth pulseaudio
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Makes Bluetooth discoverable and connectable to 0000
# Description: Start Bluetooth-Agent at boot time.
### END INIT INFO
#! /bin/sh
# /etc/init.d/bluetooth-agent
USER=root
HOME=/root
export USER HOME
case "$1" in
start)
echo "setting bluetooth discoverable"
sudo hciconfig hci0 piscan
start-stop-daemon -S -x /usr/bin/bluetooth-agent -c pi -b -- 0000
echo "bluetooth-agent startet pw: 0000"
;;
stop)
echo "Stopping bluetooth-agent"
start-stop-daemon -K -x /usr/bin/bluetooth-agent
;;
*)
echo "Usage: /etc/init.d/bluetooth-agent {start|stop}"
exit 1
;;
esac
exit 0
#!/bin/bash
echo "Executing bluetooth script...|$ACTION|" >> /var/log/bluetooth_dev
ACTION=$(expr "$ACTION" : "\([a-zA-Z]\+\).*")
if [ "$ACTION" = "add" ]
then
# Turn off BT discover mode before connecting existing BT device to audio
hciconfig hci0 noscan
# set the audio output to the analog
# COMMENT THIS LINE OUT IF YOU WANT TO OUTPUT AUDIO THROUGH HDMI
#amixer cset numid=3 1
# Set volume level to 100 percent
amixer set Master 100%
pacmd set-sink-volume 0 65537
for dev in $(find /sys/devices/virtual/input/ -name input*)
do
if [ -f "$dev/name" ]
then
mac=$(cat "$dev/name" | sed 's/:/_/g')
bluez_dev=bluez_source.$mac
sleep 1
CONFIRM=`sudo -u pi pactl list short | grep $bluez_dev`
if [ ! -z "$CONFIRM" ]
then
echo "Setting bluez_source to: $bluez_dev" >> /var/log/bluetooth_dev
echo pactl load-module module-loopback source=$bluez_dev rate=44100 adjust_time=0 >> /var/log/bluetooth_dev
sudo -u pi pactl load-module module-loopback source=$bluez_dev rate=44100 adjust_time=0 >> /var/log/bluetooth_dev
fi
fi
done
fi
if [ "$ACTION" = "remove" ]
then
# Turn on bluetooth discovery if device disconnects
sudo hciconfig hci0 piscan
fi

#Setup

Let's Install the packages

sudo apt-get upgrade
sudo apt-get install bluez pulseaudio-module-bluetooth python-gobject python-gobject-2 bluez-tools

First, let’s go ahead and add our user pi to the Pulse audio group so we the user can play audio through it.

sudo usermod –a –G lp pi

Now, let’s go ahead and enable A2DP in our Bluetooth configuration. Run the following command: sudo nano /etc/bluetooth/audio.conf

This will open the text editor nano with that config file. Add the follow text under [General]:

Enable=Source,Sink,Media,Socket

Save it.

Next, let’s modify the Pulse daemon configuration file to change its resampling method. sudo nano /etc/pulse/daemon.conf

Look for the following line: resample-method = speex-float-3

If the line doesn’t have a ; in front of it, please put a ; there so it looks like: ; resample-method = speex-float-3

And then add the following line underneath that. resample-method = trivial

Next find ; exit-idle-time = 20

And then add the following line underneath that. exit-idle-time = -1

Before moving on, let’s also go ahead and rename our Bluetooth device (odds are you don’t want the name to be raspberry-pi0) as well as redefine the Bluetooth class device from 'Computer' to 'Portable audio device'. There are two locations you should modify.

sudo nano /etc/bluetooth/main.conf

Change the Name parameter. I chose to do a play on the Bplay. Name = Bplay

Next, you’ll have to modify the config of your specific device. The directory is based on your Bluetooth device’s MAC address so just hit TAB when typing that out and you’ll find yours.

sudo nano /var/lib/bluetooth/[bluetooth mac address]/config

Edit the name directive again. name Bplay

Let's now setup the auto-conenct scripts

sudo nano /etc/udev/rules.d/99-input.rules

There should be just a single line there that looks like: SUBSYSTEM=="input", GROUP="input", MODE="0660"

Underneath it, let’s go ahead and add the following line: KERNEL=="input[0-9]*", RUN+="/usr/lib/udev/bluetooth"

Save and exit.

Now let’s actually save that script that the above rule file is referencing. First check to see if a udev/ directory exists. Do sudo ls –la /usr/lib/udev . If it doesn’t exist go ahead and create it like so: sudo mkdir /usr/lib/udev

sudo nano /usr/lib/udev/bluetooth

Copy and paste the contents of bluetooth-change.sh file.

Now let’s modify the permissions of the file to make it executable. sudo chmod 774 /usr/lib/udev/bluetooth

Automating Bluetooth discovery and auto accepting connections

sudo nano /etc/init.d/bluetooth-agent

Go ahead and copy paste bluetooth-agent.sh into the text editor.

Save and exit nano.This script basically is just a standard start/stop script for Bluetooth discoverability. Go ahead and give the script execute permissions and then add it to the list of programs that start on start-up.

sudo chmod 755 /etc/init.d/bluetooth-agent
sudo update-rc.d bluetooth-agent defaults

#Additional Info's

To debug use pulseaudio -vvvv --log-level=debug

@franklindee
Copy link

HI
/etc/bluetooth/audio.conf can i cange main.conf????

sudo nano /var/lib/bluetooth/[bluetooth mac address]/config cannot find it

there is setting but is empty
please help

thank you

@shark0der
Copy link

shark0der commented May 27, 2016

I've succeeded to turn my pi into bluetooth speakers! A couple of notes:

Udev rule

Instead of adding/editing udev rules and creating the bluetooth-agent service, I've added

load-module module-bluetooth-discover
load-module module-bluetooth-policy

to my pulse config /etc/pulse/system.pa, YMMV, see next note.

Pulseaudio systemd unit

Heads up: Since I am running my pi in headless mode (no X11), I had to add a systemd unit to start pulseaudio in system mode at system boot (although it is not recommended, but it is running as pulse user so I guess that's OK).
Here's the my /etc/systemd/system/pulseaudio.service file:

[Unit]
Description=PulseAudio Daemon

[Install]
WantedBy=multi-user.target

[Service]
Type=simple
PrivateTmp=true
ExecStart=/usr/bin/pulseaudio --system --realtime --disallow-exit --no-cpu-limit

Don't forget to run systemctl enable pulseaudio so it would actually start at boot.

BT name and class

  • I haven't changed the BT name since it automatically takes the hostname and I'm comfortable using that.
  • The Enable=Source,Sink,Media,Socket is deprecated and pulseaudio was emiting a warning to syslog: bluetoothd[363]: Unknown key Enable in main.conf so I removed it - no need for it.
  • I still had to edit the bluetooth configuration file /etc/bluetooth/main.conf (yes, main not audio) and added this to the general section:
    Class = 0x20041C so now my computer recognizes the pi as an audio device.

Pairing

I've used bluetoothctl and issued the following 3 commands:

power on
pairable on
discoverable on

After this it is possible to connect using your phone/laptop (android 5.1/ubuntu 16.04 in my case) and it will pair successfully.

@PortiESP
Copy link

PortiESP commented Jan 5, 2021

Anyone has problems with the file /etc/init.d/bluetooth-agent, the line (start-stop-daemon -S -x /usr/bin/bluetooth-agent -c pi -b -- 0000
) returns an exception because the file /usr/bin/bluetooth-agent doesnt exists, also qhen i power of it waits 1min30seg becacuse a "A stop job is running for bluetooth auth agent"

@JulyIghor
Copy link

yes, solved by creating empty file that name

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