I am trying to play audio from Raspbian to a bluetooth speaker using A2DP.
From looking at test/simple-endpoint
in the bluez source, it appears that running it without arguments should register an endpoint with the A2DP_SOURCE_UUID
of 0000110A-0000-1000-8000-00805F9B34FB
. However, I don't see any of the endpoint's callback methods being called (SelectConfiguration
/SetConfiguration
) when using bluetoothctl
to connect to a bluetooth speaker. I tried with two different types of bluetooth speakers.
If I instead run simple-endpoint
in "sbcsink" mode, and then connect my phone to it, I do see the endpoint's methods called (SelectConfiguration
/SetConfiguration
). So endpoints appear to be working for the A2DP sink uuid, but not the source one.
I'm able to find a org.bluez.MediaTransport1
corresponding to the bluetooth speaker by iterating through dbus managed objects:
import dbus
bus = dbus.SystemBus()
manager = dbus.Interface(bus.get_object('org.bluez', '/'), 'org.freedesktop.DBus.ObjectManager')
for path, ifaces in manager.GetManagedObjects().items():
transport = ifaces.get('org.bluez.MediaTransport1')
if transport is None:
continue
transport_obj = dbus.Interface(bus.get_object('org.bluez', path), 'org.bluez.MediaTransport1')
(fd, read_mtu, write_mtu) = transport_obj.Acquire('w')
taken_fd = fd.take()
print(path, fd, taken_fd, read_mtu, write_mtu)
I'm able to write to the transport's file descriptor taken_fd
, but I can't control the audio configuration like I think I would if the transport had been acquired via a org.bluez.MediaEndpoint1
. Also this seems kinda hacky, I'm not sure this transport is meant for me to access in this way. I would expect to get access to the transport via MediaEndpoint1
's SetConfiguration
.
I observed this behavior with bluez 5.43 on Rasbian Stretch. I also tried updating to the latest bluez 5.50 and saw the same behavior.
What is the expected way to use bluez as an audio source?
I figured out the problem by running bluetoothd
in debug mode, and found that SetConfiguration
/SetConfiguration
was being called on a previously registered endpoint with a path of /A2DP/SBC/Source/1
. Searching online for this path led me to discover that it was associated with bluealsa
, which was registering the endpoint on system startup, and then was receiving the media endpoint callbacks instead of my endpoint. After killing bluealsa
, my audio source endpoint was then able to receive the media endpoint callbacks as expected.