I’d like to share a project I’ve been working on that bridges the gap between high-quality digital audio and wireless convenience, all natively integrated into Home Assistant via ESPHome.
The Hardware
The device is built around an ESP32-Wrover and features:
Digital SPDIF Output: For lossless audio transmission to the amplifier/receiver.
LCD Display: Shows real-time track information (Artist, Album, Title).
3 Physical Buttons: For direct media control (Play/Pause/Stop, Next, Previous).
The Software: SendSpin & The Custom A2DP Component
For the audio streaming from Home Assistant, I used SendSpin as the media source, with fully Music Assistant support.
However, what truly sets this project apart from other ESPHome-based audio solutions is the deep, native integration of Bluetooth A2DP.
Instead of using external scripts or complex workarounds, I developed a custom ESPHome component based on the ESP32-A2DP library by pschatzmann. My goal was to make A2DP a native ESPHome component, similar to Sendspin.
The custom component exposes the following entities directly in Home Assistant:
Hub To enable/disable A2DP sink mode.
Automations: Native triggers for Bluetooth connection events.
Media Source: Seamless integration with HA’s media player source speaker component.
Text and Numeric Sensors to show song informations
Switches to control the bluetooth connection state and enable or disable the stack.
I’ve made the component as flexible and well-documented as possible. If you’re looking to add reliable Bluetooth audio to your ESP32 setup without leaving the ESPHome ecosystem, I highly recommend giving this component a try.
Hi
Thanks a lot for the share. Do you think it’ll be compatible with Sonocota Louder ESP32 ? (Video review – Sonocotta) no risk of conflict with Sendspin code ?
Sure, why not? My player already uses Sendspin + A2DP, with automatic switching between the sources:
Automatically switch to A2DP when a Bluetooth connection is established, stopping Sendspin.
Disconnect Bluetooth if the user requests to play something via Sendspin.
Keep in mind that Wi-Fi + BT stacks are very resource-intensive, so you are a bit limited in terms of available RAM. Try to avoid adding anything unnecessary and use static Wi-Fi settings instead of a captive portal, for example.
Take a look to the yaml and the docs present in my repository to have an idea on how to integrate it with your device
If you have a physical RJ45 module (I’ve seen the Sonocota has optional Ethernet), you will save plenty of flash and RAM, so your ESP32 will be happier
BTW The CD Player is an ESP8266 with ESPHome and ATAPI Module to interface with the IDE CD Player. The Player itself is connected to the Hi-Fi via Digital (Yep another SPDIF interface here), so completely lossless. 400€ Quality sound, smart connected, with a recovered old CD Player and a sub 1€ ESP8266
Here is a screenshot of the device playing via A2DP
@PxPert Thanks a lot for the details and impatient to try that in my Louder ESP32.
You should indicate in the Example complete code the code also to call the repository that is needed
So far not working at all as when I add the external ressource for your repo in ESPHome it blocks loading of the dependencies for Louder I’ll have to investigate in ESPHome documentation to try to understand what is the problem and way to go around it
I just added your block after the block for the Louder (tried also before in code but same):
# ===== Packages =====
packages:
esparagus_remote:
url: https://github.com/sonocotta/esp32-audio-dock
ref: main
files:
# Option A: TAS58xx configured with ganged 15-band EQ
- firmware/esphome/packages/dac-tas58xx.yaml
# Option B: TAS58xx configured with individual 15-band EQ per channel
# - firmware/esphome/packages/dac-tas58xx-biamp.yaml
# Option C: TAS58xx configured with bi-amp mode, with filters applied to both channels (HF or LF)
# - firmware/esphome/packages/dac-tas58xx-presets.yaml
- firmware/esphome/packages/audio.yaml
- firmware/esphome/packages/sendspin.yaml
# Optional: OLED displays clock when idling, and track/artist info when playing
# - firmware/esphome/packages/sendspin-addon-oled.yaml
- firmware/esphome/packages/sendspin-audio-addon-external-dac.yaml
- firmware/esphome/packages/sendspin-addon-dac-enable.yaml
- firmware/esphome/packages/sendspin-addon-tas58xx.yaml
- firmware/esphome/packages/light.yaml
- firmware/esphome/packages/ir-receiver.yaml
- firmware/esphome/packages/monitoring.yaml
- firmware/esphome/packages/monitoring-wifi.yaml
external_components:
source: github://PxPert/a2dp_sink
#a2dp_sink:
# name: "My A2DP Sink" # (Required) Friendly name for the device
# auto_reconnect: true # (Optional, default: true) Reconnect to last paired device
# minimal_bluetooth: true
As soon as external components is uncommented, ESPHome tells me: Platform not found: 'audio_dac.tas58xx'
Sorry, I only checked the yaml included in the repo and not the actual readme with the included example.
So far not working at all as when I add the external ressource for your repo in ESPHome it blocks loading of the dependencies for Louder I’ll have to investigate in ESPHome documentation to try to understand what is the problem and way to go around it
I just added your block after the block for the Louder (tried also before in code but same):
You are probably overriding the external_components of the packages because you’re not declaring the child ad an array but as an object instead.
Try replacing
No problem and thanks for the trick regarding external_components but in all matters it’s a dead issue as A2DP is only possible only on ESP32 with Bluetooth and not only Bluetooth BLE so only possible with ESP-32 and ESP32-S31 as of today (perhaps you should indicate it more clearly on github to avoid others doing same mistake as me
Yes, unfortunately only the Louders with a bare ESP32 (the WROVER, not the S3 ones) are supported, because of lacking Bluetooth Classic support.
I’ve update the readme to better clarify that.
Tecnically you could use another ESP32 (Even the base WROOM, they’re cheap and you can find them for 3$), and connect it via I2S to the louder to get A2DP, but it’s a long journey to get it done…
Yeah the best way would be probably to replace the ESP32 chip of the Louder with the one supporting bull BT but I don’t have enough soldering skills to do that without destroying the printed circuit board
Nope, this is only for A2DP Sink. What you need is A2DP Source functionality, which is a totally different implementation. Anyway, WiFi and BT cannot coexist for massive data transfer at the same time, so you’d need an Ethernet module and use the WiFi radio only for BT.
Or more simply, replace the louder 32 with the same model based on the bare ESP32 I’ve seen from they’re website they sell same models with either ESP32-S3 and ESP32 WROVER (the bare ESP32 + PSRAM) variants (That’s why I initially answered you it should be supported):
In the meantime, I’ve added the configuration for the ESP Muse Luxe to the repository. It can work both as a smart player with BT + Sendspin + Voice Assistant support, and as a ‘dumb’ Bluetooth player, so you can take it with you when you go out More details about the implementation are in the muse-luxe.yaml YAML file provided
Thanks for clarification and if I understand well I loose my time two times: first because it’s not possible to use in same time Wifi and BT on ESP32 and second because your implementation doesn’t allow to stream audio to the ESP from a bluetooth compatible device like a phone right ?
Yep I have one two but as I wanted to use them outside they’ll be used only in Wifi so incompatible with BT use in same time right ?
This project is exactly designed to allow playing audio from a BT Source (A phone, for example) to an ESP32 Player (the Sink). What it’s not designed for is the opposite direction (Stream from ESP32 to a BT device).
BT A2DP and WiFi can coexist on the ESP32, but they share the same 2.4 GHz radio resources. Since A2DP requires a continuous, high-priority data stream, it can cause latency or instability for WiFi communications if both are under heavy load simultaneously. However, you can keep the ESP32 connected to WiFi and HA for status updates or remote control while playing from BT source.
if you request audio playback via WiFi (Sendspin) while BT A2DP is active, the BT connection is automatically disconnected from the audio stream (though the device remains discoverable for future pairing).
Conversely, if you connect a new BT device while Sendspin is playing, the WiFi audio is interrupted to switch to the higher-priority BT A2DP stream (but the ESP32 remains connected to HA).