diff --git a/internal/types/event/events.go b/internal/types/event/events.go index 1f6cc26e..3d767960 100644 --- a/internal/types/event/events.go +++ b/internal/types/event/events.go @@ -11,6 +11,7 @@ const ( SIGNAL_ANSWER = "signal/answer" SIGNAL_PROVIDE = "signal/provide" SIGNAL_CANDIDATE = "signal/candidate" + SIGNAL_VIDEO = "signal/video" ) const ( diff --git a/internal/types/message/messages.go b/internal/types/message/messages.go index fff6313b..7c6d7aaf 100644 --- a/internal/types/message/messages.go +++ b/internal/types/message/messages.go @@ -57,6 +57,11 @@ type SignalAnswer struct { SDP string `json:"sdp"` } +type SignalVideo struct { + Event string `json:"event,omitempty"` + VideoID string `json:"video_id"` +} + ///////////////////////////// // Member ///////////////////////////// diff --git a/internal/webrtc/manager.go b/internal/webrtc/manager.go index 0b59c9cd..aaf9d81c 100644 --- a/internal/webrtc/manager.go +++ b/internal/webrtc/manager.go @@ -57,6 +57,8 @@ func (manager *WebRTCManagerCtx) Start() { videoIDs := manager.capture.VideoIDs() manager.videoTracks = map[string]*webrtc.TrackLocalStaticSample{} for _, videoID := range videoIDs { + videoID := videoID + video, ok := manager.capture.Video(videoID) if !ok { manager.logger.Warn().Str("videoID", videoID).Msg("video stream not found, skipping") @@ -65,12 +67,12 @@ func (manager *WebRTCManagerCtx) Start() { track, err := webrtc.NewTrackLocalStaticSample(video.Codec().Capability, "video", "stream") if err != nil { - manager.logger.Panic().Err(err).Msgf("unable to create video (%s) track", videoID) + manager.logger.Panic().Err(err).Str("videoID", videoID).Msg("unable to create video track") } video.OnSample(func(sample types.Sample) { if err := track.WriteSample(media.Sample(sample)); err != nil && err != io.ErrClosedPipe { - manager.logger.Warn().Err(err).Msgf("video (%s) pipeline failed to write", videoID) + manager.logger.Warn().Err(err).Str("videoID", videoID).Msg("vide pipeline failed to write") } }) @@ -141,16 +143,12 @@ func (manager *WebRTCManagerCtx) CreatePeer(session types.Session) (*webrtc.Sess }) } - _, err = connection.AddTransceiverFromTrack(manager.audioTrack, webrtc.RtpTransceiverInit{ - Direction: webrtc.RTPTransceiverDirectionSendonly, - }) + _, err = connection.AddTrack(manager.audioTrack) if err != nil { return nil, err } - videoTransceiver, err := connection.AddTransceiverFromTrack(manager.videoTracks[manager.defaultVideoID], webrtc.RtpTransceiverInit{ - Direction: webrtc.RTPTransceiverDirectionSendonly, - }) + videoSender, err := connection.AddTrack(manager.videoTracks[manager.defaultVideoID]) if err != nil { return nil, err } @@ -206,13 +204,13 @@ func (manager *WebRTCManagerCtx) CreatePeer(session types.Session) (*webrtc.Sess }) session.SetWebRTCPeer(&WebRTCPeerCtx{ - api: api, - engine: engine, - settings: settings, - connection: connection, - configuration: configuration, - videoTracks: manager.videoTracks, - videoTransceiver: videoTransceiver, + api: api, + engine: engine, + settings: settings, + connection: connection, + configuration: configuration, + videoTracks: manager.videoTracks, + videoSender: videoSender, }) return connection.LocalDescription(), nil diff --git a/internal/webrtc/peer.go b/internal/webrtc/peer.go index 2c72e048..284f1a10 100644 --- a/internal/webrtc/peer.go +++ b/internal/webrtc/peer.go @@ -7,13 +7,13 @@ import ( ) type WebRTCPeerCtx struct { - api *webrtc.API - engine *webrtc.MediaEngine - settings *webrtc.SettingEngine - connection *webrtc.PeerConnection - configuration *webrtc.Configuration - videoTracks map[string]*webrtc.TrackLocalStaticSample - videoTransceiver *webrtc.RTPTransceiver + api *webrtc.API + engine *webrtc.MediaEngine + settings *webrtc.SettingEngine + connection *webrtc.PeerConnection + configuration *webrtc.Configuration + videoTracks map[string]*webrtc.TrackLocalStaticSample + videoSender *webrtc.RTPSender } func (webrtc_peer *WebRTCPeerCtx) SignalAnswer(sdp string) error { @@ -33,7 +33,7 @@ func (webrtc_peer *WebRTCPeerCtx) SetVideoID(videoID string) error { return fmt.Errorf("videoID not found in available tracks") } - return webrtc_peer.videoTransceiver.Sender().ReplaceTrack(track) + return webrtc_peer.videoSender.ReplaceTrack(track) } func (webrtc_peer *WebRTCPeerCtx) Destroy() error { diff --git a/internal/websocket/handler/handler.go b/internal/websocket/handler/handler.go index 2a1ef34a..95e59c2f 100644 --- a/internal/websocket/handler/handler.go +++ b/internal/websocket/handler/handler.go @@ -59,6 +59,11 @@ func (h *MessageHandlerCtx) Message(session types.Session, raw []byte) bool { err = utils.Unmarshal(payload, raw, func() error { return h.signalCandidate(session, payload) }) + case event.SIGNAL_VIDEO: + payload := &message.SignalVideo{} + err = utils.Unmarshal(payload, raw, func() error { + return h.signalVideo(session, payload) + }) // Control Events case event.CONTROL_RELEASE: diff --git a/internal/websocket/handler/signal.go b/internal/websocket/handler/signal.go index b85f78e8..ecf25b56 100644 --- a/internal/websocket/handler/signal.go +++ b/internal/websocket/handler/signal.go @@ -44,3 +44,13 @@ func (h *MessageHandlerCtx) signalCandidate(session types.Session, payload *mess return peer.SignalCandidate(*payload.ICECandidateInit) } + +func (h *MessageHandlerCtx) signalVideo(session types.Session, payload *message.SignalVideo) error { + peer := session.GetWebRTCPeer() + if peer == nil { + h.logger.Debug().Msg("webRTC peer does not exist") + return nil + } + + return peer.SetVideoID(payload.VideoID) +}