diff --git a/internal/streams/streams.go b/internal/streams/streams.go index afc6c4d3..fc8c13c7 100644 --- a/internal/streams/streams.go +++ b/internal/streams/streams.go @@ -9,6 +9,8 @@ import ( "github.com/AlexxIT/go2rtc/internal/api" "github.com/AlexxIT/go2rtc/internal/app" + "github.com/AlexxIT/go2rtc/pkg/probe" + "github.com/AlexxIT/go2rtc/pkg/tcp" "github.com/rs/zerolog" ) @@ -148,7 +150,27 @@ func streamsHandler(w http.ResponseWriter, r *http.Request) { // Not sure about all this API. Should be rewrited... switch r.Method { case "GET": - api.ResponsePrettyJSON(w, streams[src]) + stream := Get(src) + if stream == nil { + http.Error(w, "", http.StatusNotFound) + return + } + + cons := probe.NewProbe(query) + if len(cons.Medias) != 0 { + cons.RemoteAddr = tcp.RemoteAddr(r) + cons.UserAgent = r.UserAgent() + if err := stream.AddConsumer(cons); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + api.ResponsePrettyJSON(w, stream) + + stream.RemoveConsumer(cons) + } else { + api.ResponsePrettyJSON(w, streams[src]) + } case "PUT": name := query.Get("name") diff --git a/pkg/probe/probe.go b/pkg/probe/probe.go new file mode 100644 index 00000000..bdc49bf5 --- /dev/null +++ b/pkg/probe/probe.go @@ -0,0 +1,70 @@ +package probe + +import ( + "net/url" + "strings" + + "github.com/AlexxIT/go2rtc/pkg/core" +) + +type Probe struct { + Type string `json:"type,omitempty"` + RemoteAddr string `json:"remote_addr,omitempty"` + UserAgent string `json:"user_agent,omitempty"` + Medias []*core.Media `json:"medias,omitempty"` + Receivers []*core.Receiver `json:"receivers,omitempty"` + Senders []*core.Sender `json:"senders,omitempty"` +} + +func NewProbe(query url.Values) *Probe { + c := &Probe{Type: "probe"} + c.Medias = core.ParseQuery(query) + + for _, value := range query["microphone"] { + media := &core.Media{Kind: core.KindAudio, Direction: core.DirectionRecvonly} + + for _, name := range strings.Split(value, ",") { + name = strings.ToUpper(name) + switch name { + case "", "COPY": + name = core.CodecAny + } + media.Codecs = append(media.Codecs, &core.Codec{Name: name}) + } + + c.Medias = append(c.Medias, media) + } + + return c +} + +func (p *Probe) GetMedias() []*core.Media { + return p.Medias +} + +func (p *Probe) AddTrack(media *core.Media, codec *core.Codec, track *core.Receiver) error { + sender := core.NewSender(media, codec) + sender.Bind(track) + p.Senders = append(p.Senders, sender) + return nil +} + +func (p *Probe) GetTrack(media *core.Media, codec *core.Codec) (*core.Receiver, error) { + receiver := core.NewReceiver(media, codec) + p.Receivers = append(p.Receivers, receiver) + return receiver, nil +} + +func (p *Probe) Start() error { + return nil +} + +func (p *Probe) Stop() error { + for _, receiver := range p.Receivers { + receiver.Close() + } + for _, sender := range p.Senders { + sender.Close() + } + return nil +}