From 1fc2cf31750756647e14669cc2de587ffedbaa86 Mon Sep 17 00:00:00 2001 From: Alexey Khit Date: Wed, 8 Mar 2023 17:33:00 +0300 Subject: [PATCH] Update WebRTC type in info JSON --- cmd/hass/api.go | 4 ++-- cmd/webrtc/client.go | 7 +++++++ cmd/webrtc/init.go | 7 ++++++- cmd/webrtc/server.go | 32 +++++++++++++++++++++++--------- cmd/webtorrent/init.go | 2 +- pkg/streamer/helpers.go | 23 +++++++++++++++++++++++ pkg/webrtc/conn.go | 2 ++ pkg/webrtc/consumer.go | 2 +- pkg/webtorrent/client.go | 2 ++ 9 files changed, 67 insertions(+), 14 deletions(-) diff --git a/cmd/hass/api.go b/cmd/hass/api.go index 87939d61..95d0eb7e 100644 --- a/cmd/hass/api.go +++ b/cmd/hass/api.go @@ -79,7 +79,7 @@ func initAPI() { return } - s, err = webrtc.ExchangeSDP(stream, string(offer), r.UserAgent()) + s, err = webrtc.ExchangeSDP(stream, string(offer), "WebRTC/Hass sync", r.UserAgent()) if err != nil { log.Error().Err(err).Msg("[api.hass] exchange SDP") return @@ -117,7 +117,7 @@ func initAPI() { } } - str, err = webrtc.ExchangeSDP(stream, string(offer), r.UserAgent()) + str, err = webrtc.ExchangeSDP(stream, string(offer), "WebRTC/Hass sync", r.UserAgent()) if err != nil { return } diff --git a/cmd/webrtc/client.go b/cmd/webrtc/client.go index dc7b2404..94cc6798 100644 --- a/cmd/webrtc/client.go +++ b/cmd/webrtc/client.go @@ -27,6 +27,8 @@ func streamsHandler(url string) (streamer.Producer, error) { return nil, errors.New("unsupported url: " + url) } +// asyncClient can connect only to go2rtc server +// ex: ws://localhost:1984/api/ws?src=camera1 func asyncClient(url string) (streamer.Producer, error) { // 1. Connect to signalign server ws, _, err := websocket.DefaultDialer.Dial(url, nil) @@ -49,6 +51,8 @@ func asyncClient(url string) (streamer.Producer, error) { var sendOffer core.Waiter prod := webrtc.NewConn(pc) + prod.Desc = "WebRTC/WebSocket async" + prod.Mode = streamer.ModeActiveProducer prod.Listen(func(msg any) { switch msg := msg.(type) { case pion.PeerConnectionState: @@ -123,6 +127,7 @@ func asyncClient(url string) (streamer.Producer, error) { } // syncClient - support WebRTC-HTTP Egress Protocol (WHEP) +// ex: http://localhost:1984/api/webrtc?src=camera1 func syncClient(url string) (streamer.Producer, error) { // 2. Create PeerConnection pc, err := PeerConnection(true) @@ -132,6 +137,8 @@ func syncClient(url string) (streamer.Producer, error) { } prod := webrtc.NewConn(pc) + prod.Desc = "WebRTC/WHEP sync" + prod.Mode = streamer.ModeActiveProducer medias := []*streamer.Media{ {Kind: streamer.KindVideo, Direction: streamer.DirectionRecvonly}, diff --git a/cmd/webrtc/init.go b/cmd/webrtc/init.go index 49ef761f..b0ffc5ca 100644 --- a/cmd/webrtc/init.go +++ b/cmd/webrtc/init.go @@ -6,6 +6,7 @@ import ( "github.com/AlexxIT/go2rtc/cmd/app" "github.com/AlexxIT/go2rtc/cmd/streams" "github.com/AlexxIT/go2rtc/pkg/core" + "github.com/AlexxIT/go2rtc/pkg/streamer" "github.com/AlexxIT/go2rtc/pkg/webrtc" pion "github.com/pion/webrtc/v3" "github.com/rs/zerolog" @@ -103,6 +104,8 @@ func asyncHandler(tr *api.Transport, msg *api.Message) error { var sendAnswer core.Waiter cons := webrtc.NewConn(pc) + cons.Desc = "WebRTC/WebSocket async" + cons.Mode = streamer.ModePassiveConsumer cons.UserAgent = tr.Request.UserAgent() cons.Listen(func(msg any) { switch msg := msg.(type) { @@ -168,7 +171,7 @@ func asyncHandler(tr *api.Transport, msg *api.Message) error { return nil } -func ExchangeSDP(stream *streams.Stream, offer string, userAgent string) (answer string, err error) { +func ExchangeSDP(stream *streams.Stream, offer, desc, userAgent string) (answer string, err error) { pc, err := PeerConnection(false) if err != nil { log.Error().Err(err).Caller().Send() @@ -177,6 +180,8 @@ func ExchangeSDP(stream *streams.Stream, offer string, userAgent string) (answer // create new webrtc instance conn := webrtc.NewConn(pc) + conn.Desc = desc + conn.Mode = streamer.ModePassiveConsumer conn.UserAgent = userAgent conn.Listen(func(msg interface{}) { switch msg := msg.(type) { diff --git a/cmd/webrtc/server.go b/cmd/webrtc/server.go index a27e7a23..2f189a8b 100644 --- a/cmd/webrtc/server.go +++ b/cmd/webrtc/server.go @@ -3,6 +3,7 @@ package webrtc import ( "encoding/json" "github.com/AlexxIT/go2rtc/cmd/streams" + "github.com/AlexxIT/go2rtc/pkg/streamer" "github.com/AlexxIT/go2rtc/pkg/webrtc" pion "github.com/pion/webrtc/v3" "io" @@ -90,7 +91,18 @@ func outputWebRTC(w http.ResponseWriter, r *http.Request) { offer = string(body) } - answer, err := ExchangeSDP(stream, offer, r.UserAgent()) + var desc string + + switch mediaType { + case "application/json": + desc = "WebRTC/JSON sync" + case MimeSDP: + desc = "WebRTC/WHEP sync" + default: + desc = "WebRTC/HTTP sync" + } + + answer, err := ExchangeSDP(stream, offer, desc, r.UserAgent()) if err != nil { log.Error().Err(err).Caller().Send() http.Error(w, err.Error(), http.StatusInternalServerError) @@ -147,16 +159,18 @@ func inputWebRTC(w http.ResponseWriter, r *http.Request) { } // create new webrtc instance - conn := webrtc.NewConn(pc) - conn.UserAgent = r.UserAgent() + prod := webrtc.NewConn(pc) + prod.Desc = "WebRTC/WHIP sync" + prod.Mode = streamer.ModePassiveProducer + prod.UserAgent = r.UserAgent() - if err = conn.SetOffer(string(offer)); err != nil { + if err = prod.SetOffer(string(offer)); err != nil { log.Warn().Err(err).Caller().Send() http.Error(w, err.Error(), http.StatusInternalServerError) return } - answer, err := conn.GetCompleteAnswer() + answer, err := prod.GetCompleteAnswer() if err == nil { answer, err = syncCanditates(answer) } @@ -169,13 +183,13 @@ func inputWebRTC(w http.ResponseWriter, r *http.Request) { log.Trace().Msgf("[webrtc] WHIP answer\n%s", answer) id := strconv.FormatInt(time.Now().UnixNano(), 36) - sessions[id] = conn + sessions[id] = prod - conn.Listen(func(msg interface{}) { + prod.Listen(func(msg interface{}) { switch msg := msg.(type) { case pion.PeerConnectionState: if msg == pion.PeerConnectionStateClosed { - stream.RemoveProducer(conn) + stream.RemoveProducer(prod) if _, ok := sessions[id]; ok { delete(sessions, id) } @@ -183,7 +197,7 @@ func inputWebRTC(w http.ResponseWriter, r *http.Request) { } }) - stream.AddProducer(conn) + stream.AddProducer(prod) w.Header().Set("Content-Type", MimeSDP) w.Header().Set("Location", "webrtc?id="+id) diff --git a/cmd/webtorrent/init.go b/cmd/webtorrent/init.go index 3872e89c..4dc223aa 100644 --- a/cmd/webtorrent/init.go +++ b/cmd/webtorrent/init.go @@ -47,7 +47,7 @@ func Init() { if stream == nil { return "", errors.New(api.StreamNotFound) } - return webrtc.ExchangeSDP(stream, offer, "webtorrent") + return webrtc.ExchangeSDP(stream, offer, "WebRTC/WebTorrent sync", "") }, } diff --git a/pkg/streamer/helpers.go b/pkg/streamer/helpers.go index 10688a70..e674f0af 100644 --- a/pkg/streamer/helpers.go +++ b/pkg/streamer/helpers.go @@ -5,6 +5,29 @@ import ( "time" ) +type Mode byte + +const ( + ModeActiveProducer Mode = iota + 1 // typical source (client) + ModePassiveConsumer + ModePassiveProducer + ModeActiveConsumer +) + +func (m Mode) String() string { + switch m { + case ModeActiveProducer: + return "active producer" + case ModePassiveConsumer: + return "passive consumer" + case ModePassiveProducer: + return "passive producer" + case ModeActiveConsumer: + return "active consumer" + } + return "unknown" +} + type Info struct { Type string `json:"type,omitempty"` URL string `json:"url,omitempty"` diff --git a/pkg/webrtc/conn.go b/pkg/webrtc/conn.go index dc9360ca..ea76b25d 100644 --- a/pkg/webrtc/conn.go +++ b/pkg/webrtc/conn.go @@ -10,6 +10,8 @@ type Conn struct { streamer.Element UserAgent string + Desc string + Mode streamer.Mode pc *webrtc.PeerConnection diff --git a/pkg/webrtc/consumer.go b/pkg/webrtc/consumer.go index 9e73bf50..f4d12b77 100644 --- a/pkg/webrtc/consumer.go +++ b/pkg/webrtc/consumer.go @@ -113,7 +113,7 @@ func (c *Conn) AddTrack(media *streamer.Media, track *streamer.Track) *streamer. func (c *Conn) MarshalJSON() ([]byte, error) { info := &streamer.Info{ - Type: "WebRTC", + Type: c.Desc + " " + c.Mode.String(), RemoteAddr: c.remote, UserAgent: c.UserAgent, Medias: c.medias, diff --git a/pkg/webtorrent/client.go b/pkg/webtorrent/client.go index 0142d50e..fb8a20c6 100644 --- a/pkg/webtorrent/client.go +++ b/pkg/webtorrent/client.go @@ -15,6 +15,8 @@ import ( func NewClient(tracker, share, pwd string, pc *pion.PeerConnection) (*webrtc.Conn, error) { // 1. Create WebRTC producer prod := webrtc.NewConn(pc) + prod.Desc = "WebRTC/WebTorrent sync" + prod.Mode = streamer.ModeActiveProducer medias := []*streamer.Media{ {Kind: streamer.KindVideo, Direction: streamer.DirectionRecvonly},