AmpliPi icon indicating copy to clipboard operation
AmpliPi copied to clipboard

Feature Request - Add Bluetooth support

Open linknum23 opened this issue 4 years ago • 15 comments

How should Bluetooth support be added to AmpliPi?

linknum23 avatar Jul 30 '21 18:07 linknum23

@vszander has started working on integrating Bluetooth audio into AmpliPi, here's his question (with minor edits):

I was able to stream Bluetooth audio from my smart phone to my AmpliPi dev image using this method which is compatible with ALSA. The Bluetooth stream is going to the default channel on the soundcard. How can we make the Bluetooth stream an AmpliPi input?

linknum23 avatar Jul 30 '21 18:07 linknum23

First of all thanks for looking into this, @vszander! Based on how streams currently work it looks like you will want to test this by launching bluealsa-aplay from the command line on your pi (assuming you have already installed it). Looking at the docs for bluealsa-aplay it looks like you just need to specify the ALSA device using the -D flag, so you may want to test using bluealsa-aplay -D ch0 (and ch1, ch2...). Try it out and see how it works for you (and report back your findings).

linknum23 avatar Jul 30 '21 18:07 linknum23

I was playing around with this today and have it working on my Pi 2b with a USB bluetooth adapter, outputting through ALSA to ch0/ch1/ch2/ch3. I think it would be easy to create a simple AmpliPi stream for this, and could quickly get more complicated if someone wanted to control specific Bluetooth devices or run multiple Bluetooth streams at once. Here is the information I used and how I configured it:

Setup Guide: https://gist.github.com/Pindar/e259bec5c3ab862f4ff5f1fbcb11bfc1 Controlling Bluetooth and Metadata: https://scribles.net/controlling-bluetooth-audio-on-raspberry-pi/ Bluealsa - Available Features (aac, apt-x): https://github.com/Arkq/bluez-alsa/wiki/Installation-from-source

INSTALL:

sudo apt-get install bluealsa python-dbus libasound2-dev

SETUP (these services should only be running when the AmpliPi stream is active):

sudo systemctl disable bluetooth sudo systemctl disable bluealsa

##Edit /etc/bluetooth/main.conf: Name = AmpliPi Bluetooth DiscoverableTimeout = 0 Class = 0x200400

##Set up A2DP Bluetooth Agent for headless bluetooth discovery https://gist.github.com/Pindar/e259bec5c3ab862f4ff5f1fbcb11bfc1#install-the-a2dp-bluetooth-agent

START (when the AmpliPi stream is started, run these in this order):

sudo systemctl start bluetooth sudo systemctl start bluealsa sudo systemctl start bt-agent-a2dp.service # This service is used to automatically allow bluetooth devices to connect) bluealsa-aplay -d ch0 00:00:00:00:00:00 # This is the process that takes the audio from bluetooth and sends to ALSA via -d. The 00:00... allows for any bluetooth device. Maybe this could be used to send different bluetooth devices out different AmpliPi outputs?

STOP (when AmpliPi stream is stopped, run these in this order):

kill bluealsa-aplay sudo systemctl stop bt-agent-a2dp.service sudo systemctl stop bluealsa sudo systemctl stop bluetooth

kjk2010 avatar Aug 13 '21 01:08 kjk2010

Is there a specific reason all of those Bluetooth services need to be stopped and started every time a Bluetooth stream is connected? Is this just so that we can have control over the name to connect to? Or maybe the security issue of always allowing any Bluetooth device to connect?

Here's what I am hoping the workflow for Bluetooth devices would look like:

  • At AmpliPi startup
    • Discover Bluetooth device, enable/disable Bluetooth single stream in the loaded configuration based on availability (we will need to add this disable/enable streams field)
  • On stream connection
    • connect Bluetooth device to one of the outputs (ch0-3)

Also as a side note, I'm guessing those of you that are using Bluetooth will be using a module with a nice antenna to get extra range? I was just looking at this: https://www.amazon.com/dp/B08LVH5BCP, maybe we should buy one and test it out around Jason's house.,.

linknum23 avatar Aug 13 '21 17:08 linknum23

My reasoning behind starting and stopping the services is that my phone will stay connected to the RPi's Bluetooth and continue streaming audio, even though bluealsa-aplay isn't running. At least in my use case, I would only want my phone to connect to Bluetooth on the AmpliPi when one of the sources has a Bluetooth stream running, then disconnect from it when the stream has been stopped. It might be possible to script something with bluetoothctl to allow and drop connected devices when a stream is activated and deactivated, but I'm not sure.

I don't believe it's a security issue leaving the services running and automatically accepting connections, as long as the Class setting is set to 0x200400 which says only audio devices can connect (http://bluetooth-pentest.narod.ru/software/bluetooth_class_of_device-service_generator.html).

I like the look of that Bluetooth adapter. I do plan on using one like that instead of my current tiny dongle that only reaches 10ft.

kjk2010 avatar Aug 13 '21 21:08 kjk2010

I think that use case makes the most sense. Is there anyway to enable/disable a single Bluetooth device, instead of the whole service? That could potentially simplify things here and also provide a longer term route to support 2 or more Bluetooth devices/streams.

linknum23 avatar Aug 16 '21 14:08 linknum23

The bluetoothctl has the ability to disconnect devices, but then they'll automatically reconnect at some point. There are also trust/untrust options, as well as block/unblock options, but then you have to deal with finding specific device IDs for the commands.

One potential option might be to turn the Bluetooth power on and off using bluetoothctl: bluetoothctl -- power off bluetoothctl -- power on

This would disconnect active Bluetooth connections when power is off, and allow them to reconnect when power is back on. All the background services can stay running.

On Mon, Aug 16, 2021 at 7:54 AM Lincoln Lorenz @.***> wrote:

I think that use case makes the most sense. Is there anyway to enable/disable a single Bluetooth device, instead of the whole service? That could potentially simplify things here and also provide a longer term route to support 2 or more Bluetooth devices/streams.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/micro-nova/AmpliPi/issues/150#issuecomment-899576681, or unsubscribe https://github.com/notifications/unsubscribe-auth/AKNOZ24BJWOBPSUSLQO3EQDT5ERDJANCNFSM5BI7IS2A . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&utm_campaign=notification-email .

--

KJ Koning Shout! Radio Services http://www.shoutservices.com

kjk2010 avatar Aug 16 '21 18:08 kjk2010

Please forgive me if I messed something up here as I don't have a Bluetooth device connected to AmpliPi to test with.

  1. Doesn't the device name already exist in some paired devices list, since it needs to be paired with the Rpi's Bluetooth? We could expose this device list in the API to build a drop down, in addition to having some way indicate a wildcard device.
  2. If you gracefully signal the bluealsa-aplay process (e.g. via Ctrl-c), does it disconnect from your phone/Bluetooth-audio-source?

I'm still trying to reduce the complexity of starting and stopping the Bluetooth stack here...

linknum23 avatar Aug 16 '21 19:08 linknum23

  1. Yes. sudo bluetoothctl devices will provide a list of paired devices, connected or not. You can use the device ID to query the status of the device itself: sudo bluetoothctl info 01:23:45:67:89:01 - Name: moto g(7) power Alias: moto g(7) power Class: 0x005a020c Icon: phone Paired: yes Trusted: no Blocked: no Connected: yes LegacyPairing: no UUID: OBEX Object Push (00001105-0000-1000-8000-00805f9b34fb) UUID: Audio Source (0000110a-0000-1000-8000-00805f9b34fb) UUID: A/V Remote Control Target (0000110c-0000-1000-8000-00805f9b34fb) UUID: Advanced Audio Distribu.. (0000110d-0000-1000-8000-00805f9b34fb) UUID: A/V Remote Control (0000110e-0000-1000-8000-00805f9b34fb) UUID: Headset AG (00001112-0000-1000-8000-00805f9b34fb) UUID: PANU (00001115-0000-1000-8000-00805f9b34fb) UUID: NAP (00001116-0000-1000-8000-00805f9b34fb) UUID: Handsfree Audio Gateway (0000111f-0000-1000-8000-00805f9b34fb) UUID: Phonebook Access Server (0000112f-0000-1000-8000-00805f9b34fb) UUID: Message Access Server (00001132-0000-1000-8000-00805f9b34fb) UUID: PnP Information (00001200-0000-1000-8000-00805f9b34fb) UUID: Generic Access Profile (00001800-0000-1000-8000-00805f9b34fb) UUID: Generic Attribute Profile (00001801-0000-1000-8000-00805f9b34fb) Modalias: bluetooth:v001Dp1200d1436

Unfortunately, it doesn't have a single command to return the status, and I haven't been able to get a bash single line command to work, although it should be possible (none of these worked for me: https://superuser.com/questions/1500383/bluetoothctl-list-connected-devices)

  1. Gracefully stopping bluealsa-aplay does not disconnect the phone's bluetooth connection or the phone's bluetooth audio source, so (at least in my single test) my phone continues to play music as if it's connected. It does this without starting bluealsa-aplay too. I can envision a script that starts and stops bluealsa-aplay and also connects/disconnects devices or powers on/off the Bluetooth adapter, depending on the desired behavior.

On Mon, Aug 16, 2021 at 12:37 PM Lincoln Lorenz @.***> wrote:

Please forgive me if I messaged something up here as I don't have a Bluetooth device connected to AmpliPi to test with.

  1. Doesn't the device name already exist in some paired devices list, since it needs to be paired with the Rpi's Bluetooth? We could expose this device list in the API to build a drop down, in addition to having some way indicate a wildcard device.
  2. If you gracefully signal the bluealsa-aplay process (e.g. via Ctrl-c), does it disconnect from your phone/Bluetooth-audio-source?

I'm still trying to reduce the complexity of starting and stopping the Bluetooth stack here...

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/micro-nova/AmpliPi/issues/150#issuecomment-899768054, or unsubscribe https://github.com/notifications/unsubscribe-auth/AKNOZ2ZU2PJ4C7M4COOJGXDT5FSI3ANCNFSM5BI7IS2A . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&utm_campaign=notification-email .

--

KJ Koning Shout! Radio Services http://www.shoutservices.com

kjk2010 avatar Aug 17 '21 04:08 kjk2010

A vote for supporting more than 1 Bluetooth stream.

Scenario: 2 kids each with a set of ceiling speakers in their rooms.

I was planning to get a pair of BT to RCA devices to handle this, but if it could be done directly on the device with a BT dongle instead of using up RCA inputs that would be fantastic!

bs42 avatar Aug 23 '21 21:08 bs42

Sorry I dropped off line recently....
I love kjk2010's suggested approach. Unfortunately, I was unable to implement - but I didn't take time to MAKE the suggested driver. I also like supporting multiple bluetooth. @kjk2010 , super writeup !

vszander avatar Sep 17 '21 16:09 vszander

I've set up basic Bluetooth support on my dev Pi, and the good news is it can support at least 2 active streams to different zones using a single Bluetooth dongle. I still have to figure out how to handle disconnecting devices when the Bluetooth stream isn't active, reconnecting when it is active, pairing new devices, and the possibility of accessing metadata and using remote controls (next,.prev, start, pause).

kjk2010 avatar Oct 04 '21 05:10 kjk2010

@kjk2010 We are getting a long range Bluetooth adapter tomorrow, Let us know if there's anything you would like help with.

linknum23 avatar Oct 05 '21 14:10 linknum23

I had a thought today, this would be a low priority item but it could be really useful to have bluetooth output as an option.

Use case: I have a yamaha receiver running a room with 7ch speakers and want to sync that up with the music playing in the rest of the house and bluetooth is something built into that receiver which could be a way to accomplish that link other than trying to run a set of RCA cables through the walls to get them over to the AmpliPi and take up one of it's outputs.

bs42 avatar Nov 22 '21 20:11 bs42

I haven't fully thought through how to handle extra outputs, one limitation of the current design of AmpliPi would only be able to support this for digital/streaming input sources. That said Bluetooth would be a pretty cool way to support this. Another way to integrate with smart receivers would be with DLNA.

linknum23 avatar Nov 23 '21 00:11 linknum23

I've put together a basic, but fully-functioning Bluetooth stream example here: https://github.com/kjkoning/amplipi-bluetooth-example It requires a USB Bluetooth dongle. I'm using this one on my AmpliPi: https://www.amazon.com/gp/product/B08LVH5BCP/, but it should work with any Linux-compatible adapter.

I'm curious for any feedback, both on if it works at all for others, and if the way it works makes sense and is user-friendly. If this is something worthy of a PR to include in a future version, there will need to be some work on making sure a Bluetooth adapter is installed and working before allowing the Bluetooth stream to be selected.

kjkoning avatar Nov 22 '22 06:11 kjkoning

Awesome! We'll try integrating this and see where it goes. I think the combination of this and our initial start on bluetooth here will hopefully get us -pretty far.

linknum23 avatar Nov 22 '22 16:11 linknum23

@kjkoning I'm trying out your code and I can connect and play music to the Bluetooth stream successfully! Did you also get the media controls working? For me, bluetooth.py is crashing because the dbus module doesn't exist for some reason, which is needed by dbus_tools in bluezero. I have python-dbus/python3-dbus installed so the dbus module should exist.

jonahshader avatar Dec 20 '22 19:12 jonahshader

Ah I fixed it. The packages were only in the venv, so I had to change the subprocess launches to use the venv instead of python3.

jonahshader avatar Dec 20 '22 20:12 jonahshader

We added a prerelease with Bluetooth support. Check it out at https://github.com/micro-nova/AmpliPi/releases/tag/0.2.1-bluetooth-beta.0

linknum23 avatar Mar 20 '23 21:03 linknum23

Has anyone had a chance to evaluate this? We haven't gotten any feedback yet...

linknum23 avatar Mar 28 '23 18:03 linknum23

Was just looking into bluetooth to add onto the AmpliPi and stumbled across this feature thread.

I already ordered a bluetooth receiver and some RCA cables because the distance from the unit to my need of bluetooth might not cover it. But, a USB extension may assist in that regard and not have the need for either and not need to power another entity.

Would I lose my settings switching to the pre-release bluetooth support build and/or if I wanted to switch off of it? Not sure when you guys were looking to fold it into the future 0.2.2+

rwarner avatar Aug 03 '23 20:08 rwarner

You won't lose your settings. The forward migration should work fine. If anything its going back to the 0.2.1 release where you might? have some issues. I would back up your config before grabbing the Bluetooth pre release. That way you can roll back to that if you decide to go back to 0.2.1 before we make a new release.

On Thu, Aug 3, 2023, 16:27 Ryan Warner @.***> wrote:

Was just looking into bluetooth to add onto the AmpliPi and stumbled across this feature thread.

I ordered already ordered a bluetooth receiver and some RCA cables because the distance from the unit to my need of bluetooth might not cover it. But, a USB extension may assist in that regard.

Would I lose my settings switching to the pre-release bluetooth support build and/or if I wanted to switch off of it? Not sure when you guys were looking to fold it into the future 0.2.2+

— Reply to this email directly, view it on GitHub https://github.com/micro-nova/AmpliPi/issues/150#issuecomment-1664604605, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAEZPO5FRECUWIGVZVKTAU3XTQCSDANCNFSM5BI7IS2A . You are receiving this because you authored the thread.Message ID: @.***>

linknum23 avatar Aug 03 '23 23:08 linknum23

I've been using the prerelease, and it's working well. No issues to report yet.

kjkoning avatar Sep 03 '23 19:09 kjkoning

Sweet. It will be integrated in our 0.3.0 release coming in the next week or so.

On Sun, Sep 3, 2023, 15:11 kjkoning @.***> wrote:

I've been using the prerelease, and it's working well. No issues to report yet.

— Reply to this email directly, view it on GitHub https://github.com/micro-nova/AmpliPi/issues/150#issuecomment-1704379017, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAEZPOYQXI25BGVL6ZOQN33XYTI7DANCNFSM5BI7IS2A . You are receiving this because you authored the thread.Message ID: @.***>

linknum23 avatar Sep 29 '23 13:09 linknum23