From 0e4f2327d4348a0d205f4db5a6921fffbee4b47a Mon Sep 17 00:00:00 2001 From: m1k1o Date: Thu, 24 Sep 2020 08:09:02 +0200 Subject: [PATCH 01/10] add rtmp broadcast --- .m1k1o/base/Dockerfile | 4 +- docker-compose.dev.yaml | 7 ++- server/cmd/serve.go | 1 + server/internal/gst/gst.c | 4 ++ server/internal/gst/gst.go | 8 ++- server/internal/gst/gst.h | 1 + server/internal/remote/manager.go | 64 +++++++++++++++++++++-- server/internal/types/config/broadcast.go | 16 +++--- server/neko.go | 4 +- 9 files changed, 90 insertions(+), 19 deletions(-) diff --git a/.m1k1o/base/Dockerfile b/.m1k1o/base/Dockerfile index 8db7947..7371cb5 100644 --- a/.m1k1o/base/Dockerfile +++ b/.m1k1o/base/Dockerfile @@ -8,7 +8,7 @@ WORKDIR /src # install dependencies RUN set -eux; apt-get update; \ apt-get install -y --no-install-recommends git cmake make libx11-dev libxrandr-dev libxtst-dev \ - libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev gstreamer1.0-plugins-base gstreamer1.0-plugins-good; \ + libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly; \ # # install libclipboard set -eux; \ @@ -69,7 +69,7 @@ RUN set -eux; apt-get update; \ # # gst apt-get install -y --no-install-recommends libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev \ - gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-pulseaudio; \ + gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-pulseaudio; \ # # create a non-root user groupadd --gid $USER_GID $USERNAME; \ diff --git a/docker-compose.dev.yaml b/docker-compose.dev.yaml index de16131..12c1b8a 100644 --- a/docker-compose.dev.yaml +++ b/docker-compose.dev.yaml @@ -12,9 +12,12 @@ services: - SYS_ADMIN environment: DISPLAY: :99.0 - NEKO_SCREEN: '1280x720@30' + NEKO_SCREEN: '1920x1080@30' NEKO_PASSWORD: neko NEKO_PASSWORD_ADMIN: admin NEKO_BIND: :8080 NEKO_EPR: 52000-52010 - NEKO_NAT1TO1: 192.168.1.20 \ No newline at end of file + NEKO_NAT1TO1: 192.168.1.20 + NEKO_BROADCAST: 'true' + NEKO_RTMP: 'rtmp://192.168.1.20/live/neko' + diff --git a/server/cmd/serve.go b/server/cmd/serve.go index 2c7dfde..b6a7807 100644 --- a/server/cmd/serve.go +++ b/server/cmd/serve.go @@ -20,6 +20,7 @@ func init() { neko.Service.Server, neko.Service.WebRTC, neko.Service.Remote, + neko.Service.Broadcast, neko.Service.WebSocket, } diff --git a/server/internal/gst/gst.c b/server/internal/gst/gst.c index 1ce97f4..924787f 100644 --- a/server/internal/gst/gst.c +++ b/server/internal/gst/gst.c @@ -84,6 +84,10 @@ void gstreamer_send_start_pipeline(GstElement *pipeline, int pipelineId) { gst_element_set_state(pipeline, GST_STATE_PLAYING); } +void gstreamer_send_play_pipeline(GstElement *pipeline) { + gst_element_set_state(pipeline, GST_STATE_PLAYING); +} + void gstreamer_send_stop_pipeline(GstElement *pipeline) { gst_element_set_state(pipeline, GST_STATE_NULL); } diff --git a/server/internal/gst/gst.go b/server/internal/gst/gst.go index 1c0eb90..8999cc7 100644 --- a/server/internal/gst/gst.go +++ b/server/internal/gst/gst.go @@ -68,7 +68,8 @@ func init() { func CreateRTMPPipeline(pipelineDevice string, pipelineDisplay string, pipelineRTMP string) (*Pipeline, error) { video := fmt.Sprintf(videoSrc, pipelineDisplay) audio := fmt.Sprintf(audioSrc, pipelineDevice) - return CreatePipeline(fmt.Sprintf("%s ! x264enc ! flv. ! %s ! faac ! flv. ! flvmux name='flv' ! rtmpsink location='%s'", video, audio, pipelineRTMP), "", 0) + + return CreatePipeline(fmt.Sprintf("flvmux name=mux ! rtmpsink location='%s' live=1 %s voaacenc ! mux. %s x264enc bframes=0 key-int-max=60 byte-stream=true tune=zerolatency speed-preset=veryfast ! mux.", pipelineRTMP, audio, video), "", 0) } // CreateAppPipeline creates a GStreamer Pipeline @@ -228,6 +229,11 @@ func (p *Pipeline) Start() { C.gstreamer_send_start_pipeline(p.Pipeline, C.int(p.id)) } +// Play starts the GStreamer Pipeline +func (p *Pipeline) Play() { + C.gstreamer_send_play_pipeline(p.Pipeline) +} + // Stop stops the GStreamer Pipeline func (p *Pipeline) Stop() { C.gstreamer_send_stop_pipeline(p.Pipeline) diff --git a/server/internal/gst/gst.h b/server/internal/gst/gst.h index 943e8b9..7c6965f 100644 --- a/server/internal/gst/gst.h +++ b/server/internal/gst/gst.h @@ -11,6 +11,7 @@ extern void goHandlePipelineBuffer(void *buffer, int bufferLen, int samples, int GstElement *gstreamer_send_create_pipeline(char *pipeline); void gstreamer_send_start_pipeline(GstElement *pipeline, int pipelineId); +void gstreamer_send_play_pipeline(GstElement *pipeline); void gstreamer_send_stop_pipeline(GstElement *pipeline); void gstreamer_send_start_mainloop(void); void gstreamer_init(void); diff --git a/server/internal/remote/manager.go b/server/internal/remote/manager.go index 4b89d85..193e70d 100644 --- a/server/internal/remote/manager.go +++ b/server/internal/remote/manager.go @@ -17,20 +17,23 @@ type RemoteManager struct { logger zerolog.Logger video *gst.Pipeline audio *gst.Pipeline + rtmp *gst.Pipeline config *config.Remote + broadcast *config.Broadcast cleanup *time.Ticker shutdown chan bool emmiter events.EventEmmiter streaming bool } -func New(config *config.Remote) *RemoteManager { +func New(config *config.Remote, broadcast *config.Broadcast) *RemoteManager { return &RemoteManager{ logger: log.With().Str("module", "remote").Logger(), cleanup: time.NewTicker(1 * time.Second), shutdown: make(chan bool), emmiter: events.New(), config: config, + broadcast: broadcast, streaming: false, } } @@ -70,6 +73,11 @@ func (manager *RemoteManager) Shutdown() error { manager.logger.Info().Msgf("remote shutting down") manager.video.Stop() manager.audio.Stop() + + if manager.broadcast.Enabled { + manager.rtmp.Stop() + } + manager.cleanup.Stop() manager.shutdown <- true return nil @@ -98,6 +106,12 @@ func (manager *RemoteManager) StartStream() { Str("screen_resolution", fmt.Sprintf("%dx%d@%d", manager.config.ScreenWidth, manager.config.ScreenHeight, manager.config.ScreenRate)). Msgf("Pipelines starting...") + if manager.broadcast.Enabled { + manager.logger.Info(). + Str("rtmp_pipeline_src", manager.rtmp.Src). + Msgf("Prtmp pipeline is starting...") + } + xorg.Display(manager.config.Display) if !xorg.ValidScreenSize(manager.config.ScreenWidth, manager.config.ScreenHeight, manager.config.ScreenRate) { @@ -109,6 +123,11 @@ func (manager *RemoteManager) StartStream() { manager.createPipelines() manager.video.Start() manager.audio.Start() + + if manager.broadcast.Enabled { + manager.rtmp.Play() + } + manager.streaming = true } @@ -116,6 +135,11 @@ func (manager *RemoteManager) StopStream() { manager.logger.Info().Msgf("Pipelines shutting down...") manager.video.Stop() manager.audio.Stop() + + if manager.broadcast.Enabled { + manager.rtmp.Stop() + } + manager.streaming = false } @@ -140,7 +164,18 @@ func (manager *RemoteManager) createPipelines() { manager.config.AudioParams, ) if err != nil { - manager.logger.Panic().Err(err).Msg("unable to screate audio pipeline") + manager.logger.Panic().Err(err).Msg("unable to create audio pipeline") + } + + if manager.broadcast.Enabled { + manager.rtmp, err = gst.CreateRTMPPipeline( + manager.config.Device, + manager.config.Display, + manager.broadcast.RTMP, + ) + if err != nil { + manager.logger.Panic().Err(err).Msg("unable to create rtmp pipeline") + } } } @@ -150,8 +185,18 @@ func (manager *RemoteManager) ChangeResolution(width int, height int, rate int) } manager.video.Stop() + + if manager.broadcast.Enabled { + manager.rtmp.Stop() + } + defer func() { manager.video.Start() + + if manager.broadcast.Enabled { + manager.rtmp.Play() + } + manager.logger.Info().Msg("starting video pipeline...") }() @@ -159,17 +204,26 @@ func (manager *RemoteManager) ChangeResolution(width int, height int, rate int) return err } - video, err := gst.CreateAppPipeline( + manager.video, err := gst.CreateAppPipeline( manager.config.VideoCodec, manager.config.Display, manager.config.VideoParams, ) - if err != nil { manager.logger.Panic().Err(err).Msg("unable to create new video pipeline") } - manager.video = video + if manager.broadcast.Enabled { + manager.rtmp, err = gst.CreateRTMPPipeline( + manager.config.Device, + manager.config.Display, + manager.broadcast.RTMP, + ) + if err != nil { + manager.logger.Panic().Err(err).Msg("unable to create new rtmp pipeline") + } + } + return nil } diff --git a/server/internal/types/config/broadcast.go b/server/internal/types/config/broadcast.go index 35c3502..d01e528 100644 --- a/server/internal/types/config/broadcast.go +++ b/server/internal/types/config/broadcast.go @@ -7,10 +7,10 @@ import ( type Broadcast struct { Enabled bool - Display string - Device string - AudioParams string - VideoParams string + // Display string + // Device string + // AudioParams string + // VideoParams string RTMP string } @@ -40,9 +40,9 @@ func (Broadcast) Init(cmd *cobra.Command) error { func (s *Broadcast) Set() { s.Enabled = viper.GetBool("broadcast") - s.Display = viper.GetString("display") - s.Device = viper.GetString("device") - s.AudioParams = viper.GetString("cast_audio") - s.VideoParams = viper.GetString("cast_video") + // s.Display = viper.GetString("display") + // s.Device = viper.GetString("device") + // s.AudioParams = viper.GetString("cast_audio") + // s.VideoParams = viper.GetString("cast_video") s.RTMP = viper.GetString("rtmp") } diff --git a/server/neko.go b/server/neko.go index 155abf3..e962edb 100644 --- a/server/neko.go +++ b/server/neko.go @@ -61,6 +61,7 @@ func init() { Root: &config.Root{}, Server: &config.Server{}, Remote: &config.Remote{}, + Broadcast: &config.Broadcast{}, WebRTC: &config.WebRTC{}, WebSocket: &config.WebSocket{}, } @@ -99,6 +100,7 @@ type Neko struct { Version *Version Root *config.Root Remote *config.Remote + Broadcast *config.Broadcast Server *config.Server WebRTC *config.WebRTC WebSocket *config.WebSocket @@ -117,7 +119,7 @@ func (neko *Neko) Preflight() { func (neko *Neko) Start() { - remoteManager := remote.New(neko.Remote) + remoteManager := remote.New(neko.Remote, neko.Broadcast) remoteManager.Start() sessionManager := session.New(remoteManager) From 76670684371d9979ceb1932038452a4a894c4b4b Mon Sep 17 00:00:00 2001 From: m1k1o Date: Thu, 24 Sep 2020 08:17:32 +0200 Subject: [PATCH 02/10] fix --- server/internal/remote/manager.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/server/internal/remote/manager.go b/server/internal/remote/manager.go index 193e70d..f1c440f 100644 --- a/server/internal/remote/manager.go +++ b/server/internal/remote/manager.go @@ -204,7 +204,7 @@ func (manager *RemoteManager) ChangeResolution(width int, height int, rate int) return err } - manager.video, err := gst.CreateAppPipeline( + video, err := gst.CreateAppPipeline( manager.config.VideoCodec, manager.config.Display, manager.config.VideoParams, @@ -212,9 +212,10 @@ func (manager *RemoteManager) ChangeResolution(width int, height int, rate int) if err != nil { manager.logger.Panic().Err(err).Msg("unable to create new video pipeline") } + manager.video = video if manager.broadcast.Enabled { - manager.rtmp, err = gst.CreateRTMPPipeline( + rtmp, err = gst.CreateRTMPPipeline( manager.config.Device, manager.config.Display, manager.broadcast.RTMP, @@ -222,6 +223,7 @@ func (manager *RemoteManager) ChangeResolution(width int, height int, rate int) if err != nil { manager.logger.Panic().Err(err).Msg("unable to create new rtmp pipeline") } + manager.rtmp = rtmp } return nil From d95947d4ec2faab7f94a316c71d5de9239f36924 Mon Sep 17 00:00:00 2001 From: m1k1o Date: Thu, 24 Sep 2020 08:18:28 +0200 Subject: [PATCH 03/10] fix -> : --- server/internal/remote/manager.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/internal/remote/manager.go b/server/internal/remote/manager.go index f1c440f..9ad36d9 100644 --- a/server/internal/remote/manager.go +++ b/server/internal/remote/manager.go @@ -215,7 +215,7 @@ func (manager *RemoteManager) ChangeResolution(width int, height int, rate int) manager.video = video if manager.broadcast.Enabled { - rtmp, err = gst.CreateRTMPPipeline( + rtmp, err := gst.CreateRTMPPipeline( manager.config.Device, manager.config.Display, manager.broadcast.RTMP, From b2afd1af6d31167d0d56917b070c746a24fadcf0 Mon Sep 17 00:00:00 2001 From: m1k1o Date: Sat, 26 Sep 2020 23:04:15 +0200 Subject: [PATCH 04/10] use BroadcatManager --- server/internal/broadcast/manager.go | 32 ++++++--- server/internal/gst/gst.go | 2 +- server/internal/remote/manager.go | 83 +++++------------------ server/internal/types/broadcast.go | 6 ++ server/internal/types/config/broadcast.go | 26 +++---- server/neko.go | 5 +- 6 files changed, 64 insertions(+), 90 deletions(-) create mode 100644 server/internal/types/broadcast.go diff --git a/server/internal/broadcast/manager.go b/server/internal/broadcast/manager.go index 753b53b..ae5a73d 100644 --- a/server/internal/broadcast/manager.go +++ b/server/internal/broadcast/manager.go @@ -3,6 +3,7 @@ package broadcast import ( "github.com/rs/zerolog" "github.com/rs/zerolog/log" + "n.eko.moe/neko/internal/gst" "n.eko.moe/neko/internal/types/config" ) @@ -10,34 +11,49 @@ import ( type BroadcastManager struct { logger zerolog.Logger pipeline *gst.Pipeline + remote *config.Remote config *config.Broadcast } -func New(config *config.Broadcast) *BroadcastManager { +func New(remote *config.Remote, config *config.Broadcast) *BroadcastManager { return &BroadcastManager{ logger: log.With().Str("module", "remote").Logger(), + remote: remote, config: config, } } func (manager *BroadcastManager) Start() { + if !manager.config.Enabled { + return + } + var err error manager.pipeline, err = gst.CreateRTMPPipeline( - manager.config.Device, - manager.config.Display, + manager.remote.Device, + manager.remote.Display, manager.config.RTMP, ) + + manager.logger.Info(). + Str("audio_device", manager.remote.Device). + Str("video_display", manager.remote.Display). + Str("rtmp_pipeline_src", manager.pipeline.Src). + Msgf("RTMP pipeline is starting...") + if err != nil { manager.logger.Panic().Err(err).Msg("unable to create rtmp pipeline") + return } - manager.pipeline.Start() + manager.pipeline.Play() } -func (manager *BroadcastManager) Shutdown() error { - if manager.pipeline != nil { - manager.pipeline.Stop() +func (manager *BroadcastManager) Stop() { + if manager.pipeline == nil { + return } - return nil + manager.pipeline.Stop() + manager.pipeline = nil } diff --git a/server/internal/gst/gst.go b/server/internal/gst/gst.go index 8999cc7..e2679de 100644 --- a/server/internal/gst/gst.go +++ b/server/internal/gst/gst.go @@ -69,7 +69,7 @@ func CreateRTMPPipeline(pipelineDevice string, pipelineDisplay string, pipelineR video := fmt.Sprintf(videoSrc, pipelineDisplay) audio := fmt.Sprintf(audioSrc, pipelineDevice) - return CreatePipeline(fmt.Sprintf("flvmux name=mux ! rtmpsink location='%s' live=1 %s voaacenc ! mux. %s x264enc bframes=0 key-int-max=60 byte-stream=true tune=zerolatency speed-preset=veryfast ! mux.", pipelineRTMP, audio, video), "", 0) + return CreatePipeline(fmt.Sprintf("flvmux name=mux ! rtmpsink location='%s live=1' %s voaacenc ! mux. %s x264enc bframes=0 key-int-max=60 byte-stream=true tune=zerolatency speed-preset=veryfast ! mux.", pipelineRTMP, audio, video), "", 0) } // CreateAppPipeline creates a GStreamer Pipeline diff --git a/server/internal/remote/manager.go b/server/internal/remote/manager.go index 9ad36d9..3ed2f00 100644 --- a/server/internal/remote/manager.go +++ b/server/internal/remote/manager.go @@ -17,16 +17,15 @@ type RemoteManager struct { logger zerolog.Logger video *gst.Pipeline audio *gst.Pipeline - rtmp *gst.Pipeline config *config.Remote - broadcast *config.Broadcast + broadcast types.BroadcastManager cleanup *time.Ticker shutdown chan bool emmiter events.EventEmmiter streaming bool } -func New(config *config.Remote, broadcast *config.Broadcast) *RemoteManager { +func New(config *config.Remote, broadcast types.BroadcastManager) *RemoteManager { return &RemoteManager{ logger: log.With().Str("module", "remote").Logger(), cleanup: time.NewTicker(1 * time.Second), @@ -47,7 +46,16 @@ func (manager *RemoteManager) AudioCodec() string { } func (manager *RemoteManager) Start() { + xorg.Display(manager.config.Display) + + if !xorg.ValidScreenSize(manager.config.ScreenWidth, manager.config.ScreenHeight, manager.config.ScreenRate) { + manager.logger.Warn().Msgf("invalid screen option %dx%d@%d", manager.config.ScreenWidth, manager.config.ScreenHeight, manager.config.ScreenRate) + } else if err := xorg.ChangeScreenSize(manager.config.ScreenWidth, manager.config.ScreenHeight, manager.config.ScreenRate); err != nil { + manager.logger.Warn().Err(err).Msg("unable to change screen size") + } + manager.createPipelines() + manager.broadcast.Start() go func() { defer func() { @@ -73,10 +81,7 @@ func (manager *RemoteManager) Shutdown() error { manager.logger.Info().Msgf("remote shutting down") manager.video.Stop() manager.audio.Stop() - - if manager.broadcast.Enabled { - manager.rtmp.Stop() - } + manager.broadcast.Stop() manager.cleanup.Stop() manager.shutdown <- true @@ -96,6 +101,8 @@ func (manager *RemoteManager) OnAudioFrame(listener func(sample types.Sample)) { } func (manager *RemoteManager) StartStream() { + manager.createPipelines() + manager.logger.Info(). Str("video_display", manager.config.Display). Str("video_codec", manager.config.VideoCodec). @@ -106,28 +113,8 @@ func (manager *RemoteManager) StartStream() { Str("screen_resolution", fmt.Sprintf("%dx%d@%d", manager.config.ScreenWidth, manager.config.ScreenHeight, manager.config.ScreenRate)). Msgf("Pipelines starting...") - if manager.broadcast.Enabled { - manager.logger.Info(). - Str("rtmp_pipeline_src", manager.rtmp.Src). - Msgf("Prtmp pipeline is starting...") - } - - xorg.Display(manager.config.Display) - - if !xorg.ValidScreenSize(manager.config.ScreenWidth, manager.config.ScreenHeight, manager.config.ScreenRate) { - manager.logger.Warn().Msgf("invalid screen option %dx%d@%d", manager.config.ScreenWidth, manager.config.ScreenHeight, manager.config.ScreenRate) - } else if err := xorg.ChangeScreenSize(manager.config.ScreenWidth, manager.config.ScreenHeight, manager.config.ScreenRate); err != nil { - manager.logger.Warn().Err(err).Msg("unable to change screen size") - } - - manager.createPipelines() manager.video.Start() manager.audio.Start() - - if manager.broadcast.Enabled { - manager.rtmp.Play() - } - manager.streaming = true } @@ -135,11 +122,6 @@ func (manager *RemoteManager) StopStream() { manager.logger.Info().Msgf("Pipelines shutting down...") manager.video.Stop() manager.audio.Stop() - - if manager.broadcast.Enabled { - manager.rtmp.Stop() - } - manager.streaming = false } @@ -166,17 +148,6 @@ func (manager *RemoteManager) createPipelines() { if err != nil { manager.logger.Panic().Err(err).Msg("unable to create audio pipeline") } - - if manager.broadcast.Enabled { - manager.rtmp, err = gst.CreateRTMPPipeline( - manager.config.Device, - manager.config.Display, - manager.broadcast.RTMP, - ) - if err != nil { - manager.logger.Panic().Err(err).Msg("unable to create rtmp pipeline") - } - } } func (manager *RemoteManager) ChangeResolution(width int, height int, rate int) error { @@ -185,17 +156,11 @@ func (manager *RemoteManager) ChangeResolution(width int, height int, rate int) } manager.video.Stop() - - if manager.broadcast.Enabled { - manager.rtmp.Stop() - } + manager.broadcast.Stop() defer func() { manager.video.Start() - - if manager.broadcast.Enabled { - manager.rtmp.Play() - } + manager.broadcast.Start() manager.logger.Info().Msg("starting video pipeline...") }() @@ -204,7 +169,8 @@ func (manager *RemoteManager) ChangeResolution(width int, height int, rate int) return err } - video, err := gst.CreateAppPipeline( + var err error + manager.video, err = gst.CreateAppPipeline( manager.config.VideoCodec, manager.config.Display, manager.config.VideoParams, @@ -212,19 +178,6 @@ func (manager *RemoteManager) ChangeResolution(width int, height int, rate int) if err != nil { manager.logger.Panic().Err(err).Msg("unable to create new video pipeline") } - manager.video = video - - if manager.broadcast.Enabled { - rtmp, err := gst.CreateRTMPPipeline( - manager.config.Device, - manager.config.Display, - manager.broadcast.RTMP, - ) - if err != nil { - manager.logger.Panic().Err(err).Msg("unable to create new rtmp pipeline") - } - manager.rtmp = rtmp - } return nil } diff --git a/server/internal/types/broadcast.go b/server/internal/types/broadcast.go new file mode 100644 index 0000000..7b4d698 --- /dev/null +++ b/server/internal/types/broadcast.go @@ -0,0 +1,6 @@ +package types + +type BroadcastManager interface { + Start() + Stop() +} diff --git a/server/internal/types/config/broadcast.go b/server/internal/types/config/broadcast.go index d01e528..bfef102 100644 --- a/server/internal/types/config/broadcast.go +++ b/server/internal/types/config/broadcast.go @@ -7,15 +7,13 @@ import ( type Broadcast struct { Enabled bool - // Display string - // Device string + RTMP string // AudioParams string // VideoParams string - RTMP string } func (Broadcast) Init(cmd *cobra.Command) error { - cmd.PersistentFlags().Bool("broadcast", false, "use PCMA audio codec") + cmd.PersistentFlags().Bool("broadcast", false, "turn on boradcasting") if err := viper.BindPFlag("broadcast", cmd.PersistentFlags().Lookup("broadcast")); err != nil { return err } @@ -25,24 +23,22 @@ func (Broadcast) Init(cmd *cobra.Command) error { return err } - cmd.PersistentFlags().String("cast_audio", "", "audio codec parameters to use for broadcasting") - if err := viper.BindPFlag("cast_audio", cmd.PersistentFlags().Lookup("cast_audio")); err != nil { - return err - } + // cmd.PersistentFlags().String("cast_audio", "", "audio codec parameters to use for broadcasting") + // if err := viper.BindPFlag("cast_audio", cmd.PersistentFlags().Lookup("cast_audio")); err != nil { + // return err + // } - cmd.PersistentFlags().String("cast_video", "", "video codec parameters to use for broadcasting") - if err := viper.BindPFlag("cast_video", cmd.PersistentFlags().Lookup("cast_video")); err != nil { - return err - } + // cmd.PersistentFlags().String("cast_video", "", "video codec parameters to use for broadcasting") + // if err := viper.BindPFlag("cast_video", cmd.PersistentFlags().Lookup("cast_video")); err != nil { + // return err + // } return nil } func (s *Broadcast) Set() { s.Enabled = viper.GetBool("broadcast") - // s.Display = viper.GetString("display") - // s.Device = viper.GetString("device") + s.RTMP = viper.GetString("rtmp") // s.AudioParams = viper.GetString("cast_audio") // s.VideoParams = viper.GetString("cast_video") - s.RTMP = viper.GetString("rtmp") } diff --git a/server/neko.go b/server/neko.go index e962edb..447979b 100644 --- a/server/neko.go +++ b/server/neko.go @@ -6,6 +6,7 @@ import ( "os/signal" "runtime" + "n.eko.moe/neko/internal/broadcast" "n.eko.moe/neko/internal/http" "n.eko.moe/neko/internal/remote" "n.eko.moe/neko/internal/session" @@ -109,6 +110,7 @@ type Neko struct { server *http.Server sessionManager *session.SessionManager remoteManager *remote.RemoteManager + broadcastManager *broadcast.BroadcastManager webRTCManager *webrtc.WebRTCManager webSocketHandler *websocket.WebSocketHandler } @@ -118,8 +120,9 @@ func (neko *Neko) Preflight() { } func (neko *Neko) Start() { + broadcastManager := broadcast.New(neko.Remote, neko.Broadcast) - remoteManager := remote.New(neko.Remote, neko.Broadcast) + remoteManager := remote.New(neko.Remote, broadcastManager) remoteManager.Start() sessionManager := session.New(remoteManager) From ea80f07bcd68d7f03a5468f9bc490eecf17bc4fd Mon Sep 17 00:00:00 2001 From: m1k1o Date: Sun, 27 Sep 2020 00:10:34 +0200 Subject: [PATCH 05/10] add WS handlers --- server/internal/broadcast/manager.go | 35 +++++++++++--- server/internal/types/broadcast.go | 4 ++ server/internal/types/event/events.go | 6 +++ server/internal/types/message/messages.go | 11 +++++ server/internal/websocket/broadcast.go | 56 +++++++++++++++++++++++ server/internal/websocket/handler.go | 23 +++++++--- server/internal/websocket/session.go | 5 ++ server/internal/websocket/websocket.go | 39 ++++++++-------- server/neko.go | 2 +- 9 files changed, 149 insertions(+), 32 deletions(-) create mode 100644 server/internal/websocket/broadcast.go diff --git a/server/internal/broadcast/manager.go b/server/internal/broadcast/manager.go index ae5a73d..bca83cf 100644 --- a/server/internal/broadcast/manager.go +++ b/server/internal/broadcast/manager.go @@ -13,18 +13,22 @@ type BroadcastManager struct { pipeline *gst.Pipeline remote *config.Remote config *config.Broadcast + enabled bool + url string } func New(remote *config.Remote, config *config.Broadcast) *BroadcastManager { return &BroadcastManager{ - logger: log.With().Str("module", "remote").Logger(), - remote: remote, - config: config, + logger: log.With().Str("module", "remote").Logger(), + remote: remote, + config: config, + enabled: false, + url: "", } } func (manager *BroadcastManager) Start() { - if !manager.config.Enabled { + if !manager.enabled || manager.IsActive() { return } @@ -32,7 +36,7 @@ func (manager *BroadcastManager) Start() { manager.pipeline, err = gst.CreateRTMPPipeline( manager.remote.Device, manager.remote.Display, - manager.config.RTMP, + manager.url, ) manager.logger.Info(). @@ -50,10 +54,29 @@ func (manager *BroadcastManager) Start() { } func (manager *BroadcastManager) Stop() { - if manager.pipeline == nil { + if !manager.IsActive() { return } manager.pipeline.Stop() manager.pipeline = nil } + +func (manager *BroadcastManager) IsActive() bool { + return manager.pipeline != nil +} + +func (manager *BroadcastManager) Create(url string) { + manager.url = url + manager.enabled = true + manager.Start() +} + +func (manager *BroadcastManager) Destroy() { + manager.Stop() + manager.enabled = false +} + +func (manager *BroadcastManager) GetUrl() string { + return manager.url +} diff --git a/server/internal/types/broadcast.go b/server/internal/types/broadcast.go index 7b4d698..fee3fd5 100644 --- a/server/internal/types/broadcast.go +++ b/server/internal/types/broadcast.go @@ -3,4 +3,8 @@ package types type BroadcastManager interface { Start() Stop() + IsActive() bool + Create(url string) + Destroy() + GetUrl() string } diff --git a/server/internal/types/event/events.go b/server/internal/types/event/events.go index 7b9d31b..b97c49c 100644 --- a/server/internal/types/event/events.go +++ b/server/internal/types/event/events.go @@ -36,6 +36,12 @@ const ( SCREEN_SET = "screen/set" ) +const ( + BORADCAST_STATUS = "broadcast/status" + BORADCAST_CREATE = "broadcast/create" + BORADCAST_DESTROY = "broadcast/destroy" +) + const ( ADMIN_BAN = "admin/ban" ADMIN_KICK = "admin/kick" diff --git a/server/internal/types/message/messages.go b/server/internal/types/message/messages.go index 8113e33..fcf04f3 100644 --- a/server/internal/types/message/messages.go +++ b/server/internal/types/message/messages.go @@ -110,3 +110,14 @@ type ScreenConfigurations struct { Event string `json:"event"` Configurations map[int]types.ScreenConfiguration `json:"configurations"` } + +type BroadcastStatus struct { + Event string `json:"event"` + URL string `json:"url"` + IsActive bool `json:"isActive"` +} + +type BroadcastCreate struct { + Event string `json:"event"` + URL string `json:"url"` +} diff --git a/server/internal/websocket/broadcast.go b/server/internal/websocket/broadcast.go new file mode 100644 index 0000000..c2d6a88 --- /dev/null +++ b/server/internal/websocket/broadcast.go @@ -0,0 +1,56 @@ +package websocket + +import ( + "n.eko.moe/neko/internal/types" + "n.eko.moe/neko/internal/types/event" + "n.eko.moe/neko/internal/types/message" +) + +func (h *MessageHandler) boradcastCreate(session types.Session, payload *message.BroadcastCreate) error { + if !session.Admin() { + h.logger.Debug().Msg("user not admin") + return nil + } + + h.broadcast.Create(payload.URL) + + if err := h.boradcastStatus(session); err != nil { + return err + } + + return nil +} + +func (h *MessageHandler) boradcastDestroy(session types.Session) error { + if !session.Admin() { + h.logger.Debug().Msg("user not admin") + return nil + } + + h.broadcast.Destroy() + + if err := h.boradcastStatus(session); err != nil { + return err + } + + return nil +} + +func (h *MessageHandler) boradcastStatus(session types.Session) error { + if !session.Admin() { + h.logger.Debug().Msg("user not admin") + return nil + } + + if err := session.Send( + message.BroadcastStatus{ + Event: event.BORADCAST_STATUS, + IsActive: h.broadcast.IsActive(), + URL: h.broadcast.GetUrl(), + }); err != nil { + h.logger.Warn().Err(err).Msgf("sending event %s has failed", event.BORADCAST_STATUS) + return err + } + + return nil +} diff --git a/server/internal/websocket/handler.go b/server/internal/websocket/handler.go index 5693c97..af829c8 100644 --- a/server/internal/websocket/handler.go +++ b/server/internal/websocket/handler.go @@ -13,12 +13,13 @@ import ( ) type MessageHandler struct { - logger zerolog.Logger - sessions types.SessionManager - webrtc types.WebRTCManager - remote types.RemoteManager - banned map[string]bool - locked bool + logger zerolog.Logger + sessions types.SessionManager + webrtc types.WebRTCManager + remote types.RemoteManager + broadcast types.BroadcastManager + banned map[string]bool + locked bool } func (h *MessageHandler) Connected(id string, socket *WebSocket) (bool, string, error) { @@ -123,6 +124,16 @@ func (h *MessageHandler) Message(id string, raw []byte) error { return h.screenSet(id, session, payload) }), "%s failed", header.Event) + // Boradcast Events + case event.BORADCAST_CREATE: + payload := &message.BroadcastCreate{} + return errors.Wrapf( + utils.Unmarshal(payload, raw, func() error { + return h.boradcastCreate(session, payload) + }), "%s failed", header.Event) + case event.BORADCAST_DESTROY: + return errors.Wrapf(h.boradcastDestroy(session), "%s failed", header.Event) + // Admin Events case event.ADMIN_LOCK: return errors.Wrapf(h.adminLock(id, session), "%s failed", header.Event) diff --git a/server/internal/websocket/session.go b/server/internal/websocket/session.go index 23d71cd..9151aa2 100644 --- a/server/internal/websocket/session.go +++ b/server/internal/websocket/session.go @@ -17,6 +17,11 @@ func (h *MessageHandler) SessionCreated(id string, session types.Session) error if err := h.screenConfigurations(id, session); err != nil { return err } + + // send broadcast status if admin + if err := h.boradcastStatus(session); err != nil { + return err + } } return nil diff --git a/server/internal/websocket/websocket.go b/server/internal/websocket/websocket.go index c7d8523..77e9651 100644 --- a/server/internal/websocket/websocket.go +++ b/server/internal/websocket/websocket.go @@ -16,26 +16,27 @@ import ( "n.eko.moe/neko/internal/utils" ) -func New(sessions types.SessionManager, remote types.RemoteManager, webrtc types.WebRTCManager, conf *config.WebSocket) *WebSocketHandler { +func New(sessions types.SessionManager, remote types.RemoteManager, broadcast types.BroadcastManager, webrtc types.WebRTCManager, conf *config.WebSocket) *WebSocketHandler { logger := log.With().Str("module", "websocket").Logger() return &WebSocketHandler{ - logger: logger, - conf: conf, - sessions: sessions, - remote: remote, - upgrader: websocket.Upgrader{ + logger: logger, + conf: conf, + sessions: sessions, + remote: remote, + upgrader: websocket.Upgrader{ CheckOrigin: func(r *http.Request) bool { return true }, }, handler: &MessageHandler{ - logger: logger.With().Str("subsystem", "handler").Logger(), - remote: remote, - sessions: sessions, - webrtc: webrtc, - banned: make(map[string]bool), - locked: false, + logger: logger.With().Str("subsystem", "handler").Logger(), + remote: remote, + broadcast: broadcast, + sessions: sessions, + webrtc: webrtc, + banned: make(map[string]bool), + locked: false, }, } } @@ -44,13 +45,13 @@ func New(sessions types.SessionManager, remote types.RemoteManager, webrtc types const pingPeriod = 60 * time.Second type WebSocketHandler struct { - logger zerolog.Logger - upgrader websocket.Upgrader - sessions types.SessionManager - remote types.RemoteManager - conf *config.WebSocket - handler *MessageHandler - shutdown chan bool + logger zerolog.Logger + upgrader websocket.Upgrader + sessions types.SessionManager + remote types.RemoteManager + conf *config.WebSocket + handler *MessageHandler + shutdown chan bool } func (ws *WebSocketHandler) Start() error { diff --git a/server/neko.go b/server/neko.go index 447979b..6c3d616 100644 --- a/server/neko.go +++ b/server/neko.go @@ -130,7 +130,7 @@ func (neko *Neko) Start() { webRTCManager := webrtc.New(sessionManager, remoteManager, neko.WebRTC) webRTCManager.Start() - webSocketHandler := websocket.New(sessionManager, remoteManager, webRTCManager, neko.WebSocket) + webSocketHandler := websocket.New(sessionManager, remoteManager, broadcastManager, webRTCManager, neko.WebSocket) webSocketHandler.Start() server := http.New(neko.Server, webSocketHandler) From f6bc7350a8750ebbb30f6e1d4ad5e69f04a8a911 Mon Sep 17 00:00:00 2001 From: m1k1o Date: Sun, 27 Sep 2020 01:13:34 +0200 Subject: [PATCH 06/10] add Broadcast GUI --- client/src/components/settings.vue | 64 ++++++++++++++++++++++++++++++ client/src/locale/en-us.ts | 2 + client/src/neko/events.ts | 11 +++++ client/src/neko/index.ts | 7 ++++ client/src/neko/messages.ts | 15 +++++++ client/src/store/settings.ts | 18 +++++++++ 6 files changed, 117 insertions(+) diff --git a/client/src/components/settings.vue b/client/src/components/settings.vue index b5ae941..612ee18 100644 --- a/client/src/components/settings.vue +++ b/client/src/components/settings.vue @@ -48,6 +48,19 @@ +
  • @@ -220,6 +233,30 @@ } } } + + .input { + display: block; + height: 30px; + text-align: right; + padding: 0 10px; + margin-left: 10px; + line-height: 30px; + text-overflow: ellipsis; + border: 1px solid transparent; + border-radius: 5px; + color: white; + background-color: $background-tertiary; + font-weight: lighter; + user-select: auto; + + &::selection { + background: $text-normal; + } + + &[disabled] { + background: none; + } + } } } } @@ -230,6 +267,12 @@ @Component({ name: 'neko-settings' }) export default class extends Vue { + private broadcast_url: string = ''; + + get admin() { + return this.$accessor.user.admin + } + get connected() { return this.$accessor.connected } @@ -282,6 +325,27 @@ return this.$accessor.settings.keyboard_layout } + get broadcast_is_active() { + return this.$accessor.settings.broadcast_is_active + } + + set broadcast_is_active(value: boolean) { + if (value) { + this.$accessor.settings.broadcastCreate(this.broadcast_url) + } else { + this.$accessor.settings.broadcastDestroy() + } + } + + get broadcast_url_remote() { + return this.$accessor.settings.broadcast_url + } + + @Watch('broadcast_url_remote', { immediate: true }) + onBroadcastUrlChange() { + this.broadcast_url = this.broadcast_url_remote + } + set keyboard_layout(value: string) { this.$accessor.settings.setKeyboardLayout(value) this.$accessor.remote.changeKeyboard() diff --git a/client/src/locale/en-us.ts b/client/src/locale/en-us.ts index 2cb4932..2f91038 100644 --- a/client/src/locale/en-us.ts +++ b/client/src/locale/en-us.ts @@ -61,6 +61,8 @@ export const setting = { ignore_emotes: 'Ignore Emotes', chat_sound: 'Play Chat Sound', keyboard_layout: 'Change Keyboard Layout', + broadcast_is_active: 'Broadcast Enabled', + broadcast_url: 'RTMP url', } export const connection = { diff --git a/client/src/neko/events.ts b/client/src/neko/events.ts index 9298751..b2bb043 100644 --- a/client/src/neko/events.ts +++ b/client/src/neko/events.ts @@ -38,6 +38,11 @@ export const EVENT = { RESOLUTION: 'screen/resolution', SET: 'screen/set', }, + BROADCAST: { + STATUS: "broadcast/status", + CREATE: "broadcast/create", + DESTROY: "broadcast/destroy", + }, ADMIN: { BAN: 'admin/ban', KICK: 'admin/kick', @@ -60,6 +65,7 @@ export type WebSocketEvents = | SignalEvents | ChatEvents | ScreenEvents + | BroadcastEvents | AdminEvents export type ControlEvents = @@ -76,6 +82,11 @@ export type SignalEvents = typeof EVENT.SIGNAL.ANSWER | typeof EVENT.SIGNAL.PROV export type ChatEvents = typeof EVENT.CHAT.MESSAGE | typeof EVENT.CHAT.EMOTE export type ScreenEvents = typeof EVENT.SCREEN.CONFIGURATIONS | typeof EVENT.SCREEN.RESOLUTION | typeof EVENT.SCREEN.SET +export type BroadcastEvents = + | typeof EVENT.BROADCAST.STATUS + | typeof EVENT.BROADCAST.CREATE + | typeof EVENT.BROADCAST.DESTROY + export type AdminEvents = | typeof EVENT.ADMIN.BAN | typeof EVENT.ADMIN.KICK diff --git a/client/src/neko/index.ts b/client/src/neko/index.ts index e1f5b83..6769827 100644 --- a/client/src/neko/index.ts +++ b/client/src/neko/index.ts @@ -326,6 +326,13 @@ export class NekoClient extends BaseClient implements EventEmitter { }) } + ///////////////////////////// + // Broadcast Events + ///////////////////////////// + protected [EVENT.BROADCAST.STATUS](payload: BroadcastStatusPayload) { + this.$accessor.settings.broadcastStatus(payload) + } + ///////////////////////////// // Admin Events ///////////////////////////// diff --git a/client/src/neko/messages.ts b/client/src/neko/messages.ts index 27c737b..cc4ced5 100644 --- a/client/src/neko/messages.ts +++ b/client/src/neko/messages.ts @@ -22,6 +22,7 @@ export type WebSocketMessages = | ScreenResolutionMessage | ScreenConfigurationsMessage | ChatMessage + | BroadcastCreateMessage export type WebSocketPayloads = | SignalProvidePayload @@ -37,6 +38,7 @@ export type WebSocketPayloads = | ScreenResolutionPayload | ScreenConfigurationsPayload | AdminPayload + | BroadcastStatusPayload export interface WebSocketMessage { event: WebSocketEvents | string @@ -177,6 +179,19 @@ export interface ScreenConfigurationsPayload { configurations: ScreenConfigurations } +/* + BROADCAST PAYLOADS +*/ +export interface BroadcastCreateMessage extends WebSocketMessage { + event: typeof EVENT.BROADCAST.CREATE + url: string +} + +export interface BroadcastStatusPayload extends WebSocketMessage { + url: string + isActive: boolean +} + /* ADMIN PAYLOADS */ diff --git a/client/src/store/settings.ts b/client/src/store/settings.ts index eb1295d..96c0c56 100644 --- a/client/src/store/settings.ts +++ b/client/src/store/settings.ts @@ -1,5 +1,6 @@ import { getterTree, mutationTree, actionTree } from 'typed-vuex' import { get, set } from '~/utils/localstorage' +import { EVENT } from '~/neko/events' import { accessor } from '~/store' export const namespaced = true @@ -18,6 +19,9 @@ export const state = () => { keyboard_layout: get('keyboard_layout', 'us'), keyboard_layouts_list: {} as KeyboardLayouts, + + broadcast_is_active: false, + broadcast_url: "", } } @@ -57,6 +61,10 @@ export const mutations = mutationTree(state, { setKeyboardLayoutsList(state, value: KeyboardLayouts) { state.keyboard_layouts_list = value }, + setBroadcastStatus(state, { url, isActive }) { + state.broadcast_url = url, + state.broadcast_is_active = isActive + }, }) export const actions = actionTree( @@ -71,5 +79,15 @@ export const actions = actionTree( }) .catch(console.error) }, + + broadcastStatus({ getters }, { url, isActive }) { + accessor.settings.setBroadcastStatus({ url, isActive }) + }, + broadcastCreate({ getters }, url: string) { + $client.sendMessage(EVENT.BROADCAST.CREATE, { url }) + }, + broadcastDestroy({ getters }) { + $client.sendMessage(EVENT.BROADCAST.DESTROY) + }, }, ) From a347b3e7b416381be279dd62a0981a96f6aaaee5 Mon Sep 17 00:00:00 2001 From: m1k1o Date: Sun, 27 Sep 2020 01:14:21 +0200 Subject: [PATCH 07/10] update packages --- client/package.json | 56 ++++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/client/package.json b/client/package.json index 6497810..1bd2179 100644 --- a/client/package.json +++ b/client/package.json @@ -19,49 +19,49 @@ "lint": "vue-cli-service lint" }, "dependencies": { - "@fortawesome/fontawesome-free": "^5.13.0", - "animejs": "^3.1.0", + "@fortawesome/fontawesome-free": "^5.14.0", + "animejs": "^3.2.0", "axios": "^0.19.1", - "date-fns": "^2.11.1", + "date-fns": "^2.16.1", "emoji-datasource": "^5.0.1", "emojilib": "^2.4.0", - "eventemitter3": "^4.0.0", + "eventemitter3": "^4.0.7", "resize-observer-polyfill": "^1.5.1", "simple-markdown": "^0.7.2", - "sweetalert2": "^9.10.9", - "typed-vuex": "^0.1.17", + "sweetalert2": "^9.17.2", + "typed-vuex": "^0.1.21", "v-tooltip": "^2.0.3", - "vue": "^2.6.10", - "vue-class-component": "^7.2.3", + "vue": "^2.6.12", + "vue-class-component": "^7.2.6", "vue-clickaway": "^2.2.2", - "vue-context": "^5.1.0", - "vue-i18n": "^8.16.0", + "vue-context": "^5.2.0", + "vue-i18n": "^8.21.1", "vue-notification": "^1.3.20", - "vue-property-decorator": "^8.4.1", - "vuex": "^3.1.3" + "vue-property-decorator": "^8.5.1", + "vuex": "^3.5.1" }, "devDependencies": { - "@types/animejs": "^3.1.0", - "@types/node": "^13.7.0", + "@types/animejs": "^3.1.2", + "@types/node": "^13.13.21", "@types/vue": "^2.0.0", "@types/vue-clickaway": "^2.2.0", - "@typescript-eslint/eslint-plugin": "^2.26.0", - "@typescript-eslint/parser": "^2.26.0", - "@vue/cli-plugin-babel": "^4.1.0", - "@vue/cli-plugin-eslint": "^4.1.0", - "@vue/cli-plugin-typescript": "^4.1.0", - "@vue/cli-plugin-vuex": "^4.1.0", - "@vue/cli-service": "^4.1.0", + "@typescript-eslint/eslint-plugin": "^2.34.0", + "@typescript-eslint/parser": "^2.34.0", + "@vue/cli-plugin-babel": "^4.5.6", + "@vue/cli-plugin-eslint": "^4.5.6", + "@vue/cli-plugin-typescript": "^4.5.6", + "@vue/cli-plugin-vuex": "^4.5.6", + "@vue/cli-service": "^4.5.6", "@vue/eslint-config-prettier": "^6.0.0", - "@vue/eslint-config-typescript": "^5.0.2", + "@vue/eslint-config-typescript": "^5.1.0", "eslint": "^6.8.0", - "eslint-plugin-prettier": "^3.1.1", + "eslint-plugin-prettier": "^3.1.4", "eslint-plugin-vue": "^6.2.2", - "node-sass": "^4.12.0", - "prettier": "^2.0.2", + "node-sass": "^4.14.1", + "prettier": "^2.1.2", "sass-loader": "^8.0.0", - "ts-node": "^8.6.2", - "typescript": "^3.8.3", - "vue-template-compiler": "^2.6.10" + "ts-node": "^8.10.2", + "typescript": "^3.9.7", + "vue-template-compiler": "^2.6.12" } } From 16e2481c1c4cf502bdfb73fdfb4195bf69452c57 Mon Sep 17 00:00:00 2001 From: m1k1o Date: Sun, 27 Sep 2020 01:17:20 +0200 Subject: [PATCH 08/10] comment out unused configs --- server/internal/types/config/broadcast.go | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/server/internal/types/config/broadcast.go b/server/internal/types/config/broadcast.go index bfef102..f928448 100644 --- a/server/internal/types/config/broadcast.go +++ b/server/internal/types/config/broadcast.go @@ -6,22 +6,16 @@ import ( ) type Broadcast struct { - Enabled bool - RTMP string + // Enabled bool // AudioParams string // VideoParams string } func (Broadcast) Init(cmd *cobra.Command) error { - cmd.PersistentFlags().Bool("broadcast", false, "turn on boradcasting") - if err := viper.BindPFlag("broadcast", cmd.PersistentFlags().Lookup("broadcast")); err != nil { - return err - } - - cmd.PersistentFlags().String("rtmp", "", "RMTP url for broadcasting") - if err := viper.BindPFlag("rtmp", cmd.PersistentFlags().Lookup("rtmp")); err != nil { - return err - } + // cmd.PersistentFlags().Bool("broadcast", false, "enable boradcasting") + // if err := viper.BindPFlag("broadcast", cmd.PersistentFlags().Lookup("broadcast")); err != nil { + // return err + // } // cmd.PersistentFlags().String("cast_audio", "", "audio codec parameters to use for broadcasting") // if err := viper.BindPFlag("cast_audio", cmd.PersistentFlags().Lookup("cast_audio")); err != nil { @@ -37,8 +31,7 @@ func (Broadcast) Init(cmd *cobra.Command) error { } func (s *Broadcast) Set() { - s.Enabled = viper.GetBool("broadcast") - s.RTMP = viper.GetString("rtmp") + // s.Enabled = viper.GetBool("broadcast") // s.AudioParams = viper.GetString("cast_audio") // s.VideoParams = viper.GetString("cast_video") } From aa1a3ec413370de4631ec4b0d0712141daa57f02 Mon Sep 17 00:00:00 2001 From: m1k1o Date: Sun, 27 Sep 2020 01:34:18 +0200 Subject: [PATCH 09/10] fix client bugs --- client/src/neko/index.ts | 1 + client/src/neko/messages.ts | 7 +++---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/client/src/neko/index.ts b/client/src/neko/index.ts index 6769827..5913175 100644 --- a/client/src/neko/index.ts +++ b/client/src/neko/index.ts @@ -18,6 +18,7 @@ import { ControlClipboardPayload, ScreenConfigurationsPayload, ScreenResolutionPayload, + BroadcastStatusPayload, AdminPayload, AdminTargetPayload, } from './messages' diff --git a/client/src/neko/messages.ts b/client/src/neko/messages.ts index cc4ced5..3530c7c 100644 --- a/client/src/neko/messages.ts +++ b/client/src/neko/messages.ts @@ -22,7 +22,6 @@ export type WebSocketMessages = | ScreenResolutionMessage | ScreenConfigurationsMessage | ChatMessage - | BroadcastCreateMessage export type WebSocketPayloads = | SignalProvidePayload @@ -39,6 +38,7 @@ export type WebSocketPayloads = | ScreenConfigurationsPayload | AdminPayload | BroadcastStatusPayload + | BroadcastCreatePayload export interface WebSocketMessage { event: WebSocketEvents | string @@ -182,12 +182,11 @@ export interface ScreenConfigurationsPayload { /* BROADCAST PAYLOADS */ -export interface BroadcastCreateMessage extends WebSocketMessage { - event: typeof EVENT.BROADCAST.CREATE +export interface BroadcastCreatePayload { url: string } -export interface BroadcastStatusPayload extends WebSocketMessage { +export interface BroadcastStatusPayload { url: string isActive: boolean } From 88c0337a164345d269364fb2819fe0916b3c2873 Mon Sep 17 00:00:00 2001 From: m1k1o Date: Sun, 27 Sep 2020 01:34:33 +0200 Subject: [PATCH 10/10] remove broadcast Config --- server/cmd/serve.go | 1 - server/internal/broadcast/manager.go | 4 +-- server/internal/types/config/broadcast.go | 37 ----------------------- server/neko.go | 4 +-- 4 files changed, 2 insertions(+), 44 deletions(-) delete mode 100644 server/internal/types/config/broadcast.go diff --git a/server/cmd/serve.go b/server/cmd/serve.go index b6a7807..2c7dfde 100644 --- a/server/cmd/serve.go +++ b/server/cmd/serve.go @@ -20,7 +20,6 @@ func init() { neko.Service.Server, neko.Service.WebRTC, neko.Service.Remote, - neko.Service.Broadcast, neko.Service.WebSocket, } diff --git a/server/internal/broadcast/manager.go b/server/internal/broadcast/manager.go index bca83cf..8937ffa 100644 --- a/server/internal/broadcast/manager.go +++ b/server/internal/broadcast/manager.go @@ -12,16 +12,14 @@ type BroadcastManager struct { logger zerolog.Logger pipeline *gst.Pipeline remote *config.Remote - config *config.Broadcast enabled bool url string } -func New(remote *config.Remote, config *config.Broadcast) *BroadcastManager { +func New(remote *config.Remote) *BroadcastManager { return &BroadcastManager{ logger: log.With().Str("module", "remote").Logger(), remote: remote, - config: config, enabled: false, url: "", } diff --git a/server/internal/types/config/broadcast.go b/server/internal/types/config/broadcast.go deleted file mode 100644 index f928448..0000000 --- a/server/internal/types/config/broadcast.go +++ /dev/null @@ -1,37 +0,0 @@ -package config - -import ( - "github.com/spf13/cobra" - "github.com/spf13/viper" -) - -type Broadcast struct { - // Enabled bool - // AudioParams string - // VideoParams string -} - -func (Broadcast) Init(cmd *cobra.Command) error { - // cmd.PersistentFlags().Bool("broadcast", false, "enable boradcasting") - // if err := viper.BindPFlag("broadcast", cmd.PersistentFlags().Lookup("broadcast")); err != nil { - // return err - // } - - // cmd.PersistentFlags().String("cast_audio", "", "audio codec parameters to use for broadcasting") - // if err := viper.BindPFlag("cast_audio", cmd.PersistentFlags().Lookup("cast_audio")); err != nil { - // return err - // } - - // cmd.PersistentFlags().String("cast_video", "", "video codec parameters to use for broadcasting") - // if err := viper.BindPFlag("cast_video", cmd.PersistentFlags().Lookup("cast_video")); err != nil { - // return err - // } - - return nil -} - -func (s *Broadcast) Set() { - // s.Enabled = viper.GetBool("broadcast") - // s.AudioParams = viper.GetString("cast_audio") - // s.VideoParams = viper.GetString("cast_video") -} diff --git a/server/neko.go b/server/neko.go index 6c3d616..7d4dabb 100644 --- a/server/neko.go +++ b/server/neko.go @@ -62,7 +62,6 @@ func init() { Root: &config.Root{}, Server: &config.Server{}, Remote: &config.Remote{}, - Broadcast: &config.Broadcast{}, WebRTC: &config.WebRTC{}, WebSocket: &config.WebSocket{}, } @@ -101,7 +100,6 @@ type Neko struct { Version *Version Root *config.Root Remote *config.Remote - Broadcast *config.Broadcast Server *config.Server WebRTC *config.WebRTC WebSocket *config.WebSocket @@ -120,7 +118,7 @@ func (neko *Neko) Preflight() { } func (neko *Neko) Start() { - broadcastManager := broadcast.New(neko.Remote, neko.Broadcast) + broadcastManager := broadcast.New(neko.Remote) remoteManager := remote.New(neko.Remote, broadcastManager) remoteManager.Start()