Thanks
This release leans heavily on two contributors.
@Mr-Tao built the stereo pair lifecycle, the telnet URL rollback,
and the migration data preflight, and did the groundwork for the player's
source-selection state, each validated against real hardware.
@yongxin-ms tracked down the TuneIn browsing failures:
the profile navigate 500, categories that came back empty,
child items that never showed, and stations that would not play.
Thank you both.
Noteworthy
- Stereo pairing is back. Two SoundTouch 10 speakers can be joined into
a persistent LEFT/RIGHT pair again, which Bose's shutdown took away. The
pair appears in the player as a single device, and the CLI gains
group create,group rename,group remove, andgroup status.
This is a real pair, not a temporary multi-room zone. Both speakers must
be online, stereo-capable, standalone, and outside any zone. Lifecycle
operations verify fresh state on both speakers before and after acting,
carry the current pair as a guard so a pair that changed underneath is
never clobbered, and report a partial transition as degraded with
per-speaker detail rather than claiming success. - The web player got a lot more trustworthy. A speaker advertises
RadioBrowser, TuneIn, Local Internet Radio and stored music servers as
selectable sources, but they are not really inputs, and selecting one
plainly left the speaker reporting that source forever while it carried on
playing something else. Those now resume the most recent station or open
the right browser instead. Selecting a source also reports whether it
actually took effect, rather than leaving the interface looking successful
when the speaker rejected it moments later. And losing contact with the
service no longer reloads the page into the browser's error page: the
player says it is reconnecting and recovers on its own. - Migration checks your account data before touching the speaker.
Migration could start changing a device before knowing whether AfterTouch
could reproduce that speaker's presets, so an incomplete snapshot could
clear them on the next sync. It now verifies the stored account, device
and presets against both the live speaker and the rendered account first,
and refuses with an explanation rather than proceeding. Speakers sharing
one account with your other speakers are fine, which is the normal
arrangement; that case is a note, not a refusal. - Speaker URLs can be restored without SSH. A telnet-only rollback
restores the four original Bose service URLs through the port-17000
shell, available from the CLI (setup revert --method telnet), the API,
and the web UI. It restores only those URL fields: DNS, CA certificates,
SSH access, account pairing and presets are untouched, and the speaker
still needs a reboot and a check afterwards. - TuneIn browsing fixes. Opening a station profile returned a 500 and
some categories showed nothing or refused to play. Browsing into
containers, paging through longer lists, and playing episodes all work
again. An item of a kind AfterTouch does not recognise is now offered
with a note rather than silently dropped or silently assumed playable. - The player works on older Safari and iPadOS 15 again. Those browsers
lack import maps, so the interface failed to load at all.
Smaller changes
- Devices that were configured but unreachable when the service started are
now retried instead of being missing until the next discovery scan. - The on-device installer checks free space before replacing the running
binary, and compresses its rollback backup to reduce disk pressure. - The player's WebSocket now enforces same-origin, ignoring the port so a
reverse-proxied setup still connects. - Adding a speaker to a multi-room zone is refused when the current source
cannot be shared, instead of failing part-way. - Device settings are now driven by what each speaker reports it supports,
rather than assumed. - Long now-playing titles no longer overflow their card.
- Presets and recents survive concurrent writes: all read-modify-write paths
go through a single atomic update. - Zone membership, device naming, and stereo-pair state are kept consistent
when several updates arrive at once, including after a speaker is renamed
or a pair is dissolved. - Go toolchain 1.27.1; dependency updates for
filippo.io/age,
golang.org/x/crypto,chromedp/cdproto, andgo-json-experiment/json. - New reference documentation for the player's source handling and selection
state, and corrections to the source-selection guide, which had listed
sources as directly selectable that are not.
What's Changed
- fix(install): gzip rollback backups + preflight disk-space check by @gesellix in #645
- Retry configured player devices during discovery by @Mr-Tao in #644
- ci(deps): bump the codeql-action group with 3 updates by @dependabot[bot] in #650
- fix(service): retry persisted player devices during startup by @Mr-Tao in #652
- fix(player): support browsers without import maps by @Mr-Tao in #649
- fix(bmx): mint a fresh TuneIn access token instead of echoing input by @yongxin-ms in #661
- fix: address CodeQL alerts 318-320 (device-status guard, debug log, unused var) by @gesellix in #667
- chore(player): tighten shim dependency handling by @Mr-Tao in #664
- fix(player): project stereo pairs as logical devices by @Mr-Tao in #654
- ci(deps): bump softprops/action-gh-release from 3.0.2 to 3.0.3 by @dependabot[bot] in #675
- ci(deps): bump the codeql-action group with 3 updates by @dependabot[bot] in #674
- Bump golang.org/x/crypto to v0.56.0 by @gesellix in #679
- docker(deps): bump golang from 1.27.0-alpine to 1.27.1-alpine by @dependabot[bot] in #678
- deps(deps): bump filippo.io/age from 1.3.1 to 1.3.2 by @dependabot[bot] in #680
- Stabilize browser compatibility tests against chromedp startup flakiness by @gesellix in #682
- Bump Go toolchain requirement to 1.27.1 by @gesellix in #681
- fix(player): serialize browser WebSocket writes by @Mr-Tao in #665
- fix(player): publish speaker events immediately by @Mr-Tao in #666
- fix(player): enforce same-origin WebSockets by @Mr-Tao in #669
- feat: manage stereo pair lifecycle by @Mr-Tao in #655
- fix(handlers): stop TestCheck443Reachability_LANProbeMatchesListenerOutcome dialing a real IP by @gesellix in #684
- fix(player): constrain long now-playing metadata by @Mr-Tao in #671
- fix(player): guard multiroom zone creation by @Mr-Tao in #659
- docs(player): explain stereo-pair AirPlay limit by @Mr-Tao in #672
- fix(stereo): stop treating an unreachable external Marge as a hard block by @gesellix in #685
- feat(client): add capability-driven device settings by @Mr-Tao in #673
- fix(tunein): profile navigate 500, empty content, and broken episode playback by @yongxin-ms in #677
- refactor(tunein): consolidate profile-navigate duplication found in PR #677's review by @gesellix in #686
- fix(player): harden device state projection by @Mr-Tao in #668
- fix(player): reconcile source selection state by @gesellix in #687
- fix(player): reconnect in place instead of reloading the page by @gesellix in #688
- fix(setup): verify account data before migration by @Mr-Tao in #657
- setup: add telnet URL rollback by @Mr-Tao in #647
- chore(deps): bump cdproto and go-json-experiment by @gesellix in #689
New Contributors
- @Mr-Tao made their first contribution in #644
- @yongxin-ms made their first contribution in #661
Full Changelog: v0.129.0...v0.130.0
Quick downloads
Most people only need one of these two:
soundtouch-service — the local server that replaces the Bose cloud. Point your speaker at it and you keep full control; the built-in web UI on port 8000 handles setup.
| Platform | Download | Checksum |
|---|---|---|
| Raspberry Pi (64-bit) / ARM64 Linux | soundtouch-service-v0.130.0-linux-arm64 | sha256 |
| Raspberry Pi (32-bit) / ARMv7 | soundtouch-service-v0.130.0-linux-armv7 | sha256 |
| Linux (64-bit PC) | soundtouch-service-v0.130.0-linux-amd64 | sha256 |
| macOS (Apple Silicon) | soundtouch-service-v0.130.0-darwin-arm64 | sha256 |
| macOS (Intel) | soundtouch-service-v0.130.0-darwin-amd64 | sha256 |
| Windows (64-bit) | soundtouch-service-v0.130.0-windows-amd64.exe | sha256 |
| FreeBSD (64-bit) | soundtouch-service-v0.130.0-freebsd-amd64 | sha256 |
soundtouch-cli — command-line control of any device: playback, presets, sources, multiroom zones, discovery, and migration. Good for scripting and home automation.
| Platform | Download | Checksum |
|---|---|---|
| Raspberry Pi (64-bit) / ARM64 Linux | soundtouch-cli-v0.130.0-linux-arm64 | sha256 |
| Raspberry Pi (32-bit) / ARMv7 | soundtouch-cli-v0.130.0-linux-armv7 | sha256 |
| Linux (64-bit PC) | soundtouch-cli-v0.130.0-linux-amd64 | sha256 |
| macOS (Apple Silicon) | soundtouch-cli-v0.130.0-darwin-arm64 | sha256 |
| macOS (Intel) | soundtouch-cli-v0.130.0-darwin-amd64 | sha256 |
| Windows (64-bit) | soundtouch-cli-v0.130.0-windows-amd64.exe | sha256 |
| FreeBSD (64-bit) | soundtouch-cli-v0.130.0-freebsd-amd64 | sha256 |
Everything else (soundtouch-player, soundtouch-backup, other platforms, Docker, install scripts): Downloads page.