diff --git a/cmd/watcher/watcher.go b/cmd/watcher/watcher.go index c0cc769..070685d 100644 --- a/cmd/watcher/watcher.go +++ b/cmd/watcher/watcher.go @@ -14,6 +14,7 @@ import ( "connectrpc.com/connect" pb "github.com/chathaway-codes/home-sensors/v2/gen" servicepb "github.com/chathaway-codes/home-sensors/v2/gen/genconnect" + "github.com/chathaway-codes/home-sensors/v2/internal/filewrite" "github.com/chathaway-codes/home-sensors/v2/internal/h264video" "github.com/chathaway-codes/home-sensors/v2/internal/sensors" "github.com/chathaway-codes/home-sensors/v2/internal/watcher/config" @@ -60,12 +61,20 @@ func main() { log.Fatal().Err(err).Msg("failed to get default sensor") } + filewrite, err := filewrite.Default.Get(vid) + if err != nil { + log.Fatal().Err(err).Msg("failed to get default filewriter") + } + go vid.Run() defer vid.Done() go sensors.Run() defer sensors.Done() + go filewrite.Run() + defer filewrite.Done() + sensorCh, sensorDone := sensors.Join() defer sensorDone() diff --git a/dbuild.deb b/dbuild.deb new file mode 100644 index 0000000..3b8badf Binary files /dev/null and b/dbuild.deb differ diff --git a/internal/filewrite/filewrite.go b/internal/filewrite/filewrite.go new file mode 100644 index 0000000..1545f5f --- /dev/null +++ b/internal/filewrite/filewrite.go @@ -0,0 +1,102 @@ +// Package filewite adds a function to write the data stream to a file +package filewrite + +import ( + "context" + "fmt" + "os" + "path" + "time" + + "github.com/chathaway-codes/home-sensors/v2/internal/h264video" + "github.com/chathaway-codes/home-sensors/v2/internal/watcher/config" + "github.com/rs/zerolog/log" +) + +var Default = &Mod{} + +type FileWrite struct { + cfg *config.Config + cancelFunc func() + ctx context.Context + video *h264video.Video +} + +func New(video *h264video.Video, cfg *config.Config) (*FileWrite, error) { + ctx, cancelFunc := context.WithCancel(context.Background()) + + return &FileWrite{ + cfg: cfg, + cancelFunc: cancelFunc, + video: video, + ctx: ctx, + }, nil + +} + +// Run launches the commands and begins creating data. It will block until Done is called. +func (v *FileWrite) Run() { + // Confirm that the target directory is a directory + stat, err := os.Stat(v.cfg.LocalCopy) + log := log.With().Str("directory", v.cfg.LocalCopy).Logger() + if err != nil { + log.Fatal().Err(err).Msg("failed to open path") + } + if !stat.IsDir() { + log.Fatal().Msg("path is not directory") + } + // Start snooping + videoCh, codec, done := v.video.Join() + defer done() + + // TODO: what do with codec? + log.Info().Str("codec", codec).Msg("got video codec") + + now := time.Now() + fileName := path.Join(v.cfg.LocalCopy, fmt.Sprintf("%s.h264", now.Format("2006-01-02T15:04:05"))) + writer, err := os.Create(fileName) + if err != nil { + log.Fatal().Err(err).Str("file", fileName).Msg("failed to create file") + } + + for bytes := range videoCh { + select { + case <-v.ctx.Done(): + return + default: + // do nothing + } + + _, err := writer.Write(bytes) + if err != nil { + log.Fatal().Str("file", fileName).Err(err).Msg("failed to write bytes") + } + // Split it every half hour or so + if time.Since(now) > time.Minute*30 { + now = time.Now() + if err := writer.Close(); err != nil { + log.Fatal().Err(err).Msg("failed to close file") + } + fileName := path.Join(v.cfg.LocalCopy, fmt.Sprintf("%s.h264", now.Format("2006-01-02T15:04:05"))) + writer, err = os.Create(fileName) + if err != nil { + log.Fatal().Err(err).Str("file", fileName).Msg("failed to create file") + } + } + } +} + +// Done stops the processing. +func (v *FileWrite) Done() { + v.cancelFunc() +} + +type Mod struct{} + +func (m *Mod) Get(video *h264video.Video) (*FileWrite, error) { + cfg, err := config.Default.Get() + if err != nil { + return nil, err + } + return New(video, cfg) +} diff --git a/internal/watcher/config/config.go b/internal/watcher/config/config.go index 74f8284..cddfe26 100644 --- a/internal/watcher/config/config.go +++ b/internal/watcher/config/config.go @@ -23,6 +23,7 @@ type Config struct { IVFCmd *Cmd `yaml:"ivf"` SensorCmd *Cmd `yaml:"sensor"` SensorRateMS int64 `yaml:"sensor_rate_ms"` + LocalCopy string `yaml:"local_copy"` } func New(source []byte, name string) (*Config, error) { diff --git a/sample.yaml b/sample.yaml index 64b5a39..784cefe 100644 --- a/sample.yaml +++ b/sample.yaml @@ -10,3 +10,4 @@ sensor: arguments: - "44.33889713096721 1015.1977693083448 23.60542243081727" sensor_rate_ms: 10000 +local_copy: /tmp/hello1/ \ No newline at end of file diff --git a/signaler b/signaler new file mode 100755 index 0000000..d09399a Binary files /dev/null and b/signaler differ diff --git a/watcher b/watcher new file mode 100755 index 0000000..ba61757 Binary files /dev/null and b/watcher differ