From 728e27da34e6c308d3f72b8ce56149f60a4846db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0ediv=C3=BD?= Date: Sun, 16 Apr 2023 23:34:02 +0200 Subject: [PATCH] minor changes, moving things around. --- internal/webrtc/manager.go | 41 +++++++++------ internal/webrtc/peer.go | 79 ++++++++++++++-------------- internal/websocket/handler/signal.go | 11 +++- pkg/types/webrtc.go | 5 +- 4 files changed, 75 insertions(+), 61 deletions(-) diff --git a/internal/webrtc/manager.go b/internal/webrtc/manager.go index 2aa24ce1..536d4fd3 100644 --- a/internal/webrtc/manager.go +++ b/internal/webrtc/manager.go @@ -26,24 +26,32 @@ import ( "github.com/demodesk/neko/pkg/types/message" ) -// the duration without network activity before a Agent is considered disconnected. Default is 5 Seconds -const disconnectedTimeout = 4 * time.Second +const ( + // size of receiving channel used to buffer incoming TCP packets + tcpReadChanBufferSize = 50 -// the duration without network activity before a Agent is considered failed after disconnected. Default is 25 Seconds -const failedTimeout = 6 * time.Second + // size of buffer used to buffer outgoing TCP packets. Default is 4MB + tcpWriteBufferSizeInBytes = 4 * 1024 * 1024 -// how often the ICE Agent sends extra traffic if there is no activity, if media is flowing no traffic will be sent. Default is 2 seconds -const keepAliveInterval = 2 * time.Second + // the duration without network activity before a Agent is considered disconnected. Default is 5 Seconds + disconnectedTimeout = 4 * time.Second -// send a PLI on an interval so that the publisher is pushing a keyframe every rtcpPLIInterval -const rtcpPLIInterval = 3 * time.Second + // the duration without network activity before a Agent is considered failed after disconnected. Default is 25 Seconds + failedTimeout = 6 * time.Second -// how often we check the bitrate of each client. Default is 250ms -const bitrateCheckInterval = 250 * time.Millisecond + // how often the ICE Agent sends extra traffic if there is no activity, if media is flowing no traffic will be sent. Default is 2 seconds + keepAliveInterval = 2 * time.Second + + // send a PLI on an interval so that the publisher is pushing a keyframe every rtcpPLIInterval + rtcpPLIInterval = 3 * time.Second + + // how often we check the bitrate of each client. Default is 250ms + bitrateCheckInterval = 250 * time.Millisecond +) func New(desktop types.DesktopManager, capture types.CaptureManager, config *config.WebRTC) *WebRTCManagerCtx { configuration := webrtc.Configuration{ - SDPSemantics: webrtc.SDPSemanticsUnifiedPlanWithFallback, + SDPSemantics: webrtc.SDPSemanticsUnifiedPlan, } if !config.ICELite { @@ -112,14 +120,14 @@ func (manager *WebRTCManagerCtx) Start() { }) if err != nil { - manager.logger.Panic().Err(err).Msg("unable to setup ice TCP mux") + manager.logger.Fatal().Err(err).Msg("unable to setup ice TCP mux") } manager.tcpMux = ice.NewTCPMuxDefault(ice.TCPMuxParams{ Listener: tcpListener, Logger: logger.NewLogger("ice-tcp"), - ReadBufferSize: 32, // receiving channel size - WriteBufferSize: 4 * 1024 * 1024, // write buffer size, 4MB + ReadBufferSize: tcpReadChanBufferSize, + WriteBufferSize: tcpWriteBufferSizeInBytes, }) } @@ -131,7 +139,7 @@ func (manager *WebRTCManagerCtx) Start() { ) if err != nil { - manager.logger.Panic().Err(err).Msg("unable to setup ice UDP mux") + manager.logger.Fatal().Err(err).Msg("unable to setup ice UDP mux") } } @@ -174,6 +182,7 @@ func (manager *WebRTCManagerCtx) newPeerConnection(bitrate int, codecs []codec.R LoggerFactory: pionlog.New(logger), } + settings.DisableMediaEngineCopy(true) settings.SetICETimeouts(disconnectedTimeout, failedTimeout, keepAliveInterval) settings.SetNAT1To1IPs(manager.config.NAT1To1IPs, webrtc.ICECandidateTypeHost) settings.SetLite(manager.config.ICELite) @@ -361,7 +370,7 @@ func (manager *WebRTCManagerCtx) CreatePeer(session types.Session, bitrate int, iceTrickle: manager.config.ICETrickle, } - manager.logger.Info(). + logger.Info(). Int("target_bitrate", bitrate). Msg("estimated initial peer bitrate") diff --git a/internal/webrtc/peer.go b/internal/webrtc/peer.go index ca9b01ad..311276c4 100644 --- a/internal/webrtc/peer.go +++ b/internal/webrtc/peer.go @@ -32,6 +32,10 @@ type WebRTCPeerCtx struct { iceTrickle bool } +// +// connection +// + func (peer *WebRTCPeerCtx) CreateOffer(ICERestart bool) (*webrtc.SessionDescription, error) { peer.mu.Lock() defer peer.mu.Unlock() @@ -77,24 +81,11 @@ func (peer *WebRTCPeerCtx) setLocalDescription(description webrtc.SessionDescrip return peer.connection.LocalDescription(), nil } -func (peer *WebRTCPeerCtx) SetOffer(sdp string) error { +func (peer *WebRTCPeerCtx) SetRemoteDescription(desc webrtc.SessionDescription) error { peer.mu.Lock() defer peer.mu.Unlock() - return peer.connection.SetRemoteDescription(webrtc.SessionDescription{ - SDP: sdp, - Type: webrtc.SDPTypeOffer, - }) -} - -func (peer *WebRTCPeerCtx) SetAnswer(sdp string) error { - peer.mu.Lock() - defer peer.mu.Unlock() - - return peer.connection.SetRemoteDescription(webrtc.SessionDescription{ - SDP: sdp, - Type: webrtc.SDPTypeAnswer, - }) + return peer.connection.SetRemoteDescription(desc) } func (peer *WebRTCPeerCtx) SetCandidate(candidate webrtc.ICECandidateInit) error { @@ -104,6 +95,21 @@ func (peer *WebRTCPeerCtx) SetCandidate(candidate webrtc.ICECandidateInit) error return peer.connection.AddICECandidate(candidate) } +func (peer *WebRTCPeerCtx) Destroy() { + peer.mu.Lock() + defer peer.mu.Unlock() + + if peer.connection != nil { + err := peer.connection.Close() + peer.logger.Err(err).Msg("peer connection destroyed") + peer.connection = nil + } +} + +// +// video +// + func (peer *WebRTCPeerCtx) SetVideoBitrate(peerBitrate int) error { peer.mu.Lock() defer peer.mu.Unlock() @@ -198,6 +204,24 @@ func (peer *WebRTCPeerCtx) SetPaused(isPaused bool) error { return nil } +func (peer *WebRTCPeerCtx) SetVideoAuto(videoAuto bool) { + // if estimator is enabled, enable video auto bitrate + if peer.estimator != nil { + peer.videoTrack.SetVideoAuto(videoAuto) + } else { + peer.logger.Warn().Msg("estimator is disabled or in passive mode, cannot change video auto") + peer.videoTrack.SetVideoAuto(false) // ensure video auto is disabled + } +} + +func (peer *WebRTCPeerCtx) VideoAuto() bool { + return peer.videoTrack.VideoAuto() +} + +// +// data channel +// + func (peer *WebRTCPeerCtx) SendCursorPosition(x, y int) error { peer.mu.Lock() defer peer.mu.Unlock() @@ -257,28 +281,3 @@ func (peer *WebRTCPeerCtx) SendCursorImage(cur *types.CursorImage, img []byte) e return peer.dataChannel.Send(buffer.Bytes()) } - -func (peer *WebRTCPeerCtx) Destroy() { - peer.mu.Lock() - defer peer.mu.Unlock() - - if peer.connection != nil { - err := peer.connection.Close() - peer.logger.Err(err).Msg("peer connection destroyed") - peer.connection = nil - } -} - -func (peer *WebRTCPeerCtx) SetVideoAuto(videoAuto bool) { - // if estimator is enabled, enable video auto bitrate - if peer.estimator != nil { - peer.videoTrack.SetVideoAuto(videoAuto) - } else { - peer.logger.Warn().Msg("estimator is disabled or in passive mode, cannot change video auto") - peer.videoTrack.SetVideoAuto(false) // ensure video auto is disabled - } -} - -func (peer *WebRTCPeerCtx) VideoAuto() bool { - return peer.videoTrack.VideoAuto() -} diff --git a/internal/websocket/handler/signal.go b/internal/websocket/handler/signal.go index f596f61d..f25f2bc1 100644 --- a/internal/websocket/handler/signal.go +++ b/internal/websocket/handler/signal.go @@ -6,6 +6,7 @@ import ( "github.com/demodesk/neko/pkg/types" "github.com/demodesk/neko/pkg/types/event" "github.com/demodesk/neko/pkg/types/message" + "github.com/pion/webrtc/v3" ) func (h *MessageHandlerCtx) signalRequest(session types.Session, payload *message.SignalVideo) error { @@ -83,7 +84,10 @@ func (h *MessageHandlerCtx) signalOffer(session types.Session, payload *message. return errors.New("webRTC peer does not exist") } - err := peer.SetOffer(payload.SDP) + err := peer.SetRemoteDescription(webrtc.SessionDescription{ + SDP: payload.SDP, + Type: webrtc.SDPTypeOffer, + }) if err != nil { return err } @@ -108,7 +112,10 @@ func (h *MessageHandlerCtx) signalAnswer(session types.Session, payload *message return errors.New("webRTC peer does not exist") } - return peer.SetAnswer(payload.SDP) + return peer.SetRemoteDescription(webrtc.SessionDescription{ + SDP: payload.SDP, + Type: webrtc.SDPTypeAnswer, + }) } func (h *MessageHandlerCtx) signalCandidate(session types.Session, payload *message.SignalCandidate) error { diff --git a/pkg/types/webrtc.go b/pkg/types/webrtc.go index ad5c503d..b255e6da 100644 --- a/pkg/types/webrtc.go +++ b/pkg/types/webrtc.go @@ -20,9 +20,8 @@ type ICEServer struct { type WebRTCPeer interface { CreateOffer(ICERestart bool) (*webrtc.SessionDescription, error) CreateAnswer() (*webrtc.SessionDescription, error) - SetOffer(sdp string) error - SetAnswer(sdp string) error - SetCandidate(candidate webrtc.ICECandidateInit) error + SetRemoteDescription(webrtc.SessionDescription) error + SetCandidate(webrtc.ICECandidateInit) error SetVideoBitrate(bitrate int) error SetVideoID(videoID string) error