mirror of
https://github.com/AlexxIT/go2rtc.git
synced 2025-10-18 22:24:38 +08:00
Code refactoring for ffmpeg device and virtual
This commit is contained in:
@@ -1,11 +1,9 @@
|
|||||||
package device
|
package device
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/AlexxIT/go2rtc/internal/api"
|
"github.com/AlexxIT/go2rtc/internal/api"
|
||||||
@@ -17,24 +15,15 @@ func Init(bin string) {
|
|||||||
api.HandleFunc("api/ffmpeg/devices", apiDevices)
|
api.HandleFunc("api/ffmpeg/devices", apiDevices)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetInput(src string) (string, error) {
|
func GetInput(src string) string {
|
||||||
i := strings.IndexByte(src, '?')
|
query, err := url.ParseQuery(src)
|
||||||
if i < 0 {
|
|
||||||
return "", errors.New("empty query: " + src)
|
|
||||||
}
|
|
||||||
|
|
||||||
query, err := url.ParseQuery(src[i+1:])
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
runonce.Do(initDevices)
|
runonce.Do(initDevices)
|
||||||
|
|
||||||
if input := queryToInput(query); input != "" {
|
return queryToInput(query)
|
||||||
return input, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return "", errors.New("wrong query: " + src)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var Bin string
|
var Bin string
|
||||||
|
@@ -189,21 +189,21 @@ func parseArgs(s string) *ffmpeg.Args {
|
|||||||
s += "?video&audio"
|
s += "?video&audio"
|
||||||
}
|
}
|
||||||
args.Input = inputTemplate("rtsp", s, query)
|
args.Input = inputTemplate("rtsp", s, query)
|
||||||
} else if strings.HasPrefix(s, "device?") {
|
} else if i = strings.Index(s, "?"); i > 0 {
|
||||||
var err error
|
switch s[:i] {
|
||||||
args.Input, err = device.GetInput(s)
|
case "device":
|
||||||
if err != nil {
|
args.Input = device.GetInput(s[i+1:])
|
||||||
return nil
|
case "virtual":
|
||||||
}
|
args.Input = virtual.GetInput(s[i+1:])
|
||||||
} else if strings.HasPrefix(s, "virtual?") {
|
|
||||||
var err error
|
|
||||||
if args.Input, err = virtual.GetInput(s[8:]); err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
args.Input = inputTemplate("file", s, query)
|
args.Input = inputTemplate("file", s, query)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if args.Input == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
if query["async"] != nil {
|
if query["async"] != nil {
|
||||||
args.Input = "-use_wallclock_as_timestamps 1 -async 1 " + args.Input
|
args.Input = "-use_wallclock_as_timestamps 1 -async 1 " + args.Input
|
||||||
}
|
}
|
||||||
|
@@ -4,56 +4,59 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetInput(src string) (string, error) {
|
func GetInput(src string) string {
|
||||||
query, err := url.ParseQuery(src)
|
query, err := url.ParseQuery(src)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// set defaults (using Add instead of Set)
|
input := "-re"
|
||||||
query.Add("video", "testsrc")
|
|
||||||
query.Add("size", "1920x1080")
|
|
||||||
query.Add("decimals", "2")
|
|
||||||
|
|
||||||
// https://ffmpeg.org/ffmpeg-filters.html
|
for _, video := range query["video"] {
|
||||||
video := query.Get("video")
|
// https://ffmpeg.org/ffmpeg-filters.html
|
||||||
input := "-re -f lavfi -i " + video
|
sep := "=" // first separator
|
||||||
|
|
||||||
sep := "=" // first separator
|
if video == "" {
|
||||||
for key, values := range query {
|
video = "testsrc=decimals=2" // default video
|
||||||
value := values[0]
|
sep = ":"
|
||||||
|
|
||||||
// https://ffmpeg.org/ffmpeg-utils.html#video-size-syntax
|
|
||||||
switch key {
|
|
||||||
case "color", "rate", "duration", "sar":
|
|
||||||
case "size":
|
|
||||||
switch value {
|
|
||||||
case "720":
|
|
||||||
value = "1280x720" // crf=1 -> 12 Mbps
|
|
||||||
case "1080":
|
|
||||||
value = "1920x1080" // crf=1 -> 25 Mbps
|
|
||||||
case "2K":
|
|
||||||
value = "2560x1440" // crf=1 -> 43 Mbps
|
|
||||||
case "4K":
|
|
||||||
value = "3840x2160" // crf=1 -> 103 Mbps
|
|
||||||
case "8K":
|
|
||||||
value = "7680x4230" // https://reolink.com/blog/8k-resolution/
|
|
||||||
}
|
|
||||||
case "decimals":
|
|
||||||
if video != "testsrc" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
|
|
||||||
input += sep + key + "=" + value
|
input += " -f lavfi -i " + video
|
||||||
sep = ":" // next separator
|
|
||||||
|
// set defaults (using Add instead of Set)
|
||||||
|
query.Add("size", "1920x1080")
|
||||||
|
|
||||||
|
for key, values := range query {
|
||||||
|
value := values[0]
|
||||||
|
|
||||||
|
// https://ffmpeg.org/ffmpeg-utils.html#video-size-syntax
|
||||||
|
switch key {
|
||||||
|
case "color", "rate", "duration", "sar", "decimals":
|
||||||
|
case "size":
|
||||||
|
switch value {
|
||||||
|
case "720":
|
||||||
|
value = "1280x720" // crf=1 -> 12 Mbps
|
||||||
|
case "1080":
|
||||||
|
value = "1920x1080" // crf=1 -> 25 Mbps
|
||||||
|
case "2K":
|
||||||
|
value = "2560x1440" // crf=1 -> 43 Mbps
|
||||||
|
case "4K":
|
||||||
|
value = "3840x2160" // crf=1 -> 103 Mbps
|
||||||
|
case "8K":
|
||||||
|
value = "7680x4230" // https://reolink.com/blog/8k-resolution/
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
input += sep + key + "=" + value
|
||||||
|
sep = ":" // next separator
|
||||||
|
}
|
||||||
|
|
||||||
|
if s := query.Get("format"); s != "" {
|
||||||
|
input += ",format=" + s
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if s := query.Get("format"); s != "" {
|
return input
|
||||||
input += ",format=" + s
|
|
||||||
}
|
|
||||||
|
|
||||||
return input, nil
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user