Files
cctv/server/hooks.go
2026-04-22 23:35:59 +01:00

68 lines
2.0 KiB
Go

package main
import (
"fmt"
"net/url"
"git.koval.net/cyclane/cctv/server/ingest"
"git.koval.net/cyclane/cctv/server/models"
"github.com/pocketbase/pocketbase/core"
"golang.org/x/sync/errgroup"
)
func handleCameraUpdate(e *core.RecordEvent) error {
if e.Record.Collection().Name != "cameras" {
return e.Next()
}
camera := &models.Camera{}
camera.SetProxyRecord(e.Record)
log := e.App.Logger().With("camera", camera.Id)
// Encrypt password
password := camera.PasswordRaw()
log.Info("Old password", "password", password)
if err := camera.SetPassword(password, e.App.EncryptionEnv()); err != nil {
return fmt.Errorf("failed to encrypt password: %w", err)
}
log.Info("New password", "password", camera.PasswordRaw())
onvifProfiles, err := ingest.GetOnvifProfiles(e.Context, camera.OnvifHost(), camera.Username(), password)
if err != nil {
return fmt.Errorf("failed to find onvif profiles: %w", err)
}
if err := e.Next(); err != nil {
return err
}
streams, err := e.App.FindCollectionByNameOrId("streams")
if err != nil {
return fmt.Errorf("failed to find streams collection: %w", err)
}
errGroup := &errgroup.Group{}
for _, p := range onvifProfiles {
log.Debug("Found ONVIF profile", "name", p.Name, "token", p.Token)
errGroup.Go(func() error {
log := log.With("profile", p.Token)
rawURL := p.URI.String()
rtspUrl := p.URI
rtspUrl.User = url.UserPassword(camera.Username(), password)
stats, err := ingest.GetStreamStats(e.Context, log, rtspUrl, string(p.Token))
if err != nil {
return fmt.Errorf("failed to get stream stats for profile %s: %w", p.Token, err)
}
log.Debug("Retrieved stream stats", "fps", stats.FPS, "width", stats.Width, "height", stats.Height)
stream := &models.Stream{}
stream.SetProxyRecord(core.NewRecord(streams))
stream.SetCameraID(camera.Id)
stream.SetURL(rawURL)
stream.SetFPS(stats.FPS)
stream.SetWidth(stats.Width)
stream.SetHeight(stats.Height)
return e.App.Save(stream)
})
}
return errGroup.Wait()
}