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.
109 lines
2.2 KiB
Plaintext
109 lines
2.2 KiB
Plaintext
# Python
|
|
__pycache__/
|
|
*.py[cod]
|
|
*$py.class
|
|
*.so
|
|
.Python
|
|
build/
|
|
develop-eggs/
|
|
dist/
|
|
downloads/
|
|
eggs/
|
|
.eggs/
|
|
lib/
|
|
lib64/
|
|
parts/
|
|
sdist/
|
|
var/
|
|
wheels/
|
|
*.egg-info/
|
|
.installed.cfg
|
|
*.egg
|
|
|
|
# Virtual Environment
|
|
.venv/
|
|
venv/
|
|
ENV/
|
|
env/
|
|
|
|
# Kivy
|
|
*.pyc
|
|
|
|
# Media files (optional - remove if you want to track media)
|
|
#
|
|
# Coverage matters here: `media/*.mp4` matches files directly in media/, but NOT
|
|
# media/edited_media/1/foo.jpg. Playlist content is downloaded per-site and must
|
|
# never be committed, so the whole tree is ignored and only the directory
|
|
# structure (via .gitkeep) is tracked.
|
|
media/*.jpg
|
|
media/*.jpeg
|
|
media/*.png
|
|
media/*.gif
|
|
media/*.bmp
|
|
media/*.mp4
|
|
media/*.avi
|
|
media/*.mkv
|
|
media/*.mov
|
|
media/*.webm
|
|
media/**/*.jpg
|
|
media/**/*.jpeg
|
|
media/**/*.png
|
|
media/**/*.gif
|
|
media/**/*.bmp
|
|
media/**/*.mp4
|
|
media/**/*.avi
|
|
media/**/*.mkv
|
|
media/**/*.mov
|
|
media/**/*.webm
|
|
|
|
# Playlist cache (auto-generated from the server per device)
|
|
playlists/server_playlist_*.json
|
|
playlists/server_playlist.json
|
|
|
|
# Logs
|
|
*.log
|
|
.kivy/
|
|
|
|
# IDE
|
|
.vscode/
|
|
.idea/
|
|
*.swp
|
|
*.swo
|
|
|
|
# OS
|
|
.DS_Store
|
|
Thumbs.db
|
|
|
|
.player_heartbear
|
|
|
|
# NOTE: the line above is a long-standing typo for `.player_heartbeat` and is
|
|
# kept only so nothing changes for existing clones. The correct patterns are
|
|
# below — without them the player's runtime state files get committed (they
|
|
# change every 10 seconds, which would create endless noise and merge conflicts).
|
|
.player_heartbeat
|
|
.player_stop_requested
|
|
logs/startup_marker.txt
|
|
logs/startup_crash.log
|
|
logs/console_out.txt
|
|
logs/console_err.txt
|
|
logs/watchdog_test_*.txt
|
|
|
|
# Player credentials — live auth_code/player_id/server_url. Never commit these:
|
|
# a bundled copy made fresh builds boot "already authenticated" against an old
|
|
# server and play a stale playlist.
|
|
player_auth.json
|
|
src/player_auth.json
|
|
working_files/player_auth.json
|
|
|
|
# Runtime browser profile (cache, not source). The player launches Chromium with
|
|
# a dedicated --user-data-dir so it never touches the operator's own profile.
|
|
# The wildcard covers probe/test profiles (e.g. .kiosk-profile-probe), which
|
|
# otherwise get picked up as untracked files and are several MB of cache each.
|
|
.kiosk-profile/
|
|
.kiosk-profile-*/
|
|
.webview2-profile/
|
|
|
|
# Monitoring output (generated per run, not source)
|
|
logs/monitor*.csv
|
|
logs/monitor*.log
|