From d0102779ed2cafbb35c863d32645e45dc95f9563 Mon Sep 17 00:00:00 2001 From: Ella Pietraroia Date: Mon, 23 Dec 2019 15:27:46 +1030 Subject: [PATCH 1/2] stderr implementation in webcam same stderr messages made avaliable in raspivid.go now in webcam, so can see when there are problems with with the webcam, rather then our code --- device/webcam/webcam.go | 42 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/device/webcam/webcam.go b/device/webcam/webcam.go index 0ac08751..47c1d46c 100644 --- a/device/webcam/webcam.go +++ b/device/webcam/webcam.go @@ -28,6 +28,7 @@ import ( "errors" "fmt" "io" + "io/ioutil" "os/exec" "strings" @@ -61,15 +62,19 @@ var ( // Webcam is an implementation of the AVDevice interface for a Webcam. Webcam // uses an ffmpeg process to pipe the video data from the webcam. type Webcam struct { - out io.ReadCloser - log config.Logger - cfg config.Config - cmd *exec.Cmd + out io.ReadCloser + log config.Logger + cfg config.Config + cmd *exec.Cmd + done chan struct{} } // New returns a new Webcam. func New(l config.Logger) *Webcam { - return &Webcam{log: l} + return &Webcam{ + log: l, + done: make(chan struct{}), + } } // Name returns the name of the device. @@ -151,6 +156,32 @@ func (w *Webcam) Start() error { return fmt.Errorf("failed to create pipe: %w", err) } + stderr, err := w.cmd.StderrPipe() + if err != nil { + return fmt.Errorf("could not pipe command error: %w", err) + } + + go func() { + for { + select { + case <-w.done: + w.cfg.Logger.Log(logger.Info, "raspivid.Stop() called, finished checking stderr") + return + default: + buf, err := ioutil.ReadAll(stderr) + if err != nil { + w.cfg.Logger.Log(logger.Error, "could not read stderr", "error", err) + return + } + + if len(buf) != 0 { + w.cfg.Logger.Log(logger.Error, "error from raspivid stderr", "error", string(buf)) + return + } + } + } + }() + err = w.cmd.Start() if err != nil { return fmt.Errorf("failed to start ffmpeg: %w", err) @@ -161,6 +192,7 @@ func (w *Webcam) Start() error { // Stop will kill the ffmpeg process and close the output pipe. func (w *Webcam) Stop() error { + close(w.done) if w.cmd == nil || w.cmd.Process == nil { return errors.New("ffmpeg process was never started") } From 0da4c3b618cfb28c3153912b86a76a60176ad980 Mon Sep 17 00:00:00 2001 From: Ella Pietraroia Date: Mon, 23 Dec 2019 15:37:20 +1030 Subject: [PATCH 2/2] device/webcam/webcam.go: fixed error output --- device/webcam/webcam.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/device/webcam/webcam.go b/device/webcam/webcam.go index 47c1d46c..fbb3a91b 100644 --- a/device/webcam/webcam.go +++ b/device/webcam/webcam.go @@ -165,7 +165,7 @@ func (w *Webcam) Start() error { for { select { case <-w.done: - w.cfg.Logger.Log(logger.Info, "raspivid.Stop() called, finished checking stderr") + w.cfg.Logger.Log(logger.Info, "webcam.Stop() called, finished checking stderr") return default: buf, err := ioutil.ReadAll(stderr) @@ -175,7 +175,7 @@ func (w *Webcam) Start() error { } if len(buf) != 0 { - w.cfg.Logger.Log(logger.Error, "error from raspivid stderr", "error", string(buf)) + w.cfg.Logger.Log(logger.Error, "error from webcam stderr", "error", string(buf)) return } }