diff --git a/cmd/serve.go b/cmd/serve.go index 81d2cdd0..09352739 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -17,6 +17,7 @@ func init() { } configs := []config.Config{ + neko.Service.Configs.Desktop, neko.Service.Configs.Capture, neko.Service.Configs.WebRTC, neko.Service.Configs.Session, diff --git a/internal/api/room/screen.go b/internal/api/room/screen.go index 6f762d5e..0e8d6c9b 100644 --- a/internal/api/room/screen.go +++ b/internal/api/room/screen.go @@ -48,7 +48,7 @@ func (h *RoomHandler) ScreenConfigurationChange(w http.ResponseWriter, r *http.R return } - if err := h.capture.ChangeResolution(data.Width, data.Height, data.Rate); err != nil { + if err := h.desktop.ChangeScreenSize(data.Width, data.Height, data.Rate); err != nil { _ = render.Render(w, r, utils.ErrUnprocessableEntity(err)) return } diff --git a/internal/capture/manager.go b/internal/capture/manager.go index cdf9d067..cd83b89e 100644 --- a/internal/capture/manager.go +++ b/internal/capture/manager.go @@ -1,8 +1,6 @@ package capture import ( - "fmt" - "github.com/kataras/go-events" "github.com/rs/zerolog" "github.com/rs/zerolog/log" @@ -42,15 +40,15 @@ func New(desktop types.DesktopManager, config *config.Capture) *CaptureManagerCt } func (manager *CaptureManagerCtx) Start() { - manager.logger.Info(). - Str("screen_resolution", fmt.Sprintf("%dx%d@%d", manager.config.ScreenWidth, manager.config.ScreenHeight, manager.config.ScreenRate)). - Msgf("Setting screen resolution...") - - if err := manager.desktop.ChangeScreenSize(manager.config.ScreenWidth, manager.config.ScreenHeight, manager.config.ScreenRate); err != nil { - manager.logger.Warn().Err(err).Msg("unable to change screen size") - } - manager.StartBroadcastPipeline() + + manager.desktop.OnScreenSizeChange(func(width int, height int, rate int) { + manager.video_stop <- true + manager.StopBroadcastPipeline() + + manager.createVideoPipeline() + manager.StartBroadcastPipeline() + }) } func (manager *CaptureManagerCtx) Shutdown() error { @@ -102,18 +100,6 @@ func (manager *CaptureManagerCtx) Streaming() bool { return manager.streaming } -func (manager *CaptureManagerCtx) ChangeResolution(width int, height int, rate int) error { - manager.video_stop <- true - manager.StopBroadcastPipeline() - - defer func() { - manager.createVideoPipeline() - manager.StartBroadcastPipeline() - }() - - return manager.desktop.ChangeScreenSize(width, height, rate) -} - func (manager *CaptureManagerCtx) createVideoPipeline() { var err error diff --git a/internal/config/capture.go b/internal/config/capture.go index 500f7df5..5d6ea659 100644 --- a/internal/config/capture.go +++ b/internal/config/capture.go @@ -1,9 +1,6 @@ package config import ( - "regexp" - "strconv" - "github.com/pion/webrtc/v2" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -16,9 +13,6 @@ type Capture struct { AudioParams string VideoCodec string VideoParams string - ScreenWidth int - ScreenHeight int - ScreenRate int BroadcastPipeline string } @@ -43,11 +37,6 @@ func (Capture) Init(cmd *cobra.Command) error { return err } - cmd.PersistentFlags().String("screen", "1280x720@30", "default screen resolution and framerate") - if err := viper.BindPFlag("screen", cmd.PersistentFlags().Lookup("screen")); err != nil { - return err - } - // video codecs cmd.PersistentFlags().Bool("vp8", false, "use VP8 video codec") if err := viper.BindPFlag("vp8", cmd.PersistentFlags().Lookup("vp8")); err != nil { @@ -121,25 +110,5 @@ func (s *Capture) Set() { s.Display = viper.GetString("display") s.VideoCodec = videoCodec s.VideoParams = viper.GetString("video") - - s.ScreenWidth = 1280 - s.ScreenHeight = 720 - s.ScreenRate = 30 - - r := regexp.MustCompile(`([0-9]{1,4})x([0-9]{1,4})@([0-9]{1,3})`) - res := r.FindStringSubmatch(viper.GetString("screen")) - - if len(res) > 0 { - width, err1 := strconv.ParseInt(res[1], 10, 64) - height, err2 := strconv.ParseInt(res[2], 10, 64) - rate, err3 := strconv.ParseInt(res[3], 10, 64) - - if err1 == nil && err2 == nil && err3 == nil { - s.ScreenWidth = int(width) - s.ScreenHeight = int(height) - s.ScreenRate = int(rate) - } - } - s.BroadcastPipeline = viper.GetString("broadcast_pipeline") } diff --git a/internal/config/desktop.go b/internal/config/desktop.go new file mode 100644 index 00000000..bd484b05 --- /dev/null +++ b/internal/config/desktop.go @@ -0,0 +1,45 @@ +package config + +import ( + "regexp" + "strconv" + + "github.com/spf13/cobra" + "github.com/spf13/viper" +) + +type Desktop struct { + ScreenWidth int + ScreenHeight int + ScreenRate int +} + +func (Desktop) Init(cmd *cobra.Command) error { + cmd.PersistentFlags().String("screen", "1280x720@30", "default screen size and framerate") + if err := viper.BindPFlag("screen", cmd.PersistentFlags().Lookup("screen")); err != nil { + return err + } + + return nil +} + +func (s *Desktop) Set() { + s.ScreenWidth = 1280 + s.ScreenHeight = 720 + s.ScreenRate = 30 + + r := regexp.MustCompile(`([0-9]{1,4})x([0-9]{1,4})@([0-9]{1,3})`) + res := r.FindStringSubmatch(viper.GetString("screen")) + + if len(res) > 0 { + width, err1 := strconv.ParseInt(res[1], 10, 64) + height, err2 := strconv.ParseInt(res[2], 10, 64) + rate, err3 := strconv.ParseInt(res[3], 10, 64) + + if err1 == nil && err2 == nil && err3 == nil { + s.ScreenWidth = int(width) + s.ScreenHeight = int(height) + s.ScreenRate = int(rate) + } + } +} diff --git a/internal/desktop/manager.go b/internal/desktop/manager.go index aac9304b..0238c085 100644 --- a/internal/desktop/manager.go +++ b/internal/desktop/manager.go @@ -1,12 +1,14 @@ package desktop import ( + "fmt" "time" "github.com/kataras/go-events" "github.com/rs/zerolog" "github.com/rs/zerolog/log" + "demodesk/neko/internal/config" "demodesk/neko/internal/desktop/xorg" ) @@ -14,15 +16,19 @@ type DesktopManagerCtx struct { logger zerolog.Logger cleanup *time.Ticker shutdown chan bool + emmiter events.EventEmmiter display string + config *config.Desktop } -func New(display string) *DesktopManagerCtx { +func New(display string, config *config.Desktop) *DesktopManagerCtx { return &DesktopManagerCtx{ logger: log.With().Str("module", "desktop").Logger(), cleanup: time.NewTicker(1 * time.Second), shutdown: make(chan bool), + emmiter: events.New(), display: display, + config: config, } } @@ -33,6 +39,14 @@ func (manager *DesktopManagerCtx) Start() { xorg.GetScreenConfigurations() + manager.logger.Info(). + Str("screen_size", fmt.Sprintf("%dx%d@%d", manager.config.ScreenWidth, manager.config.ScreenHeight, manager.config.ScreenRate)). + Msgf("Setting initial screen size...") + + if err := xorg.ChangeScreenSize(manager.config.ScreenWidth, manager.config.ScreenHeight, manager.config.ScreenRate); err != nil { + manager.logger.Warn().Err(err).Msg("unable to set initial screen size") + } + go func() { defer func() { xorg.DisplayClose() @@ -50,6 +64,12 @@ func (manager *DesktopManagerCtx) Start() { }() } +func (manager *DesktopManagerCtx) OnScreenSizeChange(listener func(width int, height int, rate int)) { + manager.emmiter.On("screen_size_change", func(payload ...interface{}) { + listener(payload[0].(int), payload[1].(int), payload[2].(int)) + }) +} + func (manager *DesktopManagerCtx) Shutdown() error { manager.logger.Info().Msgf("remote shutting down") diff --git a/internal/desktop/xorg.go b/internal/desktop/xorg.go index 59e8643b..3f25e53a 100644 --- a/internal/desktop/xorg.go +++ b/internal/desktop/xorg.go @@ -5,10 +5,6 @@ import ( "demodesk/neko/internal/desktop/xorg" ) -func (manager *DesktopManagerCtx) ChangeScreenSize(width int, height int, rate int) error { - return xorg.ChangeScreenSize(width, height, rate) -} - func (manager *DesktopManagerCtx) Move(x, y int) { xorg.Move(x, y) } @@ -45,6 +41,15 @@ func (manager *DesktopManagerCtx) GetScreenSize() *types.ScreenSize { return xorg.GetScreenSize() } +func (manager *DesktopManagerCtx) ChangeScreenSize(width int, height int, rate int) error { + if err := xorg.ChangeScreenSize(width, height, rate); err != nil { + return err + } + + manager.emmiter.Emit("screen_size_change", width, height, rate) + return nil +} + func (manager *DesktopManagerCtx) SetKeyboardLayout(layout string) { xorg.SetKeyboardLayout(layout) } diff --git a/internal/types/capture.go b/internal/types/capture.go index f54f3191..ca4ddc20 100644 --- a/internal/types/capture.go +++ b/internal/types/capture.go @@ -19,8 +19,6 @@ type CaptureManager interface { StopStream() Streaming() bool - ChangeResolution(width int, height int, rate int) error - // broacast StartBroadcast(url string) StopBroadcast() diff --git a/internal/types/desktop.go b/internal/types/desktop.go index 34f81647..f9168c23 100644 --- a/internal/types/desktop.go +++ b/internal/types/desktop.go @@ -15,6 +15,7 @@ type ScreenConfiguration struct { type DesktopManager interface { Start() Shutdown() error + OnScreenSizeChange(listener func(width int, height int, rate int)) // xorg ChangeScreenSize(width int, height int, rate int) error diff --git a/internal/websocket/handler/screen.go b/internal/websocket/handler/screen.go index 48dd15ec..d7249d23 100644 --- a/internal/websocket/handler/screen.go +++ b/internal/websocket/handler/screen.go @@ -12,7 +12,7 @@ func (h *MessageHandlerCtx) screenSet(session types.Session, payload *message.Sc return nil } - if err := h.capture.ChangeResolution(payload.Width, payload.Height, payload.Rate); err != nil { + if err := h.desktop.ChangeScreenSize(payload.Width, payload.Height, payload.Rate); err != nil { h.logger.Warn().Err(err).Msgf("unable to change screen size") return err } diff --git a/neko.go b/neko.go index c91574dd..c01aed72 100644 --- a/neko.go +++ b/neko.go @@ -62,6 +62,7 @@ func init() { }, Configs: &Configs{ Root: &config.Root{}, + Desktop: &config.Desktop{}, Capture: &config.Capture{}, WebRTC: &config.WebRTC{}, Session: &config.Session{}, @@ -101,6 +102,7 @@ func (i *Version) Details() string { type Configs struct { Root *config.Root + Desktop *config.Desktop Capture *config.Capture WebRTC *config.WebRTC Session *config.Session @@ -128,6 +130,7 @@ func (neko *Neko) Preflight() { func (neko *Neko) Start() { neko.desktopManager = desktop.New( neko.Configs.Capture.Display, + neko.Configs.Desktop, ) neko.desktopManager.Start()