Skip to content

Instantly share code, notes, and snippets.

@gmuth
Last active August 2, 2026 12:51
Show Gist options
  • Select an option

  • Save gmuth/3cb7945df6654a965a8a4c60de2627b5 to your computer and use it in GitHub Desktop.

Select an option

Save gmuth/3cb7945df6654a965a8a4c60de2627b5 to your computer and use it in GitHub Desktop.
Soundploy - A selfcontained solution for Bose SoundTouch speakers to preset and play custom radio streams without using a BMX service

SoundPloy V1 - selfcontained

A selfcontained solution for Bose SoundTouch speakers to preset and play custom radio streams without using a BMX service. If root access is too complicated for you look at SoundPloy V2. The idea was first documented here: deborahgu/soundcork#62

Pre-requisites

  • The speaker is connected to your network
  • You know it's IP or hostname
  • You have root access to the speaker via remote_services file or via 3.5 mm audio jack
  • Free disk space is available on the root filesystem
  • You have a list of stream URLs you want to use as presets

Prepare presets on USB drive

Make sure you meet the required prior conditions from above. Create a Bose stream json file for each preset and place it in the root of the USB drive's filesystem. For example, for AC/DC on preset 1 you would create file 1.json with the following content

{
  "audio": {
    "hasPlaylist": false,
    "isRealtime": true,
    "streamUrl": "http://streams.radiobob.de/bob-acdc/mp3-192/mediaplayer"
  },
  "name": "AC/DC",
  "streamType": "liveRadio"
}

For stream urls I recommend to use http only and avoid https. If anyone provides a guide how to update the trusted certificates on device let me know.

Configure device

This step will install file services.json and configure the bmxRegistryUrl accordingly. Additionally, it creates or overrides Sources.xml. Plug in the USB drive to the device, login to the speaker with user root and run:

curl -s soundploy.gmuth.de/v1/install | sh && reboot
Set preset 1
Set preset 2
Set preset 3
Set preset 4
Set preset 5
Set preset 6
The system is going down for reboot NOW!

After reboot, the presets should be available and you can start listening to your custom streams.

Update presets

To update presets, simply change the content of the json files on the USB drive. Then, plug in the USB drive again, login to the speaker with user root and run: copy_presets. No reboot is required, the new presets are available immediately. Expert users can run rw and vi /opt/Bose/html/1.json to update their presets on device.

Radio-Browser stations or other remote services

You are not limited by the stream json files from localhost - remote services can also be used. Check out the example POST requests in the Postman Workspace Bose SoundTouch.

Supported devices

We've successfully tested this on SoundTouch 20 Series 1 and SoundTouch 10. A technical requirement is that /opt/Bose/html is internally served via port 8080. In case your device uses another port you need to fix the preset location url or use the orion station api (examples in Postman collection). To validate the location url is reachable run curl on the device.

curl -i http://localhost:8080/1.json

@gmuth

gmuth commented May 14, 2026

Copy link
Copy Markdown
Author

@tommyhobbs, thanks for your additional documentation. https://github.com/tommyhobbs/BoseSoundTouchGuide

@flobran

flobran commented May 14, 2026

Copy link
Copy Markdown

This is superb and super easy. Got my ST20 up and running again. Thanks for sharing

@TVO99

TVO99 commented May 14, 2026

Copy link
Copy Markdown

Hello,
I'm trying to run this program. I'm on root on my soundtouch 20. I've executed the script but I get this error (see below).
I think it's because before this, I was trying to install the aftertouch service which also failed to install due to disk space full errors.
Now, I see that I only have 12KB free on ubi0:rootfs, probably because of the partly installed aftertouch

so I tried to remove it (rm /opt/aftertouch/aftertouch-service) but it won't let me, this error appears:

rm: can't remove '/opt/aftertouch/aftertouch-service': Read-only file system

What should I do now? do a factory reset?

root@spotty:aftertouch# curl -s soundploy.gmuth.de/v1/install | sh && reboot
(23) Failed writing body
Failed to install services-local
Failed to install copy_presets
Set preset 1
cp: can't create '/opt/Bose/html/1.json': No space left on device
Failed to copy "1.json" from USB drive
Set preset 2
cp: can't stat '/media/sda1/2.json': No such file or directory
Failed to copy "2.json" from USB drive
Set preset 3
cp: can't stat '/media/sda1/3.json': No such file or directory
Failed to copy "3.json" from USB drive
Set preset 4
cp: can't stat '/media/sda1/4.json': No such file or directory
Failed to copy "4.json" from USB drive
Set preset 5
cp: can't stat '/media/sda1/5.json': No such file or directory
Failed to copy "5.json" from USB drive
Set preset 6
cp: can't stat '/media/sda1/6.json': No such file or directory
Failed to copy "6.json" from USB drive

Broadcast message from root@spotty (pts/0) (Thu May 14 18:18:07 2026):

The system is going down for reboot NOW!

@TVO99

TVO99 commented May 14, 2026

Copy link
Copy Markdown

to continue on my previous message: I was thinking of a factory reset, but will I still be able to access my soundtouch after that (with the bose cloud servers being down) ?

@musnuxer

musnuxer commented May 14, 2026 via email

Copy link
Copy Markdown

@flobran

flobran commented May 14, 2026

Copy link
Copy Markdown

to continue on my previous message: I was thinking of a factory reset, but will I still be able to access my soundtouch after that (with the bose cloud servers being down) ?

No need for factory reset. Use the uninstall which comes with aftertouch (worked for me as I was running into disk full too). Then use the install here and you will be fine.

@phfuh

phfuh commented May 15, 2026

Copy link
Copy Markdown

Here is a one-click solution. No root access or knowledge of Telnet or Postman is required: https://codeberg.org/phfu/soundtouch-preset-manager/src/branch/main/electron-app/readme.md

@Olivier822

Copy link
Copy Markdown

@phfuh
Your one-clic solution works very well on my first soundtouch. I had just to enable the "Set server URL configuration on SoundTouch device" for the 2 first preset due to an error message on preset 2 but maybe is because I haven't wait enough (reboot).

All the coding dummies (like me) thank you. I will spread the news.

If I well understanding your code, you have switch the bose cloud by an other one. What will happen if this new cloud is switching off?

@gmuth

gmuth commented May 17, 2026

Copy link
Copy Markdown
Author

@Olivier822, it's really up to you which service registry file you want to use: local on device (soundploy v1), LAN server, soundploy v2, codeberg, github or your own webspace. For the 2nd step (getting the stream url) you also have a variety of options: static stream json on localhost/device, orion station style urls with the stream included in the data parameter, radio station id to stream url resolver for tunein, radio-browser or others. To play a stream the device has to complete both steps successfully.

@GaryNebbett

GaryNebbett commented May 18, 2026

Copy link
Copy Markdown

Hello @gmuth, the SoundTouch web server for port 80 (http) just executes the script /opt/Bose/pts-handler. If one extends that script with something like the code below, then one can dispense with creating/maintaining the /opt/Bose/html/[1..6].json files.

    # LOCAL_INTERNET_RADIO
    if [[ "$path" =~ /local/station\?data=(.+) ]]; then
        json=$(base64 -d <<< ${BASH_REMATCH[1]})
        if [[ "$json" =~ \"name\"[:space:]*:[:space:]*\"([^\"]*)\" ]]; then name=${BASH_REMATCH[1]}; fi
        if [[ "$json" =~ \"streamUrl\"[:space:]*:[:space:]*\"([^\"]*)\" ]]; then strm=${BASH_REMATCH[1]}; fi
        printf "\
HTTP/1.1 200 OK\r
Content-Type: application/json\r
\r
{\r
  \"name\": \"%s\",\r
  \"streamType\": \"liveRadio\",\r
  \"audio\": {\r
    \"streamUrl\": \"%s\",\r
    \"hasPlaylist\": true\r
  }\r
}\r
" "$name" "$strm"
        exit 0
    fi

    # TUNEIN
    if [[ "$path" =~ /tunein/v1/playback/station/(.+) ]]; then
        station=${BASH_REMATCH[1]}
        name=$(curl -sf https://opml.radiotime.com/describe.ashx?id=$station | xmllint --xpath 'string(//opml/body/outline/station/name/.)' -)
        strm=$(curl -sf https://opml.radiotime.com/tune.ashx?id=$station\&formats=mp3,aac,ogg | head -1)
        printf "\
HTTP/1.1 200 OK\r
Content-Type: application/json\r
\r
{\r
  \"name\": \"%s\",\r
  \"streamType\": \"liveRadio\",\r
  \"audio\": {\r
    \"streamUrl\": \"%s\",\r
    \"hasPlaylist\": true\r
  }\r
}\r
" "$name" "$strm"
        exit 0
    fi

@gmuth

gmuth commented May 18, 2026

Copy link
Copy Markdown
Author

Hello @gmuth, the SoundTouch web server for port 80 (http) just executes the script /opt/Bose/pts-handler. If one extends that script with something like the code below, then one can dispense with creating/maintaining the /opt/Bose/html/[1..6].json files. It should be possible to also add a local endpoint for TuneIn since curl is available on the SoundTouch.

Unfortunately this depends on your device and firmware. The pts-handler might be an option on some devices but not an all devices. My ST20s (Series I) port 80 is served by GoAhead-Webs - not the pts handler.

You're thinking in the right direction though. The next level of solutions are onboard solutions where required APIs are implemented on the device itself. I run my own bmx implementation on the device to resolve TuneIn ids for radio stations and podcast episodes.

@GaryNebbett

GaryNebbett commented May 18, 2026

Copy link
Copy Markdown

I am surprised about that difference - my device is a SoundTouch 20 too (bought in 2017 with firmware version 27.0.6.46330.5043500 epdbuild.trunk.hepdswbld04.2022-08-04T11:20:29).

I mostly code on Windows with C# (that is what I am using for the "local server" approach) so I am keen to keep the "onboard" approach as simple as possible (it is an unfamiliar environment to me) - I think that SoundPloy ideas + pts-handler modifications + Bluetooth (for anything other than radio) will be my sweet spot.

In practice, I seldom change stations - the SoundTouch just plays "SWR1 BW" :-)

@tommyhobbs

tommyhobbs commented May 19, 2026

Copy link
Copy Markdown

Hello, I'm trying to run this program. I'm on root on my soundtouch 20. I've executed the script but I get this error (see below). I think it's because before this, I was trying to install the aftertouch service which also failed to install due to disk space full errors. Now, I see that I only have 12KB free on ubi0:rootfs, probably because of the partly installed aftertouch

so I tried to remove it (rm /opt/aftertouch/aftertouch-service) but it won't let me, this error appears:

rm: can't remove '/opt/aftertouch/aftertouch-service': Read-only file system

What should I do now? do a factory reset?

root@spotty:aftertouch# curl -s soundploy.gmuth.de/v1/install | sh && reboot (23) Failed writing body Failed to install services-local Failed to install copy_presets Set preset 1 cp: can't create '/opt/Bose/html/1.json': No space left on device Failed to copy "1.json" from USB drive Set preset 2 cp: can't stat '/media/sda1/2.json': No such file or directory Failed to copy "2.json" from USB drive Set preset 3 cp: can't stat '/media/sda1/3.json': No such file or directory Failed to copy "3.json" from USB drive Set preset 4 cp: can't stat '/media/sda1/4.json': No such file or directory Failed to copy "4.json" from USB drive Set preset 5 cp: can't stat '/media/sda1/5.json': No such file or directory Failed to copy "5.json" from USB drive Set preset 6 cp: can't stat '/media/sda1/6.json': No such file or directory Failed to copy "6.json" from USB drive

Broadcast message from root@spotty (pts/0) (Thu May 14 18:18:07 2026):

The system is going down for reboot NOW!

Hey @TVO99 ! I had the same issue after attempting to install Aftertouch and it got half way and ran out of storage on my ST10. The uninstall script didn't run successfully. I'd recommend trying to manually remove Aftertouch. Run ls /mvt/nv/aftertouch and see if anything is there also ls /media/aftertouch . If so try removing them to free up space rm -rf /mvt/nv/aftertouch rm -rf /media/aftertouch? Best of luck!

@gmuth

gmuth commented May 20, 2026

Copy link
Copy Markdown
Author

Hey @TVO99 ! I had the same issue after attempting to install Aftertouch and it got half way and ran out of storage on my ST10. The uninstall script didn't run successfully. I'd recommend trying to manually remove Aftertouch. Run ls /mvt/nv/aftertouch and see if anything is there also ls /media/aftertouch . If so try removing them to free up space rm -rf /mvt/nv/aftertouch rm -rf /media/aftertouch? Best of luck!

mount -oremount,rw / && rm -rf /opt/aftertouch /mnt/nv/aftertouch && df -m

@Qocksyyy

Copy link
Copy Markdown

Hello, i got root acces to the Bose Wave SoundTouch using the 3.5 mm Serial Port method and ran your script to setup the presets. the presets are now set under /opt/Bose/html but when i press the Buttons on the remote the preset doesnt play( it still trys to open the old preset), does Soundploy not work for Bose Wave Soundtouch with pedestal, or does any one of you have a clue why it might not be working?
Bose
@gmuth

@gmuth

gmuth commented May 23, 2026

Copy link
Copy Markdown
Author

Hello, i got root acces to the Bose Wave SoundTouch using the 3.5 mm Serial Port method.

Cool, you're an expert!

(it still trys to open the old preset)

Old preset names appear because they are cached and haven't been changed. I've updated the install script to set new item names.

does Soundploy not work for Bose Wave Soundtouch with pedestal?

I don't know. Maybe it does not serve /opt/Bose/html internally on port 8080. Try 80, 82, 8080 or 17008.

@Jazzflyer

Jazzflyer commented May 24, 2026

Copy link
Copy Markdown

V2 yields 1005 UNKNOWN_SOURCE_ERROR.
V1 works.

For Unix newbies like me it is useful to know that one should not copy the '#' at the beginning of the curl command into the SSH session as it is just an indicator of root access.

Thank you.

@TechAmbi

TechAmbi commented May 26, 2026

Copy link
Copy Markdown

@phfuh
Does this also work if the device has previously been factory reset?
https://codeberg.org/phfu/soundtouch-preset-manager/src/branch/main/electron-app/readme.md

@phfuh

phfuh commented May 27, 2026

Copy link
Copy Markdown

Untested. However, your device needs to be connected to the network in order for telnet calls to work. Following a fresh reset, it appears this condition is not being met.

@SrFeniksi

SrFeniksi commented Jun 2, 2026

Copy link
Copy Markdown

@gmuth Create a json file is not a problem for me. But I don't understand how to "login as root and run". Could you help me? My apologize I'm dummi. I never use Powershell before the 6th May.

Thanks

If you device have an usb port, you can format the pendrive on fat32 then create an empty file named: remote_services, then you get an ssh open, just connect

@pointy56

pointy56 commented Jun 9, 2026

Copy link
Copy Markdown

@gmuth I don't know if you've seen this idea that I've recently posted in the Aftertouch discussion - I'd be interested in your thoughts/advice.
gesellix/Bose-SoundTouch#487
Martin

@Qocksyyy

Copy link
Copy Markdown

After installing SoundPloy on a Bose SoundTouch, the display shows "SoundTouch not Configured" even though streams play fine.

Root cause: SystemConfigurationDB.xml has empty AccountAssociatedEMail and AccountUUID fields.
The firmware treats this as "setup incomplete".

Fix (requires SSH/root on the device)

Backup

cp /mnt/nv/BoseApp-Persistence/1/SystemConfigurationDB.xml
/mnt/nv/BoseApp-Persistence/1/SystemConfigurationDB.xml.bak

Fill empty fields with dummy values

cd /mnt/nv/BoseApp-Persistence/1
sed -i 's||soundploy@local|' SystemConfigurationDB.xml
sed -i 's||00000000-0000-0000-0000-000000000001|' SystemConfigurationDB.xml
sed -i 's||en-US|' SystemConfigurationDB.xml

Reboot

reboot

@JRpersonal

Copy link
Copy Markdown

I develop SoundTouch Reborn (STR), so I have an interest here, saying that first.

Someone in this thread asked for a simple UI where you enter the IP, a stream URL and a preset number. That is roughly what I ended up building, so it may be useful to mention.

STR has a desktop app for Windows, macOS and Linux where you pick the speaker, pick or paste a station, and drop it onto one of the buttons 1 to 6. Station search comes from radio browser, and a plain stream URL can be typed in by hand. No curl and no root shell needed for normal use.

What is different from most approaches here: the agent runs on the speaker itself, a small Go binary in /mnt/nv/streborn. Nothing else keeps running in your network afterwards, no Pi, no NAS, no container, no Home Assistant and no router change. Installation goes over the local network from the desktop app, the USB stick route is only a fallback these days. Playback uses the UPnP AVTransport the firmware already has, the hardware buttons are caught on the firmware's local WebSocket bus, and the old Bose hostnames are pinned to 127.0.0.1 in /etc/hosts so the firmware stops waiting on servers that no longer exist.

Verified on real hardware: SoundTouch 10, 20, 30, 300 and Portable, Wave SoundTouch series III and IV, SA-4, SA-5 and CineMate. Spotify Connect works, Premium is Spotify's requirement. Amazon Music is not possible on this hardware.

MIT licensed, free, donations only, still before 1.0, one person working on it.
https://st-reborn.de
https://github.com/JRpersonal/streborn

Independent project, not affiliated with Bose. Bose and SoundTouch are trademarks of Bose Corporation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment