Add on-screen clock overlay (outlined text, configurable corner/timezone)
A small always-on-top mpv window renders the local time in a screen corner. Implementation notes: - Transparent lavfi canvas (color=...@0.0, --alpha=yes) so the camera video shows through; no new dependencies. If the compositor can't do alpha it degrades to a dark backing, still legible. - Time drawn as an ASS osd-overlay pushed over mpv IPC once a second: white fill + black outline (\bord), so it reads on both bright (day) and dark (night) scenes without sampling the picture. Formatting the text in Go avoids any filtergraph escaping. - Time computed with time.LoadLocation against a configured IANA zone (default "Local"), so it's correct regardless of the host clock's zone and handles DST. A bad zone name fails at startup. - Managed on the daemon's own context (survives layout switches); the daemon keeps it positioned and raised above camera tiles. ensureClock is a no-op when the clock config + resolution are unchanged, so a reload never disturbs it. Config: new `clock` section (enabled, timezone, format, corner, font_size, width, height, margin) with defaults and corner validation. Documented in README and config.example (shipped enabled, America/Denver, 24-hour w/ seconds). Tests cover corner geometry. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
29
internal/daemon/clock_test.go
Normal file
29
internal/daemon/clock_test.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package daemon
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/lwoodard/rtsp-streamer/internal/config"
|
||||
)
|
||||
|
||||
func TestClockRectCorners(t *testing.T) {
|
||||
cl := config.Clock{Width: 300, Height: 72, Margin: 24}
|
||||
const w, h = 1920, 1080
|
||||
cases := map[string][2]int{
|
||||
"bottom-right": {1920 - 300 - 24, 1080 - 72 - 24},
|
||||
"bottom-left": {24, 1080 - 72 - 24},
|
||||
"top-right": {1920 - 300 - 24, 24},
|
||||
"top-left": {24, 24},
|
||||
"": {1920 - 300 - 24, 1080 - 72 - 24}, // default = bottom-right
|
||||
}
|
||||
for corner, want := range cases {
|
||||
cl.Corner = corner
|
||||
r := clockRect(w, h, cl)
|
||||
if r.X != want[0] || r.Y != want[1] {
|
||||
t.Errorf("corner %q: got (%d,%d), want (%d,%d)", corner, r.X, r.Y, want[0], want[1])
|
||||
}
|
||||
if r.W != 300 || r.H != 72 {
|
||||
t.Errorf("corner %q: size (%d,%d), want (300,72)", corner, r.W, r.H)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user