discover · compare · collections · requirements · contribute · feed · watching · stats · help with your tokens
Mihonarium/StreamToSpeaker · source
Snapshot 0 · 2026-11-04T12:47:28Z · Rust · MPL-2.0
Content fingerprint
f5a00c2641c14e7d5d5e2036652b91f839c2baf54293770751c22e12e3efd093GitHub description at capture
Virtual audio output for Windows that streams your PC's sound to AirPlay, Sonos, and UPnP speakers.
README at capture

[](https://github.com/Mihonarium/StreamToSpeaker/actions/workflows/build.yml)
[](LICENSE)
[](LICENSE-BINARIES.md)
Stream To Speaker adds a virtual audio output to Windows and streams it over
the network — to Sonos, IKEA SYMFONISK, KEF, Denon HEOS, MoOde and Volumio
over **UPnP / OpenHome**, and to HomePod, AirPort Express and shairport-sync
over **AirPlay**. Windows volume and the speaker's own buttons stay in sync.
It also has experimental support for **Sendspin** (Music Assistant's
streaming protocol): it can stream to Sendspin speakers and offer the PC's
sound to Music Assistant as an input (optional, off by default).
## Install
*Directly or from the Microsoft Store.*
**[⬇ Download](https://github.com/Mihonarium/StreamToSpeaker/releases/latest/download/StreamToSpeakerSetup.exe)**
and run it. Needs Windows 10 1809+ / Windows 11, x64 (not ARM64 or Windows Server).
<a href="https://apps.microsoft.com/detail/xpfm3gjl2tdg30?referrer=appbadge&mode=full" target="_blank" rel="noopener noreferrer">
<img src="https://get.microsoft.com/images/en-us%20dark.svg" width="150"/>
</a>
## Use
1. Set **Stream To Speaker** as the Windows audio output — or route a single
app to it in the Volume Mixer.
2. Pick a speaker in the app.
Sonos speakers grouped in the Sonos app show up as one entry ("Living Room +
Kitchen"); audio plays on the whole group and the volume slider moves the
group volume. To stream to a single speaker, ungroup it in the Sonos app.
Sound lagging behind video → **−25 / −100 ms**. No sound → **Resync**
(`Ctrl+Shift+R`). Speaker missing → **↻ Rescan**; check it's on the same
network as the PC.
Sendspin support is experimental and off by default: tick *Enable Sendspin*
in the *Sendspin and Music Assistant* card to list Sendspin speakers and offer
the Music Assistant input. Sendspin speakers play directly, without Music
Assistant. One that asks to be paired shows or says a code (or has one printed
on it): type it in when the app asks; it's remembered.
**Music Assistant input (experimental):** tick *Offer this computer as a Music Assistant input*
and enable the Sendspin Source plugin in Music Assistant. The first time, open
this computer in Music Assistant's player settings and run its setup; the app
shows a 6-digit code to type in there. After that, select *Music Assistant* in
the speaker list to send the PC's audio there; it gets audio only while that is
selected. Music Assistant chooses the speaker: set *Automatically play line-in
on* in this computer's player settings there, or play the input from Browse.
Closing the window minimises to the tray; quit from the tray menu.
Speakers that stream over UPnP fetch the PC's audio from a plain HTTP URL on
the PC. By default any device on the same network can play whatever the PC
plays from that URL, from the moment the app starts (before you pick a
speaker) and whichever speaker you play on — AirPlay, HomePod, Sendspin and
Music Assistant included — unless you turn streaming off.
**Advanced → Privacy mode** serves that URL only to the speaker you're
streaming to and the other speakers of its Sonos group (as grouped when you
picked it): their addresses are allowed for as long as the session lasts, and
switching speakers cuts off anything still listening from the old one. A
refused device is named in a message, so you can tell a phone from a speaker;
if a speaker stays silent (one grouped after you picked the group, say), pick
it again or turn privacy mode off. AirPlay, Sendspin and Music Assistant
playback doesn't use the URL, so privacy mode never affects it. Disabling
streaming or forgetting the speaker closes the URL to every other device
either way.
**Web UI:** to switch speakers or nudge latency from your phone, click *Enable
web UI* in the *Web UI* card and open the link it shows (*Copy link*, or *Open
in browser* on the PC). The link holds a secret key, so anyone with it can
control the app on your network; *Make a new link* replaces it, and the old one
stops working. Running headless or as a service, with no window to show the
link, `stream-to-speaker.exe --web-link` prints it; run it as the Windows
account the app runs under. Scripts send the same key with every API call —
see [TECHNICAL.md](TECHNICAL.md#http-api).
Once a day the app asks GitHub whether a newer release exists and, if so,
shows a link to it. Nothing is downloaded or installed by itself. Turn the
check off under **Advanced** if you'd rather not.
## CLI flags
```
--headless No GUI; run as a CLI service.
--no-tray GUI window only, no tray icon.
--web Enable the web UI + HTTP/JSON API, both behind a
secret link (shown in the window; printed once at
start with --headless). Off by default; when off,
only /stream.raw is served.
--web-link Print the web UI's link and exit — for headless and
service installs. Run it as the account the app
runs under, with the app's --port / --advertise-ip.
--source <auto|driver|wasapi-loopback|sine>
Audio input. Default 'auto': kernel driver, falling
back to WASAPI loopback.
--player <name-or-ip> Speaker to use: name substring or IPv4. Omit to pick
in the GUI (or the terminal picker in --headless).
--no-interactive Skip the terminal picker even in a TTY.
--list-speakers Print discovered speakers and exit.
--no-discovery Skip discovery; only serve HTTP.
--port <N> TCP port. Default 5901.
--bind <ip> HTTP bind address. Default 0.0.0.0.
--advertise-ip <ip> IP to give every speaker and to search from.
Default: per speaker, this PC's address on that
speaker's network; search on every interface.
--initial-buffer-ms <N> Prebuffer hint sent to the speaker. Default 50.
--silence-pace-ms <N> Pacing of silence packets. Default 10 (real-time);
higher drains the speaker's buffer between tracks.
--rate-fudge-ppm <N> Clock-skew compensation. Default 0.
--latency-adjust-step-frames <N>
Frames added or dropped per packet while adjusting
latency. Default 4.
--no-silence-injection Don't inject a low noise floor during silence.
--silence-packets-threshold <N>
Consecutive silent packets before quiescence.
--ssdp-interval <N> Minutes between re-discoveries. Default 5.
--log-level <level> error / warn / info / debug / trace. Default info.
```
Tuning the last group: [TECHNICAL.md](TECHNICAL.md#latency-control).
## Verifying a download
```
gh attestation verify StreamToSpeakerSetup.exe -R Mihonarium/StreamToSpeaker
```
proves the file was built by this repository's CI from a specific commit.
Offline: `--bundle <file>.sigstore.json`, shipped with each release.
The driver is [certified by Microsoft](https://partner.microsoft.com/en-us/dashboard/hardware/Driver/DownloadCertificationReport/95342530/14599256519720956/1152921505701928485).
From the next release on, the Microsoft-signed driver inside each release installer is checked against a rebuild from this source by the [Driver reproducibility](.github/workflows/driver-reproducibility.yml) workflow before the installer is signed (the installers of v0.1.6, v0.1.9 and v0.1.10 were checked afterwards by the same workflow), and each installer build logs which driver package it bundled. (Pre-releases built with the test-signed driver, which needs testsigning mode, skip that check.)
## Developers
Architecture, building from source, HTTP API: [TECHNICAL.md](TECHNICAL.md).
Driver signing pipeline: [docs/driver-signing.md](docs/driver-signing.md).
## License
Source [MPL-2.0](LICENSE). Released binaries: free to install and use,
no redistribution or modification — [LICENSE-BINARIES.md](LICENSE-BINARIES.md).
Driver scaffold derives from Microsoft's sysvad sample (MIT); UPnP/SSDP
patterns from [swyh-rs](https://github.com/dheijl/swyh-rs) (MIT).