Initial commit, pt. 45

This commit is contained in:
Dmitrii Okunev
2024-07-15 02:27:16 +01:00
parent 806fb12032
commit a37fa68e10
7 changed files with 153 additions and 49 deletions

View File

@@ -126,7 +126,7 @@ func main() {
cfg, cfg,
_ui, _ui,
func(ctx context.Context, c config.Config) error { func(ctx context.Context, c config.Config) error {
return config.WriteConfigToPath(ctx, configPathExpanded, cfg) return config.WriteConfigToPath(ctx, configPathExpanded, c)
}, },
belt.CtxBelt(ctx), belt.CtxBelt(ctx),
) )

View File

@@ -748,7 +748,7 @@ func (d *StreamD) StartStreamServer(
return fmt.Errorf("unable to start stream server: %w", err) return fmt.Errorf("unable to start stream server: %w", err)
} }
d.Config.StreamServer = d.StreamServer.Config logger.Tracef(ctx, "new StreamServer.Servers config == %#+v", d.Config.StreamServer.Servers)
err = d.SaveConfig(ctx) err = d.SaveConfig(ctx)
if err != nil { if err != nil {
return fmt.Errorf("unable to save config: %w", err) return fmt.Errorf("unable to save config: %w", err)
@@ -789,7 +789,6 @@ func (d *StreamD) StopStreamServer(
return fmt.Errorf("unable to stop server %#+v: %w", *srv, err) return fmt.Errorf("unable to stop server %#+v: %w", *srv, err)
} }
d.Config.StreamServer = d.StreamServer.Config
err = d.SaveConfig(ctx) err = d.SaveConfig(ctx)
if err != nil { if err != nil {
return fmt.Errorf("unable to save the config: %w", err) return fmt.Errorf("unable to save the config: %w", err)
@@ -859,7 +858,6 @@ func (d *StreamD) AddStreamDestination(
return fmt.Errorf("unable to add stream destination server: %w", err) return fmt.Errorf("unable to add stream destination server: %w", err)
} }
d.Config.StreamServer = d.StreamServer.Config
err = d.SaveConfig(ctx) err = d.SaveConfig(ctx)
if err != nil { if err != nil {
return fmt.Errorf("unable to save the config: %w", err) return fmt.Errorf("unable to save the config: %w", err)
@@ -883,7 +881,6 @@ func (d *StreamD) RemoveStreamDestination(
return fmt.Errorf("unable to remove stream destination server: %w", err) return fmt.Errorf("unable to remove stream destination server: %w", err)
} }
d.Config.StreamServer = d.StreamServer.Config
err = d.SaveConfig(ctx) err = d.SaveConfig(ctx)
if err != nil { if err != nil {
return fmt.Errorf("unable to save the config: %w", err) return fmt.Errorf("unable to save the config: %w", err)
@@ -941,7 +938,6 @@ func (d *StreamD) AddStreamForward(
return fmt.Errorf("unable to add the stream forwarding: %w", err) return fmt.Errorf("unable to add the stream forwarding: %w", err)
} }
d.Config.StreamServer = d.StreamServer.Config
err = d.SaveConfig(ctx) err = d.SaveConfig(ctx)
if err != nil { if err != nil {
return fmt.Errorf("unable to save the config: %w", err) return fmt.Errorf("unable to save the config: %w", err)
@@ -970,7 +966,6 @@ func (d *StreamD) RemoveStreamForward(
return fmt.Errorf("unable to remove the stream forwarding: %w", err) return fmt.Errorf("unable to remove the stream forwarding: %w", err)
} }
d.Config.StreamServer = d.StreamServer.Config
err = d.SaveConfig(ctx) err = d.SaveConfig(ctx)
if err != nil { if err != nil {
return fmt.Errorf("unable to save the config: %w", err) return fmt.Errorf("unable to save the config: %w", err)

View File

@@ -160,10 +160,22 @@ func (p *Panel) displayStreamServers(
logger.Debugf(ctx, "displayStreamServers") logger.Debugf(ctx, "displayStreamServers")
defer logger.Debugf(ctx, "/displayStreamServers") defer logger.Debugf(ctx, "/displayStreamServers")
for _, srv := range streamServers { c := widget.NewList(
_ = srv func() int {
} return len(streamServers)
},
func() fyne.CanvasObject {
return widget.NewLabel("")
},
func(idx widget.ListItemID, co fyne.CanvasObject) {
o := co.(*widget.Label)
srv := streamServers[idx]
o.SetText(fmt.Sprintf("%s://%s", srv.Type, srv.ListenAddr))
},
)
p.streamServersWidget.RemoveAll()
p.streamServersWidget.Add(c)
} }
func (p *Panel) openAddStreamWindow() {} func (p *Panel) openAddStreamWindow() {}

View File

@@ -58,7 +58,7 @@ func New(
err := ln.Close() err := ln.Close()
errmon.ObserveErrorCtx(ctx, err) errmon.ObserveErrorCtx(ctx, err)
}() }()
logger.Infof(ctx, "started RTMP server at %d", cfg.Listen) logger.Infof(ctx, "started RTMP server at %s", cfg.Listen)
go func() { go func() {
for { for {

View File

@@ -72,7 +72,7 @@ func New(
err := ln.Close() err := ln.Close()
errmon.ObserveErrorCtx(ctx, err) errmon.ObserveErrorCtx(ctx, err)
}() }()
logger.Infof(ctx, "started RTSP server at %d", cfg.ListenAddr) logger.Infof(ctx, "started RTSP server at %s", cfg.ListenAddr)
go func() { go func() {
for { for {

View File

@@ -13,7 +13,7 @@ import (
type StreamServer struct { type StreamServer struct {
sync.Mutex sync.Mutex
Config types.Config Config *types.Config
StreamHandler *streams.StreamHandler StreamHandler *streams.StreamHandler
ServerHandlers []types.ServerHandler ServerHandlers []types.ServerHandler
StreamDestinations []types.StreamDestination StreamDestinations []types.StreamDestination
@@ -23,6 +23,12 @@ func New(cfg *types.Config) *StreamServer {
if cfg == nil { if cfg == nil {
cfg = &types.Config{} cfg = &types.Config{}
} }
if cfg.Streams == nil {
cfg.Streams = map[types.StreamID]*types.StreamConfig{}
}
if cfg.Destinations == nil {
cfg.Destinations = map[types.DestinationID]*types.DestinationConfig{}
}
s := streams.NewStreamHandler() s := streams.NewStreamHandler()
s.HandleFunc("rtmp", rtmpserver.StreamsHandle) s.HandleFunc("rtmp", rtmpserver.StreamsHandle)
@@ -37,35 +43,38 @@ func New(cfg *types.Config) *StreamServer {
return &StreamServer{ return &StreamServer{
StreamHandler: s, StreamHandler: s,
Config: *cfg, Config: cfg,
} }
} }
func (s *StreamServer) Init(ctx context.Context) error { func (s *StreamServer) Init(ctx context.Context) error {
s.Lock()
defer s.Unlock()
cfg := s.Config cfg := s.Config
for _, srv := range cfg.Servers { for _, srv := range cfg.Servers {
err := s.StartServer(ctx, srv.Type, srv.Listen) err := s.startServer(ctx, srv.Type, srv.Listen)
if err != nil { if err != nil {
return fmt.Errorf("unable to initialize %s server at %s: %w", srv.Type, srv.Listen, err) return fmt.Errorf("unable to initialize %s server at %s: %w", srv.Type, srv.Listen, err)
} }
} }
for dstID, dstCfg := range cfg.Destinations { for dstID, dstCfg := range cfg.Destinations {
err := s.AddStreamDestination(ctx, dstID, dstCfg.URL) err := s.addStreamDestination(ctx, dstID, dstCfg.URL)
if err != nil { if err != nil {
return fmt.Errorf("unable to initialize stream destination '%s' to %#+v: %w", dstID, dstCfg, err) return fmt.Errorf("unable to initialize stream destination '%s' to %#+v: %w", dstID, dstCfg, err)
} }
} }
for streamID, streamCfg := range cfg.Streams { for streamID, streamCfg := range cfg.Streams {
err := s.AddIncomingStream(ctx, streamID) err := s.addIncomingStream(ctx, streamID)
if err != nil { if err != nil {
return fmt.Errorf("unable to initialize stream '%s': %w", streamID, err) return fmt.Errorf("unable to initialize stream '%s': %w", streamID, err)
} }
for _, fwd := range streamCfg.Forwardings { for _, fwd := range streamCfg.Forwardings {
err := s.AddStreamForward(ctx, streamID, fwd) err := s.addStreamForward(ctx, streamID, fwd)
if err != nil { if err != nil {
return fmt.Errorf("unable to launch stream forward from '%s' to '%s': %w", streamID, fwd, err) return fmt.Errorf("unable to launch stream forward from '%s' to '%s': %w", streamID, fwd, err)
} }
@@ -89,6 +98,24 @@ func (s *StreamServer) StartServer(
ctx context.Context, ctx context.Context,
serverType types.ServerType, serverType types.ServerType,
listenAddr string, listenAddr string,
) error {
s.Lock()
defer s.Unlock()
err := s.startServer(ctx, serverType, listenAddr)
if err != nil {
return err
}
s.Config.Servers = append(s.Config.Servers, types.Server{
Type: serverType,
Listen: listenAddr,
})
return nil
}
func (s *StreamServer) startServer(
ctx context.Context,
serverType types.ServerType,
listenAddr string,
) error { ) error {
var srv types.ServerHandler var srv types.ServerHandler
var err error var err error
@@ -108,13 +135,7 @@ func (s *StreamServer) StartServer(
return err return err
} }
s.Lock()
defer s.Unlock()
s.ServerHandlers = append(s.ServerHandlers, srv) s.ServerHandlers = append(s.ServerHandlers, srv)
s.Config.Servers = append(s.Config.Servers, types.Server{
Type: serverType,
Listen: listenAddr,
})
return nil return nil
} }
@@ -136,6 +157,12 @@ func (s *StreamServer) StopServer(
) error { ) error {
s.Lock() s.Lock()
defer s.Unlock() defer s.Unlock()
for idx, srv := range s.Config.Servers {
if srv.Listen == server.ListenAddr() {
s.Config.Servers = append(s.Config.Servers[:idx], s.Config.Servers[idx+1:]...)
break
}
}
return s.stopServer(ctx, server) return s.stopServer(ctx, server)
} }
@@ -143,13 +170,6 @@ func (s *StreamServer) stopServer(
ctx context.Context, ctx context.Context,
server types.ServerHandler, server types.ServerHandler,
) error { ) error {
for idx, srv := range s.Config.Servers {
if srv.Listen == server.ListenAddr() {
s.Config.Servers = append(s.Config.Servers[:idx], s.Config.Servers[idx+1:]...)
break
}
}
idx, err := s.findServer(ctx, server) idx, err := s.findServer(ctx, server)
if err != nil { if err != nil {
return err return err
@@ -165,7 +185,12 @@ func (s *StreamServer) AddIncomingStream(
) error { ) error {
s.Lock() s.Lock()
defer s.Unlock() defer s.Unlock()
return s.addIncomingStream(ctx, streamID) err := s.addIncomingStream(ctx, streamID)
if err != nil {
return err
}
s.Config.Streams[streamID] = &types.StreamConfig{}
return nil
} }
func (s *StreamServer) addIncomingStream( func (s *StreamServer) addIncomingStream(
@@ -179,7 +204,6 @@ func (s *StreamServer) addIncomingStream(
if err != nil { if err != nil {
return fmt.Errorf("unable to create the stream '%s': %w", streamID, err) return fmt.Errorf("unable to create the stream '%s': %w", streamID, err)
} }
s.Config.Streams[streamID] = &types.StreamConfig{}
return nil return nil
} }
@@ -216,6 +240,7 @@ func (s *StreamServer) RemoveIncomingStream(
) error { ) error {
s.Lock() s.Lock()
defer s.Unlock() defer s.Unlock()
delete(s.Config.Streams, streamID)
return s.removeIncomingStream(ctx, streamID) return s.removeIncomingStream(ctx, streamID)
} }
@@ -227,7 +252,6 @@ func (s *StreamServer) removeIncomingStream(
return fmt.Errorf("stream '%s' does not exist", streamID) return fmt.Errorf("stream '%s' does not exist", streamID)
} }
s.StreamHandler.Delete(string(streamID)) s.StreamHandler.Delete(string(streamID))
delete(s.Config.Streams, streamID)
return nil return nil
} }
@@ -243,7 +267,13 @@ func (s *StreamServer) AddStreamForward(
) error { ) error {
s.Lock() s.Lock()
defer s.Unlock() defer s.Unlock()
return s.addStreamForward(ctx, streamID, destinationID) err := s.addStreamForward(ctx, streamID, destinationID)
if err != nil {
return err
}
streamConfig := s.Config.Streams[streamID]
streamConfig.Forwardings = append(streamConfig.Forwardings, destinationID)
return nil
} }
func (s *StreamServer) addStreamForward( func (s *StreamServer) addStreamForward(
@@ -263,8 +293,6 @@ func (s *StreamServer) addStreamForward(
if err != nil { if err != nil {
return fmt.Errorf("unable to start publishing '%s' to '%s': %w", streamID, dst.URL, err) return fmt.Errorf("unable to start publishing '%s' to '%s': %w", streamID, dst.URL, err)
} }
streamConfig := s.Config.Streams[streamID]
streamConfig.Forwardings = append(streamConfig.Forwardings, destinationID)
return nil return nil
} }
@@ -307,14 +335,6 @@ func (s *StreamServer) RemoveStreamForward(
) error { ) error {
s.Lock() s.Lock()
defer s.Unlock() defer s.Unlock()
return s.removeStreamForward(ctx, streamID, dstID)
}
func (s *StreamServer) removeStreamForward(
ctx context.Context,
streamID types.StreamID,
dstID types.DestinationID,
) error {
streamCfg := s.Config.Streams[streamID] streamCfg := s.Config.Streams[streamID]
for idx, _dstID := range streamCfg.Forwardings { for idx, _dstID := range streamCfg.Forwardings {
if _dstID != dstID { if _dstID != dstID {
@@ -323,7 +343,14 @@ func (s *StreamServer) removeStreamForward(
streamCfg.Forwardings = append(streamCfg.Forwardings[:idx], streamCfg.Forwardings[idx+1:]...) streamCfg.Forwardings = append(streamCfg.Forwardings[:idx], streamCfg.Forwardings[idx+1:]...)
break break
} }
return s.removeStreamForward(ctx, streamID, dstID)
}
func (s *StreamServer) removeStreamForward(
ctx context.Context,
streamID types.StreamID,
dstID types.DestinationID,
) error {
stream := s.StreamHandler.Get(string(streamID)) stream := s.StreamHandler.Get(string(streamID))
if stream == nil { if stream == nil {
return fmt.Errorf("unable to find a source stream with ID '%s'", streamID) return fmt.Errorf("unable to find a source stream with ID '%s'", streamID)
@@ -370,7 +397,12 @@ func (s *StreamServer) AddStreamDestination(
) error { ) error {
s.Mutex.Lock() s.Mutex.Lock()
defer s.Mutex.Unlock() defer s.Mutex.Unlock()
return s.addStreamDestination(ctx, destinationID, url) err := s.addStreamDestination(ctx, destinationID, url)
if err != nil {
return err
}
s.Config.Destinations[destinationID] = &types.DestinationConfig{URL: url}
return nil
} }
func (s *StreamServer) addStreamDestination( func (s *StreamServer) addStreamDestination(
@@ -382,7 +414,6 @@ func (s *StreamServer) addStreamDestination(
ID: destinationID, ID: destinationID,
URL: url, URL: url,
}) })
s.Config.Destinations[destinationID] = &types.DestinationConfig{URL: url}
return nil return nil
} }
@@ -392,7 +423,23 @@ func (s *StreamServer) RemoveStreamDestination(
) error { ) error {
s.Mutex.Lock() s.Mutex.Lock()
defer s.Mutex.Unlock() defer s.Mutex.Unlock()
for _, streamCfg := range s.Config.Streams {
for fIdx, destID := range streamCfg.Forwardings {
if destID != destinationID {
continue
}
streamCfg.Forwardings = append(streamCfg.Forwardings[:fIdx], streamCfg.Forwardings[fIdx+1:]...)
break
}
}
delete(s.Config.Destinations, destinationID)
return s.removeStreamDestination(ctx, destinationID)
}
func (s *StreamServer) removeStreamDestination(
ctx context.Context,
destinationID types.DestinationID,
) error {
streamForwards, err := s.listStreamForwards(ctx) streamForwards, err := s.listStreamForwards(ctx)
if err != nil { if err != nil {
return fmt.Errorf("unable to list stream forwardings: %w", err) return fmt.Errorf("unable to list stream forwardings: %w", err)
@@ -403,8 +450,6 @@ func (s *StreamServer) RemoveStreamDestination(
} }
} }
delete(s.Config.Destinations, destinationID)
for i := range s.StreamDestinations { for i := range s.StreamDestinations {
if s.StreamDestinations[i].ID == destinationID { if s.StreamDestinations[i].ID == destinationID {
s.StreamDestinations = append(s.StreamDestinations[:i], s.StreamDestinations[i+1:]...) s.StreamDestinations = append(s.StreamDestinations[:i], s.StreamDestinations[i+1:]...)

View File

@@ -1,8 +1,11 @@
package types package types
import ( import (
"encoding/json"
"fmt" "fmt"
"io" "io"
"github.com/goccy/go-yaml"
) )
type ServerType int type ServerType int
@@ -11,6 +14,7 @@ const (
ServerTypeUndefined = ServerType(iota) ServerTypeUndefined = ServerType(iota)
ServerTypeRTMP ServerTypeRTMP
ServerTypeRTSP ServerTypeRTSP
endOfServerType
) )
func (t ServerType) String() string { func (t ServerType) String() string {
@@ -26,6 +30,54 @@ func (t ServerType) String() string {
} }
} }
func (t ServerType) MarshalJSON() ([]byte, error) {
return json.Marshal(t.String())
}
func ParseServerType(s string) (ServerType, error) {
for c := ServerTypeUndefined; c < endOfServerType; c++ {
if c.String() == s {
return c, nil
}
}
return ServerTypeUndefined, fmt.Errorf("unexpected server type value '%s'", s)
}
func (t *ServerType) UnmarshalJSON(b []byte) error {
var s string
err := json.Unmarshal(b, &s)
if err != nil {
return err
}
c, err := ParseServerType(s)
if err != nil {
return err
}
*t = c
return nil
}
func (t ServerType) MarshalYAML() ([]byte, error) {
return yaml.Marshal(t.String())
}
func (t *ServerType) UnmarshalYAML(b []byte) error {
var s string
err := yaml.Unmarshal(b, &s)
if err != nil {
return err
}
c, err := ParseServerType(s)
if err != nil {
return err
}
*t = c
return nil
}
type ServerHandler interface { type ServerHandler interface {
io.Closer io.Closer