Streaming Bluetooth Audio from Phone to Raspberry Pi using ALSA


Update (Jan 8, 2020):
Step 1 has been updated to fix codebay and elba’s problems based on peacekunov’s feedback (Thanks!). Please see the comments for details.


Update (May 22, 2019):
Steps to manually enable A2DP sink role has been added based on Wolfgang and John’s feedback. (Step 1).


This post shows steps to setup Bluetooth audio sink on Raspberry Pi using bluez-alsa. Bluetooth audio sink (A2DP sink) enables Raspberry Pi to receive audio from other Bluetooth devices (e.g. smartphone) and play it through the connected speaker. Below are my setup.

 

Steps
1. Enabling Audio Profile Sink Role
1-1. Open the configuration file for bluealsa service

sudo nano /lib/systemd/system/bluealsa.service

1-2. Search the line starts with “ExecStart” and add a profile option with a2dp-sink as below.

ExecStart=/usr/bin/bluealsa -p a2dp-sink

1-3. Reboot.

sudo reboot

 

2. Bluetooth Pairing and Connection
2-1. Launch BlueZ command line interface.

bluetoothctl

2-2. Setup a pairing agent.

default-agent

2-3. Make the Raspberry Pi discoverable.

discoverable on

2-4. On your phone, search and select your Raspberry Pi from Bluetooth menu.

2-5. Confirm the pairing on both your phone and Raspberry Pi.

Request confirmation
[agent] Confirm passkey 847261 (yes/no): yes

2-6. Authorize A2DP service (first 32 bits: 0000110d). [2]

Authorize service
[agent] Authorize service 0000110d-0000-1000-8000-00805f9b34fb (yes/no): yes

Note: You may be asked about other services (such as HFP: 0000111E) depending on what services your phone supports. Just answer ‘yes’ to all the services if you are not sure.

2-7. Trust the phone so that Raspberry Pi will automatically accept connections from the phone from the next time.

trust XX:XX:XX:XX:XX:XX

Note: Replace “XX:XX:XX:XX:XX:XX” with your phone’s Bluetooth device address.

2-8. Exit from BlueZ command line interface.

exit

 

3. Audio Routing
3-1. Forward audio from the phone to Raspberry Pi’s output.

bluealsa-aplay 00:00:00:00:00:00

 

4. Verify
4-1. Launch a media player and play some music on your phone. You should be able to hear the music from Raspberry Pi’s speaker.

 

Troubleshoot : Sound Cutting Out
Raspberry Pi’s (3 / 3+ / Zero W) on-board Bluetooth+WiFi combo chip has an issue and the Bluetooth sound cuts out when WiFi is enabled [3]. If you don’t need WiFi, you can just disable the WiFi interface to avoid the sound cutting issue.

sudo ip link set wlan0 down

If you need WiFi, one of the workarounds is to disable the on-board Bluetooth and use a Bluetooth dongle (e.g. Plugable BLE Adapter, Panda Bluetooth 4.0 Adapter) instead. Below is the steps to do that.

1. Open “/etc/modprobe.d/raspi-blacklist.conf”.

sudo nano /etc/modprobe.d/raspi-blacklist.conf

2. Add lines below and save.

blacklist btbcm
blacklist hci_uart

3. Connect Bluetooth dongle on Raspberry Pi’s USB port.

4. Restart the Raspberry Pi.

sudo reboot

 

What’s Next?
If you are interested in controlling Bluetooth audio and showing the song information, please check this out.

 

References
[1] bluealsa: Couldn’t initialize controller thread: Bad file descriptor #149
[2] Service Discovery – Bluetooth SIG
[3] Pi3 bluetooth audio stutters with Wifi enabled

 

 

Sponsor Link

39 Comments

  1. thanks for the write-up.

    I’m a little stuck on 1-6 though… My bluetoothctl does not respond to ‘Authorize service’ at all. Do you know what might be missing?

    t

    1. Sorry John, it looks bluealsa changed the behavior at some point. Now we need to manually enable a2dp-sink profile first. (step 1-1 and 1-2 are newly added). Hope this will resolve your problem.

  2. Tried following your great write-up but running into the same problem like John. right after confirming pairing with “yes” the command line prompt briefly switches to the name of my android phone but soon “exits” the phone and reverts to “[bluetooth]”. Entering “Authorize service” results in “Invalid command in menu main: Authorize”.

    From what I can tell it seems as if my phone and my raspberry b+ do not stay connected. Pressing “connect” on my android phone in the bluetooth menu has no effect at all. When trying to connect from raspbian bluetooth GUI menu (via VNC) the permanent connection also fails with “Connection failed – No usable services on this device”. Seems to me as if my raspberry pi (raspbian) does not offer my phone to be used as bluetooth playback device.

    Do you have any idea what is missing to successfully bluetooth playback?

    Wolfgang

    1. Hi Wolfgang,
      I tried and got the same result as you guys. It looks bluealsa changed the behavior at some point. Now we need to manually enable a2dp-sink profile. Thankfully, it’s quite easy. I added step 1-1 and 1-2. Can you try it and let me know the result? Thanks!

      1. Thank you for your reply. Sorry for taking so long to try!
        Works perfectly now!!! So happy. Thank you for digging into it.

        Was a bit worried as there was no 2-6 for me (on Google Pixel 2 as bluetooth audi source).
        Until I discovered 3 Audio Routing 🙂

        Thanks again!

        PS: can you remove my other comment? I somehow posted at the end of the page instead of this thread.

        1. Hi Wolfgang, I’m grad it worked out for you!
          P.S. I removed your other comment as your request 😉

  3. Hello Max,

    thank You for this very useful post. Everything work as described. Even better – I do not find issue that no allow work onboard bluetooth adapter together with WiFi.

  4. is there any way to connect any mobile phone to the raspberry pi’s bluetooth same as a bluetooth speaker does ?
    In this tutorial we can connect devices only after a complete set of commands

    1. You need to repeat step 1 after rebooting raspberry and before connecting bluetooth device.
      Or you can edit ExecStart string in /lib/systemd/system/bluealsa.service:
      ExecStart=/usr/bin/bluealsa -p a2dp-sink

      1. Thank you peacekunov!
        I updated the Step 1 with your suggestion!

        codebay,
        Now you should be able to connect and restart music playback even after power cycle.
        Executing “bluealsa-aplay 00:00:00:00:00:00” command is still required unless you automate it at boot.

    1. Hi andrum99, I checked but I still can get it work with “bluealsa-aplay 00:00:00:00:00:00”.
      Anyways, thanks for sharing the gist, it looks very nice. (I haven’t tried it yet though)

  5. hello and thank you for this publication. Despite my perseverance I can’t get to step 2.5 (like John). I followed steps 1.1 and 1.2 but it doesn’t work. Do you have an idee to help me? thanking you.

    1. Hi elba, thank you for your feedback.
      I updated the Step 1. Can you give it a try and let me know the outcome?
      It looks something has changed and the previous method (original Step 1) doesn’t work any more.

      1. hello max. Thank you for your help unfortunately it does not work for me. I manage to have a connection but it stops after a few seconds. An idea? Is it necessary to update blueZ? something else? thank you

        1. Hi elba, what do you mean by “it stops after a few seconds”? Does that mean the connection is disconnected? If so, did you confirm that on bluetoothctl’s output? Also, after which step did you confirm the disconnection?

  6. Hi, I went through all the steps and it worked well!
    But what should I do when I want it to work without the LCD/laptop display? If I close the cmd prompt in pi, the system will be closed as well.
    Thank you.

  7. Thanks so much for this clear instruction.
    My new pi 4 is driving me round the bend with all the options for connecting Bluetooth and this worked perfectly.

  8. This worked great for me. The only problem I have is that I have to run “bluealsa-aplay 00:00:00:00:00:00” every time after I connect by iPhone to my raspberry pi. Is there any way to automate that, as I am trying to run by pi headless.

    I’ve tried adding the bluelalsa-aplay command to my rc.local file but that didn’t seem to work.
    Thanks!

    1. Hi Brian, adding “bluealsa-aplay 00:00:00:00:00:00 &” before “exit 0” in /etc/rc.local is working on my rpi.
      Can you check if the process is running by “ps -aux|grep bluealsa-aplay”?

      If the process is not running, most likely something is wrong in /etc/rc.local. But I think ideally we should create a service like https://gist.github.com/Pindar/e259bec5c3ab862f4ff5f1fbcb11bfc1, instead of executing the command in /etc/rc.local.

  9. Hi,

    All steps worked for me and I could pair my iPhone but cannot hear audio due to following issue running the last stem of tutorial:
    bluealsa-aplay 00:00:00:00:00:00
    bluealsa-aplay: BlueALSA connection failed: No such file or directory

    1. It worked when I upgraded to buster from old version of stretch.
      Also audio cuts a bit even when I disable wifi

  10. It worked when I upgraded to buster from old version of stretch.
    Also audio cuts a bit even when I disable wifi

  11. I am getting these errors on exit:

    Traceback (most recent call last):
    File “media_control.py”, line 63, in
    GLib.MainLoop().run()
    File “/usr/lib/python2.7/dist-packages/gi/overrides/GLib.py”, line 498, in run
    super(MainLoop, self).run()
    File “/usr/lib/python2.7/contextlib.py”, line 24, in __exit__
    self.gen.next()
    File “/usr/lib/python2.7/dist-packages/gi/_ossighelper.py”, line 251, in register_sigint_fallback
    signal.default_int_handler(signal.SIGINT, None)

  12. Hi Sir,
    How can i make to start playing music auto once it’s connected. It seems like I have to type in this command bluealsa-aplay 00:00:00:00:00:00 before the music can be transferred over the Pi

    Thanks

    1. Hello.
      1. how to automate it with Kodi.
      2.Allow automatic connection of any devices via bluetooth, otherwise now you need to enter YES in the console

  13. Hello, I have an issue where after typing bluealsa aplay 00:00:00:00:00:00 it says bluealsa: Couldn’t acquire D-Bus name: org.bluealsa. Thanks!

  14. Hi, sorry for the necroposting, but I just saw this guide (not had a chance to try it out yet) and I noticed
    “`
    sudo nano /lib/systemd/system/bluealsa.service
    “`
    Since that directory is owned by the system, it’s advisable to
    “`
    sudo cp /lib/systemd/system/bluealsa.service /etc/systemd/system
    sudo nano /etc/systemd/system/bluealsa.service
    “`

Comments are closed.