mirror of
https://github.com/AlexxIT/go2rtc.git
synced 2025-10-08 17:50:15 +08:00
Move ffmpeg device to separate module
This commit is contained in:
@@ -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
|
@@ -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())
|
||||||
|
if media != nil {
|
||||||
medias = append(medias, media)
|
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,
|
||||||
}
|
}
|
@@ -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
|
@@ -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()
|
||||||
}
|
}
|
@@ -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, "#") {
|
||||||
|
Reference in New Issue
Block a user