3ac7f836c4
Replaces the Windows port with a Raspberry Pi / Linux implementation on Raspberry Pi OS "Trixie" (Debian 13, aarch64, Wayland/labwc). The Windows code is removed here but preserved on the Windows-Player branch. Entry point ----------- linux/run_linux.py replaces windows/run_win.py. src/main.py stays platform-neutral; all Pi-specific behaviour is injected from linux/. Five bugs that prevented the port (all measured on real hardware) ---------------------------------------------------------------- 1. Kivy's PyPI wheel bundles an SDL2 built WITHOUT the wayland driver, so no window could be created (Trixie has no X server). linux/fix_kivy_sdl2.sh symlinks the system SDL2 over the bundled filename. 2. SDL2 requires WAYLAND_DISPLAY to be *set* - the socket alone is not enough, unlike wlopm. This broke every systemd/cron/autostart launch. linux_display.ensure_session_environment() detects and exports it. 3. Kivy's Clock resolves callbacks via func.__name__; a patch assigned under a different name crashed the player ~20s after a successful start. 4. The inherited signal_screen_activity() shelled out to tvservice, xdotool and ydotool - none exist on Trixie - and mis-escaped 'wlopm --on \*', so the display blanked after 10 minutes. 5. The launchers ran src/main.py directly, bypassing every platform patch and resolving the data directory one level too high. Web links --------- - --ozone-platform-hint=auto does NOT fall back to Wayland on Chromium 152; it aborts. The platform is now chosen explicitly. - The keyring password prompt is suppressed via the ENVIRONMENT, not the flags: launch_env() strips DBUS_SESSION_BUS_ADDRESS for the child so Chromium cannot reach gnome-keyring-daemon. - Teardown kills the whole process group (needs start_new_session=True); previously it silently fell back to terminate() and orphaned children. Video normalisation ------------------- A 4K video cannot play on a Pi 4: ffpyplayer decodes in software, measured at 0.90x realtime (1080p is 3.03x). Oversized media is downscaled to 1920x1080 at sync time using the hardware h264_v4l2m2m encoder (~31s for an 18s clip), triggered by resolution only so already-playable files are untouched. src/media_state.py owns the shared on-disk contract: a .kiwy-converting marker makes the player skip the item while it is being rebuilt, then the converted file is played instead. If nothing is playable at all (a single-item playlist whose only video is converting), the player loops the intro video rather than leaving a blank screen. Also fixed ---------- - network_monitor: replaced netsh/ifconfig/dhclient with nmcli (Trixie uses NetworkManager; ifconfig and dhclient are not even installed). - Removed the Windows-only focus keeper/guardian from main.py. - main.py: duplicate SDL_AUDIODRIVER setdefault (a silent no-op); Settings "Test connection" now uses tempfile.gettempdir(). - config/app_config.json: credentials blanked so a fresh clone runs the first-run setup flow. Verification ------------ linux/test_media_state.py 18/18, test_linux_patches.py 21/21, test_linux_browser_flags.py 27/27. Verified live against a real DigiServer: image -> weblink -> image -> video with correct durations, zero leaked Chromium processes, and no throttling over a 10 minute monitored run.
78 lines
2.0 KiB
Bash
Executable File
78 lines
2.0 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Player Status Checker
|
|
# Check if the player is running and healthy
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
HEARTBEAT_FILE="$SCRIPT_DIR/.player_heartbeat"
|
|
STOP_FLAG_FILE="$SCRIPT_DIR/.player_stop_requested"
|
|
LOG_FILE="$SCRIPT_DIR/player_watchdog.log"
|
|
|
|
echo "=========================================="
|
|
echo "Kivy Signage Player - Status Check"
|
|
echo "=========================================="
|
|
echo ""
|
|
|
|
# Check for stop flag
|
|
if [ -f "$STOP_FLAG_FILE" ]; then
|
|
echo "🛑 Stop Flag: PRESENT (user requested exit)"
|
|
echo " Watchdog will not restart player"
|
|
echo " To restart: ./start.sh"
|
|
echo ""
|
|
fi
|
|
|
|
# Check if player process is running
|
|
# Matches the linux/run_linux.py entry point (src/main.py is only a module).
|
|
PLAYER_PID=$(pgrep -f "run_linux.py" | head -1)
|
|
|
|
if [ -z "$PLAYER_PID" ]; then
|
|
echo "Status: ❌ NOT RUNNING"
|
|
echo ""
|
|
echo "Player process is not running"
|
|
else
|
|
echo "Status: ✓ RUNNING"
|
|
echo "PID: $PLAYER_PID"
|
|
echo ""
|
|
|
|
# Check heartbeat
|
|
if [ -f "$HEARTBEAT_FILE" ]; then
|
|
last_update=$(stat -c %Y "$HEARTBEAT_FILE" 2>/dev/null || echo 0)
|
|
current_time=$(date +%s)
|
|
diff=$((current_time - last_update))
|
|
|
|
echo "Heartbeat: $(date -d @${last_update} '+%Y-%m-%d %H:%M:%S')"
|
|
echo "Last update: ${diff}s ago"
|
|
|
|
if [ $diff -lt 60 ]; then
|
|
echo "Health: ✓ HEALTHY"
|
|
else
|
|
echo "Health: ⚠️ STALE (may be frozen)"
|
|
fi
|
|
else
|
|
echo "Heartbeat: Not found (player may be starting)"
|
|
fi
|
|
fi
|
|
|
|
echo ""
|
|
|
|
# Show watchdog status
|
|
if pgrep -f "start.sh" > /dev/null; then
|
|
echo "Watchdog: ✓ ACTIVE"
|
|
else
|
|
echo "Watchdog: ❌ NOT RUNNING"
|
|
echo ""
|
|
echo "To start with watchdog: ./start.sh"
|
|
fi
|
|
|
|
echo ""
|
|
|
|
# Show last few log entries
|
|
if [ -f "$LOG_FILE" ]; then
|
|
echo "=========================================="
|
|
echo "Recent Log Entries (last 10):"
|
|
echo "=========================================="
|
|
tail -10 "$LOG_FILE"
|
|
fi
|
|
|
|
echo ""
|