Rewrite stream info API

This commit is contained in:
Alexey Khit
2023-01-15 23:51:20 +03:00
parent bc4e032830
commit dcb457235c
25 changed files with 232 additions and 162 deletions
-31
View File
@@ -3,7 +3,6 @@ package api
import (
"encoding/json"
"github.com/AlexxIT/go2rtc/cmd/app"
"github.com/AlexxIT/go2rtc/cmd/streams"
"github.com/rs/zerolog"
"net"
"net/http"
@@ -41,7 +40,6 @@ func Init() {
HandleFunc("api", apiHandler)
HandleFunc("api/config", configHandler)
HandleFunc("api/exit", exitHandler)
HandleFunc("api/streams", streamsHandler)
HandleFunc("api/ws", apiWS)
// ensure we can listen without errors
@@ -124,32 +122,3 @@ func exitHandler(w http.ResponseWriter, r *http.Request) {
code, _ := strconv.Atoi(s)
os.Exit(code)
}
func streamsHandler(w http.ResponseWriter, r *http.Request) {
src := r.URL.Query().Get("src")
name := r.URL.Query().Get("name")
if name == "" {
name = src
}
switch r.Method {
case "PUT":
streams.New(name, src)
return
case "DELETE":
streams.Delete(src)
return
}
var v interface{}
if src != "" {
v = streams.Get(src)
} else {
v = streams.All()
}
e := json.NewEncoder(w)
e.SetIndent("", " ")
_ = e.Encode(v)
}
+12 -3
View File
@@ -27,7 +27,10 @@ func handlerKeyframe(w http.ResponseWriter, r *http.Request) {
exit := make(chan []byte)
cons := &mjpeg.Consumer{}
cons := &mjpeg.Consumer{
RemoteAddr: r.RemoteAddr,
UserAgent: r.UserAgent(),
}
cons.Listen(func(msg interface{}) {
switch msg := msg.(type) {
case []byte:
@@ -68,7 +71,10 @@ func handlerStream(w http.ResponseWriter, r *http.Request) {
flusher := w.(http.Flusher)
cons := &mjpeg.Consumer{}
cons := &mjpeg.Consumer{
RemoteAddr: r.RemoteAddr,
UserAgent: r.UserAgent(),
}
cons.Listen(func(msg interface{}) {
switch msg := msg.(type) {
case []byte:
@@ -109,7 +115,10 @@ func handlerWS(tr *api.Transport, _ *api.Message) error {
return errors.New(api.StreamNotFound)
}
cons := &mjpeg.Consumer{}
cons := &mjpeg.Consumer{
RemoteAddr: tr.Request.RemoteAddr,
UserAgent: tr.Request.UserAgent(),
}
cons.Listen(func(msg interface{}) {
if data, ok := msg.([]byte); ok {
tr.Write(data)
+4 -1
View File
@@ -80,7 +80,10 @@ func handlerMP4(w http.ResponseWriter, r *http.Request) {
exit := make(chan error)
cons := &mp4.Consumer{}
cons := &mp4.Consumer{
RemoteAddr: r.RemoteAddr,
UserAgent: r.UserAgent(),
}
cons.Listen(func(msg interface{}) {
if data, ok := msg.([]byte); ok {
if _, err := w.Write(data); err != nil && exit != nil {
+4 -1
View File
@@ -18,7 +18,10 @@ func handlerWSMSE(tr *api.Transport, msg *api.Message) error {
return errors.New(api.StreamNotFound)
}
cons := &mp4.Consumer{}
cons := &mp4.Consumer{
RemoteAddr: tr.Request.RemoteAddr,
UserAgent: tr.Request.UserAgent(),
}
cons.UserAgent = tr.Request.UserAgent()
cons.RemoteAddr = tr.Request.RemoteAddr
+15
View File
@@ -0,0 +1,15 @@
package streams
import (
"encoding/json"
"github.com/AlexxIT/go2rtc/pkg/streamer"
)
type Consumer struct {
element streamer.Consumer
tracks []*streamer.Track
}
func (c *Consumer) MarshalJSON() ([]byte, error) {
return json.Marshal(c.element)
}
+10
View File
@@ -1,6 +1,7 @@
package streams
import (
"encoding/json"
"github.com/AlexxIT/go2rtc/pkg/streamer"
"strings"
"sync"
@@ -91,6 +92,15 @@ func (p *Producer) GetTrack(media *streamer.Media, codec *streamer.Codec) *strea
return track
}
func (p *Producer) MarshalJSON() ([]byte, error) {
if p.element != nil {
return json.Marshal(p.element)
}
info := streamer.Info{URL: p.url}
return json.Marshal(info)
}
// internals
func (p *Producer) start() {
+9 -19
View File
@@ -10,11 +10,6 @@ import (
"sync/atomic"
)
type Consumer struct {
element streamer.Consumer
tracks []*streamer.Track
}
type Stream struct {
producers []*Producer
consumers []*Consumer
@@ -199,24 +194,19 @@ producers:
func (s *Stream) MarshalJSON() ([]byte, error) {
if !s.mu.TryLock() {
log.Warn().Msgf("[streams] json locked")
return []byte(`null`), nil
return json.Marshal(nil)
}
var v []interface{}
for _, prod := range s.producers {
if prod.element != nil {
v = append(v, prod.element)
}
}
for _, cons := range s.consumers {
// cons.element always not nil
v = append(v, cons.element)
var info struct {
Producers []*Producer `json:"producers"`
Consumers []*Consumer `json:"consumers"`
}
info.Producers = s.producers
info.Consumers = s.consumers
s.mu.Unlock()
if len(v) == 0 {
v = nil
}
return json.Marshal(v)
return json.Marshal(info)
}
func (s *Stream) removeConsumer(i int) {
+26 -11
View File
@@ -1,9 +1,12 @@
package streams
import (
"encoding/json"
"github.com/AlexxIT/go2rtc/cmd/api"
"github.com/AlexxIT/go2rtc/cmd/app"
"github.com/AlexxIT/go2rtc/cmd/app/store"
"github.com/rs/zerolog"
"net/http"
)
func Init() {
@@ -22,6 +25,8 @@ func Init() {
for name, item := range store.GetDict("streams") {
streams[name] = NewStream(item)
}
api.HandleFunc("api/streams", streamsHandler)
}
func Get(name string) *Stream {
@@ -48,19 +53,29 @@ func GetOrNew(src string) *Stream {
return New(src, src)
}
func Delete(name string) {
delete(streams, name)
}
func streamsHandler(w http.ResponseWriter, r *http.Request) {
src := r.URL.Query().Get("src")
func All() map[string]interface{} {
all := map[string]interface{}{}
for name, stream := range streams {
all[name] = stream
//if stream.Active() {
// all[name] = stream
//}
switch r.Method {
case "PUT":
name := r.URL.Query().Get("name")
if name == "" {
name = src
}
New(name, src)
return
case "DELETE":
delete(streams, src)
return
}
if src != "" {
e := json.NewEncoder(w)
e.SetIndent("", " ")
_ = e.Encode(streams[src])
} else {
_ = json.NewEncoder(w).Encode(streams)
}
return all
}
var log zerolog.Logger