#!/bin/sh # Squeezelite Controller - SecuBox Virtual Player CLI set -e # Colors RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' CYAN='\033[0;36m' NC='\033[0m' log() { echo -e "${GREEN}[Squeezelite]${NC} $1"; } warn() { echo -e "${YELLOW}[Squeezelite]${NC} $1"; } error() { echo -e "${RED}[Squeezelite]${NC} $1" >&2; } uci_get() { uci -q get "squeezelite.$1" 2>/dev/null || echo "$2"; } #--- Status --- cmd_status() { echo -e "${CYAN}=== Squeezelite Player Status ===${NC}" local enabled=$(uci_get main.enabled 0) local name=$(uci_get main.name "SecuBox-Player") local server=$(uci_get main.server "") local auto_discover=$(uci_get main.auto_discover 1) echo "Player Name: $name" echo "Enabled: $([ "$enabled" = "1" ] && echo "Yes" || echo "No")" if pgrep -f "squeezelite" >/dev/null 2>&1; then echo -e "Process: ${GREEN}Running${NC}" local pid=$(pgrep -f "squeezelite" | head -1) echo "PID: $pid" else echo -e "Process: ${RED}Stopped${NC}" fi echo "" if [ -n "$server" ]; then echo "Server: $server" elif [ "$auto_discover" = "1" ]; then echo "Server: Auto-discover (Lyrion on network)" else echo "Server: Not configured" fi # Check Lyrion availability local lyrion_host=$(uci_get main.server "127.0.0.1") if curl -s "http://${lyrion_host}:9000/status.html" >/dev/null 2>&1; then echo -e "Lyrion Server: ${GREEN}Available${NC}" else echo -e "Lyrion Server: ${YELLOW}Not detected${NC}" fi } #--- Discover Lyrion --- cmd_discover() { log "Searching for Lyrion Music Server..." # Check localhost first if curl -s "http://127.0.0.1:9000/status.html" >/dev/null 2>&1; then log "Found Lyrion at 127.0.0.1:9000" echo "127.0.0.1" return 0 fi # Check LXC container local lxc_ip=$(lxc-info -n lyrion 2>/dev/null | grep "IP:" | awk '{print $2}' | head -1) if [ -n "$lxc_ip" ] && curl -s "http://${lxc_ip}:9000/status.html" >/dev/null 2>&1; then log "Found Lyrion in LXC at $lxc_ip:9000" echo "$lxc_ip" return 0 fi # Network scan for Slim Protocol (port 3483) for ip in $(ip route | grep -oE "192\.168\.[0-9]+\.[0-9]+" | head -1 | sed 's/\.[0-9]*$/.1/'); do local subnet=$(echo $ip | sed 's/\.[0-9]*$//') for host in $(seq 1 254); do local target="${subnet}.${host}" if nc -z -w 1 "$target" 3483 2>/dev/null; then log "Found Lyrion at $target" echo "$target" return 0 fi done & done wait error "No Lyrion server found" return 1 } #--- Connect to Server --- cmd_connect() { local server="$1" if [ -z "$server" ]; then # Auto-discover server=$(cmd_discover 2>/dev/null) if [ -z "$server" ]; then error "No server specified and auto-discover failed" return 1 fi fi log "Connecting to Lyrion at $server..." uci set squeezelite.main.server="$server" uci set squeezelite.main.enabled='1' uci commit squeezelite /etc/init.d/squeezelite restart sleep 2 if pgrep -f "squeezelite" >/dev/null 2>&1; then log "Connected to $server" else error "Failed to connect" return 1 fi } #--- Disconnect --- cmd_disconnect() { log "Disconnecting..." /etc/init.d/squeezelite stop uci set squeezelite.main.enabled='0' uci commit squeezelite log "Disconnected" } #--- Enable FIFO Output (for streaming) --- cmd_fifo() { case "$1" in enable) local path="${2:-/tmp/squeezelite.pcm}" log "Enabling FIFO output to $path..." uci set squeezelite.streaming.fifo_output='1' uci set squeezelite.streaming.fifo_path="$path" uci commit squeezelite # Create FIFO [ -p "$path" ] || mkfifo "$path" log "FIFO enabled. Restart player to apply." ;; disable) log "Disabling FIFO output..." uci set squeezelite.streaming.fifo_output='0' uci commit squeezelite log "FIFO disabled. Restart player to apply." ;; status) local enabled=$(uci_get streaming.fifo_output 0) local path=$(uci_get streaming.fifo_path "/tmp/squeezelite.pcm") echo "FIFO Output: $([ "$enabled" = "1" ] && echo "Enabled" || echo "Disabled")" echo "FIFO Path: $path" [ -p "$path" ] && echo "FIFO exists: Yes" || echo "FIFO exists: No" ;; *) echo "Usage: squeezelitectl fifo {enable|disable|status} [path]" ;; esac } #--- List Audio Devices --- cmd_devices() { echo -e "${CYAN}=== Audio Output Devices ===${NC}" if command -v aplay >/dev/null 2>&1; then aplay -L 2>/dev/null | grep -E "^(default|hw:|plughw:|sysdefault)" | head -20 else echo "alsa-utils not installed" fi } #--- Set Output Device --- cmd_output() { local device="$1" if [ -z "$device" ]; then echo "Current output: $(uci_get main.output 'default')" echo "" echo "Available devices:" cmd_devices return fi log "Setting output to: $device" uci set squeezelite.main.output="$device" uci commit squeezelite log "Output set. Restart player to apply." } #--- Service Control --- cmd_start() { /etc/init.d/squeezelite start } cmd_stop() { /etc/init.d/squeezelite stop } cmd_restart() { /etc/init.d/squeezelite restart } cmd_enable() { uci set squeezelite.main.enabled='1' uci commit squeezelite /etc/init.d/squeezelite enable log "Squeezelite enabled" } cmd_disable() { uci set squeezelite.main.enabled='0' uci commit squeezelite /etc/init.d/squeezelite disable log "Squeezelite disabled" } #--- Help --- cmd_help() { cat < [options] ${GREEN}Service Commands:${NC} status Show player status start Start player stop Stop player restart Restart player enable Enable autostart disable Disable autostart ${GREEN}Connection:${NC} discover Find Lyrion servers on network connect [server] Connect to Lyrion (auto-discover if no server) disconnect Disconnect from server ${GREEN}Audio:${NC} devices List audio output devices output [device] Set/show output device ${GREEN}Streaming:${NC} fifo enable [path] Enable FIFO output for streaming bridge fifo disable Disable FIFO output fifo status Show FIFO status ${GREEN}Examples:${NC} squeezelitectl connect 192.168.1.100 squeezelitectl fifo enable /tmp/lyrion.pcm squeezelitectl output hw:0,0 EOF } #--- Main --- case "$1" in status) cmd_status ;; start) cmd_start ;; stop) cmd_stop ;; restart) cmd_restart ;; enable) cmd_enable ;; disable) cmd_disable ;; discover) cmd_discover ;; connect) shift; cmd_connect "$@" ;; disconnect) cmd_disconnect ;; devices) cmd_devices ;; output) shift; cmd_output "$@" ;; fifo) shift; cmd_fifo "$@" ;; help|--help|-h|"") cmd_help ;; *) error "Unknown command: $1" cmd_help exit 1 ;; esac