Player
- Arrow keys seek by 5s, Shift for a 30s jump on long recordings, J/L for +-30s,
Space toggles playback, and up/down adjust volume. Dragging a scrubber across a
multi-hour replay is unusable — one pixel is tens of seconds — so keys are the
practical way to move around a long recording.
- The shortcuts ignore key events from inputs, so typing a chapter time in the
replay editor no longer scrubs the video.
- Add a playback speed selector. It is a replay tool: speeding a live stream up
would only push it further ahead of the encoder's buffer.
Replay editor
- Stop playback restarting on every edit. The player's source effect depended on
the `lines` and `qualities` arrays, and callers such as the replay editor pass
fresh literals on every render, so adding a chapter or typing a title was
treated as a source change and reloaded the stream from the beginning. The
effect now depends on the resolved source URL instead of the arrays it came
from. Measured: adding three chapters leaves the media requests unchanged and
the playhead advancing.
Settings persistence
- Settings edited in the UI were applied to the in-memory settings object and
never written down, so the brand, transcode ladder and load-balancing strategy
silently reverted to the config.py defaults on every restart. They are now
saved to backend/settings.json (atomic temp-file replace) and re-applied at
startup, with only known keys accepted so a hand-edited file cannot inject
arbitrary attributes.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Backend: FastAPI + SQLAlchemy + SQLite
Frontend: React + Vite + Ant Design (serif Anthropic theme)
Media server: MediaMTX with edge node support
Load balancing: round-robin / weighted / least-conn
Multicast detection with automatic fallback
Transcoding support via FFmpeg (configurable quality)
hls.js player with line & quality switching
Admin panel with password auth
Windows compatible scripts