Fix new stream from camera entity from Hass
This commit is contained in:
+2
-59
@@ -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
@@ -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
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user