mirror of https://bitbucket.org/ausocean/av.git
revid & cmd/revid-cli: added loop mode so that input may be restarted after completion
Loop flag has been added to command line flags and in turn sets the Loop field that has been added to the config.Config struct. mode variable now also checked to see if value set to Loop, in which case revid config.Config.Loop = true. Revid.processFrom modified so that when input source has completed Revid.cfg.Loop is checked and input restarted if true.
This commit is contained in:
parent
c2329b3a3f
commit
99b931f948
|
@ -122,6 +122,7 @@ func handleFlags() config.Config {
|
||||||
httpAddressPtr = flag.String("HttpAddress", "", "Destination address of http posts")
|
httpAddressPtr = flag.String("HttpAddress", "", "Destination address of http posts")
|
||||||
verticalFlipPtr = flag.Bool("VerticalFlip", false, "Flip video vertically: Yes, No")
|
verticalFlipPtr = flag.Bool("VerticalFlip", false, "Flip video vertically: Yes, No")
|
||||||
horizontalFlipPtr = flag.Bool("HorizontalFlip", false, "Flip video horizontally: Yes, No")
|
horizontalFlipPtr = flag.Bool("HorizontalFlip", false, "Flip video horizontally: Yes, No")
|
||||||
|
loopPtr = flag.Bool("Loop", false, "Loop video if EOF encountered: true, false")
|
||||||
bitratePtr = flag.Uint("Bitrate", 0, "Bitrate of recorded video")
|
bitratePtr = flag.Uint("Bitrate", 0, "Bitrate of recorded video")
|
||||||
heightPtr = flag.Uint("Height", 0, "Height in pixels")
|
heightPtr = flag.Uint("Height", 0, "Height in pixels")
|
||||||
widthPtr = flag.Uint("Width", 0, "Width in pixels")
|
widthPtr = flag.Uint("Width", 0, "Width in pixels")
|
||||||
|
@ -179,6 +180,8 @@ func handleFlags() config.Config {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cfg.Loop = *loopPtr
|
||||||
|
|
||||||
switch *inputPtr {
|
switch *inputPtr {
|
||||||
case "Raspivid":
|
case "Raspivid":
|
||||||
cfg.Input = config.InputRaspivid
|
cfg.Input = config.InputRaspivid
|
||||||
|
|
|
@ -297,6 +297,9 @@ type Config struct {
|
||||||
MOGMinArea float64 // Used to ignore small areas of motion detection.
|
MOGMinArea float64 // Used to ignore small areas of motion detection.
|
||||||
MOGThreshold float64 // Intensity value from the KNN motion detection algorithm that is considered motion.
|
MOGThreshold float64 // Intensity value from the KNN motion detection algorithm that is considered motion.
|
||||||
MOGHistory uint // Length of MOG filter's history
|
MOGHistory uint // Length of MOG filter's history
|
||||||
|
|
||||||
|
// If true will restart reading of input after an io.EOF.
|
||||||
|
Loop bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// TypeData contains information about all of the variables that
|
// TypeData contains information about all of the variables that
|
||||||
|
|
|
@ -428,13 +428,8 @@ func (r *Revid) Start() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = r.input.Start()
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("could not start input device: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
r.wg.Add(1)
|
r.wg.Add(1)
|
||||||
go r.processFrom(r.input, 0)
|
go r.processFrom(r.input, (1000/25)*time.Millisecond)
|
||||||
|
|
||||||
r.running = true
|
r.running = true
|
||||||
return nil
|
return nil
|
||||||
|
@ -845,6 +840,11 @@ func (r *Revid) Update(vars map[string]string) error {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
r.cfg.MOGHistory = uint(v)
|
r.cfg.MOGHistory = uint(v)
|
||||||
|
case "mode":
|
||||||
|
r.cfg.Loop = false
|
||||||
|
if value == "Loop" {
|
||||||
|
r.cfg.Loop = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
r.cfg.Logger.Log(logger.Info, pkg+"revid config changed", "config", fmt.Sprintf("%+v", r.cfg))
|
r.cfg.Logger.Log(logger.Info, pkg+"revid config changed", "config", fmt.Sprintf("%+v", r.cfg))
|
||||||
|
@ -853,14 +853,35 @@ func (r *Revid) Update(vars map[string]string) error {
|
||||||
|
|
||||||
// processFrom is run as a routine to read from a input data source, lex and
|
// processFrom is run as a routine to read from a input data source, lex and
|
||||||
// then send individual access units to revid's encoders.
|
// then send individual access units to revid's encoders.
|
||||||
func (r *Revid) processFrom(read io.Reader, delay time.Duration) {
|
func (r *Revid) processFrom(in device.AVDevice, delay time.Duration) {
|
||||||
err := r.lexTo(r.filters[0], read, delay)
|
restart:
|
||||||
r.cfg.Logger.Log(logger.Debug, pkg+"finished lexing")
|
err := in.Start()
|
||||||
|
if err != nil {
|
||||||
|
r.err <- fmt.Errorf("could not start input device: %w", err)
|
||||||
|
r.wg.Done()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lex data from input device, in, until finished or an error is encountered.
|
||||||
|
// For a continuous source e.g. a camera or microphone, we should remain
|
||||||
|
// in this call indefinitely unless in.Stop() is called and an io.EOF is forced.
|
||||||
|
err = r.lexTo(r.filters[0], in, delay)
|
||||||
switch err {
|
switch err {
|
||||||
case nil: // Do nothing.
|
case nil, io.EOF, io.ErrUnexpectedEOF:
|
||||||
case io.EOF: // TODO: handle this depending on loop mode.
|
|
||||||
default:
|
default:
|
||||||
r.err <- err
|
r.err <- err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = in.Stop()
|
||||||
|
if err != nil {
|
||||||
|
r.err <- fmt.Errorf("could not stop input source: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if r.cfg.Loop {
|
||||||
|
r.cfg.Logger.Log(logger.Info, pkg+"looping input")
|
||||||
|
goto restart
|
||||||
|
}
|
||||||
|
|
||||||
|
r.cfg.Logger.Log(logger.Info, pkg+"finished lexing")
|
||||||
r.wg.Done()
|
r.wg.Done()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue