Files
go2rtc/internal/ffmpeg/jpeg.go
2023-08-30 05:57:00 +03:00

84 lines
1.7 KiB
Go

package ffmpeg
import (
"bytes"
"fmt"
"net/url"
"os/exec"
"github.com/AlexxIT/go2rtc/internal/ffmpeg/hardware"
"github.com/AlexxIT/go2rtc/pkg/core"
"github.com/AlexxIT/go2rtc/pkg/ffmpeg"
"github.com/AlexxIT/go2rtc/pkg/shell"
)
func JPEGWithQuery(b []byte, query url.Values) ([]byte, error) {
args := parseQuery(query)
return transcode(b, args.String())
}
func JPEGWithScale(b []byte, width, height int) ([]byte, error) {
args := defaultArgs()
args.AddFilter(fmt.Sprintf("scale=%d:%d", width, height))
return transcode(b, args.String())
}
func transcode(b []byte, args string) ([]byte, error) {
cmdArgs := shell.QuoteSplit(args)
cmd := exec.Command(cmdArgs[0], cmdArgs[1:]...)
cmd.Stdin = bytes.NewBuffer(b)
return cmd.Output()
}
func defaultArgs() *ffmpeg.Args {
return &ffmpeg.Args{
Bin: defaults["bin"],
Global: defaults["global"],
Input: "-i -",
Codecs: []string{defaults["mjpeg"]},
Output: defaults["output/mjpeg"],
}
}
func parseQuery(query url.Values) *ffmpeg.Args {
args := defaultArgs()
var width = -1
var height = -1
var r, hw string
for k, v := range query {
switch k {
case "width", "w":
width = core.Atoi(v[0])
case "height", "h":
height = core.Atoi(v[0])
case "rotate":
r = v[0]
case "hardware", "hw":
hw = v[0]
}
}
if width > 0 || height > 0 {
args.AddFilter(fmt.Sprintf("scale=%d:%d", width, height))
}
if r != "" {
switch r {
case "90":
args.AddFilter("transpose=1") // 90 degrees clockwise
case "180":
args.AddFilter("transpose=1,transpose=1")
case "-90", "270":
args.AddFilter("transpose=2") // 90 degrees counterclockwise
}
}
if hw != "" {
hardware.MakeHardware(args, hw, defaults)
}
return args
}