mirror of
https://github.com/gesellix/Bose-SoundTouch.git
synced 2026-08-19 00:56:16 +00:00
refactor: rename soundtouch-web to soundtouch-player (transitional alias) (refs #451)
The web player is intrinsically LAN-resident: it reaches speakers directly and only delegates cloud-only features (e.g. TTS) to a possibly-remote AfterTouch service via --service-url. That is exactly what a cloud-hosted soundtouch-service cannot do, so the standalone player binary stays useful and is not being deprecated. Rename it to state its purpose, with a transition window so existing downloads keep working. - cmd/soundtouch-web -> cmd/soundtouch-player; CLI name is now soundtouch-player. When the binary is invoked under its old name it prints a one-line rename notice (filepath.Base(os.Args[0])). - Build/release both names from the same source: Makefile (build-player + build-web alias, dev-player* targets), Dockerfile (soundtouch-player image + transitional soundtouch-web image), release.yml and ci.yml (player + web artifacts, checksums, Docker images; release notes announce the rename). The soundtouch-web binary, image, and install script remain a transitional alias to be dropped in a future release (which will break stale fetch scripts and nudge users to the release notes). - scripts/raspberry-pi/install-player.sh is canonical; install-web.sh keeps working but warns. - Sweep docs, code comments, user-facing strings, and assets (soundtouch-web-ui.png, soundtouch-web-tunein.png, soundtouch-web-roadmap.md) to soundtouch-player; README documents the rename and why the player remains separate from the embedded /app. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
2657e5411c
commit
bd62fd6658
@@ -1,7 +1,7 @@
|
||||
# Raspberry Pi installers
|
||||
|
||||
Full documentation — installation, configuration, service management, updates,
|
||||
and removal for both `soundtouch-service` and `soundtouch-web` — lives in the
|
||||
and removal for both `soundtouch-service` and `soundtouch-player` — lives in the
|
||||
project docs:
|
||||
|
||||
**[docs/content/docs/guides/RASPBERRY-PI.md](../../docs/content/docs/guides/RASPBERRY-PI.md)**
|
||||
@@ -18,7 +18,7 @@ curl -fsSL -o install.sh \
|
||||
sudo bash install.sh
|
||||
```
|
||||
|
||||
**soundtouch-web** (browser control panel):
|
||||
**soundtouch-player** (browser control panel):
|
||||
|
||||
```bash
|
||||
curl -fsSL -o install-web.sh \
|
||||
|
||||
Executable
+338
@@ -0,0 +1,338 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# ==============================================================================
|
||||
# Bose-SoundTouch soundtouch-player installer (systemd, headless)
|
||||
#
|
||||
# Usage:
|
||||
# sudo bash install-player.sh [vX.Y.Z]
|
||||
#
|
||||
# Examples (override defaults via env vars):
|
||||
#
|
||||
# sudo \
|
||||
# VERSION=v0.107.0 \
|
||||
# HTTP_PORT=8081 \
|
||||
# bash install-player.sh
|
||||
#
|
||||
# # With an AfterTouch service link for TTS (HTTPS + self-signed CA):
|
||||
# sudo \
|
||||
# SERVICE_URL=https://soundtouch.local \
|
||||
# SERVICE_CA=/var/lib/soundtouch-service/certs/ca.crt \
|
||||
# bash install-player.sh
|
||||
#
|
||||
# Or with a version argument to perform an update:
|
||||
# sudo bash install-player.sh v0.107.0
|
||||
#
|
||||
# Notes:
|
||||
# - This script downloads a release binary for your CPU (auto-detects armv7/arm64/amd64).
|
||||
# - soundtouch-player is stateless (no data directory) — it is safe to stop/restart freely.
|
||||
# - Default port is 8080 (unprivileged — no special capabilities needed).
|
||||
# - If soundtouch-service is already installed, soundtouch-player reuses the
|
||||
# existing soundtouch:soundtouch user/group.
|
||||
# - Safe to re-run; it will update the binary, env file, and unit and restart.
|
||||
# ==============================================================================
|
||||
|
||||
VERSION="${1:-${VERSION:-v0.107.0}}"
|
||||
# Normalize version prefix
|
||||
if [[ ! "$VERSION" =~ ^v ]]; then
|
||||
VERSION="v${VERSION}"
|
||||
fi
|
||||
SERVICE_NAME="${SERVICE_NAME:-soundtouch-player}"
|
||||
BIN_PATH="${BIN_PATH:-/usr/local/bin/soundtouch-player}"
|
||||
|
||||
CONFIG_DIR="${CONFIG_DIR:-/etc/soundtouch-player}"
|
||||
ENV_FILE="${ENV_FILE:-$CONFIG_DIR/soundtouch-player.env}"
|
||||
|
||||
SERVICE_USER="${SERVICE_USER:-soundtouch}"
|
||||
SERVICE_GROUP="${SERVICE_GROUP:-soundtouch}"
|
||||
|
||||
# Port (unprivileged — no CAP_NET_BIND_SERVICE needed)
|
||||
HTTP_PORT="${HTTP_PORT:-8080}"
|
||||
|
||||
# Optional discovery / device config
|
||||
BIND_ADDR="${BIND_ADDR:-}"
|
||||
DISCOVERY_INTERFACE="${DISCOVERY_INTERFACE:-}"
|
||||
SOUNDTOUCH_DEVICES="${SOUNDTOUCH_DEVICES:-}"
|
||||
|
||||
# Optional AfterTouch service link (needed for TTS / "Speak").
|
||||
# SERVICE_URL: base URL of soundtouch-service, e.g. https://soundtouch.local
|
||||
# SERVICE_CA: path to the service CA cert when it serves HTTPS with its own
|
||||
# self-signed certificate, e.g. /var/lib/soundtouch-service/certs/ca.crt
|
||||
SERVICE_URL="${SERVICE_URL:-}"
|
||||
SERVICE_CA="${SERVICE_CA:-}"
|
||||
|
||||
# Override if you want to force a specific asset suffix:
|
||||
# ARCH_ASSET=linux-armv7|linux-arm64|linux-amd64
|
||||
ARCH_ASSET="${ARCH_ASSET:-}"
|
||||
|
||||
# Internal variables
|
||||
SCRIPT_PATH="$(realpath "$0" 2>/dev/null || echo "$0")"
|
||||
IS_SELF_UPDATE="${IS_SELF_UPDATE:-false}"
|
||||
|
||||
log() { printf "\n==> %s\n" "$*"; }
|
||||
die() { echo "ERROR: $*" >&2; exit 1; }
|
||||
|
||||
need_root() {
|
||||
[[ "${EUID}" -eq 0 ]] || die "Please run as root (e.g. sudo bash $0)."
|
||||
}
|
||||
|
||||
ensure_cmd() {
|
||||
command -v "$1" >/dev/null 2>&1 || die "Missing required command: $1"
|
||||
}
|
||||
|
||||
apt_install_if_missing() {
|
||||
log "Installing dependencies: $*"
|
||||
apt-get update -y
|
||||
apt-get install -y --no-install-recommends "$@"
|
||||
}
|
||||
|
||||
detect_arch_asset() {
|
||||
local m
|
||||
m="$(uname -m)"
|
||||
|
||||
case "$m" in
|
||||
armv7l|armv6l)
|
||||
echo "linux-armv7"
|
||||
;;
|
||||
aarch64)
|
||||
echo "linux-arm64"
|
||||
;;
|
||||
x86_64|amd64)
|
||||
echo "linux-amd64"
|
||||
;;
|
||||
*)
|
||||
die "Unsupported architecture from uname -m: $m (set ARCH_ASSET manually)"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
download_url_for() {
|
||||
local asset="$1"
|
||||
echo "https://github.com/gesellix/Bose-SoundTouch/releases/download/${VERSION}/soundtouch-player-${VERSION}-${asset}"
|
||||
}
|
||||
|
||||
ensure_user_group() {
|
||||
log "Ensuring service user/group exist: ${SERVICE_USER}:${SERVICE_GROUP}"
|
||||
if ! getent group "${SERVICE_GROUP}" >/dev/null; then
|
||||
groupadd --system "${SERVICE_GROUP}"
|
||||
fi
|
||||
if ! id -u "${SERVICE_USER}" >/dev/null 2>&1; then
|
||||
useradd --system \
|
||||
--no-create-home \
|
||||
--shell /usr/sbin/nologin \
|
||||
--gid "${SERVICE_GROUP}" \
|
||||
"${SERVICE_USER}"
|
||||
fi
|
||||
}
|
||||
|
||||
ensure_dirs() {
|
||||
log "Creating config directory"
|
||||
mkdir -p "${CONFIG_DIR}"
|
||||
chmod 0755 "${CONFIG_DIR}"
|
||||
}
|
||||
|
||||
download_binary() {
|
||||
local asset url tmp=""
|
||||
asset="${ARCH_ASSET:-$(detect_arch_asset)}"
|
||||
url="$(download_url_for "$asset")"
|
||||
|
||||
log "Downloading binary for ${asset}: ${url}"
|
||||
tmp="$(mktemp -d)"
|
||||
trap 'rm -rf "${tmp}"' EXIT
|
||||
|
||||
if command -v curl >/dev/null 2>&1; then
|
||||
curl -fsSL -o "${tmp}/soundtouch-player" "${url}"
|
||||
else
|
||||
wget -qO "${tmp}/soundtouch-player" "${url}"
|
||||
fi
|
||||
|
||||
chmod +x "${tmp}/soundtouch-player"
|
||||
|
||||
if [[ -f "${BIN_PATH}" ]]; then
|
||||
log "Backing up existing binary to ${BIN_PATH}.old"
|
||||
cp -p "${BIN_PATH}" "${BIN_PATH}.old"
|
||||
fi
|
||||
|
||||
install -m 0755 "${tmp}/soundtouch-player" "${BIN_PATH}"
|
||||
log "Installed binary to ${BIN_PATH}"
|
||||
}
|
||||
|
||||
self_update() {
|
||||
if [[ "$IS_SELF_UPDATE" == "true" ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
local url="https://raw.githubusercontent.com/gesellix/Bose-SoundTouch/${VERSION}/scripts/raspberry-pi/install-player.sh"
|
||||
local tmp_script="/tmp/soundtouch-player-install-${VERSION}.sh"
|
||||
|
||||
log "Checking for installer updates for ${VERSION}..."
|
||||
log "URL: ${url}"
|
||||
|
||||
if command -v curl >/dev/null 2>&1; then
|
||||
if ! curl -fsSL -o "${tmp_script}" "${url}"; then
|
||||
log "⚠️ Could not fetch installer for ${VERSION}, continuing with current script."
|
||||
return
|
||||
fi
|
||||
else
|
||||
if ! wget -qO "${tmp_script}" "${url}"; then
|
||||
log "⚠️ Could not fetch installer for ${VERSION}, continuing with current script."
|
||||
return
|
||||
fi
|
||||
fi
|
||||
|
||||
if diff -q "${SCRIPT_PATH}" "${tmp_script}" >/dev/null 2>&1; then
|
||||
log "Installer is already up to date."
|
||||
rm -f "${tmp_script}"
|
||||
return
|
||||
fi
|
||||
|
||||
log "Newer installer found for ${VERSION}. Updating ${SCRIPT_PATH} and re-executing..."
|
||||
install -m 0755 "${tmp_script}" "${SCRIPT_PATH}"
|
||||
rm -f "${tmp_script}"
|
||||
|
||||
export IS_SELF_UPDATE="true"
|
||||
export VERSION HTTP_PORT BIND_ADDR DISCOVERY_INTERFACE SOUNDTOUCH_DEVICES
|
||||
export SERVICE_URL SERVICE_CA
|
||||
export BIN_PATH CONFIG_DIR ENV_FILE SERVICE_USER SERVICE_GROUP
|
||||
|
||||
exec "${SCRIPT_PATH}" "$@"
|
||||
}
|
||||
|
||||
write_env_file() {
|
||||
log "Updating env file: ${ENV_FILE}"
|
||||
|
||||
local vars=(
|
||||
"PORT=${HTTP_PORT}"
|
||||
"BIND_ADDR=${BIND_ADDR}"
|
||||
"DISCOVERY_INTERFACE=${DISCOVERY_INTERFACE}"
|
||||
"SOUNDTOUCH_DEVICES=${SOUNDTOUCH_DEVICES}"
|
||||
"SERVICE_URL=${SERVICE_URL}"
|
||||
"SERVICE_CA=${SERVICE_CA}"
|
||||
)
|
||||
|
||||
if [[ ! -f "${ENV_FILE}" ]]; then
|
||||
for entry in "${vars[@]}"; do
|
||||
echo "${entry}" >> "${ENV_FILE}"
|
||||
done
|
||||
else
|
||||
for entry in "${vars[@]}"; do
|
||||
local key="${entry%%=*}"
|
||||
local val="${entry#*=}"
|
||||
if ! grep -q "^${key}=" "${ENV_FILE}"; then
|
||||
echo "${key}=${val}" >> "${ENV_FILE}"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
chmod 0640 "${ENV_FILE}"
|
||||
chown root:"${SERVICE_GROUP}" "${ENV_FILE}" || true
|
||||
}
|
||||
|
||||
write_systemd_unit() {
|
||||
log "Writing systemd unit: /etc/systemd/system/${SERVICE_NAME}.service"
|
||||
cat > "/etc/systemd/system/${SERVICE_NAME}.service" <<EOF
|
||||
[Unit]
|
||||
Description=Bose SoundTouch Web UI
|
||||
Wants=network-online.target
|
||||
After=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=${SERVICE_USER}
|
||||
Group=${SERVICE_GROUP}
|
||||
EnvironmentFile=${ENV_FILE}
|
||||
ExecStart=${BIN_PATH}
|
||||
Restart=on-failure
|
||||
RestartSec=2
|
||||
|
||||
PrivateTmp=true
|
||||
ProtectSystem=strict
|
||||
ProtectHome=true
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
}
|
||||
|
||||
reload_enable_start() {
|
||||
log "Reloading systemd, enabling and starting service"
|
||||
systemctl daemon-reload
|
||||
systemctl enable "${SERVICE_NAME}.service"
|
||||
systemctl restart "${SERVICE_NAME}.service"
|
||||
|
||||
log "Verifying service health..."
|
||||
local health_url="http://localhost:${HTTP_PORT}/health"
|
||||
local max_retries=5
|
||||
local count=0
|
||||
local success=false
|
||||
|
||||
while [[ $count -lt $max_retries ]]; do
|
||||
if curl -fs "$health_url" >/dev/null 2>&1; then
|
||||
success=true
|
||||
break
|
||||
fi
|
||||
echo "Waiting for service to respond at $health_url... ($((count+1))/$max_retries)"
|
||||
sleep 2
|
||||
count=$((count+1))
|
||||
done
|
||||
|
||||
if [[ "$success" = true ]]; then
|
||||
log "✅ soundtouch-player is healthy and responding!"
|
||||
else
|
||||
log "⚠️ Service started but did not respond at $health_url within timeout."
|
||||
log "Check logs with: journalctl -u ${SERVICE_NAME}.service -n 50"
|
||||
fi
|
||||
}
|
||||
|
||||
show_status() {
|
||||
log "Service status"
|
||||
systemctl --no-pager --full status "${SERVICE_NAME}.service" || true
|
||||
|
||||
log "Listening socket (:${HTTP_PORT})"
|
||||
ss -tulpn | grep -E ":${HTTP_PORT}\b" || true
|
||||
|
||||
if command -v ufw >/dev/null 2>&1 && ufw status | grep -q "Status: active"; then
|
||||
log "Firewall check (UFW is active)"
|
||||
if ! ufw status | grep -qE "${HTTP_PORT}.*ALLOW"; then
|
||||
log "⚠️ UFW is active but port ${HTTP_PORT} might be blocked."
|
||||
log "Run: sudo ufw allow ${HTTP_PORT}/tcp"
|
||||
else
|
||||
log "✅ UFW rule for port ${HTTP_PORT} appears to be in place."
|
||||
fi
|
||||
fi
|
||||
|
||||
cat <<EOF
|
||||
|
||||
Open in your browser:
|
||||
http://<pi-ip>:${HTTP_PORT}/
|
||||
|
||||
soundtouch-player is a control panel — you can stop it when not in use:
|
||||
sudo systemctl stop ${SERVICE_NAME}
|
||||
sudo systemctl start ${SERVICE_NAME}
|
||||
|
||||
Logs:
|
||||
journalctl -u ${SERVICE_NAME}.service -e --no-pager
|
||||
EOF
|
||||
}
|
||||
|
||||
main() {
|
||||
need_root
|
||||
ensure_cmd systemctl
|
||||
ensure_cmd ss
|
||||
|
||||
if ! command -v curl >/dev/null 2>&1 && ! command -v wget >/dev/null 2>&1; then
|
||||
apt_install_if_missing curl
|
||||
fi
|
||||
|
||||
self_update "$@"
|
||||
|
||||
ensure_user_group
|
||||
ensure_dirs
|
||||
download_binary
|
||||
write_env_file
|
||||
write_systemd_unit
|
||||
reload_enable_start
|
||||
show_status
|
||||
}
|
||||
|
||||
main "$@"
|
||||
@@ -1,6 +1,17 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# ==============================================================================
|
||||
# DEPRECATED: soundtouch-web has been renamed to soundtouch-player.
|
||||
# This installer still works (the soundtouch-web release asset is published as
|
||||
# a transitional alias) but will be removed in a future release. Please switch
|
||||
# to install-player.sh, which installs the soundtouch-player binary/service.
|
||||
# ==============================================================================
|
||||
echo "NOTICE: soundtouch-web has been renamed to soundtouch-player." >&2
|
||||
echo " This installer (install-web.sh) is deprecated and will be removed" >&2
|
||||
echo " in a future release; please switch to install-player.sh." >&2
|
||||
echo >&2
|
||||
|
||||
# ==============================================================================
|
||||
# Bose-SoundTouch soundtouch-web installer (systemd, headless)
|
||||
#
|
||||
|
||||
Reference in New Issue
Block a user