Fix new stream from camera entity from Hass

This commit is contained in:
Alexey Khit
2023-04-15 07:34:38 +03:00
parent 7d3fbf2ee0
commit d633d331bb
4 changed files with 41 additions and 65 deletions
+2 -59
View File
@@ -8,7 +8,6 @@ import (
"github.com/AlexxIT/go2rtc/cmd/webrtc" "github.com/AlexxIT/go2rtc/cmd/webrtc"
"net" "net"
"net/http" "net/http"
"net/url"
"strings" "strings"
) )
@@ -25,6 +24,7 @@ func initAPI() {
api.HandleFunc("/streams", ok) api.HandleFunc("/streams", ok)
// api from RTSPtoWeb
api.HandleFunc("/stream/", func(w http.ResponseWriter, r *http.Request) { api.HandleFunc("/stream/", func(w http.ResponseWriter, r *http.Request) {
switch { switch {
// /stream/{id}/add // /stream/{id}/add
@@ -40,13 +40,7 @@ func initAPI() {
// 3. dynamic link to Hass camera // 3. dynamic link to Hass camera
stream := streams.Get(v.Name) stream := streams.Get(v.Name)
if stream == nil { if stream == nil {
// check if it is rtsp link to go2rtc stream = streams.NewTemplate(v.Name, v.Channels.First.Url)
stream = rtspStream(v.Channels.First.Url)
if stream != nil {
streams.New(v.Name, stream)
} else {
stream = streams.New(v.Name, "{input}")
}
} }
stream.SetSource(v.Channels.First.Url) stream.SetSource(v.Channels.First.Url)
@@ -90,48 +84,6 @@ func initAPI() {
_, _ = w.Write([]byte(s)) _, _ = 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 { func HassioAddr() string {
@@ -153,15 +105,6 @@ func HassioAddr() string {
return "" 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 { type addJSON struct {
Name string `json:"name"` Name string `json:"name"`
Channels struct { Channels struct {
+20 -4
View File
@@ -7,6 +7,7 @@ import (
"github.com/AlexxIT/go2rtc/cmd/app/store" "github.com/AlexxIT/go2rtc/cmd/app/store"
"github.com/rs/zerolog" "github.com/rs/zerolog"
"net/http" "net/http"
"net/url"
) )
func Init() { func Init() {
@@ -39,6 +40,20 @@ func New(name string, source any) *Stream {
return 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 { func GetOrNew(src string) *Stream {
if stream, ok := streams[src]; ok { if stream, ok := streams[src]; ok {
return stream return stream
@@ -85,11 +100,12 @@ func streamsHandler(w http.ResponseWriter, r *http.Request) {
return return
} }
if stream := Get(name); stream != nil { // support {input} templates: https://github.com/AlexxIT/go2rtc#module-hass
stream.SetSource(src) stream := Get(name)
} else { if stream == nil {
New(name, src) stream = NewTemplate(name, src)
} }
stream.SetSource(src)
case "POST": case "POST":
// with dst - redirect source to dst // with dst - redirect source to dst
-2
View File
@@ -31,8 +31,6 @@ func NewStream(source any) *Stream {
s.producers = append(s.producers, prod) s.producers = append(s.producers, prod)
} }
return s return s
case *Stream:
return source
case map[string]any: case map[string]any:
return NewStream(source["url"]) return NewStream(source["url"])
case nil: case nil:
+19
View File
@@ -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)
}