FUN WITH LINUX

HackADay: Listening to Spotify on my Pi using A2DP

28 October 2016

Raspberry Pi Logo

I installed Raspbian(Debian Jessie) with Kodi on my Raspberry Pi and I use my Pi as a Meda Center. This Media Center plays music, mostly radio stations, all day long. I can easily control this media-center using the Yatse-App on my phone. The Setup is almost perfect, but just almost. Sometimes I prefer to listen to my Spotify-Playlists. At the moment there are no really good music addons for that. So I came to the idea to pair my phone via bluetooth with my Pi and use the audio output of my phone to play the Spotify-playlists.

Requirements

  • Raspberry Pi Model 3(All the others don’t have a builtin bluetooth)
  • Headset/Speaker
  • Pulseaudio (Sound-Daemon)
  • Bluez(Bluetooth-Stack)

Installing the needed packages

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

Configuring Bluetooth

To enable all the bluetooth audio commands we have to add the following lines in the [General]-section of /etc/bluetooth/main.conf:

Enable=Source,Sink,Media 

Next we have to change the bluetooth-class:

Class = 0x00041C 

Now we have all the audio-functions we need for our bluetooth-stack. So let’s pair the phone with our raspberry. Just call bluetoothctl and use the following commands:

scan on 
trust xx:xx:xx:xx:xx:xx(phone bluetooth mac) 
connect xx:xx:xx:xx:xx:xx(phone bluetooth mac) 

To exit bluetoothctl we can hit CTRL+D. Now our phone is paired and ready to rock.

Setup the Audio-Connection

When the phone connects via bluetooth, a few commands are necessary to rock the house. One of those commands are connecting the right bluetooth-audio-source to the right audio-output-device. Fist we start as user pi the pulseaudio-daemon:

pi@raspberrypi:~ $ pulseaudio --start 

Next we can check the audio-devices:

pi@raspberrypi:~ $ pactl list sources short 0 alsa_output.0.analog-stereo.monitor module-alsa-card.c s16le 2ch 48000Hz IDLE 1 bluez_source.84_CF_BF_89_47_01 module-bluez5-device.c s16le 2ch 48000Hz RUNNING 

The output might differ, since in this example my phone is already playing music via the raspberry pi ;) To list only all the sinks we can use this command:

pi@raspberrypi:~ $ pactl list sinks short 0 alsa_output.0.analog-stereo module-alsa-card.c s16le 2ch 48000Hz RUNNING 

So now we know the input-device, and the output device and can connect it properly. When we do that, we also have to make sure that the audio volume is set correctly. We can do all this automatically as soon as we connect our phone to the pi. We will use a udev-rule to achieve this. So let’s create the file /etc/udev/rules.d/99-input.rules with the following content:

KERNEL=="input[0-9]*", RUN+="/home/pi/a2dp-autoconnect" 

The file /home/pi/a2dp-autoconnect looks like that:

#!/bin/bash
# The original script: http://blog.mrverrall.co.uk/2013/01/raspberry-pi-a2dp-bluetooth-audio.html.


# Find the right sink with `pactl list sources short`.
PA_SINK="alsa_output.0.analog-stereo"
BT_MAC=$(echo "$NAME" | sed 's/:/_/g' | sed 's/\"//g')
BT_USER=pi


sudo su - "$BT_USER" -c "pulseaudio -D"

function log {
	echo "[$(date)]: $*" >> /var/log/a2dp-autoconnect
}

function checkSource {
	# Get the current sources
	local _sources=$(sudo su - "$BT_USER" -c "pactl list sources short")

	# Check if any sources are currently running and that our new device is valid.
	if [["$_sources" =~ RUNIING]]; then
		log "Source is already RUNNING. Available sources:"
		log "$_sources"
		return
	fi

	if [[! "$_sources" =~ "$1"]] ; then
		log "Unrecognized source. Available sources:"
		log "\n$_sources"
		return
	fi

	log "Validated new source: $1."
	echo "$1"
}

function setVolume {
	log "Setting volume levels."

	# Set our volume to max
	sudo su - "$BT_USER" -c "pacmd set-sink-volume 0 65537"
	sudo su - "$BT_USER" -c "amixer set Master 100%"
}

function connect {
	log "Connecting $1."

	# Connect source to sink
	sudo su - "$BT_USER" -c 'pactl load-module module-loopback source="$1" sink="$PA_SINK" rate=44100 adjust_time=0'
}

log "Change for device $BT_MAC detected, running $ACTION."

if ["$ACTION" = "add"]
then
	incoming=bluez_source."$BT_MAC"
	if [! -z $(checkSource "$incoming")] ; then
		connect "$incoming"
		setVolume
	fi
fi

I borrowed this file from here but I modified it so that it automatically starts pulseaudio. Next we have to change the permissions:

pi@raspberrypi:~ $ chmod +x a2dp-autoconnect

Let’s Rock The House

So finally we can rock the house. As soon as I start Spotify on the phone I can listen to it but I can also easily stop the music and play all my favourite radio stations using Kodi.

[ Tricks  HackADay  Raspberry  Multimedia  ]
Except where otherwise noted, content on this site is licensed under a Creative Commons Attribution 3.0 Unported License.

Copyright 2015-present Hoti