Enhance Raspberry Pi Media Center With Bluetooth A2DP (OSMC)

147,817

96

85

Posted in TechnologyRaspberry-pi

Introduction: Enhance Raspberry Pi Media Center With Bluetooth A2DP (OSMC)

Having Bluetooth connectivity and enabling Raspberry Pi to behave as A2DP source is nothing new (see a general tutorial on Instructables), but the problem I had thus far was making that work on my media center Pi which was running Raspbmc. As I found out through numerous attempts to make it work, the problem was with Raspbmc suffering a bit too much from "weight loss" it forced upon itself, so the modules that work as expected on Raspbian were failing on Raspbmc:

$ pactl list sources short
Assertion 'l' failed at pulsecore/flist.c:168, function pa_flist_pop(). Aborting.Aborted

When I learned that Raspbmc was not going to be developed any longer and that its successor -- OSMC -- will be based on Debian distro that was not butchered to fit on 2 GB SD card, I immediately planned to give that a try :-)

What I found out when I started setting up A2DP on OSMC on my Raspberry Pi 2 is that OSMC is no longer based (as its predecessor was and as Raspbian is) on Debian Wheezy, but that it is based on Debian Jessie. That means bye-bye SysVinit and hello Systemd. And that change of service manager (making all "A2DP on Rasberry Pi" available tutorials obsolete or at least not easily replicable by novice users) is the real reason for this tutorial.

Step 1: Requirements

  • Raspberry Pi
  • 4GB+ SD card with installed OSMC (Release Candidate or newer)
  • Bluetooth v4.0+ USB adapter
  • a headphones or speaker system connected to 3.5 mm phones port
  • an Internet connection (for package updates)
  • either LAN connection for SSH or an USB keyboard

A note regarding the Bluetooth v4.0+ USB adapter:

Even though I've used IOGEAR GBU521, any similar adapter should sufice, but best check the verified/supported hardware list before buying!

Step 2: Log in to a Terminal

Boot the Pi.

1) Variant: Remote terminal (SSH)

If you've a LAN connection to the Pi, the easiest way to go through this tutorial is to use SSH -- they you can copy/paste commands instead of typing them :-)

Find what your Pis IP address is and SSH into it with your favorite telnet client.

2) Variant: Local terminal

In this case, connect your keyboard, go to Power menu in XBMC and choose Exit. XMBC will close in a few seconds, but will restart immediately again. To enter the terminal, make sure you press the ESC key after you've choosen the Exit and while the OSMC screen is still showing. That will stop XBMC from staring again ad you'll have a terminal prompt with login in front of you.

Either way, the default credentials for OSMC are:

Username: osmc
Password: osmc

Step 3: Install the Necessary Packages

To get the state of repositories up-to-date, first execute:

sudo apt-get update

Optional: if you want, you can upgrade the outdated packages with:

sudo apt-get upgrade

Note: OSMC uses its own apt-get repository (http://apt.osmc.tv) for updating the system, which is a welcome change from Raspbmc, so not only does 'upgrade' upgrades the linux distro and installed 3rd party packages, it also upgrades the OSMC (media center and its packages).

After it finishes, execute this to install the necessary packages:

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

Image courtesy of: Keep Calm Network Ltd.

Step 4: Audio Configuration

Enable and load the sound module:

echo 'snd_bcm2835' | sudo tee -a /etc/modules
echo 'snd-bcm2835' | sudo tee -a /etc/modules
sudo modprobe snd_bcm2835 snd-bcm2835

Add users to pulse audio groups:

sudo usermod -a -G lp osmc
sudo usermod -a -G pulse-access,audio root sudo adduser osmc pulse-access

Heads-up: from this point forward, the tutorial uses GNU nano as terminal text editor, but you can easily use the one you prefer.

Open the configuration file for the PulseAudio daemon:

sudo nano /etc/pulse/daemon.conf

And find (press Ctrl+W, then type 'float') the line that reads:

resample-method = speex-float-1

and change it so:

; resample-method = speex-float-1
resample-method = trivial

Because we'll be running PulseAudio deamon in system mode, loading additional modules will not be possible once the deamon is started, so we need to configure their inclusion in the PulseAudio startup script for system mode:

sudo nano /etc/pulse/system.pa

and add the following lines (which check for existance and enable various modules):

.ifexists module-bluetooth-policy.so
load-module module-bluetooth-policy
.endif
.ifexists module-bluetooth-discover.so
load-module module-bluetooth-discover
.endif
.ifexists module-bluez5-device.so
load-module module-bluez5-device
.endif
.ifexists module-bluez5-discover.so
load-module module-bluez5-discover
.endif

We also need to create the service starting script:

sudo nano /etc/systemd/system/pulseaudio.service

and edit it like so:

[Unit]
Description=Pulse Audio
[Service]
Type=simple
ExecStart=/usr/bin/pulseaudio --system --disallow-exit --disallow-module-loading --disable-shm --daemonize
[Install]
WantedBy=multi-user.target

Execute these two commands to scan for new/changed units and to restart the PulseAudio service:

sudo systemctl daemon-reload
sudo systemctl enable pulseaudio.service
sudo systemctl start pulseaudio.service

All that is left to do for audio is to enable output to a prefered connector (0=auto,1=headphones,2=hdmi):

amixer cset numid=3 1

and, as volume will be controlled by the client, to set the volume level on the server side to 100 percent:

amixer set Master 100%
pacmd set-sink-volume 0 65535

Step 5: Bluetooth Configuration

To make sure A2DP audio sinks are allowed, open the config file:

sudo nano /etc/bluetooth/audio.conf

and place these three lines under [General] heading:

[General]
Enable=Source,Sink,Media,Socket
HFP=true
Class=0x20041C

Next, open another config file:

sudo nano /etc/bluetooth/main.conf

and place these lines under [General] heading:

[General]
Name = osmc
Class = 0x20041C

Next, list the BT adapter config:

sudo hciconfig -a

and note the MAC address (in form of XX:XX:XX:XX:XX:XX). You will need to specify it here:

sudo nano /var/lib/bluetooth/XX:XX:XX:XX:XX:XX/settings

where you should paste these lines:

[General]
Discoverable=true
Alias=osmc
Class=0x20041C

Bring up the BT:

connmanctl enable bluetooth
sudo hciconfig hci0 up

and in the BT control shell:

bluetoothctl

Then, execute the following commands to enable the agent and start the scan:

agent on
default-agent
discoverable on
scan on

That should display a list of visible BT clients (if not, execute 'devices' command). Next, execute the following to pair/trust your client device(s):

pair XX:XX:XX:XX:XX:XX
Request confirmation
[agent] Confirm passkey 503116 (yes/no): yes
trust XX:XX:XX:XX:XX:XX

Note: repeat the pair & trust commands for each device you want to allow to connect.

With this the Bluetooth part of the configuration is done.

Step 6: Fix for Automatic Audio After Reboot

When the past steps in the tutorial are all done, we can immediately see the effect -- the client and the Pi are connected and the client can stream audio via BT.

Woohoo! That's it!...Or, is it?

The problem comes when the Pi is restarted. Then, until someone is logged into console, PulseAudio will not work.

One solution is to enable auto-login into console.

sudo cp /lib/systemd/system/getty@.service /etc/systemd/system/autologin@.service

Next, we symlink that autologin@.service to the getty service for the tty on which we want to autologin, for example for tty1:

sudo mkdir /etc/systemd/system/getty.target.wants
sudo ln -s /etc/systemd/system/autologin@.service /etc/systemd/system/getty.target.wants/getty@tty1.service

Up to now, this is still the same as the usual getty@.service file, but the most important part is to modify the autologin@.service to actually log you in automatically. To do that, you only need to change the ExecStart line to read:

ExecStart=-/sbin/agetty -a osmc %I 38400

That's it. After this you'll briefly see the login prompt when the OSMC boots up, but it will allow PulseAudio to run even without you logged in.

reboot

Source: http://unix.stackexchange.com/a/42362

Step 7: Conclusion and Tips

My main goal was to reuse the always-on devices (media centar Raspberry Pi and Android phones/tablets) to stream online subscription music (namely Google Play Music) without needing to have PC turned on or the client device jacked in.

Naturally, the setup can be used to stream all sorts of audio through Pi. For example, gaming on tablet sounds pretty sweet when played on home stereo :)

Tip:

  • What I encountered occasionally on the phone was that sometimes it doesn't automatically reconnect to the Pi and that, when Pi (osmc) is pressed in BT phone settings, it immediately disconnects. The solution for this seems to be to turn BT on the phone off and then back on. After that (BT "reset") the phone again automatically connects to the Pi.

Nota bene:

  • I was writing down each step I applied while I was investigating how goal in this tutorial can be achieved, but when I started to verify the tutorial (on a clean OSMC install) some weeks later, the version of the OSMC was incremented and I didn't manage to reproduce it exactly step by step, so if you find some parts are off, feel free to suggest improvements in the comments (and I will hopefully update the tutorial).

Principal source of information: ArchLinux Wiki.

Honorable mention: inspired by a tutorial from dantheman_213.

Share

    Recommendations

    • Spotless Contest

      Spotless Contest
    • Microcontroller Contest

      Microcontroller Contest
    • Space Challenge

      Space Challenge
    user

    We have a be nice policy.
    Please be positive and constructive.

    Tips

    Questions

    85 Comments

    Hello,

    I'd like to thank you for this guide. It is really straight forward and it worked great for me.

    Now I want to share something I added, which will allow your friends to be able to pair and play music too, without having to configure anything on your PI.

    First you have to download the bluez source code and untar it.

    Then you have to modify bluez/test/simple-agent file replacing the following section:

    nano /usr/src/bluez-5.23/test/simple-agent

    def RequestPinCode(self, device):

    print("RequestPinCode (%s)" % (device))

    set_trusted(device)

    return “1234"

    Then I created a script to switch to discoverable mode, disable secure simple pairing and finally start this agent.

    nano /usr/bin/btscript.sh

    #!/bin/sh

    result=`ps aux | grep -i "simple-agent" | grep -v "grep" | wc -l`

    if [ $result -ge 0 ];

    then

    sudo hciconfig hci0 piscan

    sudo hciconfig hci0 sspmode 0

    sudo /usr/bin/python /usr/src/bluez-5.23/test/simple-agent &

    else

    echo "BT Agent already started"

    fi

    Finally to start the script on autologon:

    chmod +x /usr/bin/btscript.sh

    nano /etc/rc.local

    #!/bin/sh -e

    #

    # rc.local

    #

    # This script is executed at the end of each multiuser runlevel.

    # Make sure that the script will "exit 0" on success or any other

    # value on error.

    #

    # In order to enable or disable this script just change the execution

    # bits.

    #

    # By default this script does nothing.

    /usr/bin/btscript.sh

    exit 0

    Now just reboot and that’s it! You will be able to pair and play music from any bluetooth devices using the code PIN you defined in your agent (here “1234”).

    Source: http://www.linuxquestions.org/questions/linux-wireless-networking-41/setting-up-bluez-with-a-passkey-pin-to-be-used-as-headset-for-iphone-816003/

    5 replies

    Hello, I have tried to do this, but I can't find /usr/src/bluez-5.23/test/simple-agent

    @anmorfe: possibly you skipped this step:

    First you have to download the bluez source code and untar it.

    So, something like this should work for you:

    wget http://www.kernel.org/pub/linux/bluetooth/bluez-5.35.tar.xz

    tar xf bluez-5.35.tar.xz

    cd bluez-5.35

    I had somewhat mixed feelings about mixing versions, so preferred to download the sources of the version that was also installed via apt-get:

    1. If the line "deb-src ..." starts with a # (is a comment) remove the #. If it's not commented out, continue with 3

    2. sudo apt-get update

    3. cd /usr/src

    4. sudo apt-get source bluez

    This was the only missing part of pubbb's addition.

    Thank you Robert and pubbb for your description, it's literally the only one out there for jessie-based distros.

    Forgot to mention:

    Step 0: Open apt sources file: sudo nano /etc/apt/sources.list

    Nice enhancement :)

    Thanks!

    Thank you for sharing this informations. And made it and ... it works!!!

    As I use a Hifi Digi+ sound card, I did not make the first 2 parts of step 4, also did not type the command

    # amixer cset numid=3 1

    # amixer set Master 100%

    # pacmd set-sink-volume 0 6553

    Also I do not need the 6th step (OSMC RC2).

    Thank you again.

    1 reply

    Thanks for confirming :)

    Much appreciated!

    Okay, I've tried my best to blend together both the instructions above and the suggestions below and still cannot get any audio output.

    I'm using a R Pi 1 Model B while I wait for a dedicated model 3 to arrive with the OSCM July 1st image. I'm starting to wonder if something has changed in the bluetooth architecture because the folder '/etc/bluetooth' is not there and the file 'main.conf' does not exist either. I went ahead and did a 'mkdir /etc/bluetooth' and created the main.conf file with the contents suggested but that doesn't seem to have fixed the issue.

    I've also tried changing the Audio Out settings in OSMC and none of them will produce the bluetooth audio either...

    Does anyone have any ideas?

    1 reply

    Hi together,

    I have exact the same problem with my Pi 1 Model B.

    I use a fresh OSMC installation and I followed the instructions step by step, till I have to add something to the folder /etc/bluethooth. This folder does not exist.

    Is this only a problem of Pi 1?

    Torsten

    Hello Robert,

    Thanks for the great instructions. Went through them step by step and everything works! Now.. I'm interested in another addition which I think might be very much welcome by other users as well - have the BT connect event trigger an HDMI CEC message to the connected AVR / TV and get it to turn on...

    My existing RPi2 + OSMC does exactly that when turned on (including AVR input change) but when I connect to its BT from a client and stream audio it doesn't..

    Any thoughts on how to achieve that?

    Thanks again!

    O,

    1 reply

    Thanks.

    No idea how to do that, but seems it could be interresting for others, too. Maybe when you succeed you can post a followup.

    what FANTASTIC work!

    well done, sir.

    I hope this gets pulled upstream into OSMC or OpenELEC for native support

    user

    I have installed but sound from my bluetooth speaker last only for 10 sec then no sound. My speakers still connected but no sound after 5-10 sec.

    How do I get continues sound?

    Thanks

    user

    I have successfully installed on my OSMC and I can hear the sound from my Bluetooth speaker but it is only for 10 sec and then no sound.

    Also, I noticed that when I play You tube video, I can hear the sound with video.

    Any idea?

    I thought that enabling Raspberry Pi as A2DP source means to send data to be played on an A2DP sink such a bluetooth headset or speakers. But step 1 says I must connect headphones or speakers to the 3.5mm port. What is this tutorial for?

    user

    Thank you very much for your guide.

    It work great for me, I just need to set pulse audio in OSMC audio parameter instead of HDMI.

    Thank you very much one more time.

    Bye.

    Thanks for the tutorial!

    For me it worked when reverting from RC3 to RC, but after restarting the device(pi) is not detected as a ad2p speaker but rather a normal Bluetooth device(with no label). When tryign to connect to it the connection would drop after less than a second.

    I believe it may be the ad2p configs are not taking effect, but am unsure as I followed the guide exactly.

    1 reply

    Hi, I am having the same problem. It used to work fine for a couple of days, then when the pi rebooted, my bluetooth device is now Class 0x00041C and cannot be connected to anymore.

    The file /var/lib/bluetooth/XX:XX:XX:XX:XX/settings seems to get overwritten at boottime where the line Class = 0x20041C gets erased.
    I can manually set the device class back to 0x20041C using
    "hciconfig hci0 class 0x20041C" but I have to do this after every reboot.

    Any suggestion on where to fix this?