a0704efa3c
src/edit_popup.py: pass and reproduce the server-side edited-media layout
('edited_media/<media_id>/') when saving an edit, falling back to the flat
folder when no media id is available, so uploads land where the server expects.
src/get_playlists_v2.py: preserve every server field (audio, muted, description,
id, position, ...) when rewriting playlist items, instead of rebuilding fixed
dicts that silently dropped them. Web-link items keep their original http(s) url
and are never downloaded.
windows/pyi_runtime_hook.py: declare per-monitor DPI awareness before SDL/Kivy
initialise, so on a scaled display the window is not virtualised to a smaller
resolution (which left a black strip and mis-scaled media).
windows/build_win.bat: optional code signing step for PCs with Smart App Control
enabled, driven by KIWY_SIGN_PFX / KIWY_SIGN_PFX_PASSWORD or a local
kiwy_signing.pfx.
windows/build.spec, windows/README_WINDOWS_BUILD.md, windows/development-track.md:
build notes and manifest updates.
7.2 KiB
7.2 KiB
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
- Python 3.12+ (64-bit) — 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)
- FFmpeg — for video codec support
- Download from ffmpeg.org
- Add
bin\folder to your PATH
- Visual C++ Redistributable — latest
Install & Run
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
cd windows
build_win.bat
Manual Build
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.
⚙️ Configuration
- On first run, config files are created in the same folder as the executable (not in
%APPDATA%)- The .exe creates:
config/,media/,playlists/,logs/directories locally - This allows you to copy the entire
dist\KiwySignagePlayer\folder anywhere and it works
- The .exe creates:
- Edit
config\app_config.json(next to the .exe) to set your server:
{
"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:
- A device named with
card/reader/rfid - A USB HID keyboard (non-PS/2) — most card readers enumerate this way
- Any remaining keyboard (excluding touchscreens/mice)
- A device named with
- 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:
{
"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), orhook(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)
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
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)