From a6c4db2cb3cae2bd99fcfc9c37b2d15c2d561df3 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Tue, 1 Dec 2020 23:32:15 -0800 Subject: [PATCH] refactoring, enabling sending out room updates --- cmd/cli/client/client.go | 15 +- pkg/rtc/participant.go | 117 +++++++++++++--- pkg/rtc/room.go | 34 ++++- pkg/rtc/track.go | 6 +- pkg/rtc/utils.go | 49 +++++++ pkg/{service => rtc}/wsprotocol.go | 7 +- pkg/service/rtc.go | 104 ++++---------- pkg/service/utils.go | 44 ------ proto/livekit/model.pb.go | 217 ++++++++++++++++++++++------- proto/livekit/rtc.pb.go | 114 ++++++++++----- proto/model.proto | 15 +- proto/rtc.proto | 6 +- 12 files changed, 480 insertions(+), 248 deletions(-) rename pkg/{service => rtc}/wsprotocol.go (93%) delete mode 100644 pkg/service/utils.go diff --git a/cmd/cli/client/client.go b/cmd/cli/client/client.go index 652c7b440..04992072b 100644 --- a/cmd/cli/client/client.go +++ b/cmd/cli/client/client.go @@ -18,7 +18,6 @@ import ( "github.com/livekit/livekit-server/pkg/logger" "github.com/livekit/livekit-server/pkg/rtc" - "github.com/livekit/livekit-server/pkg/service" "github.com/livekit/livekit-server/proto/livekit" ) @@ -203,7 +202,7 @@ func (c *RTCClient) Run() error { // send the offer to remote req := &livekit.SignalRequest{ Message: &livekit.SignalRequest_Offer{ - Offer: service.ToProtoSessionDescription(offer), + Offer: rtc.ToProtoSessionDescription(offer), }, } c.AppendLog("connecting to remote...") @@ -215,7 +214,7 @@ func (c *RTCClient) Run() error { case *livekit.SignalResponse_Answer: c.AppendLog("connected to remote, setting desc") // remote answered the offer, establish connection - err = c.PeerConn.SetRemoteDescription(service.FromProtoSessionDescription(msg.Answer)) + err = c.PeerConn.SetRemoteDescription(rtc.FromProtoSessionDescription(msg.Answer)) if err != nil { return err } @@ -231,12 +230,12 @@ func (c *RTCClient) Run() error { case *livekit.SignalResponse_Negotiate: c.AppendLog("received negotiate", "type", msg.Negotiate.Type) - desc := service.FromProtoSessionDescription(msg.Negotiate) + desc := rtc.FromProtoSessionDescription(msg.Negotiate) if err := c.handleNegotiate(desc); err != nil { return err } case *livekit.SignalResponse_Trickle: - candidateInit := service.FromProtoTrickle(msg.Trickle) + candidateInit := rtc.FromProtoTrickle(msg.Trickle) c.AppendLog("adding remote candidate", "candidate", candidateInit.Candidate) if err := c.PeerConn.AddICECandidate(*candidateInit); err != nil { return err @@ -314,7 +313,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: service.ToProtoTrickle(&candInit), + Trickle: rtc.ToProtoTrickle(&candInit), }, }) } @@ -333,7 +332,7 @@ func (c *RTCClient) Negotiate() error { // send the offer to remote req := &livekit.SignalRequest{ Message: &livekit.SignalRequest_Negotiate{ - Negotiate: service.ToProtoSessionDescription(offer), + Negotiate: rtc.ToProtoSessionDescription(offer), }, } c.AppendLog("sending negotiate offer to remote...") @@ -369,7 +368,7 @@ func (c *RTCClient) handleNegotiate(desc webrtc.SessionDescription) error { // send remote an answer return c.SendRequest(&livekit.SignalRequest{ Message: &livekit.SignalRequest_Negotiate{ - Negotiate: service.ToProtoSessionDescription(answer), + Negotiate: rtc.ToProtoSessionDescription(answer), }, }) } diff --git a/pkg/rtc/participant.go b/pkg/rtc/participant.go index d3d4912d3..6250eb27d 100644 --- a/pkg/rtc/participant.go +++ b/pkg/rtc/participant.go @@ -16,7 +16,8 @@ import ( type Participant struct { id string - conn *webrtc.PeerConnection + peerConn *webrtc.PeerConnection + sigConn SignalConnection ctx context.Context cancel context.CancelFunc mediaEngine *MediaEngine @@ -35,10 +36,11 @@ type Participant struct { OnOffer func(webrtc.SessionDescription) // OnIceCandidate - ice candidate discovered for local peer OnICECandidate func(c *webrtc.ICECandidateInit) + OnStateChange func(p *Participant, oldState livekit.ParticipantInfo_State) OnClose func(*Participant) } -func NewParticipant(conf *WebRTCConfig, name string) (*Participant, error) { +func NewParticipant(conf *WebRTCConfig, sc SignalConnection, name string) (*Participant, error) { me := webrtc.MediaEngine{} me.RegisterDefaultCodecs() api := webrtc.NewAPI(webrtc.WithMediaEngine(me), webrtc.WithSettingEngine(conf.SettingEngine)) @@ -52,7 +54,8 @@ func NewParticipant(conf *WebRTCConfig, name string) (*Participant, error) { participant := &Participant{ id: utils.NewGuid(utils.ParticipantPrefix), name: name, - conn: pc, + peerConn: pc, + sigConn: sc, ctx: ctx, cancel: cancel, state: livekit.ParticipantInfo_JOINING, @@ -63,14 +66,30 @@ func NewParticipant(conf *WebRTCConfig, name string) (*Participant, error) { } participant.mediaEngine.RegisterDefaultCodecs() + log := logger.GetLogger() + pc.OnTrack(participant.onTrack) pc.OnICECandidate(func(c *webrtc.ICECandidate) { 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 + }, + }, + }) + if err != nil { + log.Errorw("could not send trickle", "err", err) + } + if participant.OnICECandidate != nil { - ci := c.ToJSON() participant.OnICECandidate(&ci) } }) @@ -78,7 +97,7 @@ func NewParticipant(conf *WebRTCConfig, name string) (*Participant, error) { pc.OnICEConnectionStateChange(func(state webrtc.ICEConnectionState) { logger.GetLogger().Debugw("ICE connection state changed", "state", state.String()) if state == webrtc.ICEConnectionStateConnected { - participant.state = livekit.ParticipantInfo_ACTIVE + participant.updateState(livekit.ParticipantInfo_ACTIVE) } }) @@ -108,58 +127,73 @@ func (p *Participant) ToProto() *livekit.ParticipantInfo { // Answer an offer from remote participant func (p *Participant) Answer(sdp webrtc.SessionDescription) (answer webrtc.SessionDescription, err error) { - // media engine is already set to default codecs upon startup - //if err = p.mediaEngine.PopulateFromSDP(sdp); err != nil { - // err = errors.Wrapf(err, "could not parse SDP") - // return - //} - if p.state == livekit.ParticipantInfo_JOINING { - p.state = livekit.ParticipantInfo_JOINED + p.updateState(livekit.ParticipantInfo_JOINED) } if err = p.SetRemoteDescription(sdp); err != nil { return } - answer, err = p.conn.CreateAnswer(nil) + answer, err = p.peerConn.CreateAnswer(nil) if err != nil { err = errors.Wrap(err, "could not create answer") return } - if err = p.conn.SetLocalDescription(answer); err != nil { + if err = p.peerConn.SetLocalDescription(answer); err != nil { err = errors.Wrap(err, "could not set local description") return } + // send client the answer + err = p.sigConn.WriteResponse(&livekit.SignalResponse{ + Message: &livekit.SignalResponse_Answer{ + Answer: ToProtoSessionDescription(answer), + }, + }) + if err != nil { + return + } + // only set after answered - p.conn.OnNegotiationNeeded(func() { + p.peerConn.OnNegotiationNeeded(func() { logger.GetLogger().Debugw("negotiation needed", "participantId", p.ID()) - offer, err := p.conn.CreateOffer(nil) + offer, err := p.peerConn.CreateOffer(nil) if err != nil { logger.GetLogger().Errorw("could not create offer", "err", err) return } - err = p.conn.SetLocalDescription(offer) + err = p.peerConn.SetLocalDescription(offer) if err != nil { logger.GetLogger().Errorw("could not set local description", "err", err) return } logger.GetLogger().Debugw("created new offer", "offer", offer, "onOffer", p.OnOffer) + + logger.GetLogger().Debugw("sending available offer to participant") + err = p.sigConn.WriteResponse(&livekit.SignalResponse{ + Message: &livekit.SignalResponse_Negotiate{ + Negotiate: ToProtoSessionDescription(offer), + }, + }) + if err != nil { + logger.GetLogger().Errorw("could not send offer to peer", + "err", err) + } + if p.OnOffer != nil { p.OnOffer(offer) } }) - return } // SetRemoteDescription when receiving an answer from remote func (p *Participant) SetRemoteDescription(sdp webrtc.SessionDescription) error { - if err := p.conn.SetRemoteDescription(sdp); err != nil { + if err := p.peerConn.SetRemoteDescription(sdp); err != nil { return errors.Wrap(err, "could not set remote description") } return nil @@ -167,7 +201,7 @@ func (p *Participant) SetRemoteDescription(sdp webrtc.SessionDescription) error // AddICECandidate adds candidates for remote peer func (p *Participant) AddICECandidate(candidate webrtc.ICECandidateInit) error { - if err := p.conn.AddICECandidate(candidate); err != nil { + if err := p.peerConn.AddICECandidate(candidate); err != nil { return err } return nil @@ -183,11 +217,12 @@ func (p *Participant) Close() error { if p.ctx.Err() != nil { return p.ctx.Err() } + p.updateState(livekit.ParticipantInfo_DISCONNECTED) if p.OnClose != nil { p.OnClose(p) } p.cancel() - return p.conn.Close() + return p.peerConn.Close() } // Subscribes otherPeer to all of the tracks @@ -216,6 +251,42 @@ func (p *Participant) RemoveSubscriber(peerId string) { } } +// signal connection methods +func (p *Participant) SendJoinResponse(otherParticipants []*Participant) error { + // send Join response + return p.sigConn.WriteResponse(&livekit.SignalResponse{ + Message: &livekit.SignalResponse_Join{ + Join: &livekit.JoinResponse{ + Participant: p.ToProto(), + OtherParticipants: ToProtoParticipants(otherParticipants), + }, + }, + }) +} + +func (p *Participant) SendParticipantUpdate(participants []*livekit.ParticipantInfo) error { + return p.sigConn.WriteResponse(&livekit.SignalResponse{ + Message: &livekit.SignalResponse_Update{ + Update: &livekit.ParticipantUpdate{ + Participants: participants, + }, + }, + }) +} + +func (p *Participant) updateState(state livekit.ParticipantInfo_State) { + if state == p.state { + return + } + oldState := p.state + p.state = state + if p.OnStateChange != nil { + go func() { + p.OnStateChange(p, oldState) + }() + } +} + // when a new mediaTrack is created, creates a Track and adds it to room func (p *Participant) onTrack(track *webrtc.Track, rtpReceiver *webrtc.RTPReceiver) { logger.GetLogger().Debugw("mediaTrack added", "participantId", p.ID(), "mediaTrack", track.Label()) @@ -223,7 +294,7 @@ func (p *Participant) onTrack(track *webrtc.Track, rtpReceiver *webrtc.RTPReceiv // create Receiver // p.mediaEngine.TCCExt receiver := NewReceiver(p.ctx, p.id, rtpReceiver, p.receiverConfig, 0) - pt := NewTrack(p.ctx, p.id, p.conn, track, receiver) + pt := NewTrack(p.ctx, p.id, p.peerConn, track, receiver) p.lock.Lock() p.tracks = append(p.tracks, pt) @@ -254,7 +325,7 @@ func (p *Participant) rtcpSendWorker() { } p.lock.RUnlock() if len(pkts) > 0 { - if err := p.conn.WriteRTCP(pkts); err != nil { + if err := p.peerConn.WriteRTCP(pkts); err != nil { logger.GetLogger().Errorw("error writing RTCP to peer", "peer", p.id, "err", err, diff --git a/pkg/rtc/room.go b/pkg/rtc/room.go index 6c3288d58..99b0ff486 100644 --- a/pkg/rtc/room.go +++ b/pkg/rtc/room.go @@ -62,6 +62,10 @@ func (r *Room) Join(participant *Participant) error { participant.OnPeerTrack = r.onTrackAdded + participant.OnStateChange = func(p *Participant, oldState livekit.ParticipantInfo_State) { + r.broadcastParticipantState(p) + } + logger.GetLogger().Infow("new participant joined", "id", participant.ID(), "name", participant.Name(), @@ -79,7 +83,15 @@ func (r *Room) Join(participant *Participant) error { r.participants[participant.ID()] = participant - return nil + // gather other participants and send join response + otherParticipants := make([]*Participant, 0, len(r.participants)) + for _, p := range r.participants { + if p.id != participant.id { + otherParticipants = append(otherParticipants, p) + } + } + + return participant.SendJoinResponse(otherParticipants) } func (r *Room) RemoveParticipant(id string) { @@ -113,3 +125,23 @@ func (r *Room) onTrackAdded(peer *Participant, track *Track) { } } } + +func (r *Room) broadcastParticipantState(p *Participant) { + r.lock.RLock() + defer r.lock.RUnlock() + + updates := ToProtoParticipants([]*Participant{p}) + for _, op := range r.participants { + // skip itself + if p.id == op.id { + continue + } + + err := p.SendParticipantUpdate(updates) + if err != nil { + logger.GetLogger().Errorw("could not send update to participant", + "participant", p.id, + "err", err) + } + } +} diff --git a/pkg/rtc/track.go b/pkg/rtc/track.go index 5cd6937a5..38a2017ca 100644 --- a/pkg/rtc/track.go +++ b/pkg/rtc/track.go @@ -62,12 +62,12 @@ func (t *Track) AddSubscriber(participant *Participant) error { packedId := PackTrackId(t.participantId, t.mediaTrack.ID()) // use existing SSRC with simple forwarders. adaptive forwarders require unique SSRC per layer - outTrack, err := participant.conn.NewTrack(codecs[0].PayloadType, t.mediaTrack.SSRC(), packedId, t.mediaTrack.Label()) + outTrack, err := participant.peerConn.NewTrack(codecs[0].PayloadType, t.mediaTrack.SSRC(), packedId, t.mediaTrack.Label()) if err != nil { return err } - rtpSender, err := participant.conn.AddTrack(outTrack) + rtpSender, err := participant.peerConn.AddTrack(outTrack) if err != nil { return err } @@ -78,7 +78,7 @@ func (t *Track) AddSubscriber(participant *Participant) error { delete(t.forwarders, participant.ID()) t.lock.Unlock() - if err := participant.conn.RemoveTrack(rtpSender); err != nil { + if err := participant.peerConn.RemoveTrack(rtpSender); err != nil { logger.GetLogger().Warnw("could not remove mediaTrack from forwarder", "participant", participant.ID(), "err", err) diff --git a/pkg/rtc/utils.go b/pkg/rtc/utils.go index f49c8863d..b694eaea1 100644 --- a/pkg/rtc/utils.go +++ b/pkg/rtc/utils.go @@ -2,6 +2,10 @@ package rtc import ( "strings" + + "github.com/pion/webrtc/v3" + + "github.com/livekit/livekit-server/proto/livekit" ) const ( @@ -19,3 +23,48 @@ func UnpackTrackId(packed string) (peerId string, trackId string) { func PackTrackId(participantId, trackId string) string { return participantId + trackIdSeparator + trackId } + +func ToProtoParticipants(participants []*Participant) []*livekit.ParticipantInfo { + infos := make([]*livekit.ParticipantInfo, 0, len(participants)) + for _, op := range participants { + infos = append(infos, op.ToProto()) + } + return infos +} + +func ToProtoSessionDescription(sd webrtc.SessionDescription) *livekit.SessionDescription { + return &livekit.SessionDescription{ + Type: sd.Type.String(), + Sdp: sd.SDP, + } +} + +func FromProtoSessionDescription(sd *livekit.SessionDescription) webrtc.SessionDescription { + var sdType webrtc.SDPType + switch sd.Type { + case webrtc.SDPTypeOffer.String(): + sdType = webrtc.SDPTypeOffer + case webrtc.SDPTypeAnswer.String(): + sdType = webrtc.SDPTypeAnswer + case webrtc.SDPTypePranswer.String(): + sdType = webrtc.SDPTypePranswer + case webrtc.SDPTypeRollback.String(): + sdType = webrtc.SDPTypeRollback + } + return webrtc.SessionDescription{ + Type: sdType, + SDP: sd.Sdp, + } +} + +func ToProtoTrickle(candidateInit *webrtc.ICECandidateInit) *livekit.Trickle { + return &livekit.Trickle{ + Candidate: candidateInit.Candidate, + } +} + +func FromProtoTrickle(trickle *livekit.Trickle) *webrtc.ICECandidateInit { + return &webrtc.ICECandidateInit{ + Candidate: trickle.Candidate, + } +} diff --git a/pkg/service/wsprotocol.go b/pkg/rtc/wsprotocol.go similarity index 93% rename from pkg/service/wsprotocol.go rename to pkg/rtc/wsprotocol.go index 3642e8378..d6ff20251 100644 --- a/pkg/service/wsprotocol.go +++ b/pkg/rtc/wsprotocol.go @@ -1,4 +1,4 @@ -package service +package rtc import ( "github.com/gorilla/websocket" @@ -19,9 +19,10 @@ type WSSignalConnection struct { useJSON bool } -func NewWSSignalConnection(conn *websocket.Conn, name string) *WSSignalConnection { +func NewWSSignalConnection(conn *websocket.Conn) *WSSignalConnection { return &WSSignalConnection{ - conn: conn, + conn: conn, + useJSON: true, } } diff --git a/pkg/service/rtc.go b/pkg/service/rtc.go index 596a5e763..3c0495d88 100644 --- a/pkg/service/rtc.go +++ b/pkg/service/rtc.go @@ -59,11 +59,6 @@ func (s *RTCService) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } - participant, err := rtc.NewParticipant(s.manager.Config(), pName) - if err != nil { - writeJSONError(w, http.StatusInternalServerError, "could not create participant", err.Error()) - } - // upgrade only once the basics are good to go conn, err := s.upgrader.Upgrade(w, r, nil) if err != nil { @@ -75,22 +70,25 @@ func (s *RTCService) ServeHTTP(w http.ResponseWriter, r *http.Request) { log.Infow("websocket closed by remote") return nil }) - defer func() { - log.Infow("connection returned") - }() - signalConn := NewWSSignalConnection(conn, pName) + signalConn := rtc.NewWSSignalConnection(conn) - // send Join response - signalConn.WriteResponse(&livekit.SignalResponse{ - Message: &livekit.SignalResponse_Join{ - Join: &livekit.JoinResponse{ - Participant: participant.ToProto(), - }, - }, - }) + participant, err := rtc.NewParticipant(s.manager.Config(), signalConn, pName) + if err != nil { + writeJSONError(w, http.StatusInternalServerError, "could not create participant", err.Error()) + return + } + + if err := room.Join(participant); err != nil { + writeJSONError(w, http.StatusInternalServerError, "could not join room", err.Error()) + return + } + + defer func() { + participant.Close() + log.Infow("WS connection closed") + }() // read connection and wait for commands - // TODO: pass in context from WS, so termination of WS would disconnect RTC //ctx := context.Background() for { req, err := signalConn.ReadRequest() @@ -104,7 +102,7 @@ func (s *RTCService) ServeHTTP(w http.ResponseWriter, r *http.Request) { switch msg := req.Message.(type) { case *livekit.SignalRequest_Offer: - err = s.handleJoin(signalConn, room, participant, msg.Offer.Sdp) + err = s.handleOffer(participant, msg.Offer) if err != nil { log.Errorw("could not handle join", "err", err, "participant", participant.ID()) return @@ -145,74 +143,22 @@ func (s *RTCService) ServeHTTP(w http.ResponseWriter, r *http.Request) { } } -func (s *RTCService) handleJoin(sc SignalConnection, room *rtc.Room, participant *rtc.Participant, sdp string) error { +func (s *RTCService) handleOffer(participant *rtc.Participant, offer *livekit.SessionDescription) error { log := logger.GetLogger() - log.Infow("handling join") - err := room.Join(participant) - if err != nil { - return errors.Wrap(err, "could not join room") - } - - // TODO: it might be better to return error instead of nil - participant.OnICECandidate = func(c *webrtc.ICECandidateInit) { - log.Debugw("sending ICE candidate", "participantId", participant.ID()) - err = sc.WriteResponse(&livekit.SignalResponse{ - Message: &livekit.SignalResponse_Trickle{ - Trickle: &livekit.Trickle{ - Candidate: c.Candidate, - // TODO: there are other candidateInit fields that we might want - }, - }, - }) - if err != nil { - log.Errorw("could not send trickle", "err", err) - } - } - - // send peer new offer - participant.OnOffer = func(o webrtc.SessionDescription) { - log.Debugw("sending available offer to participant") - err := sc.WriteResponse(&livekit.SignalResponse{ - Message: &livekit.SignalResponse_Negotiate{ - Negotiate: ToProtoSessionDescription(o), - }, - }) - if err != nil { - logger.GetLogger().Errorw("could not send offer to peer", - "err", err) - } - } - - offer := webrtc.SessionDescription{ - Type: webrtc.SDPTypeOffer, - SDP: sdp, - } - answer, err := participant.Answer(offer) + _, err := participant.Answer(rtc.FromProtoSessionDescription(offer)) if err != nil { return errors.Wrap(err, "could not answer offer") } - logger.GetLogger().Debugw("answered, writing response") - - // finally send answer - err = sc.WriteResponse(&livekit.SignalResponse{ - Message: &livekit.SignalResponse_Answer{ - Answer: ToProtoSessionDescription(answer), - }, - }) - - if err != nil { - return errors.Wrap(err, "could not create answer") - } - + log.Debugw("answered client offer") return nil } -func (s *RTCService) handleNegotiate(sc SignalConnection, peer *rtc.Participant, neg *livekit.SessionDescription) error { +func (s *RTCService) handleNegotiate(sc rtc.SignalConnection, peer *rtc.Participant, neg *livekit.SessionDescription) error { logger.GetLogger().Debugw("handling incoming negotiate") if neg.Type == webrtc.SDPTypeOffer.String() { - offer := FromProtoSessionDescription(neg) + offer := rtc.FromProtoSessionDescription(neg) answer, err := peer.Answer(offer) if err != nil { return err @@ -220,7 +166,7 @@ func (s *RTCService) handleNegotiate(sc SignalConnection, peer *rtc.Participant, err = sc.WriteResponse(&livekit.SignalResponse{ Message: &livekit.SignalResponse_Negotiate{ - Negotiate: ToProtoSessionDescription(answer), + Negotiate: rtc.ToProtoSessionDescription(answer), }, }) @@ -228,7 +174,7 @@ func (s *RTCService) handleNegotiate(sc SignalConnection, peer *rtc.Participant, return err } } else if neg.Type == webrtc.SDPTypeAnswer.String() { - answer := FromProtoSessionDescription(neg) + answer := rtc.FromProtoSessionDescription(neg) err := peer.SetRemoteDescription(answer) if err != nil { return err @@ -238,7 +184,7 @@ func (s *RTCService) handleNegotiate(sc SignalConnection, peer *rtc.Participant, } func (s *RTCService) handleTrickle(peer *rtc.Participant, trickle *livekit.Trickle) error { - candidateInit := FromProtoTrickle(trickle) + candidateInit := rtc.FromProtoTrickle(trickle) logger.GetLogger().Debugw("adding peer candidate", "participantId", peer.ID()) if err := peer.AddICECandidate(*candidateInit); err != nil { return err diff --git a/pkg/service/utils.go b/pkg/service/utils.go deleted file mode 100644 index 5ac686700..000000000 --- a/pkg/service/utils.go +++ /dev/null @@ -1,44 +0,0 @@ -package service - -import ( - "github.com/pion/webrtc/v3" - - "github.com/livekit/livekit-server/proto/livekit" -) - -func ToProtoSessionDescription(sd webrtc.SessionDescription) *livekit.SessionDescription { - return &livekit.SessionDescription{ - Type: sd.Type.String(), - Sdp: sd.SDP, - } -} - -func FromProtoSessionDescription(sd *livekit.SessionDescription) webrtc.SessionDescription { - var sdType webrtc.SDPType - switch sd.Type { - case webrtc.SDPTypeOffer.String(): - sdType = webrtc.SDPTypeOffer - case webrtc.SDPTypeAnswer.String(): - sdType = webrtc.SDPTypeAnswer - case webrtc.SDPTypePranswer.String(): - sdType = webrtc.SDPTypePranswer - case webrtc.SDPTypeRollback.String(): - sdType = webrtc.SDPTypeRollback - } - return webrtc.SessionDescription{ - Type: sdType, - SDP: sd.Sdp, - } -} - -func ToProtoTrickle(candidateInit *webrtc.ICECandidateInit) *livekit.Trickle { - return &livekit.Trickle{ - Candidate: candidateInit.Candidate, - } -} - -func FromProtoTrickle(trickle *livekit.Trickle) *webrtc.ICECandidateInit { - return &webrtc.ICECandidateInit{ - Candidate: trickle.Candidate, - } -} diff --git a/proto/livekit/model.pb.go b/proto/livekit/model.pb.go index 7b90fa886..28952e01e 100644 --- a/proto/livekit/model.pb.go +++ b/proto/livekit/model.pb.go @@ -81,6 +81,55 @@ func (ParticipantInfo_State) EnumDescriptor() ([]byte, []int) { return file_model_proto_rawDescGZIP(), []int{4, 0} } +type TrackInfo_Type int32 + +const ( + TrackInfo_AUDIO TrackInfo_Type = 0 + TrackInfo_VIDEO TrackInfo_Type = 1 + TrackInfo_DATA TrackInfo_Type = 2 +) + +// Enum value maps for TrackInfo_Type. +var ( + TrackInfo_Type_name = map[int32]string{ + 0: "AUDIO", + 1: "VIDEO", + 2: "DATA", + } + TrackInfo_Type_value = map[string]int32{ + "AUDIO": 0, + "VIDEO": 1, + "DATA": 2, + } +) + +func (x TrackInfo_Type) Enum() *TrackInfo_Type { + p := new(TrackInfo_Type) + *p = x + return p +} + +func (x TrackInfo_Type) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (TrackInfo_Type) Descriptor() protoreflect.EnumDescriptor { + return file_model_proto_enumTypes[1].Descriptor() +} + +func (TrackInfo_Type) Type() protoreflect.EnumType { + return &file_model_proto_enumTypes[1] +} + +func (x TrackInfo_Type) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use TrackInfo_Type.Descriptor instead. +func (TrackInfo_Type) EnumDescriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{5, 0} +} + type Node struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -363,11 +412,9 @@ type ParticipantInfo struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - State ParticipantInfo_State `protobuf:"varint,3,opt,name=state,proto3,enum=livekit.ParticipantInfo_State" json:"state,omitempty"` - HasAudio bool `protobuf:"varint,4,opt,name=has_audio,json=hasAudio,proto3" json:"has_audio,omitempty"` - HasVideo bool `protobuf:"varint,5,opt,name=has_video,json=hasVideo,proto3" json:"has_video,omitempty"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + State ParticipantInfo_State `protobuf:"varint,3,opt,name=state,proto3,enum=livekit.ParticipantInfo_State" json:"state,omitempty"` } func (x *ParticipantInfo) Reset() { @@ -423,18 +470,68 @@ func (x *ParticipantInfo) GetState() ParticipantInfo_State { return ParticipantInfo_JOINING } -func (x *ParticipantInfo) GetHasAudio() bool { - if x != nil { - return x.HasAudio - } - return false +// describing +type TrackInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Type TrackInfo_Type `protobuf:"varint,2,opt,name=type,proto3,enum=livekit.TrackInfo_Type" json:"type,omitempty"` + Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` } -func (x *ParticipantInfo) GetHasVideo() bool { - if x != nil { - return x.HasVideo +func (x *TrackInfo) Reset() { + *x = TrackInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_model_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } - return false +} + +func (x *TrackInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TrackInfo) ProtoMessage() {} + +func (x *TrackInfo) ProtoReflect() protoreflect.Message { + mi := &file_model_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TrackInfo.ProtoReflect.Descriptor instead. +func (*TrackInfo) Descriptor() ([]byte, []int) { + return file_model_proto_rawDescGZIP(), []int{5} +} + +func (x *TrackInfo) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *TrackInfo) GetType() TrackInfo_Type { + if x != nil { + return x.Type + } + return TrackInfo_AUDIO +} + +func (x *TrackInfo) GetName() string { + if x != nil { + return x.Name + } + return "" } type DataChannel struct { @@ -449,7 +546,7 @@ type DataChannel struct { func (x *DataChannel) Reset() { *x = DataChannel{} if protoimpl.UnsafeEnabled { - mi := &file_model_proto_msgTypes[5] + mi := &file_model_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -462,7 +559,7 @@ func (x *DataChannel) String() string { func (*DataChannel) ProtoMessage() {} func (x *DataChannel) ProtoReflect() protoreflect.Message { - mi := &file_model_proto_msgTypes[5] + mi := &file_model_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -475,7 +572,7 @@ func (x *DataChannel) ProtoReflect() protoreflect.Message { // Deprecated: Use DataChannel.ProtoReflect.Descriptor instead. func (*DataChannel) Descriptor() ([]byte, []int) { - return file_model_proto_rawDescGZIP(), []int{5} + return file_model_proto_rawDescGZIP(), []int{6} } func (x *DataChannel) GetSessionId() string { @@ -525,29 +622,34 @@ var file_model_proto_rawDesc = []byte{ 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, - 0x65, 0x6e, 0x22, 0xe5, 0x01, 0x0a, 0x0f, 0x50, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, + 0x65, 0x6e, 0x22, 0xab, 0x01, 0x0a, 0x0f, 0x50, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x34, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1e, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x50, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x12, 0x1b, 0x0a, 0x09, 0x68, 0x61, 0x73, 0x5f, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x08, 0x68, 0x61, 0x73, 0x41, 0x75, 0x64, 0x69, 0x6f, 0x12, 0x1b, 0x0a, - 0x09, 0x68, 0x61, 0x73, 0x5f, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x08, 0x68, 0x61, 0x73, 0x56, 0x69, 0x64, 0x65, 0x6f, 0x22, 0x3e, 0x0a, 0x05, 0x53, 0x74, - 0x61, 0x74, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x4a, 0x4f, 0x49, 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x00, - 0x12, 0x0a, 0x0a, 0x06, 0x4a, 0x4f, 0x49, 0x4e, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, - 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x10, 0x02, 0x12, 0x10, 0x0a, 0x0c, 0x44, 0x49, 0x53, 0x43, - 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x45, 0x44, 0x10, 0x03, 0x22, 0x46, 0x0a, 0x0b, 0x44, 0x61, - 0x74, 0x61, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, - 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, - 0x6f, 0x61, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, - 0x61, 0x64, 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, + 0x22, 0x3e, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x4a, 0x4f, 0x49, + 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x4a, 0x4f, 0x49, 0x4e, 0x45, 0x44, + 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x10, 0x02, 0x12, 0x10, + 0x0a, 0x0c, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x45, 0x44, 0x10, 0x03, + 0x22, 0x84, 0x01, 0x0a, 0x09, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x0e, + 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x2b, + 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x6c, + 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x49, 0x6e, 0x66, 0x6f, + 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, + 0x26, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x09, 0x0a, 0x05, 0x41, 0x55, 0x44, 0x49, 0x4f, + 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x56, 0x49, 0x44, 0x45, 0x4f, 0x10, 0x01, 0x12, 0x08, 0x0a, + 0x04, 0x44, 0x41, 0x54, 0x41, 0x10, 0x02, 0x22, 0x46, 0x0a, 0x0b, 0x44, 0x61, 0x74, 0x61, 0x43, + 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x65, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 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 ( @@ -562,25 +664,28 @@ func file_model_proto_rawDescGZIP() []byte { return file_model_proto_rawDescData } -var file_model_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_model_proto_msgTypes = make([]protoimpl.MessageInfo, 6) +var file_model_proto_enumTypes = make([]protoimpl.EnumInfo, 2) +var file_model_proto_msgTypes = make([]protoimpl.MessageInfo, 7) var file_model_proto_goTypes = []interface{}{ (ParticipantInfo_State)(0), // 0: livekit.ParticipantInfo.State - (*Node)(nil), // 1: livekit.Node - (*NodeStats)(nil), // 2: livekit.NodeStats - (*Room)(nil), // 3: livekit.Room - (*RoomInfo)(nil), // 4: livekit.RoomInfo - (*ParticipantInfo)(nil), // 5: livekit.ParticipantInfo - (*DataChannel)(nil), // 6: livekit.DataChannel + (TrackInfo_Type)(0), // 1: livekit.TrackInfo.Type + (*Node)(nil), // 2: livekit.Node + (*NodeStats)(nil), // 3: livekit.NodeStats + (*Room)(nil), // 4: livekit.Room + (*RoomInfo)(nil), // 5: livekit.RoomInfo + (*ParticipantInfo)(nil), // 6: livekit.ParticipantInfo + (*TrackInfo)(nil), // 7: livekit.TrackInfo + (*DataChannel)(nil), // 8: livekit.DataChannel } var file_model_proto_depIdxs = []int32{ - 2, // 0: livekit.Node.stats:type_name -> livekit.NodeStats + 3, // 0: livekit.Node.stats:type_name -> livekit.NodeStats 0, // 1: livekit.ParticipantInfo.state:type_name -> livekit.ParticipantInfo.State - 2, // [2:2] is the sub-list for method output_type - 2, // [2:2] is the sub-list for method input_type - 2, // [2:2] is the sub-list for extension type_name - 2, // [2:2] is the sub-list for extension extendee - 0, // [0:2] is the sub-list for field type_name + 1, // 2: livekit.TrackInfo.type:type_name -> livekit.TrackInfo.Type + 3, // [3:3] is the sub-list for method output_type + 3, // [3:3] is the sub-list for method input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name } func init() { file_model_proto_init() } @@ -650,6 +755,18 @@ func file_model_proto_init() { } } file_model_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TrackInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_model_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*DataChannel); i { case 0: return &v.state @@ -667,8 +784,8 @@ func file_model_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_model_proto_rawDesc, - NumEnums: 1, - NumMessages: 6, + NumEnums: 2, + NumMessages: 7, NumExtensions: 0, NumServices: 0, }, diff --git a/proto/livekit/rtc.pb.go b/proto/livekit/rtc.pb.go index 2b2c26d0a..ca7418260 100644 --- a/proto/livekit/rtc.pb.go +++ b/proto/livekit/rtc.pb.go @@ -143,6 +143,7 @@ type SignalResponse struct { // *SignalResponse_Answer // *SignalResponse_Negotiate // *SignalResponse_Trickle + // *SignalResponse_Update Message isSignalResponse_Message `protobuf_oneof:"message"` } @@ -213,6 +214,13 @@ func (x *SignalResponse) GetTrickle() *Trickle { return nil } +func (x *SignalResponse) GetUpdate() *ParticipantUpdate { + if x, ok := x.GetMessage().(*SignalResponse_Update); ok { + return x.Update + } + return nil +} + type isSignalResponse_Message interface { isSignalResponse_Message() } @@ -237,6 +245,11 @@ type SignalResponse_Trickle struct { Trickle *Trickle `protobuf:"bytes,4,opt,name=trickle,proto3,oneof"` } +type SignalResponse_Update struct { + // sent when participants in the room has changed + Update *ParticipantUpdate `protobuf:"bytes,5,opt,name=update,proto3,oneof"` +} + func (*SignalResponse_Join) isSignalResponse_Message() {} func (*SignalResponse_Answer) isSignalResponse_Message() {} @@ -245,6 +258,8 @@ func (*SignalResponse_Negotiate) isSignalResponse_Message() {} func (*SignalResponse_Trickle) isSignalResponse_Message() {} +func (*SignalResponse_Update) isSignalResponse_Message() {} + type Trickle struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -352,7 +367,8 @@ type JoinResponse struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Participant *ParticipantInfo `protobuf:"bytes,1,opt,name=participant,proto3" json:"participant,omitempty"` + Participant *ParticipantInfo `protobuf:"bytes,1,opt,name=participant,proto3" json:"participant,omitempty"` + OtherParticipants []*ParticipantInfo `protobuf:"bytes,2,rep,name=other_participants,json=otherParticipants,proto3" json:"other_participants,omitempty"` } func (x *JoinResponse) Reset() { @@ -394,6 +410,13 @@ func (x *JoinResponse) GetParticipant() *ParticipantInfo { return nil } +func (x *JoinResponse) GetOtherParticipants() []*ParticipantInfo { + if x != nil { + return x.OtherParticipants + } + return nil +} + type MediaControl struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -436,6 +459,8 @@ type ParticipantUpdate struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + + Participants []*ParticipantInfo `protobuf:"bytes,1,rep,name=participants,proto3" json:"participants,omitempty"` } func (x *ParticipantUpdate) Reset() { @@ -470,6 +495,13 @@ func (*ParticipantUpdate) Descriptor() ([]byte, []int) { return file_rtc_proto_rawDescGZIP(), []int{6} } +func (x *ParticipantUpdate) GetParticipants() []*ParticipantInfo { + if x != nil { + return x.Participants + } + return nil +} + var File_rtc_proto protoreflect.FileDescriptor var file_rtc_proto_rawDesc = []byte{ @@ -490,7 +522,7 @@ var file_rtc_proto_rawDesc = []byte{ 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x4d, 0x65, 0x64, 0x69, 0x61, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x48, 0x00, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x42, 0x09, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x22, 0xea, 0x01, 0x0a, 0x0e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, + 0x65, 0x22, 0xa0, 0x02, 0x0a, 0x0e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a, 0x04, 0x6a, 0x6f, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x4a, 0x6f, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x04, 0x6a, 0x6f, 0x69, @@ -504,24 +536,36 @@ var file_rtc_proto_rawDesc = []byte{ 0x74, 0x69, 0x61, 0x74, 0x65, 0x12, 0x2c, 0x0a, 0x07, 0x74, 0x72, 0x69, 0x63, 0x6b, 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x54, 0x72, 0x69, 0x63, 0x6b, 0x6c, 0x65, 0x48, 0x00, 0x52, 0x07, 0x74, 0x72, 0x69, 0x63, - 0x6b, 0x6c, 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, 0x4a, 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, 0x22, + 0x6b, 0x6c, 0x65, 0x12, 0x34, 0x0a, 0x06, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x05, 0x20, + 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, - 0x13, 0x0a, 0x11, 0x50, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 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, + 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 ( @@ -548,20 +592,23 @@ var file_rtc_proto_goTypes = []interface{}{ (*ParticipantInfo)(nil), // 7: livekit.ParticipantInfo } var file_rtc_proto_depIdxs = []int32{ - 3, // 0: livekit.SignalRequest.offer:type_name -> livekit.SessionDescription - 3, // 1: livekit.SignalRequest.negotiate:type_name -> livekit.SessionDescription - 2, // 2: livekit.SignalRequest.trickle:type_name -> livekit.Trickle - 5, // 3: livekit.SignalRequest.control:type_name -> livekit.MediaControl - 4, // 4: livekit.SignalResponse.join:type_name -> livekit.JoinResponse - 3, // 5: livekit.SignalResponse.answer:type_name -> livekit.SessionDescription - 3, // 6: livekit.SignalResponse.negotiate:type_name -> livekit.SessionDescription - 2, // 7: livekit.SignalResponse.trickle:type_name -> livekit.Trickle - 7, // 8: livekit.JoinResponse.participant:type_name -> livekit.ParticipantInfo - 9, // [9:9] is the sub-list for method output_type - 9, // [9:9] is the sub-list for method input_type - 9, // [9:9] is the sub-list for extension type_name - 9, // [9:9] is the sub-list for extension extendee - 0, // [0:9] is the sub-list for field type_name + 3, // 0: livekit.SignalRequest.offer:type_name -> livekit.SessionDescription + 3, // 1: livekit.SignalRequest.negotiate:type_name -> livekit.SessionDescription + 2, // 2: livekit.SignalRequest.trickle:type_name -> livekit.Trickle + 5, // 3: livekit.SignalRequest.control:type_name -> livekit.MediaControl + 4, // 4: livekit.SignalResponse.join:type_name -> livekit.JoinResponse + 3, // 5: livekit.SignalResponse.answer:type_name -> livekit.SessionDescription + 3, // 6: livekit.SignalResponse.negotiate:type_name -> livekit.SessionDescription + 2, // 7: livekit.SignalResponse.trickle:type_name -> livekit.Trickle + 6, // 8: livekit.SignalResponse.update:type_name -> livekit.ParticipantUpdate + 7, // 9: livekit.JoinResponse.participant:type_name -> livekit.ParticipantInfo + 7, // 10: livekit.JoinResponse.other_participants:type_name -> livekit.ParticipantInfo + 7, // 11: livekit.ParticipantUpdate.participants:type_name -> livekit.ParticipantInfo + 12, // [12:12] is the sub-list for method output_type + 12, // [12:12] is the sub-list for method input_type + 12, // [12:12] is the sub-list for extension type_name + 12, // [12:12] is the sub-list for extension extendee + 0, // [0:12] is the sub-list for field type_name } func init() { file_rtc_proto_init() } @@ -667,6 +714,7 @@ func file_rtc_proto_init() { (*SignalResponse_Answer)(nil), (*SignalResponse_Negotiate)(nil), (*SignalResponse_Trickle)(nil), + (*SignalResponse_Update)(nil), } type x struct{} out := protoimpl.TypeBuilder{ diff --git a/proto/model.proto b/proto/model.proto index e6e4955eb..a2048c9ed 100644 --- a/proto/model.proto +++ b/proto/model.proto @@ -45,10 +45,21 @@ message ParticipantInfo { string id = 1; string name = 2; State state = 3; - bool has_audio = 4; - bool has_video = 5; } +// describing +message TrackInfo { + enum Type { + AUDIO = 0; + VIDEO = 1; + DATA = 2; + } + string id = 1; + Type type = 2; + string name = 3; +} + + message DataChannel { string session_id = 1; bytes payload = 2; diff --git a/proto/rtc.proto b/proto/rtc.proto index 736f9b533..2e1bef8c0 100644 --- a/proto/rtc.proto +++ b/proto/rtc.proto @@ -24,7 +24,8 @@ message SignalResponse { SessionDescription negotiate = 3; // sent when an ICE candidate is available Trickle trickle = 4; - + // sent when participants in the room has changed + ParticipantUpdate update = 5; } } @@ -39,6 +40,7 @@ message SessionDescription { message JoinResponse { ParticipantInfo participant = 1; + repeated ParticipantInfo other_participants = 2; } message MediaControl { @@ -46,5 +48,5 @@ message MediaControl { } message ParticipantUpdate { - + repeated ParticipantInfo participants = 1; }