# Kiwy Signage Player - Windows Edition Build and run the Kiwy digital signage player on Windows as a standalone `.exe`. ## ๐Ÿ“‹ Requirements Analysis The original app was built for **Raspberry Pi (Linux)**, using these technologies: | Component | Original (RPi/Linux) | Windows Equivalent | |-----------|---------------------|-------------------| | **GUI** | Kivy 2.3+ | Kivy 2.3+ (works cross-platform) | | **Video** | ffpyplayer | ffpyplayer (needs FFmpeg DLLs) | | **Card Reader** | evdev (Linux input) | โœ… Raw Input API + LL-hook fallback | | **Screen Keep-Awake** | xset, xdotool, Wayland | `SetThreadExecutionState` (Win32 API) | | **Weblink** | chromium-browser (kiosk) | Chrome/Edge (--kiosk mode) | | **Audio** | ALSA/PulseAudio | DirectSound | | **Window Backend** | SDL2 (Wayland/X11) | SDL2 (Windows native) | | **OpenGL** | Desktop GL | ANGLE (DirectX wrapper) | ### What works on Windows - โœ… Media playback (images, videos via ffpyplayer) - โœ… Playlist sync from DigiServer (HTTP/HTTPS) - โœ… Touch & mouse controls - โœ… Settings popup - โœ… Image editing/annotation - โœ… Password-protected exit - โœ… Web links (opens in Chrome/Edge kiosk) - โœ… Network monitoring - โœ… Auto-update playlist - โœ… Card reader authentication (Raw Input API โ€” see below) ### What is disabled on Windows - โŒ HDMI power management (tvservice is RPi-specific) - โŒ WiFi restart (uses Linux `nmcli`) ## ๐Ÿš€ Quick Start (Development) ### Prerequisites 1. **Python 3.12+** (64-bit) โ€” [python.org](https://python.org) - โš ๏ธ **Python 3.13+ is NOT supported** โ€” Kivy 2.3.1 does not have pre-built wheels for it - โš ๏ธ **Python 3.14 is NOT supported** โ€” no Kivy wheels available - โœ… **Python 3.12.9** is the recommended version (confirmed working) 2. **FFmpeg** โ€” for video codec support - Download from [ffmpeg.org](https://ffmpeg.org/download.html) - Add `bin\` folder to your PATH 3. **Visual C++ Redistributable** โ€” [latest](https://aka.ms/vs/17/release/vc_redist.x64.exe) ### Install & Run ```batch cd windows REM Create virtual environment with Python 3.12 py -3.12 -m venv venv :: OR specify full path: :: "C:\Users\Dell-PC\AppData\Local\Programs\Python\Python312\python.exe" -m venv venv venv\Scripts\activate REM Install dependencies pip install -r requirements_win.txt REM Run in development mode python run_win.py ``` ## ๐Ÿ“ฆ Building the .exe ### One-Command Build ```batch cd windows build_win.bat ``` ### Manual Build ```batch cd windows venv\Scripts\activate pip install -r requirements_win.txt pyinstaller build.spec --clean --noconfirm ``` ### Output ``` windows\dist\KiwySignagePlayer\ โ”œโ”€โ”€ KiwySignagePlayer.exe # Main executable โ”œโ”€โ”€ config/ # Config files (auto-copied) โ”œโ”€โ”€ resources/ # Icons, intro video โ””โ”€โ”€ ... (supporting DLLs) ``` For a **single-file .exe**, edit `build.spec` โ€” uncomment the `exe_onefile` section and comment out the `coll = COLLECT(...)` section. ## ๐ŸŒ Web Links (embedded WebView2) Web links render with **WebView2**, embedded as a child window *inside* the Kivy window. Because it is not a separate browser process, it cannot open behind the player, cannot be handed off to an existing browser and exit, and never leaves leaked `msedge.exe`/`chrome.exe` processes behind. WebView2 has **two** parts, and they are handled differently: | Part | What it is | How it ships | |------|------------|--------------| | **SDK** | `Microsoft.Web.WebView2.Core.dll` + `WebView2Loader.dll` โ€” the API surface | Bundled in the exe (`windows\webview2_sdk\`, ~860 KB) | | **Runtime** | `msedgewebview2.exe` โ€” the actual Chromium engine | Microsoft's evergreen component. Ships with Windows 11 and nearly all Windows 10 machines. **Installed automatically on first start if missing.** | ### Automatic Runtime installation On start-up the player checks for the Runtime (registry `pv` value under the Edge Update client GUID, with a live SDK probe as fallback). If it is absent it runs the installer silently: ``` MicrosoftEdgeWebview2Setup.exe /silent /install ``` Deliberately **not elevated** โ€” an unelevated run performs a *per-user* install, so no UAC dialog ever appears on the signage display. Installers are looked up in this order, so you can drop a replacement next to the `.exe` without rebuilding: 1. `KIWY_WEBVIEW2_INSTALLER` environment variable 2. `\webview2_runtime\` 3. `\` (next to the executable) 4. bundled copy inside the exe | Installer | Size | Bundled? | Use when | |-----------|------|----------|----------| | `MicrosoftEdgeWebview2Setup.exe` | ~1.7 MB | โœ… yes | Machine has internet (downloads the Runtime) | | `MicrosoftEdgeWebView2RuntimeInstallerX64.exe` | ~203 MB | โฌœ opt-in | Machine is **offline** | To bundle the offline installer (adds ~200 MB to the exe): ```powershell cd windows .\webview2_runtime\download_runtime_installers.ps1 -Offline venv\Scripts\python.exe -m PyInstaller build.spec --clean --noconfirm ``` Re-download the installers at any time (they are Microsoft-signed; the script verifies the signature): ```powershell .\webview2_runtime\download_runtime_installers.ps1 ``` ### If WebView2 is unavailable Web links fall back to the Chrome/Edge subprocess engine (see `src/weblink_session.py`). That engine still works, but reintroduces the old drawbacks โ€” a separate browser window, possible background/z-order behaviour, and browser processes to clean up. ### Troubleshooting | Problem | Solution | |---------|----------| | Web links show a black/blank page | Check `logs\` for `[WebView2]` lines. Confirm the Runtime version is reported. | | Runtime install did not happen | A failed attempt is not retried for 6 hours (marker: `logs\.webview2_install_attempt`). Delete that file to retry immediately. | | Need it working offline | Bundle the standalone installer (see above). | ## โš™๏ธ Configuration **No configuration ships with the exe.** On a machine that has never been set up, `config\app_config.json` is absent, so after the splash video the player shows a *"Player is not configured"* notice, waits 5 seconds and then opens the **Settings** screen automatically. Enter the server details and playback starts right away โ€” no restart required. On a machine that already has a valid `config\app_config.json`, the first-run flow is skipped entirely and the cached playlist plays immediately. 1. Config is created next to the **executable** (not in `%APPDATA%`) - The .exe creates: `config/`, `media/`, `playlists/`, `logs/` locally - This allows you to copy the entire `dist\KiwySignagePlayer\` folder anywhere and it works 2. The player is considered configured once `server_ip`, `screen_name` and `quickconnect_key` all hold real values. Placeholder values (`localhost`, `kivy-player`, `1234567`, `127.0.0.1`) count as unconfigured. 3. Edit `config\app_config.json` (next to the .exe) to set your server: ```json { "server_ip": "192.168.0.109", "port": "8080", "screen_name": "Birou_IT", "quickconnect_key": "8887779", "orientation": "Landscape", "touch": "True", "max_resolution": "1920x1080", "edit_feature_enabled": true, "use_https": false, "verify_ssl": false } ``` ## ๐Ÿ’ณ Card Reader (Windows Edition) The card reader now works on Windows via the **Raw Input API** (with a low-level keyboard-hook fallback). It replaces the Linux-only `evdev` implementation automatically when `run_win.py` starts. - Detection mirrors the Linux logic: 1. A device named with `card` / `reader` / `rfid` 2. A USB HID keyboard (non-PS/2) โ€” most card readers enumerate this way 3. Any remaining keyboard (excluding touchscreens/mice) - Only keystrokes from the **selected device** are captured, so the operator's real keyboard cannot pollute card data. - Card data ends on **Enter** (same as Linux). ### Card reader config (optional) Add any of these to `config\app_config.json` next to the .exe: ```json { "card_reader_mode": "auto", // "auto" | "raw" | "hook" "card_reader_device": "", // e.g. "VID_08FF" to force a specific device "card_reader_timeout": 5 // seconds } ``` - `card_reader_mode`: `auto` (default, tries Raw Input then falls back), `raw` (force Raw Input), or `hook` (force the low-level keyboard hook). - `card_reader_device`: optional substring of the device name to pin the reader (e.g. `VID_08FF`, `HID#VID_08FF`). Run the manual test below to see the exact device names on your host. - `card_reader_timeout`: how long the swipe popup waits (default 5 s). ### Manual card reader test (no GUI) ```batch cd windows venv\Scripts\activate python win_card_reader.py ``` Swipe a card within 10 seconds โ€” the tool prints the captured data, then exits. The detected devices are listed in the console/log. ## ๐Ÿงช Testing ```batch cd windows venv\Scripts\activate python run_win.py ``` ## ๐Ÿ”ง Troubleshooting | Problem | Solution | |---------|----------| | **"ffpyplayer not found"** | Install: `pip install ffpyplayer` | | **"No video" / black screen** | Install FFmpeg and add to PATH. Try `KIVY_GL_BACKEND=angle_sdl2` or `KIVY_GL_BACKEND=gl` | | **Kivy window doesn't open** | Run from command prompt to see error messages. Ensure GPU drivers are up to date. | | **Weblinks not opening** | Install Google Chrome or Microsoft Edge | | **Can't connect to server** | Check firewall. Try `use_https: false` and `verify_ssl: false` for testing | | **Antivirus flags .exe** | Add the output folder to antivirus exclusions. This is a false positive common with PyInstaller. | ## ๐Ÿ“ Project Structure (Build) ``` Kiwy-Signage/ โ”œโ”€โ”€ windows/ โ”‚ โ”œโ”€โ”€ run_win.py # Windows entry point (patches platform differences) โ”‚ โ”œโ”€โ”€ build.spec # PyInstaller configuration โ”‚ โ”œโ”€โ”€ build_win.bat # One-click build script โ”‚ โ”œโ”€โ”€ pyi_runtime_hook.py # PyInstaller runtime hook โ”‚ โ”œโ”€โ”€ requirements_win.txt # Windows Python dependencies โ”‚ โ””โ”€โ”€ README_WINDOWS_BUILD.md # This file โ”œโ”€โ”€ src/ โ”‚ โ”œโ”€โ”€ main.py # Main application (original) โ”‚ โ”œโ”€โ”€ get_playlists_v2.py # Playlist sync โ”‚ โ”œโ”€โ”€ player_auth.py # Authentication โ”‚ โ”œโ”€โ”€ ssl_utils.py # SSL/HTTPS โ”‚ โ”œโ”€โ”€ keyboard_widget.py # On-screen keyboard โ”‚ โ”œโ”€โ”€ network_monitor.py # Network monitoring โ”‚ โ”œโ”€โ”€ edit_popup.py # Image editing โ”‚ โ””โ”€โ”€ signage_player.kv # Kivy UI layout โ”œโ”€โ”€ config/ โ”‚ โ”œโ”€โ”€ app_config.json # Player configuration โ”‚ โ””โ”€โ”€ resources/ # Icons, images, intro video โ”œโ”€โ”€ media/ # Downloaded media (created at runtime) โ”œโ”€โ”€ playlists/ # Playlist files (created at runtime) โ””โ”€โ”€ logs/ # Log files (created at runtime) ```