From f02d18654d63d0f2f4bf44de60397bce9a18857e Mon Sep 17 00:00:00 2001 From: Sergey Stepanov Date: Mon, 11 Sep 2023 20:27:06 +0300 Subject: [PATCH] Move media outta a room --- pkg/worker/coordinatorhandlers.go | 21 +++++++++++++++---- pkg/worker/media.go | 25 +++++++++++++++++----- pkg/worker/room.go | 35 ++++++++++--------------------- pkg/worker/room_test.go | 18 +++++++++++++--- 4 files changed, 63 insertions(+), 36 deletions(-) diff --git a/pkg/worker/coordinatorhandlers.go b/pkg/worker/coordinatorhandlers.go index 1519f4e75..46f133c19 100644 --- a/pkg/worker/coordinatorhandlers.go +++ b/pkg/worker/coordinatorhandlers.go @@ -108,13 +108,26 @@ func (c *coordinator) HandleGameStart(rq api.StartGameRequest[com.Uid], w *Worke return api.EmptyPacket } - // make the room - r, err := NewRoom(uid, app, w.conf, w.log.Extend(w.log.With().Str("room", uid[:5]))) - if err != nil { - c.log.Error().Err(err).Msgf("room fail") + logR := w.log.Extend(w.log.With().Str("room", uid[:5])) + aw, ah := app.ViewportSize() + + media := &WebrtcMediaPipe{ + aConf: w.conf.Encoder.Audio, + vConf: w.conf.Encoder.Video, + AudioSrcHz: app.AudioSampleRate(), + AudioFrame: w.conf.Encoder.Audio.Frame, + VideoW: aw, + VideoH: ah, + log: logR, + } + if err := media.Init(); err != nil { + c.log.Error().Err(err).Msgf("couldn't init the media") app.Close() return api.EmptyPacket } + + // make the room + r := NewRoom(uid, app, media, logR) r.HandleClose = func(room *Room) { w.router.Clear() c.CloseRoom(room.id) diff --git a/pkg/worker/media.go b/pkg/worker/media.go index 44ac1c9a0..1b7115224 100644 --- a/pkg/worker/media.go +++ b/pkg/worker/media.go @@ -107,12 +107,17 @@ type WebrtcMediaPipe struct { audioBuf buffer log *logger.Logger enc *encoder.VideoEncoder -} -func NewWebrtcMediaPipe(log *logger.Logger) *WebrtcMediaPipe { - return &WebrtcMediaPipe{log: log} + aConf config.Audio + vConf config.Video + + AudioSrcHz int + AudioFrame int + VideoW, VideoH int } +func (wmp *WebrtcMediaPipe) AudioSettings() (frame int) { return wmp.AudioFrame } + func (wmp *WebrtcMediaPipe) SetAudioCb(cb func([]byte)) { wmp.onAudio = cb } func (wmp *WebrtcMediaPipe) Destroy() { if wmp.enc != nil { @@ -121,7 +126,17 @@ func (wmp *WebrtcMediaPipe) Destroy() { } func (wmp *WebrtcMediaPipe) PushAudio(audio []int16) { wmp.audioBuf.write(audio, wmp.encodeAudio) } -func (wmp *WebrtcMediaPipe) InitAudio(srcHz int, frameSize int) error { +func (wmp *WebrtcMediaPipe) Init() error { + if err := wmp.initAudio(wmp.AudioSrcHz, wmp.AudioFrame); err != nil { + return err + } + if err := wmp.initVideo(wmp.VideoW, wmp.VideoH, wmp.vConf); err != nil { + return err + } + return nil +} + +func (wmp *WebrtcMediaPipe) initAudio(srcHz int, frameSize int) error { au, err := DefaultOpus() if err != nil { return fmt.Errorf("opus fail: %w", err) @@ -148,7 +163,7 @@ func (wmp *WebrtcMediaPipe) encodeAudio(pcm samples) { wmp.onAudio(data) } -func (wmp *WebrtcMediaPipe) InitVideo(w, h int, conf config.Video) error { +func (wmp *WebrtcMediaPipe) initVideo(w, h int, conf config.Video) error { var enc encoder.Encoder var err error wmp.log.Info().Msgf("Video codec: %v", conf.Codec) diff --git a/pkg/worker/room.go b/pkg/worker/room.go index 3c2997f3b..2b0aadea6 100644 --- a/pkg/worker/room.go +++ b/pkg/worker/room.go @@ -5,7 +5,6 @@ import ( "time" "github.com/giongto35/cloud-game/v3/pkg/com" - "github.com/giongto35/cloud-game/v3/pkg/config" "github.com/giongto35/cloud-game/v3/pkg/logger" "github.com/giongto35/cloud-game/v3/pkg/worker/caged/app" ) @@ -21,9 +20,9 @@ type AppRoom interface { } type MediaPipe interface { + AudioSettings() (frame int) Destroy() - InitAudio(srcHz int, frameSize int) error - InitVideo(w, h int, conf config.Video) error + Init() error // PushAudio pushes the 16bit PCM audio frames into an encoder. // Because we need to fill the buffer, the SetAudioCb should be // used in order to get the result. @@ -45,23 +44,16 @@ type Room struct { HandleClose func(self *Room) } -func NewRoom(id string, app app.App, conf config.WorkerConfig, log *logger.Logger) (*Room, error) { - room := &Room{id: id, app: app, users: com.NewNetMap[Session](), log: log, media: NewWebrtcMediaPipe(log)} - w, h := app.ViewportSize() - if err := room.initVideo(w, h, conf.Encoder.Video); err != nil { - return nil, err - } - if err := room.initAudio(app.AudioSampleRate(), conf.Encoder.Audio.Frame); err != nil { - return nil, err - } - return room, nil +func NewRoom(id string, app app.App, media MediaPipe, log *logger.Logger) *Room { + room := &Room{id: id, app: app, users: com.NewNetMap[Session](), log: log, media: media} + room.initVideo() + room.initAudio() + return room } -func (r *Room) initAudio(srcHz int, frame int) error { - if err := r.media.InitAudio(srcHz, frame); err != nil { - return err - } - duration := int32(time.Duration(frame) * time.Millisecond) +func (r *Room) initAudio() { + frameLen := r.media.AudioSettings() + duration := int32(time.Duration(frameLen) * time.Millisecond) emulator(r.app).SetAudioCb(func(raw app.Audio) { r.media.PushAudio(raw.Data) }) // 1 r.media.SetAudioCb(func(data []byte) { // 2 r.users.ForEach(func(u Session) { @@ -70,13 +62,9 @@ func (r *Room) initAudio(srcHz int, frame int) error { } }) }) - return nil } -func (r *Room) initVideo(w, h int, conf config.Video) error { - if err := r.media.InitVideo(w, h, conf); err != nil { - return err - } +func (r *Room) initVideo() { emulator(r.app).SetVideoCb(func(raw app.Video) { data := r.media.ProcessVideo(raw) r.users.ForEach(func(u Session) { @@ -85,7 +73,6 @@ func (r *Room) initVideo(w, h int, conf config.Video) error { } }) }) - return nil } func (r *Room) App() app.App { return r.app } diff --git a/pkg/worker/room_test.go b/pkg/worker/room_test.go index be24d9330..a8802b330 100644 --- a/pkg/worker/room_test.go +++ b/pkg/worker/room_test.go @@ -234,10 +234,22 @@ func getRoomMock(cfg roomMockConfig) roomMock { l.Fatal().Err(err).Msgf("couldn't load the game %v", cfg.game) } - room, err := NewRoom(roomId, emu, conf, l) - if err != nil { - l.Fatal().Err(err).Msgf("room creation fail") + aw, ah := emu.ViewportSize() + + media := &WebrtcMediaPipe{ + aConf: conf.Encoder.Audio, + vConf: conf.Encoder.Video, + AudioSrcHz: emu.AudioSampleRate(), + AudioFrame: conf.Encoder.Audio.Frame, + VideoW: aw, + VideoH: ah, + log: l, } + if err := media.Init(); err != nil { + l.Fatal().Err(err).Msgf("no init") + } + + room := NewRoom(roomId, emu, media, l) if !cfg.dontStartEmulator { room.StartApp() }