[GH-ISSUE #127] ESP32 based sendspin/snapcast clients not discovered by lox-audioserver #69

Open
opened 2026-02-27 19:28:13 +03:00 by kerem · 22 comments
Owner

Originally created by @martinsefcik on GitHub (Jan 19, 2026).
Original GitHub issue: https://github.com/lox-audioserver/lox-audioserver/issues/127

I tried the following Snapcast ESP32-based client: https://github.com/CarlosDerSeher/snapclient

and also a draft Sendspin client implementation for ESPHome from this PR: https://github.com/esphome/esphome/pull/12284

Both work with MusicAssistant, and the clients are automatically discovered—I don’t need to provide the server URL in the client configuration.

However, if I try the same with lox-audioserver, no clients are found.

Both MusicAssistant and lox-audioserver are running in Docker containers on my server, using host network mode.

I’m not sure what I’m doing wrong, but I would expect that if MusicAssistant is able to discover these clients, then lox-audioserver should be able to do the same. Could it be that something is missing or not yet implemented in lox-audioserver that affects client discovery for these protocols?

Originally created by @martinsefcik on GitHub (Jan 19, 2026). Original GitHub issue: https://github.com/lox-audioserver/lox-audioserver/issues/127 I tried the following Snapcast ESP32-based client: https://github.com/CarlosDerSeher/snapclient and also a draft Sendspin client implementation for ESPHome from this PR: https://github.com/esphome/esphome/pull/12284 Both work with MusicAssistant, and the clients are automatically discovered—I don’t need to provide the server URL in the client configuration. However, if I try the same with lox-audioserver, no clients are found. Both MusicAssistant and lox-audioserver are running in Docker containers on my server, using host network mode. I’m not sure what I’m doing wrong, but I would expect that if MusicAssistant is able to discover these clients, then lox-audioserver should be able to do the same. Could it be that something is missing or not yet implemented in lox-audioserver that affects client discovery for these protocols?
Author
Owner

@mr-manuel commented on GitHub (Jan 19, 2026):

Snapcast clients discover the server. Since you have MA and Lox Audioserver enabled on the same host, this could be an issue. Also because Lox Audioserver is using port 7090 and not the default port.

<!-- gh-comment-id:3769359955 --> @mr-manuel commented on GitHub (Jan 19, 2026): Snapcast clients discover the server. Since you have MA and Lox Audioserver enabled on the same host, this could be an issue. Also because Lox Audioserver is using port 7090 and not the default port.
Author
Owner

@rudyberends commented on GitHub (Jan 19, 2026):

I dont think that client has a snapcast ws implementation. So even if it discovers the Snapcast server, it will not be able to actually operate it.

The latest 4.x branch now also implements Snapcast over TCP and advertises that transport via mDNS.

However, this TCP transport runs on the default Snapcast port.
If you are running a Music Assistant instance on the same host, this can indeed cause conflicts.

<!-- gh-comment-id:3770333384 --> @rudyberends commented on GitHub (Jan 19, 2026): I dont think that client has a snapcast ws implementation. So even if it discovers the Snapcast server, it will not be able to actually operate it. The latest 4.x branch now also implements Snapcast over TCP and advertises that transport via mDNS. However, this TCP transport runs on the default Snapcast port. If you are running a Music Assistant instance on the same host, this can indeed cause conflicts.
Author
Owner

@martinsefcik commented on GitHub (Jan 21, 2026):

I’ve always run either lox-audioserver or Music Assistant, never both simultaneously.

After adding TCP support for the Snapcast protocol in lox-audioserver and providing the lox-audioserver IP address in the Snapcast client, I can connect. However, playback behaves strangely: roughly 1 second of music plays, followed by 3–5 seconds of silence, then 1 second plays again, and so on.

The same client configuration works fine with Music Assistant. I’ve tried both 500ms and 1000ms buffers for the Snapcast protocol in Music Assistant, and both work correctly.

I haven’t tested whether autodiscovery via mDNS works yet, because my development environment for lox-audioserver is in WSL2, so mDNS likely cannot reach my local network from the WSL environment. I will retest once this functionality is available in the beta Docker image.

<!-- gh-comment-id:3781092986 --> @martinsefcik commented on GitHub (Jan 21, 2026): I’ve always run either lox-audioserver or Music Assistant, never both simultaneously. After adding TCP support for the Snapcast protocol in lox-audioserver and providing the lox-audioserver IP address in the Snapcast client, I can connect. However, playback behaves strangely: roughly 1 second of music plays, followed by 3–5 seconds of silence, then 1 second plays again, and so on. The same client configuration works fine with Music Assistant. I’ve tried both 500ms and 1000ms buffers for the Snapcast protocol in Music Assistant, and both work correctly. I haven’t tested whether autodiscovery via mDNS works yet, because my development environment for lox-audioserver is in WSL2, so mDNS likely cannot reach my local network from the WSL environment. I will retest once this functionality is available in the beta Docker image.
Author
Owner

@martinsefcik commented on GitHub (Jan 26, 2026):

I was looking into the mDNS behavior, and in my setup (MA and lox-audioserver running in Docker containers with network: host), I noticed a difference:

  • Music Assistant advertises mDNS (for Snapcast and SendSpin) with only a single IP address - one of the host machine’s IP.
  • lox-audioserver, on the other hand, advertises mDNS with 30+ IP addresses: all host PC addresses, all Docker IPv4 addresses, and also IPv6 addresses.

Could this be a problem? These Snapcast and SendSpin clients (ESP32-based, but probably not only ESP32) might not be smart enough to pick the correct IP address from the same subnet. They may simply choose the first advertised address, which could be an internal Docker IP, and then fail to discover the SendSpin/Snapcast server automatically.

I also looked briefly into the Music Assistant source code to understand how mDNS is handled there, but so far I haven’t been able to identify the part responsible for selecting the single “correct” IP address to advertise via mDNS.

But mDNS is not an area I’m deeply familiar with yet, so my assumptions may be incorrect.

<!-- gh-comment-id:3800516510 --> @martinsefcik commented on GitHub (Jan 26, 2026): I was looking into the mDNS behavior, and in my setup (MA and lox-audioserver running in Docker containers with network: host), I noticed a difference: - Music Assistant advertises mDNS (for Snapcast and SendSpin) with only a single IP address - one of the host machine’s IP. - lox-audioserver, on the other hand, advertises mDNS with 30+ IP addresses: all host PC addresses, all Docker IPv4 addresses, and also IPv6 addresses. Could this be a problem? These Snapcast and SendSpin clients (ESP32-based, but probably not only ESP32) might not be smart enough to pick the correct IP address from the same subnet. They may simply choose the first advertised address, which could be an internal Docker IP, and then fail to discover the SendSpin/Snapcast server automatically. I also looked briefly into the Music Assistant source code to understand how mDNS is handled there, but so far I haven’t been able to identify the part responsible for selecting the single “correct” IP address to advertise via mDNS. But mDNS is not an area I’m deeply familiar with yet, so my assumptions may be incorrect.
Author
Owner

@rudyberends commented on GitHub (Jan 26, 2026):

Ah yeah, thanks for spotting this. I couldn’t reproduce it myself, but I can see how it happens with the current code. Music Assistant likely avoids it because they either use a different mDNS stack that can bind to a single interface/IP, or they explicitly advertise just one address. We use bonjour-service, which publishes A/AAAA records for all non‑internal interfaces, and Snapcast was advertising a hostname, which pulls in every address for that host.

This is fixed now in ff722ca: we now prefer config.system.audioserver.ip for all mDNS advertisements (loxAudio, sendspin, snapcast), and Snapcast no longer converts a provided IP into the hostname. That forces a single IP in the mDNS target, which avoids clients picking Docker/IPv6 addresses.

<!-- gh-comment-id:3800757331 --> @rudyberends commented on GitHub (Jan 26, 2026): Ah yeah, thanks for spotting this. I couldn’t reproduce it myself, but I can see how it happens with the current code. Music Assistant likely avoids it because they either use a different mDNS stack that can bind to a single interface/IP, or they explicitly advertise just one address. We use bonjour-service, which publishes A/AAAA records for all non‑internal interfaces, and Snapcast was advertising a hostname, which pulls in every address for that host. This is fixed now in ff722ca: we now prefer config.system.audioserver.ip for all mDNS advertisements (loxAudio, sendspin, snapcast), and Snapcast no longer converts a provided IP into the hostname. That forces a single IP in the mDNS target, which avoids clients picking Docker/IPv6 addresses.
Author
Owner

@rudyberends commented on GitHub (Feb 1, 2026):

mdns fixes are now in beta4. Could you try again?

<!-- gh-comment-id:3830688378 --> @rudyberends commented on GitHub (Feb 1, 2026): mdns fixes are now in beta4. Could you try again?
Author
Owner

@martinsefcik commented on GitHub (Feb 2, 2026):

It’s still not working in some scenarios. I’ll provide more details, but I need some more time to finish the testing.

<!-- gh-comment-id:3837814805 --> @martinsefcik commented on GitHub (Feb 2, 2026): It’s still not working in some scenarios. I’ll provide more details, but I need some more time to finish the testing.
Author
Owner

@martinsefcik commented on GitHub (Feb 10, 2026):

When running lox-audioserver in a Docker container with host network mode, it looks like the mDNS fix—where you used the audioserver IP directly as the hostname in the mDNS record for the Sendspin server—successfully fixed client autodiscovery (at least when using sendspin-cli).

However, it is not working with the ESP32 Sendspin client from this draft ESPHome implementation:
https://github.com/esphome/esphome/pull/12284

That said, the draft implementation has recently changed and currently does not even compile, so I cannot continue testing with it for now. I’ll try again later once it’s usable.

For Snapcast, mDNS autodiscovery is still not working. The audioserver IP is not used as the hostname in mDNS, and the service is advertised for many IP addresses (including Docker-related ones).

I did my own experiment here:
github.com/lox-audioserver/lox-audioserver@4117ace59a

I rewrote the mDNS publishing implementation and replaced bonjour-service with @homebridge/ciao. Unlike bonjour-service, ciao supports publishing mDNS records only on specific network interfaces.

This is how the mDNS records look in beta5:

Image

And this is how they look with my fix:

Image

What this change improves:

  • mDNS is published only for the IP address configured for the audioserver
    → This fixed Snapcast client discovery and removed the need to embed the audioserver IP directly into Sendspin mDNS records (which looks to me like a workaround).
  • The "normalized" audioserver name is used to construct the hostname, with a small suffix to clearly identify the service.
  • The same naming scheme is used consistently for mDNS service name.
  • mDNS records for different services now look unified and consistent.

This solution is not ideal:

A potentially better solution would be to fork bonjour-service and add support for selecting which interface(s) mDNS should be published on. I already found a fork where this functionality was added:
github.com/LGSInnovations/bonjour-service@7ad3304bcc

What do you think about this?

<!-- gh-comment-id:3881064166 --> @martinsefcik commented on GitHub (Feb 10, 2026): When running lox-audioserver in a Docker container with host network mode, it looks like the mDNS fix—where you used the audioserver IP directly as the hostname in the mDNS record for the Sendspin server—successfully fixed client autodiscovery (at least when using [sendspin-cli](https://github.com/Sendspin/sendspin-cli)). However, it is not working with the ESP32 Sendspin client from this draft ESPHome implementation: https://github.com/esphome/esphome/pull/12284 That said, the draft implementation has recently changed and currently does not even compile, so I cannot continue testing with it for now. I’ll try again later once it’s usable. For Snapcast, mDNS autodiscovery is still not working. The audioserver IP is not used as the hostname in mDNS, and the service is advertised for many IP addresses (including Docker-related ones). I did my own experiment here: https://github.com/lox-audioserver/lox-audioserver/commit/4117ace59a129e6804007820d4e6c2063509453b I rewrote the mDNS publishing implementation and replaced `bonjour-service` with `@homebridge/ciao`. Unlike bonjour-service, ciao supports publishing mDNS records only on specific network interfaces. This is how the mDNS records look in beta5: <img width="1814" height="1131" alt="Image" src="https://github.com/user-attachments/assets/a3cff95c-cd71-4412-87aa-43692d7336cb" /> And this is how they look with my fix: <img width="1819" height="1140" alt="Image" src="https://github.com/user-attachments/assets/ea619837-e5ec-4ec6-8513-a7a2547cdf22" /> What this change improves: - mDNS is published only for the IP address configured for the audioserver → This fixed Snapcast client discovery and removed the need to embed the audioserver IP directly into Sendspin mDNS records (which looks to me like a workaround). - The "normalized" audioserver name is used to construct the hostname, with a small suffix to clearly identify the service. - The same naming scheme is used consistently for mDNS service name. - mDNS records for different services now look unified and consistent. This solution is not ideal: - @homebridge/ciao is used for publishing mDNS records. - bonjour-service is still used for browsing, because ciao does not support mDNS browsing and likely never will: https://github.com/homebridge/ciao/issues/8 A potentially better solution would be to fork bonjour-service and add support for selecting which interface(s) mDNS should be published on. I already found a fork where this functionality was added: https://github.com/LGSInnovations/bonjour-service/commit/7ad3304bcc03c20cceb2013e11e5ce669a9212a6 What do you think about this?
Author
Owner

@tokylo commented on GitHub (Feb 13, 2026):

I am using the ESP32-Audio-Dock project from Sonocotta and recently purchased the new Amped ESP32‑S3‑Plus model.
First of all: these devices are fantastic. The Amped ESP32‑S3‑Plus includes:

  • a high-quality headphone jack output
  • a HiFi DAC
  • a powerful 2x 25W Class‑D amplifier
  • WiFi and Ethernet
  • and many other variants, some even with enclosures

I think these devices are an excellent match for Lox-Audioserver when using external speakers.
Here is the product link (not meant as advertising, just for reference):
https://github.com/sonocotta/esp32-audio-dock
https://www.tindie.com/products/sonocotta/amped-esp32-plus/

Problem

I flashed the amped-esp32-s3-plus-idf-sendspin firmware and the device works perfectly as a Sendspin player in Music Assistant.
Music Assistant discovers it immediately without any issues.

However, the same device is not discovered by Lox-Audioserver (V4 BETA5).

I also run several Linux-based Sendspin players, and these are detected correctly by Lox-Audioserver.
These Linux players actively connect to the Lox-Audioserver using a WebSocket URL, for example:
--url ws://192.168.x.x:7090/sendspin

This is configured via systemd and works reliably.

Expected behavior

The ESP32 Sendspin player should appear in the Lox-Audioserver device list, just like the Linux Sendspin clients.

Actual behavior

  • The ESP32-S3-Plus Sendspin player is visible in Music Assistant (mDNS discovery works).
  • The device does not appear in Lox-Audioserver.
  • It seems that the ESPHome Sendspin implementation runs in server mode only (waiting for incoming connections), while Lox-Audioserver expects client mode (the player actively connects to the server).

Analysis

The Linux Sendspin client actively connects to the Lox-Audioserver via WebSocket.
The ESPHome Sendspin component does not currently support specifying a WebSocket URL or initiating an outbound connection.

This results in:

  • Music Assistant → works (supports passive discovery)
  • Lox-Audioserver → does not work (expects active connection)

My Steps

  1. Flash amped-esp32-s3-plus-idf-sendspin firmware.
  2. Connect device to WiFi
  3. Verify that Music Assistant detects the player.
  4. Check Lox-Audioserver → device is missing.

Environment

  • Device: Amped ESP32-S3-Plus (Sonocotta)
  • Firmware: amped-esp32-s3-plus-idf-sendspin (ESPHome-based)
  • Lox-Audioserver: V4 Beta 5
  • Network: Same subnet, no firewall issues

Feature request / question

Would it be possible to add support for active WebSocket connections in Lox-Audioserver or adapt the discovery mechanism so that ESP32-based Sendspin players are detected the same way as in Music Assistant?

Music Assistant discovers the Amped ESP32‑S3‑Plus Sendspin player without any problems, so it would be great if Lox-Audioserver could support the same discovery method or allow ESP32 Sendspin clients to register themselves.

Additional context

Adding compatibility would make Lox-Audioserver even more flexible and attractive for users who want to integrate external speakers.

Thanks a lot for your work on this project!

<!-- gh-comment-id:3897932380 --> @tokylo commented on GitHub (Feb 13, 2026): I am using the ESP32-Audio-Dock project from Sonocotta and recently purchased the new **Amped ESP32‑S3‑Plus** model. First of all: these devices are fantastic. The Amped ESP32‑S3‑Plus includes: - a high-quality headphone jack output - a HiFi DAC - a powerful 2x 25W Class‑D amplifier - WiFi and Ethernet - and many other variants, some even with enclosures I think these devices are an excellent match for Lox-Audioserver when using external speakers. Here is the product link (not meant as advertising, just for reference): https://github.com/sonocotta/esp32-audio-dock https://www.tindie.com/products/sonocotta/amped-esp32-plus/ ### Problem I flashed the `amped-esp32-s3-plus-idf-sendspin` firmware and the device works perfectly as a **Sendspin player in Music Assistant**. Music Assistant discovers it immediately without any issues. However, the same device is **not discovered by Lox-Audioserver (V4 BETA5)**. I also run several Linux-based Sendspin players, and these are detected correctly by Lox-Audioserver. These Linux players actively connect to the Lox-Audioserver using a WebSocket URL, for example: --url ws://192.168.x.x:7090/sendspin This is configured via systemd and works reliably. ### Expected behavior The ESP32 Sendspin player should appear in the Lox-Audioserver device list, just like the Linux Sendspin clients. ### Actual behavior - The ESP32-S3-Plus Sendspin player is visible in Music Assistant (mDNS discovery works). - The device does **not** appear in Lox-Audioserver. - It seems that the ESPHome Sendspin implementation runs in **server mode only** (waiting for incoming connections), while Lox-Audioserver expects **client mode** (the player actively connects to the server). ### Analysis The Linux Sendspin client actively connects to the Lox-Audioserver via WebSocket. The ESPHome Sendspin component does not currently support specifying a WebSocket URL or initiating an outbound connection. This results in: - Music Assistant → works (supports passive discovery) - Lox-Audioserver → does not work (expects active connection) ### My Steps 1. Flash `amped-esp32-s3-plus-idf-sendspin` firmware. 2. Connect device to WiFi 3. Verify that Music Assistant detects the player. 4. Check Lox-Audioserver → device is missing. ### Environment - Device: Amped ESP32-S3-Plus (Sonocotta) - Firmware: `amped-esp32-s3-plus-idf-sendspin` (ESPHome-based) - Lox-Audioserver: V4 Beta 5 - Network: Same subnet, no firewall issues ### Feature request / question Would it be possible to add support for **active WebSocket connections** in Lox-Audioserver or adapt the discovery mechanism so that ESP32-based Sendspin players are detected the same way as in Music Assistant? Music Assistant discovers the Amped ESP32‑S3‑Plus Sendspin player without any problems, so it would be great if Lox-Audioserver could support the same discovery method or allow ESP32 Sendspin clients to register themselves. ### Additional context Adding compatibility would make Lox-Audioserver even more flexible and attractive for users who want to integrate external speakers. Thanks a lot for your work on this project!
Author
Owner

@rudyberends commented on GitHub (Feb 13, 2026):

I am using the ESP32-Audio-Dock project from Sonocotta and recently purchased the new Amped ESP32‑S3‑Plus model. First of all: these devices are fantastic. The Amped ESP32‑S3‑Plus includes:

  • a high-quality headphone jack output
  • a HiFi DAC
  • a powerful 2x 25W Class‑D amplifier
  • WiFi and Ethernet
  • and many other variants, some even with enclosures

I think these devices are an excellent match for Lox-Audioserver when using external speakers. Here is the product link (not meant as advertising, just for reference): https://github.com/sonocotta/esp32-audio-dock https://www.tindie.com/products/sonocotta/amped-esp32-plus/

Problem

I flashed the amped-esp32-s3-plus-idf-sendspin firmware and the device works perfectly as a Sendspin player in Music Assistant. Music Assistant discovers it immediately without any issues.

However, the same device is not discovered by Lox-Audioserver (V4 BETA5).

I also run several Linux-based Sendspin players, and these are detected correctly by Lox-Audioserver. These Linux players actively connect to the Lox-Audioserver using a WebSocket URL, for example: --url ws://192.168.x.x:7090/sendspin

This is configured via systemd and works reliably.

Expected behavior

The ESP32 Sendspin player should appear in the Lox-Audioserver device list, just like the Linux Sendspin clients.

Actual behavior

  • The ESP32-S3-Plus Sendspin player is visible in Music Assistant (mDNS discovery works).
  • The device does not appear in Lox-Audioserver.
  • It seems that the ESPHome Sendspin implementation runs in server mode only (waiting for incoming connections), while Lox-Audioserver expects client mode (the player actively connects to the server).

Analysis

The Linux Sendspin client actively connects to the Lox-Audioserver via WebSocket. The ESPHome Sendspin component does not currently support specifying a WebSocket URL or initiating an outbound connection.

This results in:

  • Music Assistant → works (supports passive discovery)
  • Lox-Audioserver → does not work (expects active connection)

My Steps

  1. Flash amped-esp32-s3-plus-idf-sendspin firmware.
  2. Connect device to WiFi
  3. Verify that Music Assistant detects the player.
  4. Check Lox-Audioserver → device is missing.

Environment

  • Device: Amped ESP32-S3-Plus (Sonocotta)
  • Firmware: amped-esp32-s3-plus-idf-sendspin (ESPHome-based)
  • Lox-Audioserver: V4 Beta 5
  • Network: Same subnet, no firewall issues

Feature request / question

Would it be possible to add support for active WebSocket connections in Lox-Audioserver or adapt the discovery mechanism so that ESP32-based Sendspin players are detected the same way as in Music Assistant?

Music Assistant discovers the Amped ESP32‑S3‑Plus Sendspin player without any problems, so it would be great if Lox-Audioserver could support the same discovery method or allow ESP32 Sendspin clients to register themselves.

Additional context

Adding compatibility would make Lox-Audioserver even more flexible and attractive for users who want to integrate external speakers.

Thanks a lot for your work on this project!

Right now, this behavior is intentional and not a bug. Lox-AudioServer SendSpin implementation expects clients to connect either via a direct URL or through autodiscovery handled by the client itself. The WebUI only displays clients that are actively connected and does not perform any discovery on its own.

This is the same approach used for Snapcast and Squeezelite. It provides a clean and controlled connection model and works reliably even when running in a container without host network support, as it does not depend on mDNS discovery.

That said, adding client discovery for SendSpin is technically straightforward. If discovery is required for these clients, I will add it in the next beta.

<!-- gh-comment-id:3898067917 --> @rudyberends commented on GitHub (Feb 13, 2026): > I am using the ESP32-Audio-Dock project from Sonocotta and recently purchased the new **Amped ESP32‑S3‑Plus** model. First of all: these devices are fantastic. The Amped ESP32‑S3‑Plus includes: > > * a high-quality headphone jack output > * a HiFi DAC > * a powerful 2x 25W Class‑D amplifier > * WiFi and Ethernet > * and many other variants, some even with enclosures > > I think these devices are an excellent match for Lox-Audioserver when using external speakers. Here is the product link (not meant as advertising, just for reference): https://github.com/sonocotta/esp32-audio-dock https://www.tindie.com/products/sonocotta/amped-esp32-plus/ > > ### Problem > > I flashed the `amped-esp32-s3-plus-idf-sendspin` firmware and the device works perfectly as a **Sendspin player in Music Assistant**. Music Assistant discovers it immediately without any issues. > > However, the same device is **not discovered by Lox-Audioserver (V4 BETA5)**. > > I also run several Linux-based Sendspin players, and these are detected correctly by Lox-Audioserver. These Linux players actively connect to the Lox-Audioserver using a WebSocket URL, for example: --url ws://192.168.x.x:7090/sendspin > > This is configured via systemd and works reliably. > > ### Expected behavior > > The ESP32 Sendspin player should appear in the Lox-Audioserver device list, just like the Linux Sendspin clients. > > ### Actual behavior > > * The ESP32-S3-Plus Sendspin player is visible in Music Assistant (mDNS discovery works). > * The device does **not** appear in Lox-Audioserver. > * It seems that the ESPHome Sendspin implementation runs in **server mode only** (waiting for incoming connections), while Lox-Audioserver expects **client mode** (the player actively connects to the server). > > ### Analysis > > The Linux Sendspin client actively connects to the Lox-Audioserver via WebSocket. The ESPHome Sendspin component does not currently support specifying a WebSocket URL or initiating an outbound connection. > > This results in: > > * Music Assistant → works (supports passive discovery) > * Lox-Audioserver → does not work (expects active connection) > > ### My Steps > > 1. Flash `amped-esp32-s3-plus-idf-sendspin` firmware. > 2. Connect device to WiFi > 3. Verify that Music Assistant detects the player. > 4. Check Lox-Audioserver → device is missing. > > ### Environment > > * Device: Amped ESP32-S3-Plus (Sonocotta) > * Firmware: `amped-esp32-s3-plus-idf-sendspin` (ESPHome-based) > * Lox-Audioserver: V4 Beta 5 > * Network: Same subnet, no firewall issues > > ### Feature request / question > > Would it be possible to add support for **active WebSocket connections** in Lox-Audioserver or adapt the discovery mechanism so that ESP32-based Sendspin players are detected the same way as in Music Assistant? > > Music Assistant discovers the Amped ESP32‑S3‑Plus Sendspin player without any problems, so it would be great if Lox-Audioserver could support the same discovery method or allow ESP32 Sendspin clients to register themselves. > > ### Additional context > > Adding compatibility would make Lox-Audioserver even more flexible and attractive for users who want to integrate external speakers. > > Thanks a lot for your work on this project! Right now, this behavior is intentional and not a bug. Lox-AudioServer SendSpin implementation expects clients to connect either via a direct URL or through autodiscovery handled by the client itself. The WebUI only displays clients that are actively connected and does not perform any discovery on its own. This is the same approach used for Snapcast and Squeezelite. It provides a clean and controlled connection model and works reliably even when running in a container without host network support, as it does not depend on mDNS discovery. That said, adding client discovery for SendSpin is technically straightforward. If discovery is required for these clients, I will add it in the next beta.
Author
Owner

@martinsefcik commented on GitHub (Feb 13, 2026):

In the Sendspin protocol specification, it is stated that:

Server initiated connections are recommended.

So we can expect that various Sendspin client implementations rely on the server initiating the connection.

<!-- gh-comment-id:3898203187 --> @martinsefcik commented on GitHub (Feb 13, 2026): In the Sendspin protocol specification, it is stated that: > Server initiated connections are recommended. So we can expect that various Sendspin client implementations rely on the server initiating the connection.
Author
Owner

@tokylo commented on GitHub (Feb 13, 2026):

That would be great if you could add this in the next beta – thank you very much.
Of course, a “client‑initiated mode” in ESPHome would also be a possible solution. I already asked in the esp32‑audio‑dock project, but they cannot implement this on their side.
However, if lox‑audioserver were able to perform automatic discovery (similar to how Music Assistant does it), the current ESPHome Sendspin implementation would work immediately and without any modifications.
Since the Sendspin specification explicitly recommends server‑initiated connections, adding this in the next beta would be a great improvement – especially for everyone using ESP32‑based hardware.
I’m looking forward to testing the feature.

<!-- gh-comment-id:3898666633 --> @tokylo commented on GitHub (Feb 13, 2026): That would be great if you could add this in the next beta – thank you very much. Of course, a “client‑initiated mode” in ESPHome would also be a possible solution. I already asked in the esp32‑audio‑dock project, but they cannot implement this on their side. However, if lox‑audioserver were able to perform automatic discovery (similar to how Music Assistant does it), the current ESPHome Sendspin implementation would work immediately and without any modifications. Since the Sendspin specification explicitly recommends server‑initiated connections, adding this in the next beta would be a great improvement – especially for everyone using ESP32‑based hardware. I’m looking forward to testing the feature.
Author
Owner

@rudyberends commented on GitHub (Feb 15, 2026):

The latest beta includes support for server-initiated connections. I validated it with functional testing, but it has not yet been extensively tested over longer runtimes.

<!-- gh-comment-id:3904144895 --> @rudyberends commented on GitHub (Feb 15, 2026): The latest beta includes support for server-initiated connections. I validated it with functional testing, but it has not yet been extensively tested over longer runtimes.
Author
Owner

@tokylo commented on GitHub (Feb 15, 2026):

Thanks for adding automatic discovery — my ESP32 is now detected.
However, it still does not play any audio, and the log shows continuous reconnect attempts.

[2026-02-15T11:11:04.528Z][INFO][Sendspin|Connector] [service=direct url=ws://esphome-web-2cc01c:8927/sendspin] Sendspin dialing client
[2026-02-15T11:11:05.097Z][DEBUG][Sendspin|Connector] [message="connect ECONNREFUSED 192.168.178.128:8927" url=ws://esphome-web-2cc01c:8927/sendspin] Sendspin socket error
[2026-02-15T11:11:05.598Z][INFO][Sendspin|Connector] [service=direct url=ws://esphome-web-2cc01c:8927/sendspin] Sendspin dialing client
[2026-02-15T11:11:05.659Z][DEBUG][Sendspin|Connector] [message="connect ECONNREFUSED 192.168.178.128:8927" url=ws://esphome-web-2cc01c:8927/sendspin] Sendspin socket error
[2026-02-15T11:11:05.760Z][INFO][Sendspin|Connector] [service=direct-fallback url=ws://esphome-web-2cc01c:8928/sendspin] Sendspin dialing client

Image

@martinsefcik does it work on your setup?
If yes, I will continue troubleshooting my ESP32.

<!-- gh-comment-id:3904263453 --> @tokylo commented on GitHub (Feb 15, 2026): Thanks for adding automatic discovery — my ESP32 is now detected. However, it still does not play any audio, and the log shows continuous reconnect attempts. [2026-02-15T11:11:04.528Z][INFO][Sendspin|Connector] [service=direct url=ws://esphome-web-2cc01c:8927/sendspin] Sendspin dialing client [2026-02-15T11:11:05.097Z][DEBUG][Sendspin|Connector] [message="connect ECONNREFUSED 192.168.178.128:8927" url=ws://esphome-web-2cc01c:8927/sendspin] Sendspin socket error [2026-02-15T11:11:05.598Z][INFO][Sendspin|Connector] [service=direct url=ws://esphome-web-2cc01c:8927/sendspin] Sendspin dialing client [2026-02-15T11:11:05.659Z][DEBUG][Sendspin|Connector] [message="connect ECONNREFUSED 192.168.178.128:8927" url=ws://esphome-web-2cc01c:8927/sendspin] Sendspin socket error [2026-02-15T11:11:05.760Z][INFO][Sendspin|Connector] [service=direct-fallback url=ws://esphome-web-2cc01c:8928/sendspin] Sendspin dialing client <img width="1014" height="725" alt="Image" src="https://github.com/user-attachments/assets/27bc4f18-7673-46a7-a08e-9708d98d0a8e" /> @martinsefcik does it work on your setup? If yes, I will continue troubleshooting my ESP32.
Author
Owner

@rudyberends commented on GitHub (Feb 15, 2026):

I can currently only test using the official sendspin-cli, and with that I can confirm that both discovery and playback via server-side initiated connections are working.

Is the IP address shown in your logs correct? Can you manually connect to 192.168.178.128:8927, for example using a browser, to verify that the service is reachable?

<!-- gh-comment-id:3904282668 --> @rudyberends commented on GitHub (Feb 15, 2026): I can currently only test using the official sendspin-cli, and with that I can confirm that both discovery and playback via server-side initiated connections are working. Is the IP address shown in your logs correct? Can you manually connect to 192.168.178.128:8927, for example using a browser, to verify that the service is reachable?
Author
Owner

@martinsefcik commented on GitHub (Feb 15, 2026):

I can confirm the client is discovered now in lox-audioserver.
But no payback yet. Based on the logs it ends in some reconnection loop.
Image

<!-- gh-comment-id:3904586753 --> @martinsefcik commented on GitHub (Feb 15, 2026): I can confirm the client is discovered now in lox-audioserver. But no payback yet. Based on the logs it ends in some reconnection loop. <img width="2350" height="530" alt="Image" src="https://github.com/user-attachments/assets/8cb396e2-ad61-47b7-bd70-cb65b9f132d6" />
Author
Owner

@rudyberends commented on GitHub (Feb 16, 2026):

Could you test using this testing image?

ghcr.io/lox-audioserver/lox-audioserver:testing-20260216140139

<!-- gh-comment-id:3909539586 --> @rudyberends commented on GitHub (Feb 16, 2026): Could you test using this testing image? ghcr.io/lox-audioserver/lox-audioserver:testing-20260216140139
Author
Owner

@tokylo commented on GitHub (Feb 17, 2026):

Thanks for the new testing image — the continuous reconnect issues are gone.
However, my ESP32‑S3 Amped client (ESPHome + PCM5122 + speaker_source + sendspin_source) still cannot play audio coming from the lox-audioserver via Sendspin.
When using Music Assistant, audio plays.

Copilot possible cause:
The lox-audioserver may be sending a different or older Sendspin/FLAC framing format that the new ESPHome speaker_source implementation cannot decode.

<!-- gh-comment-id:3916672378 --> @tokylo commented on GitHub (Feb 17, 2026): Thanks for the new testing image — the continuous reconnect issues are gone. However, my ESP32‑S3 Amped client (ESPHome + PCM5122 + speaker_source + sendspin_source) still cannot play audio coming from the lox-audioserver via Sendspin. When using Music Assistant, audio plays. Copilot possible cause: The lox-audioserver may be sending a different or older Sendspin/FLAC framing format that the new ESPHome speaker_source implementation cannot decode.
Author
Owner

@tokylo commented on GitHub (Feb 17, 2026):

How can I update Sendspin? Maybe that would help.

Image
<!-- gh-comment-id:3916874673 --> @tokylo commented on GitHub (Feb 17, 2026): How can I update Sendspin? Maybe that would help. <img width="1181" height="69" alt="Image" src="https://github.com/user-attachments/assets/b94528f8-e97a-45c7-ad3b-4392606b26b8" />
Author
Owner

@rudyberends commented on GitHub (Feb 17, 2026):

With the testing container you are already fully up to date. I am still deciding if I want to use that update functionality from within the webbrowser and it is for development only. Those current version numbers are hardcoded and will never reflect the real current version numbers. You are already on 0.2.2

To troubleshoot further we will need the logs. Preferably spam logs from a play attempt and if you can collect them, also the player logs.

<!-- gh-comment-id:3917095483 --> @rudyberends commented on GitHub (Feb 17, 2026): With the testing container you are already fully up to date. I am still deciding if I want to use that update functionality from within the webbrowser and it is for development only. Those current version numbers are hardcoded and will never reflect the real current version numbers. You are already on 0.2.2 To troubleshoot further we will need the logs. Preferably spam logs from a play attempt and if you can collect them, also the player logs.
Author
Owner

@tokylo commented on GitHub (Feb 18, 2026):

Here my logs from Lox‑Audioserver:

[2026-02-18T19:48:01.180Z][DEBUG][LoxoneHttp|Processor] [command=audio/4/roomfav/play/1/noshuffle] command received
[2026-02-18T19:48:01.182Z][INFO][Zones|Manager] [hasParentContext=false normalizedTarget=http://stream.streambase.ch/radiopilatus/aac-64/tunein resolvedTarget=http://stream.streambase.ch/radiopilatus/aac-64/tunein station="" type=favorite uri=http://stream.streambase.ch/radiopilatus/aac-64/tunein/ zoneId=4] playContent
[2026-02-18T19:48:01.184Z][DEBUG][Zones|Manager] [expandedCount=0 isAppleMusic=false isMusicAssistant=false queueSourcePath=http://stream.streambase.ch/radiopilatus/aac-64/tunein/ resolvedTarget=http://stream.streambase.ch/radiopilatus/aac-64/tunein zoneId=4] queue build resolved
[2026-02-18T19:48:01.184Z][DEBUG][Zones|Manager] [authority=local items=1 startIndex=0 target=tunein🚉b64_aHR0cDovL3N0cmVhbS5zdHJlYW1iYXNlLmNoL3JhZGlvcGlsYXR1cy9hYWMtNjQvdHVuZWlu zoneId=4] queue rebuilt
[2026-02-18T19:48:01.186Z][DEBUG][Audio|UrlProxy] [proxyUrl=http://127.0.0.1:7090/streams/proxy?u=http%3A%2F%2Fstream.streambase.ch%2Fradiopilatus%2Faac-64%2Ftunein targetUrl=http://stream.streambase.ch/radiopilatus/aac-64/tunein] proxying audio url for ffmpeg
[2026-02-18T19:48:01.187Z][INFO][Audio|Manager] [hasStream=false label=tunein🚉b64_aHR0cDovL3N0cmVhbS5zdHJlYW1iYXNlLmNoL3JhZGlvcGlsYXR1cy9hYWMtNjQvdHVuZWlu sourceKind=url zoneId=4] startWithResolvedSource
[2026-02-18T19:48:01.188Z][DEBUG][Audio|Manager] [source=tunein🚉b64_aHR0cDovL3N0cmVhbS5zdHJlYW1iYXNlLmNoL3JhZGlvcGlsYXR1cy9hYWMtNjQvdHVuZWlu zoneId=4] playback continued on same source
[2026-02-18T19:48:01.188Z][DEBUG][Zones|Manager] [action=play outputCount=1 outputTypes=["sendspin"] zoneId=4] dispatchOutputs
[2026-02-18T19:48:01.189Z][INFO][Output|Sendspin] [clientId=amped-esp32-essen source=tunein🚉b64_aHR0cDovL3N0cmVhbS5zdHJlYW1iYXNlLmNoL3JhZGlvcGlsYXR1cy9hYWMtNjQvdHVuZWlu zoneId=4 zoneName="OG Bad"] Sendspin play
[2026-02-18T19:48:01.193Z][DEBUG][Output|Sendspin] [activeFormat={"codec":"flac","sampleRate":48000,"channels":2,"bitDepth":16} requestedFormat={"codec":"flac","sampleRate":48000,"channels":2,"bitDepth":16} zoneId=4] Sendspin stream reusing existing pipeline
[2026-02-18T19:48:01.195Z][INFO][Audio|Player:4] [playContentToStartedMs=6 profile=flac ready=true sincePlaybackStartedMs=7 sincePlayContentMs=13 source=tunein🚉b64_aHR0cDovL3N0cmVhbS5zdHJlYW1iYXNlLmNoL3JhZGlvcGlsYXR1cy9hYWMtNjQvdHVuZWlu zoneId=4] playback first audio ready
[2026-02-18T19:48:01.246Z][INFO][Output|Sendspin] [clientId=amped-esp32-essen sincePlayMs=57 sinceStreamStartMs=null zoneId=4] Sendspin first audio frame sent

and ESP32 Sendspin Player:

[20:48:10.832][D][sendspin.hub:625][httpd]: Stream Started
[20:48:10.833][D][sendspin.hub:628][httpd]: Requesting high performance networking for playback
[20:48:10.833][D][media_player:113][httpd]: 'Media Player' - Setting
[20:48:10.835][D][media_player:120][httpd]: Media URL: sendspin://current
[20:48:10.835][D][media_player:126][httpd]: Announcement: no
[20:48:10.835][W][sendspin.decoder:042][Sendspin_0]: Need more data to decode FLAC header
[20:48:10.836][E][sendspin_media_source:583][Sendspin_0]: Failed to process audio codec header
[20:48:10.836][D][pcm5122:130][httpd]: Mute OFF entered
[20:48:10.836][D][pcm5122:180][httpd]: Volume: -29dB
[20:48:10.837][D][pcm5122:130][httpd]: Mute OFF entered
[20:48:10.837][D][pcm5122:180][httpd]: Volume: -29dB
[20:48:10.837][D][speaker_source_media_player:347]: Pipeline 0: Stopping active source before playing: sendspin://current
[20:48:10.850][D][sendspin.hub:534]: Persisted last played server: server (hash: 0x9707005C)
[20:48:10.850][D][sendspin.hub:874]: Group update - state: playing, id: 4, name: OG Bad
[20:48:10.850][D][pcm5122:130][httpd]: Mute OFF entered
[20:48:10.851][D][pcm5122:130][httpd]: Mute OFF entered
[20:48:10.851][D][sendspin_media_source:257]: Pipeline 0 stopping
[20:48:10.851][D][sendspin_media_source:262]: Pipeline 0 stopped
[20:48:10.855][D][sendspin_media_source:105]: sendspin_id: current
[20:48:10.857][D][sendspin_media_source:237]: Started generate task for pipeline 0
[20:48:10.870][D][switch:026]: 'Enable AMP' Turning OFF.
[20:48:10.876][D][switch:065]: 'Enable AMP' >> OFF
[20:48:10.877][D][speaker_source_media_player:303]: State changed to IDLE
[20:48:10.877][D][sendspin_media_source:246]: Pipeline 0 starting
[20:48:10.877][D][sendspin_media_source:251]: Pipeline 0 running
[20:48:10.877][D][switch:022]: 'Enable AMP' Turning ON.
[20:48:10.877][D][switch:065]: 'Enable AMP' >> ON
[20:48:10.882][D][speaker_source_media_player:303]: State changed to PLAYING
[20:48:12.856][D][sensor:118]: 'Amped-ESP32-S3-Plus-SP-Essen Free PSRAM' >> 5740.6 kB

<!-- gh-comment-id:3922863941 --> @tokylo commented on GitHub (Feb 18, 2026): Here my logs from Lox‑Audioserver: [2026-02-18T19:48:01.180Z][DEBUG][LoxoneHttp|Processor] [command=audio/4/roomfav/play/1/noshuffle] command received [2026-02-18T19:48:01.182Z][INFO][Zones|Manager] [hasParentContext=false normalizedTarget=http://stream.streambase.ch/radiopilatus/aac-64/tunein resolvedTarget=http://stream.streambase.ch/radiopilatus/aac-64/tunein station="" type=favorite uri=http://stream.streambase.ch/radiopilatus/aac-64/tunein/ zoneId=4] playContent [2026-02-18T19:48:01.184Z][DEBUG][Zones|Manager] [expandedCount=0 isAppleMusic=false isMusicAssistant=false queueSourcePath=http://stream.streambase.ch/radiopilatus/aac-64/tunein/ resolvedTarget=http://stream.streambase.ch/radiopilatus/aac-64/tunein zoneId=4] queue build resolved [2026-02-18T19:48:01.184Z][DEBUG][Zones|Manager] [authority=local items=1 startIndex=0 target=tunein:station:b64_aHR0cDovL3N0cmVhbS5zdHJlYW1iYXNlLmNoL3JhZGlvcGlsYXR1cy9hYWMtNjQvdHVuZWlu zoneId=4] queue rebuilt [2026-02-18T19:48:01.186Z][DEBUG][Audio|UrlProxy] [proxyUrl=http://127.0.0.1:7090/streams/proxy?u=http%3A%2F%2Fstream.streambase.ch%2Fradiopilatus%2Faac-64%2Ftunein targetUrl=http://stream.streambase.ch/radiopilatus/aac-64/tunein] proxying audio url for ffmpeg [2026-02-18T19:48:01.187Z][INFO][Audio|Manager] [hasStream=false label=tunein:station:b64_aHR0cDovL3N0cmVhbS5zdHJlYW1iYXNlLmNoL3JhZGlvcGlsYXR1cy9hYWMtNjQvdHVuZWlu sourceKind=url zoneId=4] startWithResolvedSource [2026-02-18T19:48:01.188Z][DEBUG][Audio|Manager] [source=tunein:station:b64_aHR0cDovL3N0cmVhbS5zdHJlYW1iYXNlLmNoL3JhZGlvcGlsYXR1cy9hYWMtNjQvdHVuZWlu zoneId=4] playback continued on same source [2026-02-18T19:48:01.188Z][DEBUG][Zones|Manager] [action=play outputCount=1 outputTypes=["sendspin"] zoneId=4] dispatchOutputs [2026-02-18T19:48:01.189Z][INFO][Output|Sendspin] [clientId=amped-esp32-essen source=tunein:station:b64_aHR0cDovL3N0cmVhbS5zdHJlYW1iYXNlLmNoL3JhZGlvcGlsYXR1cy9hYWMtNjQvdHVuZWlu zoneId=4 zoneName="OG Bad"] Sendspin play [2026-02-18T19:48:01.193Z][DEBUG][Output|Sendspin] [activeFormat={"codec":"flac","sampleRate":48000,"channels":2,"bitDepth":16} requestedFormat={"codec":"flac","sampleRate":48000,"channels":2,"bitDepth":16} zoneId=4] Sendspin stream reusing existing pipeline [2026-02-18T19:48:01.195Z][INFO][Audio|Player:4] [playContentToStartedMs=6 profile=flac ready=true sincePlaybackStartedMs=7 sincePlayContentMs=13 source=tunein:station:b64_aHR0cDovL3N0cmVhbS5zdHJlYW1iYXNlLmNoL3JhZGlvcGlsYXR1cy9hYWMtNjQvdHVuZWlu zoneId=4] playback first audio ready [2026-02-18T19:48:01.246Z][INFO][Output|Sendspin] [clientId=amped-esp32-essen sincePlayMs=57 sinceStreamStartMs=null zoneId=4] Sendspin first audio frame sent and ESP32 Sendspin Player: [20:48:10.832][D][sendspin.hub:625][httpd]: Stream Started [20:48:10.833][D][sendspin.hub:628][httpd]: Requesting high performance networking for playback [20:48:10.833][D][media_player:113][httpd]: 'Media Player' - Setting [20:48:10.835][D][media_player:120][httpd]: Media URL: sendspin://current [20:48:10.835][D][media_player:126][httpd]: Announcement: no [20:48:10.835][W][sendspin.decoder:042][Sendspin_0]: Need more data to decode FLAC header [20:48:10.836][E][sendspin_media_source:583][Sendspin_0]: Failed to process audio codec header [20:48:10.836][D][pcm5122:130][httpd]: Mute OFF entered [20:48:10.836][D][pcm5122:180][httpd]: Volume: -29dB [20:48:10.837][D][pcm5122:130][httpd]: Mute OFF entered [20:48:10.837][D][pcm5122:180][httpd]: Volume: -29dB [20:48:10.837][D][speaker_source_media_player:347]: Pipeline 0: Stopping active source before playing: sendspin://current [20:48:10.850][D][sendspin.hub:534]: Persisted last played server: server (hash: 0x9707005C) [20:48:10.850][D][sendspin.hub:874]: Group update - state: playing, id: 4, name: OG Bad [20:48:10.850][D][pcm5122:130][httpd]: Mute OFF entered [20:48:10.851][D][pcm5122:130][httpd]: Mute OFF entered [20:48:10.851][D][sendspin_media_source:257]: Pipeline 0 stopping [20:48:10.851][D][sendspin_media_source:262]: Pipeline 0 stopped [20:48:10.855][D][sendspin_media_source:105]: sendspin_id: current [20:48:10.857][D][sendspin_media_source:237]: Started generate task for pipeline 0 [20:48:10.870][D][switch:026]: 'Enable AMP' Turning OFF. [20:48:10.876][D][switch:065]: 'Enable AMP' >> OFF [20:48:10.877][D][speaker_source_media_player:303]: State changed to IDLE [20:48:10.877][D][sendspin_media_source:246]: Pipeline 0 starting [20:48:10.877][D][sendspin_media_source:251]: Pipeline 0 running [20:48:10.877][D][switch:022]: 'Enable AMP' Turning ON. [20:48:10.877][D][switch:065]: 'Enable AMP' >> ON [20:48:10.882][D][speaker_source_media_player:303]: State changed to PLAYING [20:48:12.856][D][sensor:118]: 'Amped-ESP32-S3-Plus-SP-Essen Free PSRAM' >> 5740.6 kB
Author
Owner

@martinsefcik commented on GitHub (Feb 22, 2026):

I see the same codec related error in my ESP32 Sendspin client log:

[21:30:28.614][D][speaker_source_media_player:287]: State changed to PLAYING
[21:30:28.623][W][sendspin.decoder:042][Sendspin_0]: Need more data to decode FLAC header
[21:30:28.632][E][sendspin_media_source:603][Sendspin_0]: Failed to process audio codec header
<!-- gh-comment-id:3941750214 --> @martinsefcik commented on GitHub (Feb 22, 2026): I see the same codec related error in my ESP32 Sendspin client log: ``` [21:30:28.614][D][speaker_source_media_player:287]: State changed to PLAYING [21:30:28.623][W][sendspin.decoder:042][Sendspin_0]: Need more data to decode FLAC header [21:30:28.632][E][sendspin_media_source:603][Sendspin_0]: Failed to process audio codec header ```
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/lox-audioserver#69
No description provided.