diff --git a/cmd/hass/api.go b/cmd/hass/api.go index 54a20c94..f5ff5572 100644 --- a/cmd/hass/api.go +++ b/cmd/hass/api.go @@ -8,7 +8,6 @@ import ( "github.com/AlexxIT/go2rtc/cmd/webrtc" "net" "net/http" - "net/url" "strings" ) @@ -25,6 +24,7 @@ func initAPI() { api.HandleFunc("/streams", ok) + // api from RTSPtoWeb api.HandleFunc("/stream/", func(w http.ResponseWriter, r *http.Request) { switch { // /stream/{id}/add @@ -40,13 +40,7 @@ func initAPI() { // 3. dynamic link to Hass camera stream := streams.Get(v.Name) if stream == nil { - // check if it is rtsp link to go2rtc - stream = rtspStream(v.Channels.First.Url) - if stream != nil { - streams.New(v.Name, stream) - } else { - stream = streams.New(v.Name, "{input}") - } + stream = streams.NewTemplate(v.Name, v.Channels.First.Url) } stream.SetSource(v.Channels.First.Url) @@ -90,48 +84,6 @@ func initAPI() { _, _ = w.Write([]byte(s)) } }) - - // api from RTSPtoWebRTC - api.HandleFunc("/stream", func(w http.ResponseWriter, r *http.Request) { - if err := r.ParseForm(); err != nil { - return - } - - str := r.FormValue("sdp64") - offer, err := base64.StdEncoding.DecodeString(str) - if err != nil { - return - } - - src := r.FormValue("url") - src, err = url.QueryUnescape(src) - if err != nil { - return - } - - stream := streams.Get(src) - if stream == nil { - if stream = rtspStream(src); stream != nil { - streams.New(src, stream) - } else { - stream = streams.New(src, src) - } - } - - str, err = webrtc.ExchangeSDP(stream, string(offer), "WebRTC/Hass sync", r.UserAgent()) - if err != nil { - return - } - - v := struct { - Answer string `json:"sdp64"` - }{ - Answer: base64.StdEncoding.EncodeToString([]byte(str)), - } - - w.Header().Set("Content-Type", "application/json") - _ = json.NewEncoder(w).Encode(v) - }) } func HassioAddr() string { @@ -153,15 +105,6 @@ func HassioAddr() string { return "" } -func rtspStream(url string) *streams.Stream { - if strings.HasPrefix(url, "rtsp://") { - if i := strings.IndexByte(url[7:], '/'); i > 0 { - return streams.Get(url[8+i:]) - } - } - return nil -} - type addJSON struct { Name string `json:"name"` Channels struct { diff --git a/cmd/streams/init.go b/cmd/streams/init.go index 8c5a454a..ca5ff58e 100644 --- a/cmd/streams/init.go +++ b/cmd/streams/init.go @@ -7,6 +7,7 @@ import ( "github.com/AlexxIT/go2rtc/cmd/app/store" "github.com/rs/zerolog" "net/http" + "net/url" ) func Init() { @@ -39,6 +40,20 @@ func New(name string, source any) *Stream { return stream } +func NewTemplate(name string, source any) *Stream { + // check if source links to some stream name from go2rtc + if rawURL, ok := source.(string); ok { + if u, err := url.Parse(rawURL); err == nil && u.Scheme == "rtsp" { + if stream, ok := streams[u.Path[1:]]; ok { + streams[name] = stream + return stream + } + } + } + + return New(name, "{input}") +} + func GetOrNew(src string) *Stream { if stream, ok := streams[src]; ok { return stream @@ -85,11 +100,12 @@ func streamsHandler(w http.ResponseWriter, r *http.Request) { return } - if stream := Get(name); stream != nil { - stream.SetSource(src) - } else { - New(name, src) + // support {input} templates: https://github.com/AlexxIT/go2rtc#module-hass + stream := Get(name) + if stream == nil { + stream = NewTemplate(name, src) } + stream.SetSource(src) case "POST": // with dst - redirect source to dst diff --git a/cmd/streams/stream.go b/cmd/streams/stream.go index 52997a24..2300b53e 100644 --- a/cmd/streams/stream.go +++ b/cmd/streams/stream.go @@ -31,8 +31,6 @@ func NewStream(source any) *Stream { s.producers = append(s.producers, prod) } return s - case *Stream: - return source case map[string]any: return NewStream(source["url"]) case nil: diff --git a/cmd/streams/stream_test.go b/cmd/streams/stream_test.go new file mode 100644 index 00000000..86dc92c2 --- /dev/null +++ b/cmd/streams/stream_test.go @@ -0,0 +1,19 @@ +package streams + +import ( + "github.com/stretchr/testify/require" + "testing" +) + +func TestTemplate(t *testing.T) { + source1 := "does not matter" + + stream1 := New("from_yaml", source1) + require.Len(t, streams, 1) + + stream2 := NewTemplate("camera.from_hass", "rtsp://localhost:8554/from_yaml?video") + + require.Equal(t, stream1, stream2) + require.Equal(t, stream2.producers[0].url, source1) + require.Len(t, streams, 2) +}