chore: v0.3.1 — go2rtc auto-start, live wall snapshots, MSE focus player
This commit is contained in:
parent
9de8536bdf
commit
1a017999fe
2 changed files with 29 additions and 5 deletions
17
main.go
17
main.go
|
|
@ -45,9 +45,20 @@ func main() {
|
|||
sigCh := make(chan os.Signal, 1)
|
||||
signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
|
||||
|
||||
// Initialize application.
|
||||
app := &App{Config: cfg, ConfigPath: configPath}
|
||||
|
||||
// Start go2rtc if enabled.
|
||||
if cfg.Go2RTC.Enabled {
|
||||
go2rtc := NewGo2RTCManager(cfg.Go2RTC)
|
||||
if err := go2rtc.Start(cfg.Cameras); err != nil {
|
||||
log.Printf("go2rtc: start failed: %v", err)
|
||||
}
|
||||
app.go2rtc = go2rtc
|
||||
}
|
||||
|
||||
// Start the HTTP server (blocks).
|
||||
errCh := make(chan error, 1)
|
||||
app := &App{Config: cfg, ConfigPath: configPath}
|
||||
go func() {
|
||||
errCh <- app.StartServer()
|
||||
}()
|
||||
|
|
@ -92,6 +103,7 @@ type App struct {
|
|||
Config Config
|
||||
ConfigPath string
|
||||
server *Server
|
||||
go2rtc *Go2RTCManager
|
||||
}
|
||||
|
||||
// StartServer initializes and starts the HTTP server.
|
||||
|
|
@ -106,6 +118,9 @@ func (a *App) StartServer() error {
|
|||
|
||||
// Shutdown performs a graceful shutdown of all services.
|
||||
func (a *App) Shutdown() {
|
||||
if a.go2rtc != nil {
|
||||
a.go2rtc.Stop()
|
||||
}
|
||||
if a.server != nil {
|
||||
a.server.Close()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,11 +70,20 @@ function renderLiveGrid() {
|
|||
tile.className = 'grid-tile' + (cam && cam.enabled ? '' : ' offline');
|
||||
tile.dataset.camId = cam ? cam.id : '';
|
||||
|
||||
if (cam) {
|
||||
if (cam && cam.enabled) {
|
||||
// go2rtc snapshot endpoint — refresh every 2 seconds for live preview.
|
||||
const snapshotURL = `http://${location.hostname}:1984/api/frame.jpeg?src=${cam.id}_sub`;
|
||||
tile.innerHTML = `
|
||||
<img src="${snapshotURL}" class="grid-snap" onerror="this.style.display='none'"
|
||||
style="width:100%;height:100%;object-fit:cover;position:absolute;inset:0" alt="${cam.name}">
|
||||
<span class="tile-status ${cam.online ? 'online' : 'offline'}"></span>
|
||||
<span class="tile-label">${cam.name}</span>
|
||||
`;
|
||||
// Auto-refresh snapshot.
|
||||
setInterval(() => {
|
||||
const img = tile.querySelector('img');
|
||||
if (img) img.src = snapshotURL + '&t=' + Date.now();
|
||||
}, 2000);
|
||||
tile.addEventListener('click', () => openFocus(cam));
|
||||
} else {
|
||||
tile.innerHTML = '<span class="tile-placeholder">No Camera</span>';
|
||||
|
|
@ -97,10 +106,10 @@ function updateFocus() {
|
|||
const cam = cameras[focusIdx];
|
||||
document.getElementById('focus-title').textContent = cam.name;
|
||||
document.getElementById('focus-time').textContent = new Date().toLocaleTimeString() + ' live';
|
||||
// TODO: M3 — connect to go2rtc WebRTC stream
|
||||
// go2rtc MSE stream for full-quality playback.
|
||||
const vid = document.getElementById('focus-video');
|
||||
vid.src = '';
|
||||
vid.poster = ''; // placeholder until go2rtc is wired up
|
||||
vid.src = `http://${location.hostname}:1984/api/stream.m3u8?src=${cam.id}_main`;
|
||||
vid.play().catch(() => {});
|
||||
}
|
||||
function renderThumbs() {
|
||||
const strip = document.getElementById('focus-thumbs');
|
||||
|
|
|
|||
Loading…
Reference in a new issue