Skip to main content

Raspberry Pi A2DP Bluetooth Audio Receiver

I wanted to use a Raspberry Pi to act as a Bluetooth audio receiver or my Hi-Fi so that I could connect a phone/tablet easily to some proper speakers wirelessly. Rather than reinventing the wheel 'kmonkey' has already achieved most of what I set out to do over here; check this out first.

The only issue now is the manual intervention needed to connect up a new Bluetooth source to the output sink. I initially created a simple bash script to poll pulseaudio (every 5 seconds) and run the necessary commands as and when a new device is connected. You can see the script here and all the pertinent commands are explained over in kmonkey's blog. This is all good, but will need to be run manually using something like,

# nohup ./bt_audio_attach &

This is a bit rubbish and you'll be pleased to know there is a better way to get this done, UDEV!

Over at the Raspbery Pi forums  there's some discussion on using UDEV scripts to automate this process entirely. Initially I had had some issues with their scripts and was experiencing source disconnects after ~20 seconds of playback. Another problem was that a new incoming Bluetooth connection would scupper the currently connected device which may be quite undesirable (e.g. if anyone else in the house uses another device with your setup as my wife does).

I've re-factored my original methodology into the following UDEV script at the bottom of this post. The major improvement here is that we no longer interfere with any currently running Bluetooth playback and we also add the ability to easily specify a user to run our commands as. You could always use the 'Pi' user (or your own user account), but I don't like giving random background processes my full privileges. You can create such an unprivileged user like so,

# useradd -rMN -g nogroup -G lp,audio btaudio

To trigger the udev script when a new device connects create (or modify) an even handler in /etc/udev/rules.d/99-input.rules adding the following content rules,

We're now almost running a fully headless A2DP receiver, except one problem, the 20 second cut outs. It turns out this happens because pulseaudio times out playback for users if they are not active, like our 'btaudio' user. Back at the forums some suggest running pulse as a system process, but before heading down that route you really should read this information. Instead we just need to disable timeouts by adding a line in '/etc/pulse/client.conf' to read,

extra-arguments = --exit-idle-time=-1 --log-target=syslog


OK, not quite. For reasons not yet understood this is still not working from a cold start as I would like it to. Instead it begins working only after a user has logged in, even if that user immediately logs out again. I run my setup headless and have to login once via SSH to kick things off. Once I've done that it runs seamlessly for weeks at a time. Suggestions welcome.


  1. Thank you - I couldn't get the script on the Pi forums to function but yours worked beautifully - I might add that streaming would only work properly if the pi is logged in.

    1. I total agree with you in this point. Happy to see you here !

  2. Thanks a lot, same as user below!!!

  3. I mostly got streaming over bluetooth working on the Pi but ran into the problem of pulseaudio stopping after about 20 seconds. Your post solved this for me. Thanks very much. You can get the Pi to auto login by editing the /etc/inittab file and replacing the line
    1:2345:respawn:/sbin/getty 115200 tty1
    1:2345:respawn:/bin/login -f pi tty1 /dev/tty1 2>&1

  4. I already have
    SUBSYSTEM=="input", GROUP="input", MODE="0660"
    in etc/udev/rules.d/99-input.rules

    Is it right to add the line
    SUBSYSTEM="input", GROUP="input", MODE="0660"?

    Notice the difference in = vs ==. Which is right?

  5. How about supplying an image or zip of the configs, so we don't have to repeat all the steps?

  6. Configuration insightful, you would be hit with a colossal shower as the point of convergence in the room and I think it would look like gracious they included a shower in here.

  7. How about supplying an image or zip of the configs, so we don't have to repeat all the steps?

  8. Hey, I do think the thing is that the "SWITCH" on the Aerial Wireless bluetooth Modem will be on fasten function, or maybe DOWN. It really is merely form AUDIO/MIC jack.

  9. Setup insightful new, you would be strike that has a heavy shower since the level connected with convergence inside the place and also I believe it will look like thoughtful they bundled any shower within right here.

  10. Setup informative, using attack using a colossal bath since the point of convergence in the place along with I believe it might seem like nice many people bundled a bath with right here.

  11. I mostly got alive over bluetooth alive on the Pi but ran into the botheration of pulseaudio endlessly afterwards about 20 seconds. Your column apparent this for me. Thanks actual much. You can get the Pi to auto login by alteration the /etc/inittab book and replacing the line

  12. Thank you, works great! I have a question: How about supplying an image or zip of the configs, so we don't have to repeat all the steps?

  13. I love your post, it really good and interesting.

  14. Thanks a lot for sharing us this article. Great job.

  15. Line 17: should be "RUNNING", not "RUNIING" - right?

    1. Yeah, I would imagine so, but do check that it is my mistake and not pactl's by checking the real output :)

  16. This comment has been removed by a blog administrator.


Post a Comment

Popular posts from this blog

Moodle on Centos or Red Hat 7 (with SELinux!)

Why the need for another 'Installing Moodle' guide? Two reasons, Systemd and SELinux. The steps are presented as a Bash script, which may be run on a virgin system, installing a complete working Moodle stack in one go, including enforcing SELinux. In addition to the absolute basics it also includes adding ClamAV virus for file uploads and Memcached for sessions and 'MUC'. It does not cover any extras you will need to get your site up to production, e.g. securing your database  or updating your virus definitions automatically. Neither does it do any extra PHP configuration (upload limits, execution time etc.) or any extra complexities that might be desirable. For all of this you should goto .

Spawning many VirtualBox machines from a single VDI

What I'm taking about here is a way to have many VirtualBox machines based upon a single hard drive image. There are many reasons why you might like to do this, but the most compelling is probably saving time by not having to install an OS over and over again, especially useful if you do anything like software testing. Our goal is a single vdi (virtual disk) file which contains a vanilla installation of our favourite OS which we can then use to conjure up a fresh new machine in a jiffy. Assuming you already have VirtualBox installed our first step is (maybe for the last time ever!) to install our OS into a new virtual machine. Now I shan't go through this as it's pretty straight forward and if you're reading this it's the sort of thing you have probably done a hundred times before. One thing of note during the initial setup is the 'Virtual Hard Disk' configuration. Be sure to allocate enough space to allow for all potential applications of the image. It wou

Row a Concept2 on Zwift with a $10 Raspberry Pi!

Short story, I made a program. Instructions and download here: Despite there being an appetite for rowing in Zwift the fact is a rowing machine is not a bicycle and a Concept2 rower won't connect directly to Zwift. The Zwift gods tease a rowing release every now and again, but it's been coming 'soon' for years now. Don't hold your breath. But people do row in Zwift, so how do they do it? To get the data from the rowers computer, the PM5, into something Zwift recognises as a bicycle you need a device that translates between the rower and the device running Zwift. There are solutions already available to do this. Some are expensive like the  NPE CABLE (about £90 in the UK) and some are 'free' like the  RowedBiker  app. The downside with RowedBiker is that it needs to run on a extra device separate from the one running Zwift. If you have a compatible device lying around, great, otherwise you'll need to buy one. Meanwh