Move ffmpeg device to separate module

This commit is contained in:
Alexey Khit
2022-08-28 06:29:16 +03:00
parent 38a18cab62
commit 1654ac8c82
5 changed files with 62 additions and 30 deletions

View File

@@ -1,4 +1,4 @@
package ffmpeg package device
import ( import (
"bytes" "bytes"
@@ -26,7 +26,7 @@ func deviceInputSuffix(videoIdx, audioIdx int) string {
func loadMedias() { func loadMedias() {
cmd := exec.Command( cmd := exec.Command(
tpl["bin"], "-hide_banner", "-list_devices", "true", "-f", "avfoundation", "-i", "dummy", Bin, "-hide_banner", "-list_devices", "true", "-f", "avfoundation", "-i", "dummy",
) )
var buf bytes.Buffer var buf bytes.Buffer

View File

@@ -1,9 +1,10 @@
package ffmpeg package device
import ( import (
"bytes"
"github.com/AlexxIT/go2rtc/pkg/streamer" "github.com/AlexxIT/go2rtc/pkg/streamer"
"github.com/rs/zerolog/log"
"io/ioutil" "io/ioutil"
"os/exec"
"strings" "strings"
) )
@@ -24,12 +25,25 @@ func loadMedias() {
log.Trace().Msg("[ffmpeg] " + file.Name()) log.Trace().Msg("[ffmpeg] " + file.Name())
if strings.HasPrefix(file.Name(), streamer.KindVideo) { if strings.HasPrefix(file.Name(), streamer.KindVideo) {
media := loadMedia(streamer.KindVideo, "/dev/"+file.Name()) media := loadMedia(streamer.KindVideo, "/dev/"+file.Name())
medias = append(medias, media) if media != nil {
medias = append(medias, media)
}
} }
} }
} }
func loadMedia(kind, name string) *streamer.Media { func loadMedia(kind, name string) *streamer.Media {
cmd := exec.Command(
Bin, "-hide_banner", "-f", "v4l2", "-list_formats", "all", "-i", name,
)
var buf bytes.Buffer
cmd.Stderr = &buf
_ = cmd.Run()
if !bytes.Contains(buf.Bytes(), []byte("Raw")) {
return nil
}
return &streamer.Media{ return &streamer.Media{
Kind: kind, Title: name, Kind: kind, Title: name,
} }

View File

@@ -1,4 +1,4 @@
package ffmpeg package device
import ( import (
"bytes" "bytes"
@@ -26,7 +26,7 @@ func deviceInputSuffix(videoIdx, audioIdx int) string {
func loadMedias() { func loadMedias() {
cmd := exec.Command( cmd := exec.Command(
tpl["bin"], "-hide_banner", "-list_devices", "true", "-f", "dshow", "-i", "", Bin, "-hide_banner", "-list_devices", "true", "-f", "dshow", "-i", "",
) )
var buf bytes.Buffer var buf bytes.Buffer

View File

@@ -1,16 +1,24 @@
package ffmpeg package device
import ( import (
"encoding/json" "encoding/json"
"github.com/AlexxIT/go2rtc/cmd/api"
"github.com/AlexxIT/go2rtc/cmd/app"
"github.com/AlexxIT/go2rtc/pkg/streamer" "github.com/AlexxIT/go2rtc/pkg/streamer"
"github.com/rs/zerolog/log" "github.com/rs/zerolog"
"net/http" "net/http"
"net/url" "net/url"
"strconv" "strconv"
"strings" "strings"
) )
func getDevice(src string) (string, error) { func Init() {
log = app.GetLogger("exec")
api.HandleFunc("/api/devices", handle)
}
func GetInput(src string) (string, error) {
if medias == nil { if medias == nil {
loadMedias() loadMedias()
} }
@@ -42,6 +50,8 @@ func getDevice(src string) (string, error) {
return input, nil return input, nil
} }
var Bin string
var log zerolog.Logger
var medias []*streamer.Media var medias []*streamer.Media
func findMedia(kind string, index int) *streamer.Media { func findMedia(kind string, index int) *streamer.Media {
@@ -57,7 +67,7 @@ func findMedia(kind string, index int) *streamer.Media {
return nil return nil
} }
func handleDevices(w http.ResponseWriter, r *http.Request) { func handle(w http.ResponseWriter, r *http.Request) {
if medias == nil { if medias == nil {
loadMedias() loadMedias()
} }

View File

@@ -1,9 +1,9 @@
package ffmpeg package ffmpeg
import ( import (
"github.com/AlexxIT/go2rtc/cmd/api"
"github.com/AlexxIT/go2rtc/cmd/app" "github.com/AlexxIT/go2rtc/cmd/app"
"github.com/AlexxIT/go2rtc/cmd/exec" "github.com/AlexxIT/go2rtc/cmd/exec"
"github.com/AlexxIT/go2rtc/cmd/ffmpeg/device"
"github.com/AlexxIT/go2rtc/cmd/streams" "github.com/AlexxIT/go2rtc/cmd/streams"
"github.com/AlexxIT/go2rtc/pkg/streamer" "github.com/AlexxIT/go2rtc/pkg/streamer"
"net/url" "net/url"
@@ -21,9 +21,9 @@ func Init() {
"bin": "ffmpeg", "bin": "ffmpeg",
// inputs // inputs
"link": "-i {input}",
"rtsp": "-fflags nobuffer -flags low_delay -rtsp_transport tcp -i {input}",
"file": "-re -stream_loop -1 -i {input}", "file": "-re -stream_loop -1 -i {input}",
"http": "-i {input}",
"rtsp": "-fflags nobuffer -flags low_delay -rtsp_transport tcp -i {input}",
// output // output
"out": "-rtsp_transport tcp -f rtsp {output}", "out": "-rtsp_transport tcp -f rtsp {output}",
@@ -49,7 +49,7 @@ func Init() {
app.LoadConfig(&cfg) app.LoadConfig(&cfg)
tpl = cfg.Mod tpl := cfg.Mod
streams.HandleFunc("ffmpeg", func(s string) (streamer.Producer, error) { streams.HandleFunc("ffmpeg", func(s string) (streamer.Producer, error) {
s = s[7:] // remove `ffmpeg:` s = s[7:] // remove `ffmpeg:`
@@ -60,20 +60,29 @@ func Init() {
s = s[:i] s = s[:i]
} }
var template string var input string
switch { if i := strings.IndexByte(s, ':'); i > 0 {
case strings.HasPrefix(s, "rtsp"): switch s[:i] {
template = tpl["rtsp"] case "http", "https":
case strings.HasPrefix(s, "device"): input = strings.Replace(tpl["http"], "{input}", s, 1)
template, _ = getDevice(s) case "rtsp", "rtsps":
case strings.Contains(s, "://"): input = strings.Replace(tpl["rtsp"], "{input}", s, 1)
template = tpl["link"] }
default:
template = tpl["file"]
} }
s = "exec:" + tpl["bin"] + " -hide_banner " + if input == "" {
strings.Replace(template, "{input}", s, 1) if strings.HasPrefix(s, "device?") {
var err error
input, err = device.GetInput(s)
if err != nil {
return nil, err
}
} else {
input = strings.Replace(tpl["file"], "{input}", s, 1)
}
}
s = "exec:" + tpl["bin"] + " -hide_banner " + input
if query != nil { if query != nil {
for _, raw := range query["raw"] { for _, raw := range query["raw"] {
@@ -114,11 +123,10 @@ func Init() {
return exec.Handle(s) return exec.Handle(s)
}) })
api.HandleFunc("/api/devices", handleDevices) device.Bin = cfg.Mod["bin"]
device.Init()
} }
var tpl map[string]string
func parseQuery(s string) map[string][]string { func parseQuery(s string) map[string][]string {
query := map[string][]string{} query := map[string][]string{}
for _, key := range strings.Split(s, "#") { for _, key := range strings.Split(s, "#") {