diff --git a/cmd/cli/client/client.go b/cmd/cli/client/client.go index e8cab486e..a800209cb 100644 --- a/cmd/cli/client/client.go +++ b/cmd/cli/client/client.go @@ -182,7 +182,7 @@ func (c *RTCClient) Run() error { } switch msg := res.Message.(type) { case *livekit.SignalResponse_Join: - c.AppendLog("join accepted, sending offer..") + c.AppendLog("join accepted, sending offer..", "participant", msg.Join.Participant.Id) c.localParticipant = msg.Join.Participant c.AppendLog("other participants", "count", len(msg.Join.OtherParticipants)) @@ -238,7 +238,7 @@ func (c *RTCClient) Run() error { case *livekit.SignalResponse_Trickle: candidateInit := rtc.FromProtoTrickle(msg.Trickle) c.AppendLog("adding remote candidate", "candidate", candidateInit.Candidate) - if err := c.PeerConn.AddICECandidate(*candidateInit); err != nil { + if err := c.PeerConn.AddICECandidate(candidateInit); err != nil { return err } case *livekit.SignalResponse_Update: @@ -318,7 +318,7 @@ func (c *RTCClient) SendIceCandidate(ic *webrtc.ICECandidate) error { c.AppendLog("sending trickle candidate", "candidate", candInit.Candidate) return c.SendRequest(&livekit.SignalRequest{ Message: &livekit.SignalRequest_Trickle{ - Trickle: rtc.ToProtoTrickle(&candInit), + Trickle: rtc.ToProtoTrickle(candInit), }, }) } diff --git a/pkg/rtc/participant.go b/pkg/rtc/participant.go index 7e7d46703..4ff7b41a3 100644 --- a/pkg/rtc/participant.go +++ b/pkg/rtc/participant.go @@ -74,15 +74,13 @@ func NewParticipant(conf *WebRTCConfig, sc SignalConnection, name string) (*Part if c == nil { return } + ci := c.ToJSON() // write candidate err := sc.WriteResponse(&livekit.SignalResponse{ Message: &livekit.SignalResponse_Trickle{ - Trickle: &livekit.Trickle{ - Candidate: ci.Candidate, - // TODO: there are other candidateInit fields that we might want - }, + Trickle: ToProtoTrickle(ci), }, }) if err != nil { diff --git a/pkg/rtc/room.go b/pkg/rtc/room.go index 29c4a91e3..6c6d55388 100644 --- a/pkg/rtc/room.go +++ b/pkg/rtc/room.go @@ -76,6 +76,10 @@ func (r *Room) Join(participant *Participant) error { // subscribe participant to existing tracks for _, p := range r.participants { + if p.id == participant.id { + // don't send to itself + continue + } if err := p.AddSubscriber(participant); err != nil { // TODO: log error? or disconnect? logger.GetLogger().Errorw("could not subscribe to participant", diff --git a/pkg/rtc/utils.go b/pkg/rtc/utils.go index b694eaea1..18f911704 100644 --- a/pkg/rtc/utils.go +++ b/pkg/rtc/utils.go @@ -1,6 +1,7 @@ package rtc import ( + "encoding/json" "strings" "github.com/pion/webrtc/v3" @@ -57,14 +58,15 @@ func FromProtoSessionDescription(sd *livekit.SessionDescription) webrtc.SessionD } } -func ToProtoTrickle(candidateInit *webrtc.ICECandidateInit) *livekit.Trickle { +func ToProtoTrickle(candidateInit webrtc.ICECandidateInit) *livekit.Trickle { + data, _ := json.Marshal(candidateInit) return &livekit.Trickle{ - Candidate: candidateInit.Candidate, + CandidateInit: string(data), } } -func FromProtoTrickle(trickle *livekit.Trickle) *webrtc.ICECandidateInit { - return &webrtc.ICECandidateInit{ - Candidate: trickle.Candidate, - } +func FromProtoTrickle(trickle *livekit.Trickle) webrtc.ICECandidateInit { + ci := webrtc.ICECandidateInit{} + json.Unmarshal([]byte(trickle.CandidateInit), &ci) + return ci } diff --git a/pkg/service/rtc.go b/pkg/service/rtc.go index 3c0495d88..fe218a1ff 100644 --- a/pkg/service/rtc.go +++ b/pkg/service/rtc.go @@ -43,11 +43,6 @@ func (s *RTCService) ServeHTTP(w http.ResponseWriter, r *http.Request) { pName := r.FormValue("name") log := logger.GetLogger() - log.Infow("new client connected", - "roomId", roomId, - "participantName", pName, - ) - room := s.manager.GetRoom(roomId) if room == nil { writeJSONError(w, http.StatusNotFound, "room not found") @@ -78,6 +73,12 @@ func (s *RTCService) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } + log.Infow("new client connected", + "roomId", roomId, + "name", pName, + "participant", participant.ID(), + ) + if err := room.Join(participant); err != nil { writeJSONError(w, http.StatusInternalServerError, "could not join room", err.Error()) return @@ -155,11 +156,11 @@ func (s *RTCService) handleOffer(participant *rtc.Participant, offer *livekit.Se return nil } -func (s *RTCService) handleNegotiate(sc rtc.SignalConnection, peer *rtc.Participant, neg *livekit.SessionDescription) error { - logger.GetLogger().Debugw("handling incoming negotiate") +func (s *RTCService) handleNegotiate(sc rtc.SignalConnection, participant *rtc.Participant, neg *livekit.SessionDescription) error { + logger.GetLogger().Debugw("handling incoming negotiate", "participant", participant.ID()) if neg.Type == webrtc.SDPTypeOffer.String() { offer := rtc.FromProtoSessionDescription(neg) - answer, err := peer.Answer(offer) + answer, err := participant.Answer(offer) if err != nil { return err } @@ -175,7 +176,7 @@ func (s *RTCService) handleNegotiate(sc rtc.SignalConnection, peer *rtc.Particip } } else if neg.Type == webrtc.SDPTypeAnswer.String() { answer := rtc.FromProtoSessionDescription(neg) - err := peer.SetRemoteDescription(answer) + err := participant.SetRemoteDescription(answer) if err != nil { return err } @@ -186,7 +187,7 @@ func (s *RTCService) handleNegotiate(sc rtc.SignalConnection, peer *rtc.Particip func (s *RTCService) handleTrickle(peer *rtc.Participant, trickle *livekit.Trickle) error { candidateInit := rtc.FromProtoTrickle(trickle) logger.GetLogger().Debugw("adding peer candidate", "participantId", peer.ID()) - if err := peer.AddICECandidate(*candidateInit); err != nil { + if err := peer.AddICECandidate(candidateInit); err != nil { return err } diff --git a/proto/livekit/rtc.pb.go b/proto/livekit/rtc.pb.go index ca7418260..a375f1325 100644 --- a/proto/livekit/rtc.pb.go +++ b/proto/livekit/rtc.pb.go @@ -265,7 +265,7 @@ type Trickle struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Candidate string `protobuf:"bytes,1,opt,name=candidate,proto3" json:"candidate,omitempty"` + CandidateInit string `protobuf:"bytes,1,opt,name=candidateInit,proto3" json:"candidateInit,omitempty"` } func (x *Trickle) Reset() { @@ -300,9 +300,9 @@ func (*Trickle) Descriptor() ([]byte, []int) { return file_rtc_proto_rawDescGZIP(), []int{2} } -func (x *Trickle) GetCandidate() string { +func (x *Trickle) GetCandidateInit() string { if x != nil { - return x.Candidate + return x.CandidateInit } return "" } @@ -540,32 +540,33 @@ var file_rtc_proto_rawDesc = []byte{ 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x50, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x48, 0x00, 0x52, 0x06, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x09, 0x0a, 0x07, 0x6d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x22, 0x27, 0x0a, 0x07, 0x54, 0x72, 0x69, 0x63, 0x6b, 0x6c, 0x65, 0x12, - 0x1c, 0x0a, 0x09, 0x63, 0x61, 0x6e, 0x64, 0x69, 0x64, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x09, 0x63, 0x61, 0x6e, 0x64, 0x69, 0x64, 0x61, 0x74, 0x65, 0x22, 0x3a, 0x0a, - 0x12, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x64, 0x70, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x73, 0x64, 0x70, 0x22, 0x93, 0x01, 0x0a, 0x0c, 0x4a, 0x6f, - 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3a, 0x0a, 0x0b, 0x70, 0x61, - 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x18, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x50, 0x61, 0x72, 0x74, 0x69, 0x63, - 0x69, 0x70, 0x61, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x70, 0x61, 0x72, 0x74, 0x69, - 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x12, 0x47, 0x0a, 0x12, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x5f, - 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x50, 0x61, 0x72, - 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x11, 0x6f, 0x74, - 0x68, 0x65, 0x72, 0x50, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x73, 0x22, - 0x0e, 0x0a, 0x0c, 0x4d, 0x65, 0x64, 0x69, 0x61, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x22, - 0x51, 0x0a, 0x11, 0x50, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x12, 0x3c, 0x0a, 0x0c, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, - 0x61, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6c, 0x69, 0x76, + 0x73, 0x61, 0x67, 0x65, 0x22, 0x2f, 0x0a, 0x07, 0x54, 0x72, 0x69, 0x63, 0x6b, 0x6c, 0x65, 0x12, + 0x24, 0x0a, 0x0d, 0x63, 0x61, 0x6e, 0x64, 0x69, 0x64, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x69, 0x74, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x61, 0x6e, 0x64, 0x69, 0x64, 0x61, 0x74, + 0x65, 0x49, 0x6e, 0x69, 0x74, 0x22, 0x3a, 0x0a, 0x12, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, + 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, + 0x10, 0x0a, 0x03, 0x73, 0x64, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x73, 0x64, + 0x70, 0x22, 0x93, 0x01, 0x0a, 0x0c, 0x4a, 0x6f, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x3a, 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, + 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, + 0x74, 0x2e, 0x50, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x49, 0x6e, 0x66, + 0x6f, 0x52, 0x0b, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x12, 0x47, + 0x0a, 0x12, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x5f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, + 0x61, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x50, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, - 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0c, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, - 0x74, 0x73, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2f, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, - 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x6c, 0x69, - 0x76, 0x65, 0x6b, 0x69, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x11, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x50, 0x61, 0x72, 0x74, 0x69, + 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x73, 0x22, 0x0e, 0x0a, 0x0c, 0x4d, 0x65, 0x64, 0x69, 0x61, + 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x22, 0x51, 0x0a, 0x11, 0x50, 0x61, 0x72, 0x74, 0x69, + 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x3c, 0x0a, 0x0c, + 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x50, 0x61, 0x72, + 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0c, 0x70, 0x61, + 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x73, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x69, + 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, + 0x2f, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/proto/rtc.proto b/proto/rtc.proto index 2e1bef8c0..54f8ec00c 100644 --- a/proto/rtc.proto +++ b/proto/rtc.proto @@ -30,7 +30,8 @@ message SignalResponse { } message Trickle { - string candidate = 1; + string candidateInit = 1; + } message SessionDescription {