revid/webcam.go: wrote implementations of Start, Stop and Read methods

This commit is contained in:
Saxon 2019-11-05 11:56:34 +10:30
parent 8302e959d9
commit 81d168a277
1 changed files with 54 additions and 0 deletions

View File

@ -26,7 +26,12 @@ package revid
import ( import (
"errors" "errors"
"fmt"
"io" "io"
"os/exec"
"strings"
"bitbucket.org/ausocean/utils/logger"
) )
const ( const (
@ -48,6 +53,7 @@ type Webcam struct {
out io.ReadCloser out io.ReadCloser
log Logger log Logger
cfg Config cfg Config
cmd *exec.Cmd
} }
func NewWebcam(l Logger) *Webcam { func NewWebcam(l Logger) *Webcam {
@ -78,3 +84,51 @@ func (w *Webcam) Set(c Config) error {
w.cfg = c w.cfg = c
return multiError(errs) return multiError(errs)
} }
func (w *Webcam) Start() error {
args := []string{
"-i", w.cfg.InputPath,
"-f", "h264",
"-r", fmt.Sprint(w.cfg.FrameRate),
}
br := w.cfg.Bitrate * 1000
args = append(args,
"-b:v", fmt.Sprint(br),
"-maxrate", fmt.Sprint(br),
"-bufsize", fmt.Sprint(br/2),
"-s", fmt.Sprintf("%dx%d", w.cfg.Width, w.cfg.Height),
"-",
)
w.log.Log(logger.Info, pkg+"ffmpeg args", "args", strings.Join(args, " "))
w.cmd = exec.Command("ffmpeg", args...)
var err error
w.out, err = w.cmd.StdoutPipe()
if err != nil {
return fmt.Errorf("failed to create pipe: %w", err)
}
err = w.cmd.Start()
if err != nil {
return fmt.Errorf("failed to start ffmpeg: %w", err)
}
return nil
}
func (w *Webcam) Stop() error {
if w.cmd == nil || w.cmd.Process == nil {
return errors.New("raspivid process was never started")
}
err := w.cmd.Process.Kill()
if err != nil {
return fmt.Errorf("could not kill raspivid process: %w", err)
}
return w.out.Close()
}
func (w *Webcam) Read(p []byte) (int, error) {
return w.out.Read(p)
}