#!/bin/bash # ========================================== # Analyzer + Volumio DualTab-Kiosk Session # # Phoenix owns the audio hardware and analysis. # Chromium only renders the Analyzer GUI and Volumio UI. # ========================================== set -euo pipefail SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)" # ----- Logging / Runtime ----- KIOSK_USER="${KIOSK_USER:-volumio}" LOG="${LOG:-/home/volumio/dual-kiosk.log}" CHROME_USER_DATA_DIR="${CHROME_USER_DATA_DIR:-/data/chrome-dualtabs}" PHOENIX_DIR="${PHOENIX_DIR:-$SCRIPT_DIR}" PHOENIX_BIN="${PHOENIX_BIN:-$PHOENIX_DIR/target/release/phoenix}" PHOENIX_LOG_FILE="${PHOENIX_LOG_FILE:-/home/volumio/phoenix.log}" PHOENIX_LISTEN="${PHOENIX_LISTEN:-0.0.0.0:8789}" PHOENIX_ALSA_DEVICE="${PHOENIX_ALSA_DEVICE:-hw:CARD=CODEC,DEV=0}" PHOENIX_SAMPLE_RATE="${PHOENIX_SAMPLE_RATE:-48000}" PHOENIX_PERIOD_SIZE="${PHOENIX_PERIOD_SIZE:-128}" PHOENIX_BUFFER_SIZE="${PHOENIX_BUFFER_SIZE:-512}" PHOENIX_GLOBAL_CONFIG_PATH="${PHOENIX_GLOBAL_CONFIG_PATH:-/home/volumio/.config/phoenix/global-config.json}" PHOENIX_RTA_CONFIG_PATH="${PHOENIX_RTA_CONFIG_PATH:-/home/volumio/.config/phoenix/rta-config.json}" PHOENIX_KIOSK_BROWSER_CONFIG_PATH="${PHOENIX_KIOSK_BROWSER_CONFIG_PATH:-/home/volumio/.config/phoenix/kiosk-browser-config.json}" PHOENIX_RECORDINGS_DIR_ANALYZER="${PHOENIX_RECORDINGS_DIR_ANALYZER:-/home/analyzer/Aufnahmen}" PHOENIX_RECORDINGS_DIR_VOLUMIO="${PHOENIX_RECORDINGS_DIR_VOLUMIO:-/home/volumio/Aufnahmen}" PHOENIX_LR_FRAC_DELAY_ENABLED="${PHOENIX_LR_FRAC_DELAY_ENABLED:-true}" PHOENIX_LR_FRAC_DELAY_SAMPLES="${PHOENIX_LR_FRAC_DELAY_SAMPLES:-0.996}" CHROME_BIN="${CHROME_BIN:-/usr/bin/chromium-browser}" EXT_VK="${EXT_VK:-/data/volumiokioskextensions/VirtualKeyboard}" EXT_TOGGLE="${EXT_TOGGLE:-/opt/analyzer/toggle-ext}" ANALYZER_URL="${ANALYZER_URL:-http://localhost:8088/index.html?kiosk=1}" VOLUMIO_URL="${VOLUMIO_URL:-http://localhost:3000}" mkdir -p "$(dirname "$LOG")" exec >>"$LOG" 2>&1 echo "=== $(date): session_volumio.sh START ===" resolve_extension_dir() { local current="${1:-}" shift || true if [ -n "$current" ] && [ -d "$current" ]; then printf '%s\n' "$current" return 0 fi local candidate for candidate in "$@"; do if [ -n "$candidate" ] && [ -d "$candidate" ]; then printf '%s\n' "$candidate" return 0 fi done return 1 } configure_locale() { if locale -a 2>/dev/null | grep -Eiq '^de_DE\.(utf8|UTF-8)$'; then export LANG=de_DE.UTF-8 export LC_ALL=de_DE.UTF-8 elif locale -a 2>/dev/null | grep -Eiq '^C\.UTF-?8$'; then export LANG=C.UTF-8 export LC_ALL=C.UTF-8 else export LANG=C export LC_ALL=C fi } # ----- Environment ----- export DISPLAY=:0 configure_locale export XDG_RUNTIME_DIR="${XDG_RUNTIME_DIR:-/run/user/$(id -u "$KIOSK_USER")}" mkdir -p "$XDG_RUNTIME_DIR" || true export DBUS_SESSION_BUS_ADDRESS="${DBUS_SESSION_BUS_ADDRESS:-unix:path=${XDG_RUNTIME_DIR}/bus}" if [ ! -x "$PHOENIX_BIN" ] || [ ! -s "$PHOENIX_BIN" ]; then echo "Phoenix binary missing, empty or not executable: $PHOENIX_BIN" exit 1 fi if pgrep -f "$PHOENIX_BIN" >/dev/null 2>&1; then echo "Phoenix already running; reusing existing process." else echo "Starting Phoenix: $PHOENIX_BIN" if [ "$(id -u)" -eq 0 ]; then install -d -o analyzer -g analyzer -m 0755 "$PHOENIX_RECORDINGS_DIR_ANALYZER" || true install -d -o volumio -g volumio -m 0755 "$PHOENIX_RECORDINGS_DIR_VOLUMIO" || true install -o "$KIOSK_USER" -g "$KIOSK_USER" -m 0644 /dev/null "$PHOENIX_LOG_FILE" 2>/dev/null || true sudo -u "$KIOSK_USER" env \ PHOENIX_LISTEN="$PHOENIX_LISTEN" \ PHOENIX_ALSA_DEVICE="$PHOENIX_ALSA_DEVICE" \ PHOENIX_SAMPLE_RATE="$PHOENIX_SAMPLE_RATE" \ PHOENIX_PERIOD_SIZE="$PHOENIX_PERIOD_SIZE" \ PHOENIX_BUFFER_SIZE="$PHOENIX_BUFFER_SIZE" \ PHOENIX_GLOBAL_CONFIG_PATH="$PHOENIX_GLOBAL_CONFIG_PATH" \ PHOENIX_RTA_CONFIG_PATH="$PHOENIX_RTA_CONFIG_PATH" \ PHOENIX_KIOSK_BROWSER_CONFIG_PATH="$PHOENIX_KIOSK_BROWSER_CONFIG_PATH" \ PHOENIX_RECORDINGS_DIR_ANALYZER="$PHOENIX_RECORDINGS_DIR_ANALYZER" \ PHOENIX_RECORDINGS_DIR_VOLUMIO="$PHOENIX_RECORDINGS_DIR_VOLUMIO" \ PHOENIX_LR_FRAC_DELAY_ENABLED="$PHOENIX_LR_FRAC_DELAY_ENABLED" \ PHOENIX_LR_FRAC_DELAY_SAMPLES="$PHOENIX_LR_FRAC_DELAY_SAMPLES" \ "$PHOENIX_BIN" >>"$PHOENIX_LOG_FILE" 2>&1 & else mkdir -p "$PHOENIX_RECORDINGS_DIR_ANALYZER" || true mkdir -p "$PHOENIX_RECORDINGS_DIR_VOLUMIO" || true touch "$PHOENIX_LOG_FILE" env \ PHOENIX_LISTEN="$PHOENIX_LISTEN" \ PHOENIX_ALSA_DEVICE="$PHOENIX_ALSA_DEVICE" \ PHOENIX_SAMPLE_RATE="$PHOENIX_SAMPLE_RATE" \ PHOENIX_PERIOD_SIZE="$PHOENIX_PERIOD_SIZE" \ PHOENIX_BUFFER_SIZE="$PHOENIX_BUFFER_SIZE" \ PHOENIX_GLOBAL_CONFIG_PATH="$PHOENIX_GLOBAL_CONFIG_PATH" \ PHOENIX_RTA_CONFIG_PATH="$PHOENIX_RTA_CONFIG_PATH" \ PHOENIX_KIOSK_BROWSER_CONFIG_PATH="$PHOENIX_KIOSK_BROWSER_CONFIG_PATH" \ PHOENIX_RECORDINGS_DIR_ANALYZER="$PHOENIX_RECORDINGS_DIR_ANALYZER" \ PHOENIX_RECORDINGS_DIR_VOLUMIO="$PHOENIX_RECORDINGS_DIR_VOLUMIO" \ PHOENIX_LR_FRAC_DELAY_ENABLED="$PHOENIX_LR_FRAC_DELAY_ENABLED" \ PHOENIX_LR_FRAC_DELAY_SAMPLES="$PHOENIX_LR_FRAC_DELAY_SAMPLES" \ "$PHOENIX_BIN" >>"$PHOENIX_LOG_FILE" 2>&1 & fi fi PHOENIX_HEALTH_TARGET="$PHOENIX_LISTEN" case "$PHOENIX_HEALTH_TARGET" in 0.0.0.0:*) PHOENIX_HEALTH_TARGET="127.0.0.1:${PHOENIX_HEALTH_TARGET#*:}" ;; :::*) PHOENIX_HEALTH_TARGET="[::1]:${PHOENIX_HEALTH_TARGET#*:}" ;; esac PHOENIX_HEALTH_URL="http://${PHOENIX_HEALTH_TARGET}/health" if command -v curl >/dev/null 2>&1; then echo "Waiting for Phoenix health: $PHOENIX_HEALTH_URL" for _ in $(seq 1 40); do if curl -fsS "$PHOENIX_HEALTH_URL" >/dev/null 2>&1; then echo "Phoenix is ready." break fi sleep 0.25 done else sleep 2 fi # ----- X / Browser ----- for _ in $(seq 1 30); do if xset q >/dev/null 2>&1; then break; fi sleep 0.2 done if command -v xset >/dev/null 2>&1; then xset -dpms || true xset s off || true xset s noblank || true fi if [ "$(id -u)" -eq 0 ]; then install -d -m 0755 /data install -d -o "$KIOSK_USER" -g "$KIOSK_USER" -m 0700 "$CHROME_USER_DATA_DIR" else mkdir -p "$CHROME_USER_DATA_DIR" chmod 700 "$CHROME_USER_DATA_DIR" fi pkill -9 -x chromium || true pkill -9 -f "chromium.*--kiosk" || true sleep 0.3 EXTENSIONS=() EXT_VK_RESOLVED="$(resolve_extension_dir "$EXT_VK" \ "$PHOENIX_DIR/VirtualKeyboard" \ "/data/volumiokioskextensions/VirtualKeyboard" \ "/data/VirtualKeyboard" \ "" || true)" EXT_TOGGLE_RESOLVED="$(resolve_extension_dir "$EXT_TOGGLE" \ "$PHOENIX_DIR/toggle-ext" \ "/opt/analyzer/toggle-ext" \ "" || true)" if [ -n "$EXT_VK_RESOLVED" ]; then echo "Loading VirtualKeyboard extension: $EXT_VK_RESOLVED" EXTENSIONS+=("$EXT_VK_RESOLVED") else echo "VirtualKeyboard extension not found." fi if [ -n "$EXT_TOGGLE_RESOLVED" ]; then echo "Loading tab-toggle extension: $EXT_TOGGLE_RESOLVED" EXTENSIONS+=("$EXT_TOGGLE_RESOLVED") else echo "Tab-toggle extension not found." fi EXTENSION_ARG="" if [ "${#EXTENSIONS[@]}" -gt 0 ]; then EXTENSION_ARG="$(IFS=,; echo "${EXTENSIONS[*]}")" fi CHROME_CMD=( "$CHROME_BIN" --kiosk --touch-events --user-data-dir="$CHROME_USER_DATA_DIR" --no-first-run --no-default-browser-check --disable-session-crashed-bubble --disable-restore-session-state --restore-last-session=false --disable-background-networking --disable-remote-extensions --disable-pinch --force-device-scale-factor=1 --lang=de-DE --disable-translate --disable-features=Translate,TranslateUI --memory-pressure-off --max-active-webgl-contexts=1 "$ANALYZER_URL" "$VOLUMIO_URL" ) if [ -n "$EXTENSION_ARG" ]; then CHROME_CMD+=(--load-extension="$EXTENSION_ARG") fi sudo -u "$KIOSK_USER" "${CHROME_CMD[@]}" >>"$LOG" 2>&1 & CHROME_PID=$! sleep 2 if command -v xdotool >/dev/null 2>&1; then xdotool key Ctrl+t type "$VOLUMIO_URL" key Return || true fi wait "$CHROME_PID" echo "=== $(date): session_volumio.sh END ==="