- After Kodi starts, set audiooutput.audiodevice to the HDMI sink via JSON-RPC
(Kodi otherwise defaults to the analog jack). Waits for the web server, is
overridable via MEDIAPI_KODI_AUDIO_DEVICE.
- mkdir the configured MEDIAPI_MEDIA_ROOTS so browsing works and there's a spot
to copy content into.
Verified live on the Pi: playback + HDMI audio work end to end via the app's
Player.Open path.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Playback moves to Kodi (standalone on GBM/KMS -- the smooth, hardware-decoded
LibreELEC path). mediapi becomes a thin remote: it browses media and controls
Kodi over its JSON-RPC HTTP API. This drops every mpv/DRM/X-mirror problem
(DRM-master exclusivity, gpu-next "export failed" wedges, X-mirror A/V desync,
software-decode choppiness) -- none of which had a working single config.
- new mediapi/kodi.py (stdlib JSON-RPC client); player.py rewritten to poll
and drive Kodi (Player.Open/PlayPause/Seek, Application.SetVolume,
Player.GetProperties), same public interface + keep-playing auto-advance
- config.py: KODI_* settings replace MPV_SOCKET; __init__ + api_routes updated
- delete mpv_ipc.py, the mpv/X units, start-mpv/session scripts
- new systemd/mediapi-kodi.service.template (standalone Kodi on tty1) +
scripts/configure-kodi.py (headlessly enable Kodi's JSON-RPC web server)
- install.sh now bootstraps a BARE Pi OS Lite end to end: apt base packages,
installs uv, installs Kodi, enables its web API, configures the AP, installs
+ starts services (only git need be preinstalled). Auto-seeds .env from the
example on first run.
- README + .env.example updated for the Kodi architecture
Dual HDMI is handled in hardware (external splitter off one port); no software
mirror -- see git history for why that can't work smoothly on this Pi.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Move user-specific config (login, media roots, port, AP ssid/psk, service
user) into a gitignored .env; add .env.example template.
- config.py reads .env at startup via a tiny zero-dependency parser (works for
both `uv run` and systemd), and fails loudly if required vars are unset.
- load_secret_key falls back to an ephemeral key on a read-only filesystem
instead of crashing.
- systemd units become .template files; deploy.sh renders them with the
.env-derived user/paths.
- deploy.sh: refuses to run on a read-only overlay, git pull --ff-only,
uv sync, ensure secret key, re-apply the AP from .env, install units,
restart, health-check with automatic rollback to the previous commit.
- Scrub literal credentials/ssid out of the README; document .env + deploy.sh.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>