68 lines
2.0 KiB
Go
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()
|
|
}
|