diff --git a/README.md b/README.md index 0810cb63..375a5ab5 100644 --- a/README.md +++ b/README.md @@ -921,6 +921,7 @@ API examples: - MJPEG stream: `http://192.168.1.123:1984/api/stream.mjpeg?src=camera1` - JPEG snapshots: `http://192.168.1.123:1984/api/frame.jpeg?src=camera1` +- JPEG snapshot resized to 100px: `http://192.168.1.123:1984/api/frame.jpeg?src=camera1&h=100` ### Module: Log diff --git a/internal/ffmpeg/helpers.go b/internal/ffmpeg/helpers.go index 56598fbf..f9e64d86 100644 --- a/internal/ffmpeg/helpers.go +++ b/internal/ffmpeg/helpers.go @@ -2,11 +2,17 @@ package ffmpeg import ( "bytes" + "fmt" "os/exec" ) -func TranscodeToJPEG(b []byte) ([]byte, error) { - cmd := exec.Command(defaults["bin"], "-hide_banner", "-i", "-", "-f", "mjpeg", "-") +func TranscodeToJPEG(b []byte, height ...int) ([]byte, error) { + cmdArgs := []string{defaults["bin"], "-hide_banner", "-i", "-", "-f", "mjpeg"} + if len(height) > 0 { + cmdArgs = append(cmdArgs, "-vf", fmt.Sprintf("scale=-1:%d", height[0])) + } + cmdArgs = append(cmdArgs, "-") + cmd := exec.Command(cmdArgs[0], cmdArgs[1:]...) cmd.Stdin = bytes.NewBuffer(b) return cmd.Output() } diff --git a/internal/mjpeg/init.go b/internal/mjpeg/init.go index 70ab8e00..bebe8264 100644 --- a/internal/mjpeg/init.go +++ b/internal/mjpeg/init.go @@ -61,9 +61,22 @@ func handlerKeyframe(w http.ResponseWriter, r *http.Request) { case core.CodecH264, core.CodecH265: ts := time.Now() var err error - if data, err = ffmpeg.TranscodeToJPEG(data); err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return + // Resize image if "h" parameter exists + if hParam := r.URL.Query().Get("h"); hParam != "" { + h, err := strconv.Atoi(hParam) + if err != nil { + http.Error(w, "Invalid height parameter", http.StatusBadRequest) + return + } + if data, err = ffmpeg.TranscodeToJPEG(data, h); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + } else { + if data, err = ffmpeg.TranscodeToJPEG(data); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } } log.Debug().Msgf("[mjpeg] transcoding time=%s", time.Since(ts)) }