mirror of
https://github.com/livekit/livekit.git
synced 2026-06-06 19:51:52 +00:00
use dedicated PeerConnections for sending and receiving (#19)
* protobuf updates to support new protocol * use dedicated publish & subscribe peerconnections * update client to work with dedicated PCs * fix Go client negotiation, reduced length of UUID
This commit is contained in:
+71
-73
@@ -26,9 +26,10 @@ import (
|
||||
)
|
||||
|
||||
type RTCClient struct {
|
||||
id string
|
||||
conn *websocket.Conn
|
||||
PeerConn *webrtc.PeerConnection
|
||||
id string
|
||||
conn *websocket.Conn
|
||||
publisher *rtc.PCTransport
|
||||
subscriber *rtc.PCTransport
|
||||
// sid => track
|
||||
localTracks map[string]webrtc.TrackLocal
|
||||
lock sync.Mutex
|
||||
@@ -45,8 +46,6 @@ type RTCClient struct {
|
||||
// tracks waiting to be acked, cid => trackInfo
|
||||
pendingPublishedTracks map[string]*livekit.TrackInfo
|
||||
|
||||
// pending actions to start after connected to peer
|
||||
pendingCandidates []*webrtc.ICECandidate
|
||||
pendingTrackWriters []*TrackWriter
|
||||
OnConnected func()
|
||||
|
||||
@@ -87,62 +86,62 @@ func SetAuthorizationToken(header http.Header, token string) {
|
||||
}
|
||||
|
||||
func NewRTCClient(conn *websocket.Conn) (*RTCClient, error) {
|
||||
// Create a new RTCPeerConnection
|
||||
peerConn, err := webrtc.NewPeerConnection(rtcConf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var err error
|
||||
|
||||
c := &RTCClient{
|
||||
conn: conn,
|
||||
pendingCandidates: make([]*webrtc.ICECandidate, 0),
|
||||
localTracks: make(map[string]webrtc.TrackLocal),
|
||||
pendingPublishedTracks: make(map[string]*livekit.TrackInfo),
|
||||
subscribedTracks: make(map[string][]*webrtc.TrackRemote),
|
||||
remoteParticipants: make(map[string]*livekit.ParticipantInfo),
|
||||
PeerConn: peerConn,
|
||||
me: &webrtc.MediaEngine{},
|
||||
lastPackets: make(map[string]*rtp.Packet),
|
||||
bytesReceived: make(map[string]uint64),
|
||||
}
|
||||
c.ctx, c.cancel = context.WithCancel(context.Background())
|
||||
c.me.RegisterDefaultCodecs()
|
||||
peerConn.OnICECandidate(func(ic *webrtc.ICECandidate) {
|
||||
|
||||
conf := rtc.WebRTCConfig{
|
||||
Configuration: rtcConf,
|
||||
}
|
||||
c.publisher, err = rtc.NewPCTransport(livekit.SignalTarget_PUBLISHER, &conf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// intentionally use publisher transport to have codecs pre-registered
|
||||
c.subscriber, err = rtc.NewPCTransport(livekit.SignalTarget_PUBLISHER, &conf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
c.publisher.PeerConnection().OnICECandidate(func(ic *webrtc.ICECandidate) {
|
||||
if ic == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if !c.connected.Get() {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
// not connected, save to pending
|
||||
c.pendingCandidates = append(c.pendingCandidates, ic)
|
||||
c.SendIceCandidate(ic, livekit.SignalTarget_PUBLISHER)
|
||||
})
|
||||
c.subscriber.PeerConnection().OnICECandidate(func(ic *webrtc.ICECandidate) {
|
||||
if ic == nil {
|
||||
return
|
||||
}
|
||||
|
||||
// send it through
|
||||
if err := c.SendIceCandidate(ic); err != nil {
|
||||
logger.Debugw("failed to send ice candidate", "err", err)
|
||||
}
|
||||
c.SendIceCandidate(ic, livekit.SignalTarget_SUBSCRIBER)
|
||||
})
|
||||
|
||||
peerConn.OnTrack(func(track *webrtc.TrackRemote, rtpReceiver *webrtc.RTPReceiver) {
|
||||
c.subscriber.PeerConnection().OnTrack(func(track *webrtc.TrackRemote, rtpReceiver *webrtc.RTPReceiver) {
|
||||
logger.Debugw("track received", "label", track.StreamID(), "id", track.ID(),
|
||||
"participant", c.localParticipant.Identity)
|
||||
go c.processTrack(track)
|
||||
})
|
||||
c.subscriber.PeerConnection().OnDataChannel(func(channel *webrtc.DataChannel) {
|
||||
})
|
||||
|
||||
peerConn.OnNegotiationNeeded(func() {
|
||||
c.publisher.OnNegotiationNeeded(func() {
|
||||
if !c.iceConnected.Get() {
|
||||
return
|
||||
}
|
||||
c.requestNegotiation()
|
||||
c.negotiate()
|
||||
})
|
||||
|
||||
peerConn.OnDataChannel(func(channel *webrtc.DataChannel) {
|
||||
})
|
||||
|
||||
peerConn.OnICEConnectionStateChange(func(connectionState webrtc.ICEConnectionState) {
|
||||
c.publisher.PeerConnection().OnICEConnectionStateChange(func(connectionState webrtc.ICEConnectionState) {
|
||||
logger.Debugw("ICE state has changed", "state", connectionState.String(),
|
||||
"participant", c.localParticipant.Identity)
|
||||
if connectionState == webrtc.ICEConnectionStateConnected {
|
||||
@@ -182,7 +181,7 @@ func (c *RTCClient) Run() error {
|
||||
})
|
||||
|
||||
// create a data channel, in order to work
|
||||
_, err := c.PeerConn.CreateDataChannel("_private", nil)
|
||||
_, err := c.publisher.PeerConnection().CreateDataChannel("_private", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -208,16 +207,19 @@ func (c *RTCClient) Run() error {
|
||||
logger.Debugw("other participants", "count", len(msg.Join.OtherParticipants))
|
||||
|
||||
// Create an offer to send to the other process
|
||||
offer, err := c.PeerConn.CreateOffer(nil)
|
||||
offer, err := c.publisher.PeerConnection().CreateOffer(nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logger.Debugw("created offer", "participant", c.localParticipant.Identity)
|
||||
logger.Debugw("created offer",
|
||||
"participant", c.localParticipant.Identity,
|
||||
//"sdp", offer.SDP,
|
||||
)
|
||||
|
||||
// Sets the LocalDescription, and starts our UDP listeners
|
||||
// Note: this will start the gathering of ICE candidates
|
||||
if err = c.PeerConn.SetLocalDescription(offer); err != nil {
|
||||
if err = c.publisher.PeerConnection().SetLocalDescription(offer); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -231,21 +233,28 @@ func (c *RTCClient) Run() error {
|
||||
return err
|
||||
}
|
||||
|
||||
defer c.PeerConn.Close()
|
||||
defer c.Stop()
|
||||
case *livekit.SignalResponse_Answer:
|
||||
//logger.Debugw("received server answer",
|
||||
// "participant", c.localParticipant.Identity,
|
||||
// "answer", msg.Answer.Sdp)
|
||||
c.handleAnswer(rtc.FromProtoSessionDescription(msg.Answer))
|
||||
case *livekit.SignalResponse_Offer:
|
||||
logger.Debugw("received server offer",
|
||||
"type", msg.Offer.Type)
|
||||
//logger.Debugw("received server offer",
|
||||
// "participant", c.localParticipant.Identity,
|
||||
// "sdp", msg.Offer.Sdp)
|
||||
desc := rtc.FromProtoSessionDescription(msg.Offer)
|
||||
if err := c.handleOffer(desc); err != nil {
|
||||
return err
|
||||
}
|
||||
case *livekit.SignalResponse_Negotiate:
|
||||
c.negotiate()
|
||||
case *livekit.SignalResponse_Trickle:
|
||||
candidateInit := rtc.FromProtoTrickle(msg.Trickle)
|
||||
if err := c.PeerConn.AddICECandidate(candidateInit); err != nil {
|
||||
if msg.Trickle.Target == livekit.SignalTarget_PUBLISHER {
|
||||
err = c.publisher.AddICECandidate(candidateInit)
|
||||
} else {
|
||||
err = c.subscriber.AddICECandidate(candidateInit)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case *livekit.SignalResponse_Update:
|
||||
@@ -331,7 +340,8 @@ func (c *RTCClient) Stop() {
|
||||
c.connected.TrySet(false)
|
||||
c.iceConnected.TrySet(false)
|
||||
c.conn.Close()
|
||||
c.PeerConn.Close()
|
||||
c.publisher.Close()
|
||||
c.subscriber.Close()
|
||||
c.cancel()
|
||||
}
|
||||
|
||||
@@ -346,11 +356,12 @@ func (c *RTCClient) SendRequest(msg *livekit.SignalRequest) error {
|
||||
return c.conn.WriteMessage(websocket.TextMessage, payload)
|
||||
}
|
||||
|
||||
func (c *RTCClient) SendIceCandidate(ic *webrtc.ICECandidate) error {
|
||||
candInit := ic.ToJSON()
|
||||
func (c *RTCClient) SendIceCandidate(ic *webrtc.ICECandidate, target livekit.SignalTarget) error {
|
||||
trickle := rtc.ToProtoTrickle(ic.ToJSON())
|
||||
trickle.Target = target
|
||||
return c.SendRequest(&livekit.SignalRequest{
|
||||
Message: &livekit.SignalRequest_Trickle{
|
||||
Trickle: rtc.ToProtoTrickle(candInit),
|
||||
Trickle: trickle,
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -390,7 +401,7 @@ func (c *RTCClient) AddTrack(track *webrtc.TrackLocalStaticSample, path string)
|
||||
defer c.lock.Unlock()
|
||||
c.localTracks[ti.Sid] = track
|
||||
|
||||
if _, err = c.PeerConn.AddTrack(track); err != nil {
|
||||
if _, err = c.publisher.PeerConnection().AddTrack(track); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -451,24 +462,27 @@ func (c *RTCClient) SendAddTrack(cid string, name string, trackType livekit.Trac
|
||||
})
|
||||
}
|
||||
|
||||
// handles a server initiated offer, handle on subscriber PC
|
||||
func (c *RTCClient) handleOffer(desc webrtc.SessionDescription) error {
|
||||
// always set remote description for both offer and answer
|
||||
if err := c.PeerConn.SetRemoteDescription(desc); err != nil {
|
||||
if err := c.subscriber.SetRemoteDescription(desc); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// if we received an offer, we'd have to answer
|
||||
answer, err := c.PeerConn.CreateAnswer(nil)
|
||||
answer, err := c.subscriber.PeerConnection().CreateAnswer(nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := c.PeerConn.SetLocalDescription(answer); err != nil {
|
||||
if err := c.subscriber.PeerConnection().SetLocalDescription(answer); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// send remote an answer
|
||||
logger.Debugw("sending answer")
|
||||
logger.Debugw("sending subscriber answer",
|
||||
"participant", c.localParticipant.Identity,
|
||||
//"sdp", answer,
|
||||
)
|
||||
return c.SendRequest(&livekit.SignalRequest{
|
||||
Message: &livekit.SignalRequest_Answer{
|
||||
Answer: rtc.ToProtoSessionDescription(answer),
|
||||
@@ -476,10 +490,11 @@ func (c *RTCClient) handleOffer(desc webrtc.SessionDescription) error {
|
||||
})
|
||||
}
|
||||
|
||||
// the client handles answer on the publisher PC
|
||||
func (c *RTCClient) handleAnswer(desc webrtc.SessionDescription) error {
|
||||
logger.Debugw("handling server answer", "participant", c.localParticipant.Identity)
|
||||
// remote answered the offer, establish connection
|
||||
err := c.PeerConn.SetRemoteDescription(desc)
|
||||
err := c.publisher.SetRemoteDescription(desc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -488,34 +503,17 @@ func (c *RTCClient) handleAnswer(desc webrtc.SessionDescription) error {
|
||||
// already connected
|
||||
return nil
|
||||
}
|
||||
|
||||
// add all the pending items
|
||||
c.lock.Lock()
|
||||
for _, ic := range c.pendingCandidates {
|
||||
c.SendIceCandidate(ic)
|
||||
}
|
||||
c.pendingCandidates = nil
|
||||
c.lock.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *RTCClient) requestNegotiation() error {
|
||||
logger.Debugw("requesting negotiation", "participant", c.localParticipant.Identity)
|
||||
return c.SendRequest(&livekit.SignalRequest{
|
||||
Message: &livekit.SignalRequest_Negotiate{
|
||||
Negotiate: &livekit.NegotiationRequest{},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func (c *RTCClient) negotiate() error {
|
||||
logger.Debugw("starting negotiation", "participant", c.localParticipant.Identity)
|
||||
offer, err := c.PeerConn.CreateOffer(nil)
|
||||
offer, err := c.publisher.PeerConnection().CreateOffer(nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := c.PeerConn.SetLocalDescription(offer); err != nil {
|
||||
if err := c.publisher.PeerConnection().SetLocalDescription(offer); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -591,5 +589,5 @@ func (c *RTCClient) SendNacks(count int) {
|
||||
}
|
||||
c.lock.Unlock()
|
||||
|
||||
c.PeerConn.WriteRTCP(packets)
|
||||
c.subscriber.PeerConnection().WriteRTCP(packets)
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ require (
|
||||
github.com/pion/rtp v1.6.2
|
||||
github.com/pion/sdp/v3 v3.0.4
|
||||
github.com/pion/stun v0.3.5
|
||||
github.com/pion/webrtc/v3 v3.0.5
|
||||
github.com/pion/webrtc/v3 v3.0.8
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/stretchr/testify v1.7.0
|
||||
github.com/thoas/go-funk v0.7.0
|
||||
|
||||
@@ -325,6 +325,8 @@ github.com/pion/datachannel v1.4.21 h1:3ZvhNyfmxsAqltQrApLPQMhSFNA+aT87RqyCq4OXm
|
||||
github.com/pion/datachannel v1.4.21/go.mod h1:oiNyP4gHx2DIwRzX/MFyH0Rz/Gz05OgBlayAI2hAWjg=
|
||||
github.com/pion/dtls/v2 v2.0.4 h1:WuUcqi6oYMu/noNTz92QrF1DaFj4eXbhQ6dzaaAwOiI=
|
||||
github.com/pion/dtls/v2 v2.0.4/go.mod h1:qAkFscX0ZHoI1E07RfYPoRw3manThveu+mlTDdOxoGI=
|
||||
github.com/pion/dtls/v2 v2.0.5 h1:jgQJRK2IJ9eWQAcUEZN4M0tnCi5X/cERnxH9J8qOjR0=
|
||||
github.com/pion/dtls/v2 v2.0.5/go.mod h1:QuDII+8FVvk9Dp5t5vYIMTo7hh7uBkra+8QIm7QGm10=
|
||||
github.com/pion/ice/v2 v2.0.14 h1:FxXxauyykf89SWAtkQCfnHkno6G8+bhRkNguSh9zU+4=
|
||||
github.com/pion/ice/v2 v2.0.14/go.mod h1:wqaUbOq5ObDNU5ox1hRsEst0rWfsKuH1zXjQFEWiZwM=
|
||||
github.com/pion/ice/v2 v2.0.15 h1:KZrwa2ciL9od8+TUVJiYTNsCW9J5lktBjGwW1MacEnQ=
|
||||
@@ -375,6 +377,8 @@ github.com/pion/webrtc/v3 v3.0.4 h1:Tiw3H9fpfcwkvaxonB+Gv1DG9tmgYBQaM1vBagDHP40=
|
||||
github.com/pion/webrtc/v3 v3.0.4/go.mod h1:1TmFSLpPYFTFXFHPtoq9eGP1ASTa9LC6FBh7sUY8cd4=
|
||||
github.com/pion/webrtc/v3 v3.0.5 h1:utennp7RwX+2mtyMzoOXE03IUIckiHBigjarRJZ2DqY=
|
||||
github.com/pion/webrtc/v3 v3.0.5/go.mod h1:/EDCREM8y+JrJSkoCRHpoz//qtuBCOYV4E96vEK3bz0=
|
||||
github.com/pion/webrtc/v3 v3.0.8 h1:Dgu/NZ6QAIvoNZU3qk/B35iPPx6TVHP506FfCE4SXCA=
|
||||
github.com/pion/webrtc/v3 v3.0.8/go.mod h1:C5uzSMa9sGCtfVPLA+pB0eWoW/exZ0OV0KW7JJbkvp0=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
|
||||
@@ -90,7 +90,7 @@ func (t *DataTrack) OnClose(f func()) {
|
||||
|
||||
func (t *DataTrack) AddSubscriber(participant types.Participant) error {
|
||||
label := PackDataTrackLabel(t.participantId, t.ID(), t.dataChannel.Label())
|
||||
downChannel, err := participant.PeerConnection().CreateDataChannel(label, t.dataChannelOptions())
|
||||
downChannel, err := participant.SubscriberPC().CreateDataChannel(label, t.dataChannelOptions())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -6,11 +6,10 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
repairedRTP = "urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id"
|
||||
frameMarking = "urn:ietf:params:rtp-hdrext:framemarking"
|
||||
)
|
||||
|
||||
func createMediaEngine() (*webrtc.MediaEngine, error) {
|
||||
func createPubMediaEngine() (*webrtc.MediaEngine, error) {
|
||||
me := &webrtc.MediaEngine{}
|
||||
if err := me.RegisterCodec(webrtc.RTPCodecParameters{
|
||||
RTPCodecCapability: webrtc.RTPCodecCapability{MimeType: webrtc.MimeTypeOpus, ClockRate: 48000, Channels: 2, SDPFmtpLine: "minptime=10;useinbandfec=1", RTCPFeedback: nil},
|
||||
@@ -21,7 +20,7 @@ func createMediaEngine() (*webrtc.MediaEngine, error) {
|
||||
|
||||
videoRTCPFeedback := []webrtc.RTCPFeedback{
|
||||
{webrtc.TypeRTCPFBGoogREMB, ""},
|
||||
//{webrtc.TypeRTCPFBCCM, "fir"},
|
||||
{webrtc.TypeRTCPFBCCM, "fir"},
|
||||
{webrtc.TypeRTCPFBNACK, ""},
|
||||
{webrtc.TypeRTCPFBNACK, "pli"}}
|
||||
for _, codec := range []webrtc.RTPCodecParameters{
|
||||
@@ -66,8 +65,7 @@ func createMediaEngine() (*webrtc.MediaEngine, error) {
|
||||
for _, extension := range []string{
|
||||
sdp.SDESMidURI,
|
||||
sdp.SDESRTPStreamIDURI,
|
||||
repairedRTP,
|
||||
//sdp.TransportCCURI,
|
||||
sdp.TransportCCURI,
|
||||
frameMarking,
|
||||
} {
|
||||
if err := me.RegisterHeaderExtension(webrtc.RTPHeaderExtensionCapability{URI: extension}, webrtc.RTPCodecTypeVideo); err != nil {
|
||||
@@ -86,3 +84,8 @@ func createMediaEngine() (*webrtc.MediaEngine, error) {
|
||||
|
||||
return me, nil
|
||||
}
|
||||
|
||||
func createSubMediaEngine() (*webrtc.MediaEngine, error) {
|
||||
me := &webrtc.MediaEngine{}
|
||||
return me, nil
|
||||
}
|
||||
|
||||
+13
-15
@@ -125,6 +125,9 @@ func (t *MediaTrack) AddSubscriber(sub types.Participant) error {
|
||||
}
|
||||
|
||||
codec := t.receiver.Codec()
|
||||
if err := sub.SubscriberMediaEngine().RegisterCodec(codec, t.receiver.Kind()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// using DownTrack from ion-sfu
|
||||
downTrack, err := sfu.NewDownTrack(webrtc.RTPCodecCapability{
|
||||
@@ -140,8 +143,8 @@ func (t *MediaTrack) AddSubscriber(sub types.Participant) error {
|
||||
downTrack.SetBufferFactory(bufferFactory)
|
||||
subTrack := NewSubscribedTrack(downTrack)
|
||||
|
||||
transceiver, err := sub.PeerConnection().AddTransceiverFromTrack(downTrack, webrtc.RTPTransceiverInit{
|
||||
Direction: webrtc.RTPTransceiverDirectionSendrecv,
|
||||
transceiver, err := sub.SubscriberPC().AddTransceiverFromTrack(downTrack, webrtc.RTPTransceiverInit{
|
||||
Direction: webrtc.RTPTransceiverDirectionSendonly,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -159,7 +162,7 @@ func (t *MediaTrack) AddSubscriber(sub types.Participant) error {
|
||||
t.lock.Unlock()
|
||||
|
||||
// ignore if the subscribing sub is not connected
|
||||
if sub.PeerConnection().ConnectionState() == webrtc.PeerConnectionStateClosed {
|
||||
if sub.SubscriberPC().ConnectionState() == webrtc.PeerConnectionStateClosed {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -173,7 +176,7 @@ func (t *MediaTrack) AddSubscriber(sub types.Participant) error {
|
||||
"track", t.id,
|
||||
"participantId", t.participantId,
|
||||
"destParticipant", sub.Identity())
|
||||
if err := sub.PeerConnection().RemoveTrack(sender); err != nil {
|
||||
if err := sub.SubscriberPC().RemoveTrack(sender); err != nil {
|
||||
if err == webrtc.ErrConnectionClosed {
|
||||
// sub closing, can skip removing subscribedtracks
|
||||
return
|
||||
@@ -197,7 +200,7 @@ func (t *MediaTrack) AddSubscriber(sub types.Participant) error {
|
||||
}
|
||||
|
||||
// adds a new RTP receiver to the track, returns true if this is a new track
|
||||
func (t *MediaTrack) AddReceiver(receiver *webrtc.RTPReceiver, track *webrtc.TrackRemote) {
|
||||
func (t *MediaTrack) AddReceiver(receiver *webrtc.RTPReceiver, track *webrtc.TrackRemote, twcc *twcc.Responder) {
|
||||
//rid := track.RID()
|
||||
buff, rtcpReader := bufferFactory.GetBufferPair(uint32(track.SSRC()))
|
||||
buff.OnFeedback(func(fb []rtcp.Packet) {
|
||||
@@ -208,16 +211,11 @@ func (t *MediaTrack) AddReceiver(receiver *webrtc.RTPReceiver, track *webrtc.Tra
|
||||
if t.Kind() == livekit.TrackType_AUDIO {
|
||||
// TODO: audio level stuff
|
||||
} else if t.Kind() == livekit.TrackType_VIDEO {
|
||||
// TODO: handle twcc
|
||||
//if t.twcc == nil {
|
||||
// t.twcc = twcc.NewTransportWideCCResponder(uint32(track.SSRC()))
|
||||
// t.twcc.OnFeedback(func(p rtcp.RawPacket) {
|
||||
// t.rtcpCh <- []rtcp.Packet{&p}
|
||||
// })
|
||||
//}
|
||||
buff.OnTransportWideCC(func(sn uint16, timeNS int64, marker bool) {
|
||||
//t.twcc.Push(sn, timeNS, marker)
|
||||
})
|
||||
if twcc != nil {
|
||||
buff.OnTransportWideCC(func(sn uint16, timeNS int64, marker bool) {
|
||||
twcc.Push(sn, timeNS, marker)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
rtcpReader.OnPacket(func(bytes []byte) {
|
||||
|
||||
+115
-177
@@ -7,7 +7,7 @@ import (
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/bep/debounce"
|
||||
"github.com/pion/ion-sfu/pkg/twcc"
|
||||
"github.com/pion/rtcp"
|
||||
"github.com/pion/webrtc/v3"
|
||||
"github.com/pkg/errors"
|
||||
@@ -18,32 +18,29 @@ import (
|
||||
"github.com/livekit/livekit-server/pkg/rtc/types"
|
||||
"github.com/livekit/livekit-server/pkg/utils"
|
||||
"github.com/livekit/livekit-server/proto/livekit"
|
||||
"github.com/livekit/livekit-server/version"
|
||||
)
|
||||
|
||||
const (
|
||||
placeholderDataChannel = "_private"
|
||||
sdBatchSize = 20
|
||||
negotiationFrequency = 100 * time.Millisecond
|
||||
)
|
||||
|
||||
const (
|
||||
negotiationStateNone = iota
|
||||
negotiationStateClient
|
||||
negotiationStateServer
|
||||
)
|
||||
|
||||
type ParticipantImpl struct {
|
||||
id string
|
||||
peerConn types.PeerConnection
|
||||
publisher *PCTransport
|
||||
subscriber *PCTransport
|
||||
responseSink routing.MessageSink
|
||||
receiverConfig ReceiverConfig
|
||||
isClosed utils.AtomicFlag
|
||||
mediaEngine *webrtc.MediaEngine
|
||||
identity string
|
||||
// JSON encoded metadata to pass to clients
|
||||
metadata string
|
||||
state atomic.Value // livekit.ParticipantInfo_State
|
||||
rtcpCh chan []rtcp.Packet
|
||||
|
||||
twcc *twcc.Responder
|
||||
|
||||
// tracks the current participant is subscribed to, map of otherParticipantId => []DownTrack
|
||||
subscribedTracks map[string][]types.SubscribedTrack
|
||||
// publishedTracks that participant is publishing
|
||||
@@ -51,101 +48,70 @@ type ParticipantImpl struct {
|
||||
// client intended to publish, yet to be reconciled
|
||||
pendingTracks map[string]*livekit.TrackInfo
|
||||
|
||||
negotiationCond *sync.Cond
|
||||
negotiationState int
|
||||
debouncedNegotiate func(func())
|
||||
|
||||
lock sync.RWMutex
|
||||
once sync.Once
|
||||
|
||||
// callbacks & handlers
|
||||
onTrackPublished func(types.Participant, types.PublishedTrack)
|
||||
onTrackUpdated func(types.Participant, types.PublishedTrack)
|
||||
onICECandidate func(c *webrtc.ICECandidateInit)
|
||||
onStateChange func(p types.Participant, oldState livekit.ParticipantInfo_State)
|
||||
onClose func(types.Participant)
|
||||
}
|
||||
|
||||
func NewPeerConnection(conf *WebRTCConfig) (*webrtc.PeerConnection, error) {
|
||||
me, err := createMediaEngine()
|
||||
func NewParticipant(identity string, conf *WebRTCConfig, rs routing.MessageSink, receiverConfig ReceiverConfig) (*ParticipantImpl, error) {
|
||||
// TODO: check to ensure params are valid, id and identity can't be empty
|
||||
|
||||
p := &ParticipantImpl{
|
||||
id: utils.NewGuid(utils.ParticipantPrefix),
|
||||
identity: identity,
|
||||
responseSink: rs,
|
||||
receiverConfig: receiverConfig,
|
||||
rtcpCh: make(chan []rtcp.Packet, 50),
|
||||
subscribedTracks: make(map[string][]types.SubscribedTrack),
|
||||
lock: sync.RWMutex{},
|
||||
publishedTracks: make(map[string]types.PublishedTrack, 0),
|
||||
pendingTracks: make(map[string]*livekit.TrackInfo),
|
||||
}
|
||||
p.state.Store(livekit.ParticipantInfo_JOINING)
|
||||
var err error
|
||||
|
||||
p.publisher, err = NewPCTransport(livekit.SignalTarget_PUBLISHER, conf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
se := conf.SettingEngine
|
||||
se.BufferFactory = bufferFactory.GetOrNew
|
||||
|
||||
api := webrtc.NewAPI(webrtc.WithMediaEngine(me), webrtc.WithSettingEngine(se))
|
||||
pc, err := api.NewPeerConnection(conf.Configuration)
|
||||
return pc, err
|
||||
}
|
||||
|
||||
func NewParticipant(identity string, pc types.PeerConnection, rs routing.MessageSink, receiverConfig ReceiverConfig) (*ParticipantImpl, error) {
|
||||
// TODO: check to ensure params are valid, id and identity can't be empty
|
||||
|
||||
participant := &ParticipantImpl{
|
||||
id: utils.NewGuid(utils.ParticipantPrefix),
|
||||
identity: identity,
|
||||
peerConn: pc,
|
||||
responseSink: rs,
|
||||
receiverConfig: receiverConfig,
|
||||
rtcpCh: make(chan []rtcp.Packet, 50),
|
||||
subscribedTracks: make(map[string][]types.SubscribedTrack),
|
||||
lock: sync.RWMutex{},
|
||||
negotiationCond: sync.NewCond(&sync.Mutex{}),
|
||||
publishedTracks: make(map[string]types.PublishedTrack, 0),
|
||||
pendingTracks: make(map[string]*livekit.TrackInfo),
|
||||
debouncedNegotiate: debounce.New(negotiationFrequency),
|
||||
p.subscriber, err = NewPCTransport(livekit.SignalTarget_SUBSCRIBER, conf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
participant.state.Store(livekit.ParticipantInfo_JOINING)
|
||||
|
||||
pc.OnTrack(participant.onMediaTrack)
|
||||
|
||||
pc.OnICECandidate(func(c *webrtc.ICECandidate) {
|
||||
p.publisher.pc.OnICECandidate(func(c *webrtc.ICECandidate) {
|
||||
if c == nil {
|
||||
return
|
||||
}
|
||||
|
||||
ci := c.ToJSON()
|
||||
|
||||
// write candidate
|
||||
//logger.Debugw("sending ice candidates")
|
||||
err := rs.WriteMessage(&livekit.SignalResponse{
|
||||
Message: &livekit.SignalResponse_Trickle{
|
||||
Trickle: ToProtoTrickle(ci),
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
logger.Errorw("could not send trickle", "err", err,
|
||||
"participant", identity)
|
||||
}
|
||||
|
||||
if participant.onICECandidate != nil {
|
||||
participant.onICECandidate(&ci)
|
||||
}
|
||||
p.sendIceCandidate(c, livekit.SignalTarget_PUBLISHER)
|
||||
})
|
||||
|
||||
pc.OnICEConnectionStateChange(func(state webrtc.ICEConnectionState) {
|
||||
//logger.Debugw("ICE connection state changed", "state", state.String())
|
||||
if state == webrtc.ICEConnectionStateConnected {
|
||||
participant.updateState(livekit.ParticipantInfo_ACTIVE)
|
||||
} else if state == webrtc.ICEConnectionStateDisconnected {
|
||||
go participant.Close()
|
||||
}
|
||||
})
|
||||
|
||||
pc.OnDataChannel(participant.onDataChannel)
|
||||
|
||||
// only set after answered
|
||||
pc.OnNegotiationNeeded(func() {
|
||||
logger.Debugw("negotiation needed", "participant", participant.Identity())
|
||||
if !participant.IsReady() {
|
||||
// ignore negotiation requests before connected
|
||||
p.subscriber.pc.OnICECandidate(func(c *webrtc.ICECandidate) {
|
||||
if c == nil {
|
||||
return
|
||||
}
|
||||
participant.scheduleNegotiate()
|
||||
p.sendIceCandidate(c, livekit.SignalTarget_SUBSCRIBER)
|
||||
})
|
||||
|
||||
return participant, nil
|
||||
p.publisher.pc.OnICEConnectionStateChange(func(state webrtc.ICEConnectionState) {
|
||||
//logger.Debugw("ICE connection state changed", "state", state.String())
|
||||
if state == webrtc.ICEConnectionStateConnected {
|
||||
p.updateState(livekit.ParticipantInfo_ACTIVE)
|
||||
} else if state == webrtc.ICEConnectionStateDisconnected {
|
||||
go p.Close()
|
||||
}
|
||||
})
|
||||
|
||||
p.publisher.pc.OnTrack(p.onMediaTrack)
|
||||
p.subscriber.pc.OnDataChannel(p.onDataChannel)
|
||||
|
||||
p.subscriber.OnNegotiationNeeded(p.negotiate)
|
||||
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func (p *ParticipantImpl) ID() string {
|
||||
@@ -209,15 +175,15 @@ func (p *ParticipantImpl) SetResponseSink(sink routing.MessageSink) {
|
||||
p.responseSink = sink
|
||||
}
|
||||
|
||||
func (p *ParticipantImpl) SubscriberMediaEngine() *webrtc.MediaEngine {
|
||||
return p.subscriber.me
|
||||
}
|
||||
|
||||
// callbacks for clients
|
||||
func (p *ParticipantImpl) OnTrackPublished(callback func(types.Participant, types.PublishedTrack)) {
|
||||
p.onTrackPublished = callback
|
||||
}
|
||||
|
||||
func (p *ParticipantImpl) OnICECandidate(callback func(c *webrtc.ICECandidateInit)) {
|
||||
p.onICECandidate = callback
|
||||
}
|
||||
|
||||
func (p *ParticipantImpl) OnStateChange(callback func(p types.Participant, oldState livekit.ParticipantInfo_State)) {
|
||||
p.onStateChange = callback
|
||||
}
|
||||
@@ -230,42 +196,28 @@ func (p *ParticipantImpl) OnClose(callback func(types.Participant)) {
|
||||
p.onClose = callback
|
||||
}
|
||||
|
||||
// Answer an offer from remote participant, used when clients make the initial connection
|
||||
func (p *ParticipantImpl) Answer(sdp webrtc.SessionDescription) (answer webrtc.SessionDescription, err error) {
|
||||
if p.State() != livekit.ParticipantInfo_JOINING && p.negotiationState != negotiationStateClient {
|
||||
// not in a valid state to continue
|
||||
err = ErrUnexpectedNegotiation
|
||||
return
|
||||
}
|
||||
|
||||
logger.Debugw("answering client offer", "state", p.State().String(),
|
||||
// HandleOffer an offer from remote participant, used when clients make the initial connection
|
||||
func (p *ParticipantImpl) HandleOffer(sdp webrtc.SessionDescription) (answer webrtc.SessionDescription, err error) {
|
||||
logger.Debugw("answering pub offer", "state", p.State().String(),
|
||||
"participant", p.Identity(),
|
||||
//"sdp", sdp.SDP,
|
||||
)
|
||||
|
||||
if err = p.peerConn.SetRemoteDescription(sdp); err != nil {
|
||||
if err = p.publisher.SetRemoteDescription(sdp); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
answer, err = p.peerConn.CreateAnswer(nil)
|
||||
answer, err = p.publisher.pc.CreateAnswer(nil)
|
||||
if err != nil {
|
||||
err = errors.Wrap(err, "could not create answer")
|
||||
return
|
||||
}
|
||||
|
||||
if err = p.peerConn.SetLocalDescription(answer); err != nil {
|
||||
if err = p.publisher.pc.SetLocalDescription(answer); err != nil {
|
||||
err = errors.Wrap(err, "could not set local description")
|
||||
return
|
||||
}
|
||||
|
||||
// if this is a client initiated re-negotiation, we'll need to flip back our state
|
||||
p.negotiationCond.L.Lock()
|
||||
if p.negotiationState == negotiationStateClient {
|
||||
p.negotiationState = negotiationStateNone
|
||||
p.negotiationCond.Broadcast()
|
||||
}
|
||||
p.negotiationCond.L.Unlock()
|
||||
|
||||
logger.Debugw("sending answer to client",
|
||||
"participant", p.Identity(),
|
||||
//"sdp", sdp.SDP,
|
||||
@@ -313,57 +265,32 @@ func (p *ParticipantImpl) AddTrack(clientId, name string, trackType livekit.Trac
|
||||
}
|
||||
}
|
||||
|
||||
// handles a client answer response, with subscriber PC, server initiates the offer
|
||||
// and client answers
|
||||
func (p *ParticipantImpl) HandleAnswer(sdp webrtc.SessionDescription) error {
|
||||
if sdp.Type != webrtc.SDPTypeAnswer {
|
||||
return ErrUnexpectedOffer
|
||||
}
|
||||
logger.Debugw("setting participant answer",
|
||||
logger.Debugw("setting subPC answer",
|
||||
"participant", p.Identity(),
|
||||
//"sdp", sdp.SDP,
|
||||
)
|
||||
if err := p.peerConn.SetRemoteDescription(sdp); err != nil {
|
||||
if err := p.subscriber.SetRemoteDescription(sdp); err != nil {
|
||||
return errors.Wrap(err, "could not set remote description")
|
||||
}
|
||||
|
||||
// negotiated, reset flag
|
||||
p.negotiationCond.L.Lock()
|
||||
p.negotiationState = negotiationStateNone
|
||||
p.negotiationCond.Broadcast()
|
||||
p.negotiationCond.L.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
// client requested negotiation, when it's able to, send a signal to let it
|
||||
func (p *ParticipantImpl) HandleClientNegotiation() {
|
||||
logger.Debugw("participant requested negotiation",
|
||||
"participant", p.Identity())
|
||||
// wait until client is able to request negotiation
|
||||
p.negotiationCond.L.Lock()
|
||||
for p.negotiationState != negotiationStateNone {
|
||||
p.negotiationCond.Wait()
|
||||
}
|
||||
p.negotiationState = negotiationStateClient
|
||||
p.negotiationCond.L.Unlock()
|
||||
|
||||
logger.Debugw("allowing participant to negotiate",
|
||||
"participant", p.Identity())
|
||||
err := p.responseSink.WriteMessage(&livekit.SignalResponse{
|
||||
Message: &livekit.SignalResponse_Negotiate{
|
||||
Negotiate: &livekit.NegotiationResponse{},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
logger.Errorw("could not write message", "error", err,
|
||||
"participant", p.identity)
|
||||
}
|
||||
}
|
||||
|
||||
// AddICECandidate adds candidates for remote peer
|
||||
func (p *ParticipantImpl) AddICECandidate(candidate webrtc.ICECandidateInit) error {
|
||||
if err := p.peerConn.AddICECandidate(candidate); err != nil {
|
||||
return err
|
||||
func (p *ParticipantImpl) AddICECandidate(candidate webrtc.ICECandidateInit, target livekit.SignalTarget) error {
|
||||
var err error
|
||||
if target == livekit.SignalTarget_PUBLISHER {
|
||||
err = p.publisher.AddICECandidate(candidate)
|
||||
} else {
|
||||
err = p.subscriber.AddICECandidate(candidate)
|
||||
}
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
|
||||
func (p *ParticipantImpl) Start() {
|
||||
@@ -389,25 +316,26 @@ func (p *ParticipantImpl) Close() error {
|
||||
p.lock.Unlock()
|
||||
|
||||
p.updateState(livekit.ParticipantInfo_DISCONNECTED)
|
||||
p.onICECandidate = nil
|
||||
p.peerConn.OnDataChannel(nil)
|
||||
p.peerConn.OnICECandidate(nil)
|
||||
p.peerConn.OnNegotiationNeeded(nil)
|
||||
p.peerConn.OnTrack(nil)
|
||||
p.subscriber.pc.OnDataChannel(nil)
|
||||
p.subscriber.pc.OnICECandidate(nil)
|
||||
p.subscriber.pc.OnNegotiationNeeded(nil)
|
||||
p.subscriber.pc.OnTrack(nil)
|
||||
p.publisher.pc.OnICECandidate(nil)
|
||||
p.responseSink.Close()
|
||||
if p.onClose != nil {
|
||||
p.onClose(p)
|
||||
}
|
||||
p.peerConn.Close()
|
||||
p.publisher.Close()
|
||||
p.subscriber.Close()
|
||||
close(p.rtcpCh)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Subscribes otherPeer to all of the publishedTracks
|
||||
// Subscribes op to all publishedTracks
|
||||
func (p *ParticipantImpl) AddSubscriber(op types.Participant) error {
|
||||
p.lock.RLock()
|
||||
tracks := funk.Values(p.publishedTracks).([]types.PublishedTrack)
|
||||
p.lock.RUnlock()
|
||||
defer p.lock.RUnlock()
|
||||
|
||||
if len(tracks) == 0 {
|
||||
return nil
|
||||
@@ -444,6 +372,7 @@ func (p *ParticipantImpl) SendJoinResponse(roomInfo *livekit.Room, otherParticip
|
||||
Room: roomInfo,
|
||||
Participant: p.ToProto(),
|
||||
OtherParticipants: ToProtoParticipants(otherParticipants),
|
||||
ServerVersion: version.Version,
|
||||
},
|
||||
},
|
||||
})
|
||||
@@ -483,8 +412,8 @@ func (p *ParticipantImpl) SetTrackMuted(trackId string, muted bool) {
|
||||
}
|
||||
}
|
||||
|
||||
func (p *ParticipantImpl) PeerConnection() types.PeerConnection {
|
||||
return p.peerConn
|
||||
func (p *ParticipantImpl) SubscriberPC() *webrtc.PeerConnection {
|
||||
return p.subscriber.pc
|
||||
}
|
||||
|
||||
// add a track to the participant's subscribed list
|
||||
@@ -511,8 +440,22 @@ func (p *ParticipantImpl) RemoveSubscribedTrack(pubId string, subTrack types.Sub
|
||||
p.subscribedTracks[pubId] = tracks
|
||||
}
|
||||
|
||||
func (p *ParticipantImpl) scheduleNegotiate() {
|
||||
p.debouncedNegotiate(p.negotiate)
|
||||
func (p *ParticipantImpl) sendIceCandidate(c *webrtc.ICECandidate, target livekit.SignalTarget) {
|
||||
ci := c.ToJSON()
|
||||
|
||||
// write candidate
|
||||
//logger.Debugw("sending ice candidates")
|
||||
trickle := ToProtoTrickle(ci)
|
||||
trickle.Target = target
|
||||
err := p.responseSink.WriteMessage(&livekit.SignalResponse{
|
||||
Message: &livekit.SignalResponse_Trickle{
|
||||
Trickle: trickle,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
logger.Errorw("could not send trickle", "err", err,
|
||||
"participant", p.identity)
|
||||
}
|
||||
}
|
||||
|
||||
// initiates server-driven negotiation by creating an offer
|
||||
@@ -522,27 +465,15 @@ func (p *ParticipantImpl) negotiate() {
|
||||
return
|
||||
}
|
||||
|
||||
p.negotiationCond.L.Lock()
|
||||
for p.negotiationState != negotiationStateNone {
|
||||
p.negotiationCond.Wait()
|
||||
}
|
||||
p.negotiationState = negotiationStateServer
|
||||
p.negotiationCond.L.Unlock()
|
||||
logger.Debugw("starting server negotiation", "participant", p.Identity())
|
||||
|
||||
offer, err := p.peerConn.CreateOffer(nil)
|
||||
offer, err := p.subscriber.pc.CreateOffer(nil)
|
||||
if err != nil {
|
||||
logger.Errorw("could not create offer", "err", err)
|
||||
return
|
||||
}
|
||||
|
||||
if p.peerConn.SignalingState() != webrtc.SignalingStateStable {
|
||||
// try this again
|
||||
p.scheduleNegotiate()
|
||||
return
|
||||
}
|
||||
|
||||
err = p.peerConn.SetLocalDescription(offer)
|
||||
err = p.subscriber.pc.SetLocalDescription(offer)
|
||||
if err != nil {
|
||||
logger.Errorw("could not set local description", "err", err)
|
||||
return
|
||||
@@ -588,13 +519,9 @@ func (p *ParticipantImpl) onMediaTrack(track *webrtc.TrackRemote, rtpReceiver *w
|
||||
return
|
||||
}
|
||||
|
||||
// create ReceiverImpl
|
||||
//receiver := NewReceiver(p.rtcpCh, rtpReceiver, track, p.receiverConfig)
|
||||
|
||||
// use existing mediatrack to handle simulcast
|
||||
p.lock.RLock()
|
||||
p.lock.Lock()
|
||||
ptrack := p.publishedTracks[ti.Sid]
|
||||
p.lock.RUnlock()
|
||||
|
||||
var mt *MediaTrack
|
||||
var newTrack bool
|
||||
@@ -607,7 +534,14 @@ func (p *ParticipantImpl) onMediaTrack(track *webrtc.TrackRemote, rtpReceiver *w
|
||||
newTrack = true
|
||||
}
|
||||
|
||||
mt.AddReceiver(rtpReceiver, track)
|
||||
if p.twcc == nil {
|
||||
p.twcc = twcc.NewTransportWideCCResponder(uint32(track.SSRC()))
|
||||
p.twcc.OnFeedback(func(pkt rtcp.RawPacket) {
|
||||
p.publisher.pc.WriteRTCP([]rtcp.Packet{&pkt})
|
||||
})
|
||||
}
|
||||
mt.AddReceiver(rtpReceiver, track, p.twcc)
|
||||
p.lock.Unlock()
|
||||
|
||||
if newTrack {
|
||||
p.handleTrackPublished(mt)
|
||||
@@ -638,7 +572,7 @@ func (p *ParticipantImpl) popPendingTrack(clientId string, kind livekit.TrackTyp
|
||||
ti := p.pendingTracks[clientId]
|
||||
|
||||
// then find the first one that matches type. with MediaStreamTrack, it's possible for the client id to
|
||||
// change after being added to PeerConnection
|
||||
// change after being added to SubscriberPC
|
||||
if ti == nil {
|
||||
for cid, info := range p.pendingTracks {
|
||||
if info.Type == kind {
|
||||
@@ -690,6 +624,10 @@ func (p *ParticipantImpl) downTracksRTCPWorker() {
|
||||
for {
|
||||
time.Sleep(5 * time.Second)
|
||||
|
||||
if p.subscriber.pc.ConnectionState() != webrtc.PeerConnectionStateConnected {
|
||||
continue
|
||||
}
|
||||
|
||||
var pkts []rtcp.Packet
|
||||
var sd []rtcp.SourceDescriptionChunk
|
||||
p.lock.RLock()
|
||||
@@ -717,7 +655,7 @@ func (p *ParticipantImpl) downTracksRTCPWorker() {
|
||||
batch = sd[:size]
|
||||
sd = sd[size:]
|
||||
pkts = append(pkts, &rtcp.SourceDescription{Chunks: batch})
|
||||
if err := p.peerConn.WriteRTCP(pkts); err != nil {
|
||||
if err := p.subscriber.pc.WriteRTCP(pkts); err != nil {
|
||||
if err == io.EOF || err == io.ErrClosedPipe {
|
||||
return
|
||||
}
|
||||
@@ -740,7 +678,7 @@ func (p *ParticipantImpl) rtcpSendWorker() {
|
||||
//for _, pkt := range pkts {
|
||||
// logger.Debugw("writing RTCP", "packet", pkt)
|
||||
//}
|
||||
if err := p.peerConn.WriteRTCP(pkts); err != nil {
|
||||
if err := p.publisher.pc.WriteRTCP(pkts); err != nil {
|
||||
logger.Errorw("could not write RTCP to participant",
|
||||
"participant", p.Identity(),
|
||||
"err", err)
|
||||
|
||||
@@ -121,7 +121,7 @@ func TestDisconnectTiming(t *testing.T) {
|
||||
func newParticipantForTest(identity string) *ParticipantImpl {
|
||||
p, _ := NewParticipant(
|
||||
identity,
|
||||
&typesfakes.FakePeerConnection{},
|
||||
&WebRTCConfig{},
|
||||
&routingfakes.FakeMessageSink{},
|
||||
ReceiverConfig{})
|
||||
return p
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
package rtc
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/bep/debounce"
|
||||
"github.com/pion/webrtc/v3"
|
||||
|
||||
"github.com/livekit/livekit-server/proto/livekit"
|
||||
)
|
||||
|
||||
const (
|
||||
negotiationFrequency = 150 * time.Millisecond
|
||||
)
|
||||
|
||||
const (
|
||||
negotiationStateNone = iota
|
||||
// waiting for client answer
|
||||
negotiationStateClient
|
||||
// need to negotiate again
|
||||
negotiationStateServer
|
||||
)
|
||||
|
||||
// PCTransport is a wrapper around PeerConnection, with some helper methods
|
||||
type PCTransport struct {
|
||||
pc *webrtc.PeerConnection
|
||||
me *webrtc.MediaEngine
|
||||
|
||||
lock sync.Mutex
|
||||
pendingCandidates []webrtc.ICECandidateInit
|
||||
debouncedNegotiate func(func())
|
||||
onNegotiation func()
|
||||
|
||||
negotiationState atomic.Value
|
||||
}
|
||||
|
||||
func newPeerConnection(target livekit.SignalTarget, conf *WebRTCConfig) (*webrtc.PeerConnection, *webrtc.MediaEngine, error) {
|
||||
var me *webrtc.MediaEngine
|
||||
var err error
|
||||
if target == livekit.SignalTarget_PUBLISHER {
|
||||
me, err = createPubMediaEngine()
|
||||
} else {
|
||||
me, err = createSubMediaEngine()
|
||||
}
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
se := conf.SettingEngine
|
||||
se.DisableMediaEngineCopy(true)
|
||||
se.BufferFactory = bufferFactory.GetOrNew
|
||||
|
||||
api := webrtc.NewAPI(webrtc.WithMediaEngine(me), webrtc.WithSettingEngine(se))
|
||||
pc, err := api.NewPeerConnection(conf.Configuration)
|
||||
return pc, me, err
|
||||
}
|
||||
|
||||
func NewPCTransport(target livekit.SignalTarget, conf *WebRTCConfig) (*PCTransport, error) {
|
||||
pc, me, err := newPeerConnection(target, conf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
t := &PCTransport{
|
||||
pc: pc,
|
||||
me: me,
|
||||
debouncedNegotiate: debounce.New(negotiationFrequency),
|
||||
}
|
||||
t.negotiationState.Store(negotiationStateNone)
|
||||
|
||||
t.pc.OnNegotiationNeeded(t.negotiate)
|
||||
|
||||
return t, nil
|
||||
}
|
||||
|
||||
func (t *PCTransport) AddICECandidate(candidate webrtc.ICECandidateInit) error {
|
||||
if t.pc.RemoteDescription() == nil {
|
||||
t.lock.Lock()
|
||||
t.pendingCandidates = append(t.pendingCandidates, candidate)
|
||||
t.lock.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
return t.pc.AddICECandidate(candidate)
|
||||
}
|
||||
|
||||
func (t *PCTransport) PeerConnection() *webrtc.PeerConnection {
|
||||
return t.pc
|
||||
}
|
||||
|
||||
func (t *PCTransport) Close() {
|
||||
t.pc.Close()
|
||||
}
|
||||
|
||||
func (t *PCTransport) SetRemoteDescription(sd webrtc.SessionDescription) error {
|
||||
if err := t.pc.SetRemoteDescription(sd); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t.lock.Lock()
|
||||
for _, c := range t.pendingCandidates {
|
||||
if err := t.pc.AddICECandidate(c); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
t.pendingCandidates = nil
|
||||
t.lock.Unlock()
|
||||
|
||||
// negotiated, reset flag
|
||||
state := t.negotiationState.Load().(int)
|
||||
t.negotiationState.Store(negotiationStateNone)
|
||||
if state == negotiationStateServer && t.onNegotiation != nil {
|
||||
// need to negotiate again
|
||||
t.negotiate()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *PCTransport) OnNegotiationNeeded(f func()) {
|
||||
t.onNegotiation = f
|
||||
}
|
||||
|
||||
func (t *PCTransport) negotiate() {
|
||||
t.debouncedNegotiate(func() {
|
||||
state := t.negotiationState.Load().(int)
|
||||
// when there's an ongoing negotiation, let it finish and not disrupt its state
|
||||
if state != negotiationStateNone {
|
||||
t.negotiationState.Store(negotiationStateServer)
|
||||
return
|
||||
}
|
||||
|
||||
if t.onNegotiation != nil {
|
||||
t.onNegotiation()
|
||||
|
||||
// indicate waiting for client
|
||||
t.negotiationState.Store(negotiationStateClient)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -20,30 +20,6 @@ type WebsocketClient interface {
|
||||
WriteControl(messageType int, data []byte, deadline time.Time) error
|
||||
}
|
||||
|
||||
//counterfeiter:generate . PeerConnection
|
||||
type PeerConnection interface {
|
||||
OnICECandidate(f func(*webrtc.ICECandidate))
|
||||
OnICEConnectionStateChange(func(webrtc.ICEConnectionState))
|
||||
//OnConnectionStateChange(f func(webrtc.PeerConnectionState))
|
||||
OnTrack(f func(*webrtc.TrackRemote, *webrtc.RTPReceiver))
|
||||
OnDataChannel(func(d *webrtc.DataChannel))
|
||||
OnNegotiationNeeded(f func())
|
||||
Close() error
|
||||
SetRemoteDescription(desc webrtc.SessionDescription) error
|
||||
SetLocalDescription(desc webrtc.SessionDescription) error
|
||||
CreateOffer(options *webrtc.OfferOptions) (webrtc.SessionDescription, error)
|
||||
CreateAnswer(options *webrtc.AnswerOptions) (webrtc.SessionDescription, error)
|
||||
AddICECandidate(candidate webrtc.ICECandidateInit) error
|
||||
WriteRTCP(pkts []rtcp.Packet) error
|
||||
// used by datatrack
|
||||
CreateDataChannel(label string, options *webrtc.DataChannelInit) (*webrtc.DataChannel, error)
|
||||
// used by mediatrack
|
||||
AddTransceiverFromTrack(track webrtc.TrackLocal, init ...webrtc.RtpTransceiverInit) (*webrtc.RTPTransceiver, error)
|
||||
ConnectionState() webrtc.PeerConnectionState
|
||||
SignalingState() webrtc.SignalingState
|
||||
RemoveTrack(sender *webrtc.RTPSender) error
|
||||
}
|
||||
|
||||
//counterfeiter:generate . Participant
|
||||
type Participant interface {
|
||||
ID() string
|
||||
@@ -55,12 +31,12 @@ type Participant interface {
|
||||
SetMetadata(metadata map[string]interface{}) error
|
||||
GetResponseSink() routing.MessageSink
|
||||
SetResponseSink(sink routing.MessageSink)
|
||||
SubscriberMediaEngine() *webrtc.MediaEngine
|
||||
|
||||
AddTrack(clientId, name string, trackType livekit.TrackType)
|
||||
Answer(sdp webrtc.SessionDescription) (answer webrtc.SessionDescription, err error)
|
||||
HandleOffer(sdp webrtc.SessionDescription) (answer webrtc.SessionDescription, err error)
|
||||
HandleAnswer(sdp webrtc.SessionDescription) error
|
||||
HandleClientNegotiation()
|
||||
AddICECandidate(candidate webrtc.ICECandidateInit) error
|
||||
AddICECandidate(candidate webrtc.ICECandidateInit, target livekit.SignalTarget) error
|
||||
AddSubscriber(op Participant) error
|
||||
RemoveSubscriber(peerId string)
|
||||
SendJoinResponse(info *livekit.Room, otherParticipants []Participant) error
|
||||
@@ -71,8 +47,6 @@ type Participant interface {
|
||||
Close() error
|
||||
|
||||
// callbacks
|
||||
// OnICECandidate - ice candidate discovered for local peer
|
||||
OnICECandidate(func(c *webrtc.ICECandidateInit))
|
||||
OnStateChange(func(p Participant, oldState livekit.ParticipantInfo_State))
|
||||
// OnTrackPublished - remote added a remoteTrack
|
||||
OnTrackPublished(func(Participant, PublishedTrack))
|
||||
@@ -83,7 +57,7 @@ type Participant interface {
|
||||
// package methods
|
||||
AddSubscribedTrack(participantId string, st SubscribedTrack)
|
||||
RemoveSubscribedTrack(participantId string, st SubscribedTrack)
|
||||
PeerConnection() PeerConnection
|
||||
SubscriberPC() *webrtc.PeerConnection
|
||||
}
|
||||
|
||||
// PublishedTrack is the main interface representing a track published to the room
|
||||
|
||||
@@ -12,10 +12,11 @@ import (
|
||||
)
|
||||
|
||||
type FakeParticipant struct {
|
||||
AddICECandidateStub func(webrtc.ICECandidateInit) error
|
||||
AddICECandidateStub func(webrtc.ICECandidateInit, livekit.SignalTarget) error
|
||||
addICECandidateMutex sync.RWMutex
|
||||
addICECandidateArgsForCall []struct {
|
||||
arg1 webrtc.ICECandidateInit
|
||||
arg2 livekit.SignalTarget
|
||||
}
|
||||
addICECandidateReturns struct {
|
||||
result1 error
|
||||
@@ -47,19 +48,6 @@ type FakeParticipant struct {
|
||||
arg2 string
|
||||
arg3 livekit.TrackType
|
||||
}
|
||||
AnswerStub func(webrtc.SessionDescription) (webrtc.SessionDescription, error)
|
||||
answerMutex sync.RWMutex
|
||||
answerArgsForCall []struct {
|
||||
arg1 webrtc.SessionDescription
|
||||
}
|
||||
answerReturns struct {
|
||||
result1 webrtc.SessionDescription
|
||||
result2 error
|
||||
}
|
||||
answerReturnsOnCall map[int]struct {
|
||||
result1 webrtc.SessionDescription
|
||||
result2 error
|
||||
}
|
||||
CloseStub func() error
|
||||
closeMutex sync.RWMutex
|
||||
closeArgsForCall []struct {
|
||||
@@ -91,9 +79,18 @@ type FakeParticipant struct {
|
||||
handleAnswerReturnsOnCall map[int]struct {
|
||||
result1 error
|
||||
}
|
||||
HandleClientNegotiationStub func()
|
||||
handleClientNegotiationMutex sync.RWMutex
|
||||
handleClientNegotiationArgsForCall []struct {
|
||||
HandleOfferStub func(webrtc.SessionDescription) (webrtc.SessionDescription, error)
|
||||
handleOfferMutex sync.RWMutex
|
||||
handleOfferArgsForCall []struct {
|
||||
arg1 webrtc.SessionDescription
|
||||
}
|
||||
handleOfferReturns struct {
|
||||
result1 webrtc.SessionDescription
|
||||
result2 error
|
||||
}
|
||||
handleOfferReturnsOnCall map[int]struct {
|
||||
result1 webrtc.SessionDescription
|
||||
result2 error
|
||||
}
|
||||
IDStub func() string
|
||||
iDMutex sync.RWMutex
|
||||
@@ -130,11 +127,6 @@ type FakeParticipant struct {
|
||||
onCloseArgsForCall []struct {
|
||||
arg1 func(types.Participant)
|
||||
}
|
||||
OnICECandidateStub func(func(c *webrtc.ICECandidateInit))
|
||||
onICECandidateMutex sync.RWMutex
|
||||
onICECandidateArgsForCall []struct {
|
||||
arg1 func(c *webrtc.ICECandidateInit)
|
||||
}
|
||||
OnStateChangeStub func(func(p types.Participant, oldState livekit.ParticipantInfo_State))
|
||||
onStateChangeMutex sync.RWMutex
|
||||
onStateChangeArgsForCall []struct {
|
||||
@@ -150,16 +142,6 @@ type FakeParticipant struct {
|
||||
onTrackUpdatedArgsForCall []struct {
|
||||
arg1 func(types.Participant, types.PublishedTrack)
|
||||
}
|
||||
PeerConnectionStub func() types.PeerConnection
|
||||
peerConnectionMutex sync.RWMutex
|
||||
peerConnectionArgsForCall []struct {
|
||||
}
|
||||
peerConnectionReturns struct {
|
||||
result1 types.PeerConnection
|
||||
}
|
||||
peerConnectionReturnsOnCall map[int]struct {
|
||||
result1 types.PeerConnection
|
||||
}
|
||||
RTCPChanStub func() chan []rtcp.Packet
|
||||
rTCPChanMutex sync.RWMutex
|
||||
rTCPChanArgsForCall []struct {
|
||||
@@ -240,6 +222,26 @@ type FakeParticipant struct {
|
||||
stateReturnsOnCall map[int]struct {
|
||||
result1 livekit.ParticipantInfo_State
|
||||
}
|
||||
SubscriberMediaEngineStub func() *webrtc.MediaEngine
|
||||
subscriberMediaEngineMutex sync.RWMutex
|
||||
subscriberMediaEngineArgsForCall []struct {
|
||||
}
|
||||
subscriberMediaEngineReturns struct {
|
||||
result1 *webrtc.MediaEngine
|
||||
}
|
||||
subscriberMediaEngineReturnsOnCall map[int]struct {
|
||||
result1 *webrtc.MediaEngine
|
||||
}
|
||||
SubscriberPCStub func() *webrtc.PeerConnection
|
||||
subscriberPCMutex sync.RWMutex
|
||||
subscriberPCArgsForCall []struct {
|
||||
}
|
||||
subscriberPCReturns struct {
|
||||
result1 *webrtc.PeerConnection
|
||||
}
|
||||
subscriberPCReturnsOnCall map[int]struct {
|
||||
result1 *webrtc.PeerConnection
|
||||
}
|
||||
ToProtoStub func() *livekit.ParticipantInfo
|
||||
toProtoMutex sync.RWMutex
|
||||
toProtoArgsForCall []struct {
|
||||
@@ -254,18 +256,19 @@ type FakeParticipant struct {
|
||||
invocationsMutex sync.RWMutex
|
||||
}
|
||||
|
||||
func (fake *FakeParticipant) AddICECandidate(arg1 webrtc.ICECandidateInit) error {
|
||||
func (fake *FakeParticipant) AddICECandidate(arg1 webrtc.ICECandidateInit, arg2 livekit.SignalTarget) error {
|
||||
fake.addICECandidateMutex.Lock()
|
||||
ret, specificReturn := fake.addICECandidateReturnsOnCall[len(fake.addICECandidateArgsForCall)]
|
||||
fake.addICECandidateArgsForCall = append(fake.addICECandidateArgsForCall, struct {
|
||||
arg1 webrtc.ICECandidateInit
|
||||
}{arg1})
|
||||
arg2 livekit.SignalTarget
|
||||
}{arg1, arg2})
|
||||
stub := fake.AddICECandidateStub
|
||||
fakeReturns := fake.addICECandidateReturns
|
||||
fake.recordInvocation("AddICECandidate", []interface{}{arg1})
|
||||
fake.recordInvocation("AddICECandidate", []interface{}{arg1, arg2})
|
||||
fake.addICECandidateMutex.Unlock()
|
||||
if stub != nil {
|
||||
return stub(arg1)
|
||||
return stub(arg1, arg2)
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1
|
||||
@@ -279,17 +282,17 @@ func (fake *FakeParticipant) AddICECandidateCallCount() int {
|
||||
return len(fake.addICECandidateArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeParticipant) AddICECandidateCalls(stub func(webrtc.ICECandidateInit) error) {
|
||||
func (fake *FakeParticipant) AddICECandidateCalls(stub func(webrtc.ICECandidateInit, livekit.SignalTarget) error) {
|
||||
fake.addICECandidateMutex.Lock()
|
||||
defer fake.addICECandidateMutex.Unlock()
|
||||
fake.AddICECandidateStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeParticipant) AddICECandidateArgsForCall(i int) webrtc.ICECandidateInit {
|
||||
func (fake *FakeParticipant) AddICECandidateArgsForCall(i int) (webrtc.ICECandidateInit, livekit.SignalTarget) {
|
||||
fake.addICECandidateMutex.RLock()
|
||||
defer fake.addICECandidateMutex.RUnlock()
|
||||
argsForCall := fake.addICECandidateArgsForCall[i]
|
||||
return argsForCall.arg1
|
||||
return argsForCall.arg1, argsForCall.arg2
|
||||
}
|
||||
|
||||
func (fake *FakeParticipant) AddICECandidateReturns(result1 error) {
|
||||
@@ -443,70 +446,6 @@ func (fake *FakeParticipant) AddTrackArgsForCall(i int) (string, string, livekit
|
||||
return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3
|
||||
}
|
||||
|
||||
func (fake *FakeParticipant) Answer(arg1 webrtc.SessionDescription) (webrtc.SessionDescription, error) {
|
||||
fake.answerMutex.Lock()
|
||||
ret, specificReturn := fake.answerReturnsOnCall[len(fake.answerArgsForCall)]
|
||||
fake.answerArgsForCall = append(fake.answerArgsForCall, struct {
|
||||
arg1 webrtc.SessionDescription
|
||||
}{arg1})
|
||||
stub := fake.AnswerStub
|
||||
fakeReturns := fake.answerReturns
|
||||
fake.recordInvocation("Answer", []interface{}{arg1})
|
||||
fake.answerMutex.Unlock()
|
||||
if stub != nil {
|
||||
return stub(arg1)
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1, ret.result2
|
||||
}
|
||||
return fakeReturns.result1, fakeReturns.result2
|
||||
}
|
||||
|
||||
func (fake *FakeParticipant) AnswerCallCount() int {
|
||||
fake.answerMutex.RLock()
|
||||
defer fake.answerMutex.RUnlock()
|
||||
return len(fake.answerArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeParticipant) AnswerCalls(stub func(webrtc.SessionDescription) (webrtc.SessionDescription, error)) {
|
||||
fake.answerMutex.Lock()
|
||||
defer fake.answerMutex.Unlock()
|
||||
fake.AnswerStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeParticipant) AnswerArgsForCall(i int) webrtc.SessionDescription {
|
||||
fake.answerMutex.RLock()
|
||||
defer fake.answerMutex.RUnlock()
|
||||
argsForCall := fake.answerArgsForCall[i]
|
||||
return argsForCall.arg1
|
||||
}
|
||||
|
||||
func (fake *FakeParticipant) AnswerReturns(result1 webrtc.SessionDescription, result2 error) {
|
||||
fake.answerMutex.Lock()
|
||||
defer fake.answerMutex.Unlock()
|
||||
fake.AnswerStub = nil
|
||||
fake.answerReturns = struct {
|
||||
result1 webrtc.SessionDescription
|
||||
result2 error
|
||||
}{result1, result2}
|
||||
}
|
||||
|
||||
func (fake *FakeParticipant) AnswerReturnsOnCall(i int, result1 webrtc.SessionDescription, result2 error) {
|
||||
fake.answerMutex.Lock()
|
||||
defer fake.answerMutex.Unlock()
|
||||
fake.AnswerStub = nil
|
||||
if fake.answerReturnsOnCall == nil {
|
||||
fake.answerReturnsOnCall = make(map[int]struct {
|
||||
result1 webrtc.SessionDescription
|
||||
result2 error
|
||||
})
|
||||
}
|
||||
fake.answerReturnsOnCall[i] = struct {
|
||||
result1 webrtc.SessionDescription
|
||||
result2 error
|
||||
}{result1, result2}
|
||||
}
|
||||
|
||||
func (fake *FakeParticipant) Close() error {
|
||||
fake.closeMutex.Lock()
|
||||
ret, specificReturn := fake.closeReturnsOnCall[len(fake.closeArgsForCall)]
|
||||
@@ -674,28 +613,68 @@ func (fake *FakeParticipant) HandleAnswerReturnsOnCall(i int, result1 error) {
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeParticipant) HandleClientNegotiation() {
|
||||
fake.handleClientNegotiationMutex.Lock()
|
||||
fake.handleClientNegotiationArgsForCall = append(fake.handleClientNegotiationArgsForCall, struct {
|
||||
}{})
|
||||
stub := fake.HandleClientNegotiationStub
|
||||
fake.recordInvocation("HandleClientNegotiation", []interface{}{})
|
||||
fake.handleClientNegotiationMutex.Unlock()
|
||||
func (fake *FakeParticipant) HandleOffer(arg1 webrtc.SessionDescription) (webrtc.SessionDescription, error) {
|
||||
fake.handleOfferMutex.Lock()
|
||||
ret, specificReturn := fake.handleOfferReturnsOnCall[len(fake.handleOfferArgsForCall)]
|
||||
fake.handleOfferArgsForCall = append(fake.handleOfferArgsForCall, struct {
|
||||
arg1 webrtc.SessionDescription
|
||||
}{arg1})
|
||||
stub := fake.HandleOfferStub
|
||||
fakeReturns := fake.handleOfferReturns
|
||||
fake.recordInvocation("HandleOffer", []interface{}{arg1})
|
||||
fake.handleOfferMutex.Unlock()
|
||||
if stub != nil {
|
||||
fake.HandleClientNegotiationStub()
|
||||
return stub(arg1)
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1, ret.result2
|
||||
}
|
||||
return fakeReturns.result1, fakeReturns.result2
|
||||
}
|
||||
|
||||
func (fake *FakeParticipant) HandleClientNegotiationCallCount() int {
|
||||
fake.handleClientNegotiationMutex.RLock()
|
||||
defer fake.handleClientNegotiationMutex.RUnlock()
|
||||
return len(fake.handleClientNegotiationArgsForCall)
|
||||
func (fake *FakeParticipant) HandleOfferCallCount() int {
|
||||
fake.handleOfferMutex.RLock()
|
||||
defer fake.handleOfferMutex.RUnlock()
|
||||
return len(fake.handleOfferArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeParticipant) HandleClientNegotiationCalls(stub func()) {
|
||||
fake.handleClientNegotiationMutex.Lock()
|
||||
defer fake.handleClientNegotiationMutex.Unlock()
|
||||
fake.HandleClientNegotiationStub = stub
|
||||
func (fake *FakeParticipant) HandleOfferCalls(stub func(webrtc.SessionDescription) (webrtc.SessionDescription, error)) {
|
||||
fake.handleOfferMutex.Lock()
|
||||
defer fake.handleOfferMutex.Unlock()
|
||||
fake.HandleOfferStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeParticipant) HandleOfferArgsForCall(i int) webrtc.SessionDescription {
|
||||
fake.handleOfferMutex.RLock()
|
||||
defer fake.handleOfferMutex.RUnlock()
|
||||
argsForCall := fake.handleOfferArgsForCall[i]
|
||||
return argsForCall.arg1
|
||||
}
|
||||
|
||||
func (fake *FakeParticipant) HandleOfferReturns(result1 webrtc.SessionDescription, result2 error) {
|
||||
fake.handleOfferMutex.Lock()
|
||||
defer fake.handleOfferMutex.Unlock()
|
||||
fake.HandleOfferStub = nil
|
||||
fake.handleOfferReturns = struct {
|
||||
result1 webrtc.SessionDescription
|
||||
result2 error
|
||||
}{result1, result2}
|
||||
}
|
||||
|
||||
func (fake *FakeParticipant) HandleOfferReturnsOnCall(i int, result1 webrtc.SessionDescription, result2 error) {
|
||||
fake.handleOfferMutex.Lock()
|
||||
defer fake.handleOfferMutex.Unlock()
|
||||
fake.HandleOfferStub = nil
|
||||
if fake.handleOfferReturnsOnCall == nil {
|
||||
fake.handleOfferReturnsOnCall = make(map[int]struct {
|
||||
result1 webrtc.SessionDescription
|
||||
result2 error
|
||||
})
|
||||
}
|
||||
fake.handleOfferReturnsOnCall[i] = struct {
|
||||
result1 webrtc.SessionDescription
|
||||
result2 error
|
||||
}{result1, result2}
|
||||
}
|
||||
|
||||
func (fake *FakeParticipant) ID() string {
|
||||
@@ -889,38 +868,6 @@ func (fake *FakeParticipant) OnCloseArgsForCall(i int) func(types.Participant) {
|
||||
return argsForCall.arg1
|
||||
}
|
||||
|
||||
func (fake *FakeParticipant) OnICECandidate(arg1 func(c *webrtc.ICECandidateInit)) {
|
||||
fake.onICECandidateMutex.Lock()
|
||||
fake.onICECandidateArgsForCall = append(fake.onICECandidateArgsForCall, struct {
|
||||
arg1 func(c *webrtc.ICECandidateInit)
|
||||
}{arg1})
|
||||
stub := fake.OnICECandidateStub
|
||||
fake.recordInvocation("OnICECandidate", []interface{}{arg1})
|
||||
fake.onICECandidateMutex.Unlock()
|
||||
if stub != nil {
|
||||
fake.OnICECandidateStub(arg1)
|
||||
}
|
||||
}
|
||||
|
||||
func (fake *FakeParticipant) OnICECandidateCallCount() int {
|
||||
fake.onICECandidateMutex.RLock()
|
||||
defer fake.onICECandidateMutex.RUnlock()
|
||||
return len(fake.onICECandidateArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeParticipant) OnICECandidateCalls(stub func(func(c *webrtc.ICECandidateInit))) {
|
||||
fake.onICECandidateMutex.Lock()
|
||||
defer fake.onICECandidateMutex.Unlock()
|
||||
fake.OnICECandidateStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeParticipant) OnICECandidateArgsForCall(i int) func(c *webrtc.ICECandidateInit) {
|
||||
fake.onICECandidateMutex.RLock()
|
||||
defer fake.onICECandidateMutex.RUnlock()
|
||||
argsForCall := fake.onICECandidateArgsForCall[i]
|
||||
return argsForCall.arg1
|
||||
}
|
||||
|
||||
func (fake *FakeParticipant) OnStateChange(arg1 func(p types.Participant, oldState livekit.ParticipantInfo_State)) {
|
||||
fake.onStateChangeMutex.Lock()
|
||||
fake.onStateChangeArgsForCall = append(fake.onStateChangeArgsForCall, struct {
|
||||
@@ -1017,59 +964,6 @@ func (fake *FakeParticipant) OnTrackUpdatedArgsForCall(i int) func(types.Partici
|
||||
return argsForCall.arg1
|
||||
}
|
||||
|
||||
func (fake *FakeParticipant) PeerConnection() types.PeerConnection {
|
||||
fake.peerConnectionMutex.Lock()
|
||||
ret, specificReturn := fake.peerConnectionReturnsOnCall[len(fake.peerConnectionArgsForCall)]
|
||||
fake.peerConnectionArgsForCall = append(fake.peerConnectionArgsForCall, struct {
|
||||
}{})
|
||||
stub := fake.PeerConnectionStub
|
||||
fakeReturns := fake.peerConnectionReturns
|
||||
fake.recordInvocation("PeerConnection", []interface{}{})
|
||||
fake.peerConnectionMutex.Unlock()
|
||||
if stub != nil {
|
||||
return stub()
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1
|
||||
}
|
||||
return fakeReturns.result1
|
||||
}
|
||||
|
||||
func (fake *FakeParticipant) PeerConnectionCallCount() int {
|
||||
fake.peerConnectionMutex.RLock()
|
||||
defer fake.peerConnectionMutex.RUnlock()
|
||||
return len(fake.peerConnectionArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeParticipant) PeerConnectionCalls(stub func() types.PeerConnection) {
|
||||
fake.peerConnectionMutex.Lock()
|
||||
defer fake.peerConnectionMutex.Unlock()
|
||||
fake.PeerConnectionStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeParticipant) PeerConnectionReturns(result1 types.PeerConnection) {
|
||||
fake.peerConnectionMutex.Lock()
|
||||
defer fake.peerConnectionMutex.Unlock()
|
||||
fake.PeerConnectionStub = nil
|
||||
fake.peerConnectionReturns = struct {
|
||||
result1 types.PeerConnection
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeParticipant) PeerConnectionReturnsOnCall(i int, result1 types.PeerConnection) {
|
||||
fake.peerConnectionMutex.Lock()
|
||||
defer fake.peerConnectionMutex.Unlock()
|
||||
fake.PeerConnectionStub = nil
|
||||
if fake.peerConnectionReturnsOnCall == nil {
|
||||
fake.peerConnectionReturnsOnCall = make(map[int]struct {
|
||||
result1 types.PeerConnection
|
||||
})
|
||||
}
|
||||
fake.peerConnectionReturnsOnCall[i] = struct {
|
||||
result1 types.PeerConnection
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeParticipant) RTCPChan() chan []rtcp.Packet {
|
||||
fake.rTCPChanMutex.Lock()
|
||||
ret, specificReturn := fake.rTCPChanReturnsOnCall[len(fake.rTCPChanArgsForCall)]
|
||||
@@ -1524,6 +1418,112 @@ func (fake *FakeParticipant) StateReturnsOnCall(i int, result1 livekit.Participa
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeParticipant) SubscriberMediaEngine() *webrtc.MediaEngine {
|
||||
fake.subscriberMediaEngineMutex.Lock()
|
||||
ret, specificReturn := fake.subscriberMediaEngineReturnsOnCall[len(fake.subscriberMediaEngineArgsForCall)]
|
||||
fake.subscriberMediaEngineArgsForCall = append(fake.subscriberMediaEngineArgsForCall, struct {
|
||||
}{})
|
||||
stub := fake.SubscriberMediaEngineStub
|
||||
fakeReturns := fake.subscriberMediaEngineReturns
|
||||
fake.recordInvocation("SubscriberMediaEngine", []interface{}{})
|
||||
fake.subscriberMediaEngineMutex.Unlock()
|
||||
if stub != nil {
|
||||
return stub()
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1
|
||||
}
|
||||
return fakeReturns.result1
|
||||
}
|
||||
|
||||
func (fake *FakeParticipant) SubscriberMediaEngineCallCount() int {
|
||||
fake.subscriberMediaEngineMutex.RLock()
|
||||
defer fake.subscriberMediaEngineMutex.RUnlock()
|
||||
return len(fake.subscriberMediaEngineArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeParticipant) SubscriberMediaEngineCalls(stub func() *webrtc.MediaEngine) {
|
||||
fake.subscriberMediaEngineMutex.Lock()
|
||||
defer fake.subscriberMediaEngineMutex.Unlock()
|
||||
fake.SubscriberMediaEngineStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeParticipant) SubscriberMediaEngineReturns(result1 *webrtc.MediaEngine) {
|
||||
fake.subscriberMediaEngineMutex.Lock()
|
||||
defer fake.subscriberMediaEngineMutex.Unlock()
|
||||
fake.SubscriberMediaEngineStub = nil
|
||||
fake.subscriberMediaEngineReturns = struct {
|
||||
result1 *webrtc.MediaEngine
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeParticipant) SubscriberMediaEngineReturnsOnCall(i int, result1 *webrtc.MediaEngine) {
|
||||
fake.subscriberMediaEngineMutex.Lock()
|
||||
defer fake.subscriberMediaEngineMutex.Unlock()
|
||||
fake.SubscriberMediaEngineStub = nil
|
||||
if fake.subscriberMediaEngineReturnsOnCall == nil {
|
||||
fake.subscriberMediaEngineReturnsOnCall = make(map[int]struct {
|
||||
result1 *webrtc.MediaEngine
|
||||
})
|
||||
}
|
||||
fake.subscriberMediaEngineReturnsOnCall[i] = struct {
|
||||
result1 *webrtc.MediaEngine
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeParticipant) SubscriberPC() *webrtc.PeerConnection {
|
||||
fake.subscriberPCMutex.Lock()
|
||||
ret, specificReturn := fake.subscriberPCReturnsOnCall[len(fake.subscriberPCArgsForCall)]
|
||||
fake.subscriberPCArgsForCall = append(fake.subscriberPCArgsForCall, struct {
|
||||
}{})
|
||||
stub := fake.SubscriberPCStub
|
||||
fakeReturns := fake.subscriberPCReturns
|
||||
fake.recordInvocation("SubscriberPC", []interface{}{})
|
||||
fake.subscriberPCMutex.Unlock()
|
||||
if stub != nil {
|
||||
return stub()
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1
|
||||
}
|
||||
return fakeReturns.result1
|
||||
}
|
||||
|
||||
func (fake *FakeParticipant) SubscriberPCCallCount() int {
|
||||
fake.subscriberPCMutex.RLock()
|
||||
defer fake.subscriberPCMutex.RUnlock()
|
||||
return len(fake.subscriberPCArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeParticipant) SubscriberPCCalls(stub func() *webrtc.PeerConnection) {
|
||||
fake.subscriberPCMutex.Lock()
|
||||
defer fake.subscriberPCMutex.Unlock()
|
||||
fake.SubscriberPCStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeParticipant) SubscriberPCReturns(result1 *webrtc.PeerConnection) {
|
||||
fake.subscriberPCMutex.Lock()
|
||||
defer fake.subscriberPCMutex.Unlock()
|
||||
fake.SubscriberPCStub = nil
|
||||
fake.subscriberPCReturns = struct {
|
||||
result1 *webrtc.PeerConnection
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeParticipant) SubscriberPCReturnsOnCall(i int, result1 *webrtc.PeerConnection) {
|
||||
fake.subscriberPCMutex.Lock()
|
||||
defer fake.subscriberPCMutex.Unlock()
|
||||
fake.SubscriberPCStub = nil
|
||||
if fake.subscriberPCReturnsOnCall == nil {
|
||||
fake.subscriberPCReturnsOnCall = make(map[int]struct {
|
||||
result1 *webrtc.PeerConnection
|
||||
})
|
||||
}
|
||||
fake.subscriberPCReturnsOnCall[i] = struct {
|
||||
result1 *webrtc.PeerConnection
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeParticipant) ToProto() *livekit.ParticipantInfo {
|
||||
fake.toProtoMutex.Lock()
|
||||
ret, specificReturn := fake.toProtoReturnsOnCall[len(fake.toProtoArgsForCall)]
|
||||
@@ -1588,16 +1588,14 @@ func (fake *FakeParticipant) Invocations() map[string][][]interface{} {
|
||||
defer fake.addSubscriberMutex.RUnlock()
|
||||
fake.addTrackMutex.RLock()
|
||||
defer fake.addTrackMutex.RUnlock()
|
||||
fake.answerMutex.RLock()
|
||||
defer fake.answerMutex.RUnlock()
|
||||
fake.closeMutex.RLock()
|
||||
defer fake.closeMutex.RUnlock()
|
||||
fake.getResponseSinkMutex.RLock()
|
||||
defer fake.getResponseSinkMutex.RUnlock()
|
||||
fake.handleAnswerMutex.RLock()
|
||||
defer fake.handleAnswerMutex.RUnlock()
|
||||
fake.handleClientNegotiationMutex.RLock()
|
||||
defer fake.handleClientNegotiationMutex.RUnlock()
|
||||
fake.handleOfferMutex.RLock()
|
||||
defer fake.handleOfferMutex.RUnlock()
|
||||
fake.iDMutex.RLock()
|
||||
defer fake.iDMutex.RUnlock()
|
||||
fake.identityMutex.RLock()
|
||||
@@ -1606,16 +1604,12 @@ func (fake *FakeParticipant) Invocations() map[string][][]interface{} {
|
||||
defer fake.isReadyMutex.RUnlock()
|
||||
fake.onCloseMutex.RLock()
|
||||
defer fake.onCloseMutex.RUnlock()
|
||||
fake.onICECandidateMutex.RLock()
|
||||
defer fake.onICECandidateMutex.RUnlock()
|
||||
fake.onStateChangeMutex.RLock()
|
||||
defer fake.onStateChangeMutex.RUnlock()
|
||||
fake.onTrackPublishedMutex.RLock()
|
||||
defer fake.onTrackPublishedMutex.RUnlock()
|
||||
fake.onTrackUpdatedMutex.RLock()
|
||||
defer fake.onTrackUpdatedMutex.RUnlock()
|
||||
fake.peerConnectionMutex.RLock()
|
||||
defer fake.peerConnectionMutex.RUnlock()
|
||||
fake.rTCPChanMutex.RLock()
|
||||
defer fake.rTCPChanMutex.RUnlock()
|
||||
fake.removeSubscribedTrackMutex.RLock()
|
||||
@@ -1636,6 +1630,10 @@ func (fake *FakeParticipant) Invocations() map[string][][]interface{} {
|
||||
defer fake.startMutex.RUnlock()
|
||||
fake.stateMutex.RLock()
|
||||
defer fake.stateMutex.RUnlock()
|
||||
fake.subscriberMediaEngineMutex.RLock()
|
||||
defer fake.subscriberMediaEngineMutex.RUnlock()
|
||||
fake.subscriberPCMutex.RLock()
|
||||
defer fake.subscriberPCMutex.RUnlock()
|
||||
fake.toProtoMutex.RLock()
|
||||
defer fake.toProtoMutex.RUnlock()
|
||||
copiedInvocations := map[string][][]interface{}{}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -177,13 +177,7 @@ func (r *RoomManager) StartSession(roomName, identity, metadata string, reconnec
|
||||
"num_participants", len(room.GetParticipants()),
|
||||
)
|
||||
|
||||
pc, err := rtc.NewPeerConnection(r.config)
|
||||
if err != nil {
|
||||
logger.Errorw("could not create peerConnection", "error", err)
|
||||
return
|
||||
}
|
||||
|
||||
participant, err = rtc.NewParticipant(identity, pc, responseSink, r.config.Receiver)
|
||||
participant, err = rtc.NewParticipant(identity, r.config, responseSink, r.config.Receiver)
|
||||
if err != nil {
|
||||
logger.Errorw("could not create participant", "error", err)
|
||||
return
|
||||
@@ -266,7 +260,7 @@ func (r *RoomManager) rtcSessionWorker(room *rtc.Room, participant types.Partici
|
||||
|
||||
switch msg := req.Message.(type) {
|
||||
case *livekit.SignalRequest_Offer:
|
||||
_, err := participant.Answer(rtc.FromProtoSessionDescription(msg.Offer))
|
||||
_, err := participant.HandleOffer(rtc.FromProtoSessionDescription(msg.Offer))
|
||||
if err != nil {
|
||||
logger.Errorw("could not handle offer", "err", err, "participant", participant.Identity())
|
||||
return
|
||||
@@ -288,8 +282,6 @@ func (r *RoomManager) rtcSessionWorker(room *rtc.Room, participant types.Partici
|
||||
// jsonError(http.StatusInternalServerError, "could not handle negotiate", err.Error()))
|
||||
return
|
||||
}
|
||||
case *livekit.SignalRequest_Negotiate:
|
||||
participant.HandleClientNegotiation()
|
||||
case *livekit.SignalRequest_Trickle:
|
||||
if participant.State() == livekit.ParticipantInfo_JOINING {
|
||||
logger.Errorw("cannot trickle before offer", "participant", participant.Identity())
|
||||
@@ -299,7 +291,7 @@ func (r *RoomManager) rtcSessionWorker(room *rtc.Room, participant types.Partici
|
||||
|
||||
candidateInit := rtc.FromProtoTrickle(msg.Trickle)
|
||||
//logger.Debugw("adding peer candidate", "participant", participant.ID())
|
||||
if err := participant.AddICECandidate(candidateInit); err != nil {
|
||||
if err := participant.AddICECandidate(candidateInit, msg.Trickle.Target); err != nil {
|
||||
logger.Errorw("could not handle trickle", "participant", participant.Identity(), "err", err)
|
||||
//conn.WriteJSON(
|
||||
// jsonError(http.StatusInternalServerError, "could not handle trickle", err.Error()))
|
||||
|
||||
+1
-1
@@ -13,5 +13,5 @@ const (
|
||||
)
|
||||
|
||||
func NewGuid(prefix string) string {
|
||||
return prefix + shortuuid.New()
|
||||
return prefix + shortuuid.New()[:12]
|
||||
}
|
||||
|
||||
+193
-213
@@ -25,6 +25,52 @@ const (
|
||||
// of the legacy proto package is being used.
|
||||
const _ = proto.ProtoPackageIsVersion4
|
||||
|
||||
type SignalTarget int32
|
||||
|
||||
const (
|
||||
SignalTarget_PUBLISHER SignalTarget = 0
|
||||
SignalTarget_SUBSCRIBER SignalTarget = 1
|
||||
)
|
||||
|
||||
// Enum value maps for SignalTarget.
|
||||
var (
|
||||
SignalTarget_name = map[int32]string{
|
||||
0: "PUBLISHER",
|
||||
1: "SUBSCRIBER",
|
||||
}
|
||||
SignalTarget_value = map[string]int32{
|
||||
"PUBLISHER": 0,
|
||||
"SUBSCRIBER": 1,
|
||||
}
|
||||
)
|
||||
|
||||
func (x SignalTarget) Enum() *SignalTarget {
|
||||
p := new(SignalTarget)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
|
||||
func (x SignalTarget) String() string {
|
||||
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
||||
}
|
||||
|
||||
func (SignalTarget) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_rtc_proto_enumTypes[0].Descriptor()
|
||||
}
|
||||
|
||||
func (SignalTarget) Type() protoreflect.EnumType {
|
||||
return &file_rtc_proto_enumTypes[0]
|
||||
}
|
||||
|
||||
func (x SignalTarget) Number() protoreflect.EnumNumber {
|
||||
return protoreflect.EnumNumber(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use SignalTarget.Descriptor instead.
|
||||
func (SignalTarget) EnumDescriptor() ([]byte, []int) {
|
||||
return file_rtc_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
type SignalRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@@ -36,7 +82,6 @@ type SignalRequest struct {
|
||||
// *SignalRequest_Trickle
|
||||
// *SignalRequest_AddTrack
|
||||
// *SignalRequest_Mute
|
||||
// *SignalRequest_Negotiate
|
||||
// *SignalRequest_MuteSubscribed
|
||||
Message isSignalRequest_Message `protobuf_oneof:"message"`
|
||||
}
|
||||
@@ -115,13 +160,6 @@ func (x *SignalRequest) GetMute() *MuteTrackRequest {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *SignalRequest) GetNegotiate() *NegotiationRequest {
|
||||
if x, ok := x.GetMessage().(*SignalRequest_Negotiate); ok {
|
||||
return x.Negotiate
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *SignalRequest) GetMuteSubscribed() *MuteTrackRequest {
|
||||
if x, ok := x.GetMessage().(*SignalRequest_MuteSubscribed); ok {
|
||||
return x.MuteSubscribed
|
||||
@@ -134,12 +172,12 @@ type isSignalRequest_Message interface {
|
||||
}
|
||||
|
||||
type SignalRequest_Offer struct {
|
||||
// participant joining initially, and during negotiations
|
||||
// initial join exchange, for publisher
|
||||
Offer *SessionDescription `protobuf:"bytes,1,opt,name=offer,proto3,oneof"`
|
||||
}
|
||||
|
||||
type SignalRequest_Answer struct {
|
||||
// participant responding to server-issued offers
|
||||
// participant answering publisher offer
|
||||
Answer *SessionDescription `protobuf:"bytes,2,opt,name=answer,proto3,oneof"`
|
||||
}
|
||||
|
||||
@@ -156,14 +194,9 @@ type SignalRequest_Mute struct {
|
||||
Mute *MuteTrackRequest `protobuf:"bytes,5,opt,name=mute,proto3,oneof"`
|
||||
}
|
||||
|
||||
type SignalRequest_Negotiate struct {
|
||||
// when client needs to negotiate
|
||||
Negotiate *NegotiationRequest `protobuf:"bytes,7,opt,name=negotiate,proto3,oneof"`
|
||||
}
|
||||
|
||||
type SignalRequest_MuteSubscribed struct {
|
||||
// mute a track client is subscribed to
|
||||
MuteSubscribed *MuteTrackRequest `protobuf:"bytes,8,opt,name=mute_subscribed,json=muteSubscribed,proto3,oneof"`
|
||||
MuteSubscribed *MuteTrackRequest `protobuf:"bytes,6,opt,name=mute_subscribed,json=muteSubscribed,proto3,oneof"`
|
||||
}
|
||||
|
||||
func (*SignalRequest_Offer) isSignalRequest_Message() {}
|
||||
@@ -176,8 +209,6 @@ func (*SignalRequest_AddTrack) isSignalRequest_Message() {}
|
||||
|
||||
func (*SignalRequest_Mute) isSignalRequest_Message() {}
|
||||
|
||||
func (*SignalRequest_Negotiate) isSignalRequest_Message() {}
|
||||
|
||||
func (*SignalRequest_MuteSubscribed) isSignalRequest_Message() {}
|
||||
|
||||
type SignalResponse struct {
|
||||
@@ -192,7 +223,6 @@ type SignalResponse struct {
|
||||
// *SignalResponse_Trickle
|
||||
// *SignalResponse_Update
|
||||
// *SignalResponse_TrackPublished
|
||||
// *SignalResponse_Negotiate
|
||||
Message isSignalResponse_Message `protobuf_oneof:"message"`
|
||||
}
|
||||
|
||||
@@ -277,13 +307,6 @@ func (x *SignalResponse) GetTrackPublished() *TrackPublishedResponse {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *SignalResponse) GetNegotiate() *NegotiationResponse {
|
||||
if x, ok := x.GetMessage().(*SignalResponse_Negotiate); ok {
|
||||
return x.Negotiate
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type isSignalResponse_Message interface {
|
||||
isSignalResponse_Message()
|
||||
}
|
||||
@@ -294,12 +317,12 @@ type SignalResponse_Join struct {
|
||||
}
|
||||
|
||||
type SignalResponse_Answer struct {
|
||||
// sent when offer is answered
|
||||
// sent when server answers publisher
|
||||
Answer *SessionDescription `protobuf:"bytes,2,opt,name=answer,proto3,oneof"`
|
||||
}
|
||||
|
||||
type SignalResponse_Offer struct {
|
||||
// sent when server needs to negotiate, always offer
|
||||
// sent when server is sending subscriber an offer
|
||||
Offer *SessionDescription `protobuf:"bytes,3,opt,name=offer,proto3,oneof"`
|
||||
}
|
||||
|
||||
@@ -318,11 +341,6 @@ type SignalResponse_TrackPublished struct {
|
||||
TrackPublished *TrackPublishedResponse `protobuf:"bytes,6,opt,name=track_published,json=trackPublished,proto3,oneof"`
|
||||
}
|
||||
|
||||
type SignalResponse_Negotiate struct {
|
||||
// sent to participant when they should initiate negotiation
|
||||
Negotiate *NegotiationResponse `protobuf:"bytes,7,opt,name=negotiate,proto3,oneof"`
|
||||
}
|
||||
|
||||
func (*SignalResponse_Join) isSignalResponse_Message() {}
|
||||
|
||||
func (*SignalResponse_Answer) isSignalResponse_Message() {}
|
||||
@@ -335,8 +353,6 @@ func (*SignalResponse_Update) isSignalResponse_Message() {}
|
||||
|
||||
func (*SignalResponse_TrackPublished) isSignalResponse_Message() {}
|
||||
|
||||
func (*SignalResponse_Negotiate) isSignalResponse_Message() {}
|
||||
|
||||
type AddTrackRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@@ -406,7 +422,8 @@ type TrickleRequest struct {
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
CandidateInit string `protobuf:"bytes,1,opt,name=candidateInit,proto3" json:"candidateInit,omitempty"`
|
||||
CandidateInit string `protobuf:"bytes,1,opt,name=candidateInit,proto3" json:"candidateInit,omitempty"`
|
||||
Target SignalTarget `protobuf:"varint,2,opt,name=target,proto3,enum=livekit.SignalTarget" json:"target,omitempty"`
|
||||
}
|
||||
|
||||
func (x *TrickleRequest) Reset() {
|
||||
@@ -448,6 +465,13 @@ func (x *TrickleRequest) GetCandidateInit() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *TrickleRequest) GetTarget() SignalTarget {
|
||||
if x != nil {
|
||||
return x.Target
|
||||
}
|
||||
return SignalTarget_PUBLISHER
|
||||
}
|
||||
|
||||
type MuteTrackRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@@ -549,6 +573,7 @@ type JoinResponse struct {
|
||||
Room *Room `protobuf:"bytes,1,opt,name=room,proto3" json:"room,omitempty"`
|
||||
Participant *ParticipantInfo `protobuf:"bytes,2,opt,name=participant,proto3" json:"participant,omitempty"`
|
||||
OtherParticipants []*ParticipantInfo `protobuf:"bytes,3,rep,name=other_participants,json=otherParticipants,proto3" json:"other_participants,omitempty"`
|
||||
ServerVersion string `protobuf:"bytes,4,opt,name=server_version,json=serverVersion,proto3" json:"server_version,omitempty"`
|
||||
}
|
||||
|
||||
func (x *JoinResponse) Reset() {
|
||||
@@ -604,6 +629,13 @@ func (x *JoinResponse) GetOtherParticipants() []*ParticipantInfo {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *JoinResponse) GetServerVersion() string {
|
||||
if x != nil {
|
||||
return x.ServerVersion
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type TrackPublishedResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@@ -659,44 +691,6 @@ func (x *TrackPublishedResponse) GetTrack() *TrackInfo {
|
||||
return nil
|
||||
}
|
||||
|
||||
type NegotiationResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
}
|
||||
|
||||
func (x *NegotiationResponse) Reset() {
|
||||
*x = NegotiationResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_rtc_proto_msgTypes[8]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *NegotiationResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*NegotiationResponse) ProtoMessage() {}
|
||||
|
||||
func (x *NegotiationResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_rtc_proto_msgTypes[8]
|
||||
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 NegotiationResponse.ProtoReflect.Descriptor instead.
|
||||
func (*NegotiationResponse) Descriptor() ([]byte, []int) {
|
||||
return file_rtc_proto_rawDescGZIP(), []int{8}
|
||||
}
|
||||
|
||||
type SessionDescription struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@@ -709,7 +703,7 @@ type SessionDescription struct {
|
||||
func (x *SessionDescription) Reset() {
|
||||
*x = SessionDescription{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_rtc_proto_msgTypes[9]
|
||||
mi := &file_rtc_proto_msgTypes[8]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -722,7 +716,7 @@ func (x *SessionDescription) String() string {
|
||||
func (*SessionDescription) ProtoMessage() {}
|
||||
|
||||
func (x *SessionDescription) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_rtc_proto_msgTypes[9]
|
||||
mi := &file_rtc_proto_msgTypes[8]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -735,7 +729,7 @@ func (x *SessionDescription) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use SessionDescription.ProtoReflect.Descriptor instead.
|
||||
func (*SessionDescription) Descriptor() ([]byte, []int) {
|
||||
return file_rtc_proto_rawDescGZIP(), []int{9}
|
||||
return file_rtc_proto_rawDescGZIP(), []int{8}
|
||||
}
|
||||
|
||||
func (x *SessionDescription) GetType() string {
|
||||
@@ -763,7 +757,7 @@ type ParticipantUpdate struct {
|
||||
func (x *ParticipantUpdate) Reset() {
|
||||
*x = ParticipantUpdate{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_rtc_proto_msgTypes[10]
|
||||
mi := &file_rtc_proto_msgTypes[9]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -776,7 +770,7 @@ func (x *ParticipantUpdate) String() string {
|
||||
func (*ParticipantUpdate) ProtoMessage() {}
|
||||
|
||||
func (x *ParticipantUpdate) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_rtc_proto_msgTypes[10]
|
||||
mi := &file_rtc_proto_msgTypes[9]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -789,7 +783,7 @@ func (x *ParticipantUpdate) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use ParticipantUpdate.ProtoReflect.Descriptor instead.
|
||||
func (*ParticipantUpdate) Descriptor() ([]byte, []int) {
|
||||
return file_rtc_proto_rawDescGZIP(), []int{10}
|
||||
return file_rtc_proto_rawDescGZIP(), []int{9}
|
||||
}
|
||||
|
||||
func (x *ParticipantUpdate) GetParticipants() []*ParticipantInfo {
|
||||
@@ -804,7 +798,7 @@ var File_rtc_proto protoreflect.FileDescriptor
|
||||
var file_rtc_proto_rawDesc = []byte{
|
||||
0x0a, 0x09, 0x72, 0x74, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x6c, 0x69, 0x76,
|
||||
0x65, 0x6b, 0x69, 0x74, 0x1a, 0x0b, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x22, 0xa8, 0x03, 0x0a, 0x0d, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75,
|
||||
0x6f, 0x22, 0xeb, 0x02, 0x0a, 0x0d, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x12, 0x33, 0x0a, 0x05, 0x6f, 0x66, 0x66, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x53, 0x65, 0x73,
|
||||
0x73, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x48,
|
||||
@@ -821,89 +815,88 @@ var file_rtc_proto_rawDesc = []byte{
|
||||
0x74, 0x48, 0x00, 0x52, 0x08, 0x61, 0x64, 0x64, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x12, 0x2f, 0x0a,
|
||||
0x04, 0x6d, 0x75, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x6c, 0x69,
|
||||
0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x4d, 0x75, 0x74, 0x65, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x52,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x04, 0x6d, 0x75, 0x74, 0x65, 0x12, 0x3b,
|
||||
0x0a, 0x09, 0x6e, 0x65, 0x67, 0x6f, 0x74, 0x69, 0x61, 0x74, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x1b, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x4e, 0x65, 0x67, 0x6f,
|
||||
0x74, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00,
|
||||
0x52, 0x09, 0x6e, 0x65, 0x67, 0x6f, 0x74, 0x69, 0x61, 0x74, 0x65, 0x12, 0x44, 0x0a, 0x0f, 0x6d,
|
||||
0x75, 0x74, 0x65, 0x5f, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x64, 0x18, 0x08,
|
||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x4d,
|
||||
0x75, 0x74, 0x65, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48,
|
||||
0x00, 0x52, 0x0e, 0x6d, 0x75, 0x74, 0x65, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65,
|
||||
0x64, 0x42, 0x09, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0xa9, 0x03, 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, 0x6e, 0x12, 0x35, 0x0a, 0x06,
|
||||
0x61, 0x6e, 0x73, 0x77, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6c,
|
||||
0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x44, 0x65,
|
||||
0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x06, 0x61, 0x6e, 0x73,
|
||||
0x77, 0x65, 0x72, 0x12, 0x33, 0x0a, 0x05, 0x6f, 0x66, 0x66, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01,
|
||||
0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x53, 0x65, 0x73,
|
||||
0x73, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x48,
|
||||
0x00, 0x52, 0x05, 0x6f, 0x66, 0x66, 0x65, 0x72, 0x12, 0x33, 0x0a, 0x07, 0x74, 0x72, 0x69, 0x63,
|
||||
0x6b, 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x6c, 0x69, 0x76, 0x65,
|
||||
0x6b, 0x69, 0x74, 0x2e, 0x54, 0x72, 0x69, 0x63, 0x6b, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x48, 0x00, 0x52, 0x07, 0x74, 0x72, 0x69, 0x63, 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, 0x12, 0x4a, 0x0a, 0x0f, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x5f, 0x70, 0x75, 0x62,
|
||||
0x6c, 0x69, 0x73, 0x68, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6c,
|
||||
0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x50, 0x75, 0x62, 0x6c,
|
||||
0x69, 0x73, 0x68, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52,
|
||||
0x0e, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x64, 0x12,
|
||||
0x3c, 0x0a, 0x09, 0x6e, 0x65, 0x67, 0x6f, 0x74, 0x69, 0x61, 0x74, 0x65, 0x18, 0x07, 0x20, 0x01,
|
||||
0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x4e, 0x65, 0x67,
|
||||
0x6f, 0x74, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||
0x48, 0x00, 0x52, 0x09, 0x6e, 0x65, 0x67, 0x6f, 0x74, 0x69, 0x61, 0x74, 0x65, 0x42, 0x09, 0x0a,
|
||||
0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x5f, 0x0a, 0x0f, 0x41, 0x64, 0x64, 0x54,
|
||||
0x72, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x63,
|
||||
0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x63, 0x69, 0x64, 0x12, 0x12, 0x0a,
|
||||
0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d,
|
||||
0x65, 0x12, 0x26, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32,
|
||||
0x12, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x54,
|
||||
0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0x36, 0x0a, 0x0e, 0x54, 0x72, 0x69,
|
||||
0x63, 0x6b, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 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, 0x10, 0x4d, 0x75, 0x74, 0x65, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x03, 0x73, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x75, 0x74, 0x65, 0x64,
|
||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x6d, 0x75, 0x74, 0x65, 0x64, 0x22, 0x14, 0x0a,
|
||||
0x12, 0x4e, 0x65, 0x67, 0x6f, 0x74, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x22, 0xb6, 0x01, 0x0a, 0x0c, 0x4a, 0x6f, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70,
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x04, 0x72, 0x6f, 0x6f, 0x6d, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x52, 0x6f, 0x6f,
|
||||
0x6d, 0x52, 0x04, 0x72, 0x6f, 0x6f, 0x6d, 0x12, 0x3a, 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x74, 0x69,
|
||||
0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x18, 0x02, 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, 0x03, 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, 0x54, 0x0a, 0x16,
|
||||
0x54, 0x72, 0x61, 0x63, 0x6b, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x64, 0x52, 0x65,
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x63, 0x69, 0x64, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x03, 0x63, 0x69, 0x64, 0x12, 0x28, 0x0a, 0x05, 0x74, 0x72, 0x61, 0x63,
|
||||
0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69,
|
||||
0x74, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x05, 0x74, 0x72, 0x61,
|
||||
0x63, 0x6b, 0x22, 0x15, 0x0a, 0x13, 0x4e, 0x65, 0x67, 0x6f, 0x74, 0x69, 0x61, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 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, 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,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x04, 0x6d, 0x75, 0x74, 0x65, 0x12, 0x44,
|
||||
0x0a, 0x0f, 0x6d, 0x75, 0x74, 0x65, 0x5f, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65,
|
||||
0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69,
|
||||
0x74, 0x2e, 0x4d, 0x75, 0x74, 0x65, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x48, 0x00, 0x52, 0x0e, 0x6d, 0x75, 0x74, 0x65, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72,
|
||||
0x69, 0x62, 0x65, 0x64, 0x42, 0x09, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22,
|
||||
0xeb, 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, 0x6e, 0x12,
|
||||
0x35, 0x0a, 0x06, 0x61, 0x6e, 0x73, 0x77, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
|
||||
0x1b, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f,
|
||||
0x6e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x06,
|
||||
0x61, 0x6e, 0x73, 0x77, 0x65, 0x72, 0x12, 0x33, 0x0a, 0x05, 0x6f, 0x66, 0x66, 0x65, 0x72, 0x18,
|
||||
0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e,
|
||||
0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x48, 0x00, 0x52, 0x05, 0x6f, 0x66, 0x66, 0x65, 0x72, 0x12, 0x33, 0x0a, 0x07, 0x74,
|
||||
0x72, 0x69, 0x63, 0x6b, 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x6c,
|
||||
0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x54, 0x72, 0x69, 0x63, 0x6b, 0x6c, 0x65, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x07, 0x74, 0x72, 0x69, 0x63, 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, 0x12, 0x4a, 0x0a, 0x0f, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x5f,
|
||||
0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32,
|
||||
0x1f, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x50,
|
||||
0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||
0x48, 0x00, 0x52, 0x0e, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68,
|
||||
0x65, 0x64, 0x42, 0x09, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x5f, 0x0a,
|
||||
0x0f, 0x41, 0x64, 0x64, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x12, 0x10, 0x0a, 0x03, 0x63, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x63,
|
||||
0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x26, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03,
|
||||
0x20, 0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x54,
|
||||
0x72, 0x61, 0x63, 0x6b, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0x65,
|
||||
0x0a, 0x0e, 0x54, 0x72, 0x69, 0x63, 0x6b, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
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, 0x12, 0x2d, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74,
|
||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74,
|
||||
0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74,
|
||||
0x61, 0x72, 0x67, 0x65, 0x74, 0x22, 0x3a, 0x0a, 0x10, 0x4d, 0x75, 0x74, 0x65, 0x54, 0x72, 0x61,
|
||||
0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x69, 0x64,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x73, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x6d,
|
||||
0x75, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x6d, 0x75, 0x74, 0x65,
|
||||
0x64, 0x22, 0x14, 0x0a, 0x12, 0x4e, 0x65, 0x67, 0x6f, 0x74, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xdd, 0x01, 0x0a, 0x0c, 0x4a, 0x6f, 0x69, 0x6e,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x04, 0x72, 0x6f, 0x6f, 0x6d,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74,
|
||||
0x2e, 0x52, 0x6f, 0x6f, 0x6d, 0x52, 0x04, 0x72, 0x6f, 0x6f, 0x6d, 0x12, 0x3a, 0x0a, 0x0b, 0x70,
|
||||
0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x18, 0x02, 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, 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,
|
||||
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, 0x03, 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,
|
||||
0x12, 0x25, 0x0a, 0x0e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69,
|
||||
0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72,
|
||||
0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x54, 0x0a, 0x16, 0x54, 0x72, 0x61, 0x63, 0x6b,
|
||||
0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x12, 0x10, 0x0a, 0x03, 0x63, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03,
|
||||
0x63, 0x69, 0x64, 0x12, 0x28, 0x0a, 0x05, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x18, 0x02, 0x20, 0x01,
|
||||
0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x54, 0x72, 0x61,
|
||||
0x63, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x05, 0x74, 0x72, 0x61, 0x63, 0x6b, 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, 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, 0x2a, 0x2d, 0x0a, 0x0c,
|
||||
0x53, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x0d, 0x0a, 0x09,
|
||||
0x50, 0x55, 0x42, 0x4c, 0x49, 0x53, 0x48, 0x45, 0x52, 0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x53,
|
||||
0x55, 0x42, 0x53, 0x43, 0x52, 0x49, 0x42, 0x45, 0x52, 0x10, 0x01, 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 (
|
||||
@@ -918,17 +911,18 @@ func file_rtc_proto_rawDescGZIP() []byte {
|
||||
return file_rtc_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_rtc_proto_msgTypes = make([]protoimpl.MessageInfo, 11)
|
||||
var file_rtc_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
|
||||
var file_rtc_proto_msgTypes = make([]protoimpl.MessageInfo, 10)
|
||||
var file_rtc_proto_goTypes = []interface{}{
|
||||
(*SignalRequest)(nil), // 0: livekit.SignalRequest
|
||||
(*SignalResponse)(nil), // 1: livekit.SignalResponse
|
||||
(*AddTrackRequest)(nil), // 2: livekit.AddTrackRequest
|
||||
(*TrickleRequest)(nil), // 3: livekit.TrickleRequest
|
||||
(*MuteTrackRequest)(nil), // 4: livekit.MuteTrackRequest
|
||||
(*NegotiationRequest)(nil), // 5: livekit.NegotiationRequest
|
||||
(*JoinResponse)(nil), // 6: livekit.JoinResponse
|
||||
(*TrackPublishedResponse)(nil), // 7: livekit.TrackPublishedResponse
|
||||
(*NegotiationResponse)(nil), // 8: livekit.NegotiationResponse
|
||||
(SignalTarget)(0), // 0: livekit.SignalTarget
|
||||
(*SignalRequest)(nil), // 1: livekit.SignalRequest
|
||||
(*SignalResponse)(nil), // 2: livekit.SignalResponse
|
||||
(*AddTrackRequest)(nil), // 3: livekit.AddTrackRequest
|
||||
(*TrickleRequest)(nil), // 4: livekit.TrickleRequest
|
||||
(*MuteTrackRequest)(nil), // 5: livekit.MuteTrackRequest
|
||||
(*NegotiationRequest)(nil), // 6: livekit.NegotiationRequest
|
||||
(*JoinResponse)(nil), // 7: livekit.JoinResponse
|
||||
(*TrackPublishedResponse)(nil), // 8: livekit.TrackPublishedResponse
|
||||
(*SessionDescription)(nil), // 9: livekit.SessionDescription
|
||||
(*ParticipantUpdate)(nil), // 10: livekit.ParticipantUpdate
|
||||
(TrackType)(0), // 11: livekit.TrackType
|
||||
@@ -939,29 +933,28 @@ var file_rtc_proto_goTypes = []interface{}{
|
||||
var file_rtc_proto_depIdxs = []int32{
|
||||
9, // 0: livekit.SignalRequest.offer:type_name -> livekit.SessionDescription
|
||||
9, // 1: livekit.SignalRequest.answer:type_name -> livekit.SessionDescription
|
||||
3, // 2: livekit.SignalRequest.trickle:type_name -> livekit.TrickleRequest
|
||||
2, // 3: livekit.SignalRequest.add_track:type_name -> livekit.AddTrackRequest
|
||||
4, // 4: livekit.SignalRequest.mute:type_name -> livekit.MuteTrackRequest
|
||||
5, // 5: livekit.SignalRequest.negotiate:type_name -> livekit.NegotiationRequest
|
||||
4, // 6: livekit.SignalRequest.mute_subscribed:type_name -> livekit.MuteTrackRequest
|
||||
6, // 7: livekit.SignalResponse.join:type_name -> livekit.JoinResponse
|
||||
9, // 8: livekit.SignalResponse.answer:type_name -> livekit.SessionDescription
|
||||
9, // 9: livekit.SignalResponse.offer:type_name -> livekit.SessionDescription
|
||||
3, // 10: livekit.SignalResponse.trickle:type_name -> livekit.TrickleRequest
|
||||
10, // 11: livekit.SignalResponse.update:type_name -> livekit.ParticipantUpdate
|
||||
7, // 12: livekit.SignalResponse.track_published:type_name -> livekit.TrackPublishedResponse
|
||||
8, // 13: livekit.SignalResponse.negotiate:type_name -> livekit.NegotiationResponse
|
||||
11, // 14: livekit.AddTrackRequest.type:type_name -> livekit.TrackType
|
||||
12, // 15: livekit.JoinResponse.room:type_name -> livekit.Room
|
||||
13, // 16: livekit.JoinResponse.participant:type_name -> livekit.ParticipantInfo
|
||||
13, // 17: livekit.JoinResponse.other_participants:type_name -> livekit.ParticipantInfo
|
||||
14, // 18: livekit.TrackPublishedResponse.track:type_name -> livekit.TrackInfo
|
||||
13, // 19: livekit.ParticipantUpdate.participants:type_name -> livekit.ParticipantInfo
|
||||
20, // [20:20] is the sub-list for method output_type
|
||||
20, // [20:20] is the sub-list for method input_type
|
||||
20, // [20:20] is the sub-list for extension type_name
|
||||
20, // [20:20] is the sub-list for extension extendee
|
||||
0, // [0:20] is the sub-list for field type_name
|
||||
4, // 2: livekit.SignalRequest.trickle:type_name -> livekit.TrickleRequest
|
||||
3, // 3: livekit.SignalRequest.add_track:type_name -> livekit.AddTrackRequest
|
||||
5, // 4: livekit.SignalRequest.mute:type_name -> livekit.MuteTrackRequest
|
||||
5, // 5: livekit.SignalRequest.mute_subscribed:type_name -> livekit.MuteTrackRequest
|
||||
7, // 6: livekit.SignalResponse.join:type_name -> livekit.JoinResponse
|
||||
9, // 7: livekit.SignalResponse.answer:type_name -> livekit.SessionDescription
|
||||
9, // 8: livekit.SignalResponse.offer:type_name -> livekit.SessionDescription
|
||||
4, // 9: livekit.SignalResponse.trickle:type_name -> livekit.TrickleRequest
|
||||
10, // 10: livekit.SignalResponse.update:type_name -> livekit.ParticipantUpdate
|
||||
8, // 11: livekit.SignalResponse.track_published:type_name -> livekit.TrackPublishedResponse
|
||||
11, // 12: livekit.AddTrackRequest.type:type_name -> livekit.TrackType
|
||||
0, // 13: livekit.TrickleRequest.target:type_name -> livekit.SignalTarget
|
||||
12, // 14: livekit.JoinResponse.room:type_name -> livekit.Room
|
||||
13, // 15: livekit.JoinResponse.participant:type_name -> livekit.ParticipantInfo
|
||||
13, // 16: livekit.JoinResponse.other_participants:type_name -> livekit.ParticipantInfo
|
||||
14, // 17: livekit.TrackPublishedResponse.track:type_name -> livekit.TrackInfo
|
||||
13, // 18: livekit.ParticipantUpdate.participants:type_name -> livekit.ParticipantInfo
|
||||
19, // [19:19] is the sub-list for method output_type
|
||||
19, // [19:19] is the sub-list for method input_type
|
||||
19, // [19:19] is the sub-list for extension type_name
|
||||
19, // [19:19] is the sub-list for extension extendee
|
||||
0, // [0:19] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_rtc_proto_init() }
|
||||
@@ -1068,18 +1061,6 @@ func file_rtc_proto_init() {
|
||||
}
|
||||
}
|
||||
file_rtc_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*NegotiationResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_rtc_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*SessionDescription); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -1091,7 +1072,7 @@ func file_rtc_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_rtc_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_rtc_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ParticipantUpdate); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -1110,7 +1091,6 @@ func file_rtc_proto_init() {
|
||||
(*SignalRequest_Trickle)(nil),
|
||||
(*SignalRequest_AddTrack)(nil),
|
||||
(*SignalRequest_Mute)(nil),
|
||||
(*SignalRequest_Negotiate)(nil),
|
||||
(*SignalRequest_MuteSubscribed)(nil),
|
||||
}
|
||||
file_rtc_proto_msgTypes[1].OneofWrappers = []interface{}{
|
||||
@@ -1120,20 +1100,20 @@ func file_rtc_proto_init() {
|
||||
(*SignalResponse_Trickle)(nil),
|
||||
(*SignalResponse_Update)(nil),
|
||||
(*SignalResponse_TrackPublished)(nil),
|
||||
(*SignalResponse_Negotiate)(nil),
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_rtc_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 11,
|
||||
NumEnums: 1,
|
||||
NumMessages: 10,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_rtc_proto_goTypes,
|
||||
DependencyIndexes: file_rtc_proto_depIdxs,
|
||||
EnumInfos: file_rtc_proto_enumTypes,
|
||||
MessageInfos: file_rtc_proto_msgTypes,
|
||||
}.Build()
|
||||
File_rtc_proto = out.File
|
||||
|
||||
+12
-13
@@ -7,18 +7,16 @@ import "model.proto";
|
||||
|
||||
message SignalRequest {
|
||||
oneof message {
|
||||
// participant joining initially, and during negotiations
|
||||
// initial join exchange, for publisher
|
||||
SessionDescription offer = 1;
|
||||
// participant responding to server-issued offers
|
||||
// participant answering publisher offer
|
||||
SessionDescription answer = 2;
|
||||
TrickleRequest trickle = 3;
|
||||
AddTrackRequest add_track = 4;
|
||||
// mute the participant's own tracks
|
||||
MuteTrackRequest mute = 5;
|
||||
// when client needs to negotiate
|
||||
NegotiationRequest negotiate = 7;
|
||||
// mute a track client is subscribed to
|
||||
MuteTrackRequest mute_subscribed = 8;
|
||||
MuteTrackRequest mute_subscribed = 6;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,9 +24,9 @@ message SignalResponse {
|
||||
oneof message {
|
||||
// sent when join is accepted
|
||||
JoinResponse join = 1;
|
||||
// sent when offer is answered
|
||||
// sent when server answers publisher
|
||||
SessionDescription answer = 2;
|
||||
// sent when server needs to negotiate, always offer
|
||||
// sent when server is sending subscriber an offer
|
||||
SessionDescription offer = 3;
|
||||
// sent when an ICE candidate is available
|
||||
TrickleRequest trickle = 4;
|
||||
@@ -36,11 +34,14 @@ message SignalResponse {
|
||||
ParticipantUpdate update = 5;
|
||||
// sent to the participant when their track has been published
|
||||
TrackPublishedResponse track_published = 6;
|
||||
// sent to participant when they should initiate negotiation
|
||||
NegotiationResponse negotiate = 7;
|
||||
}
|
||||
}
|
||||
|
||||
enum SignalTarget {
|
||||
PUBLISHER = 0;
|
||||
SUBSCRIBER = 1;
|
||||
}
|
||||
|
||||
message AddTrackRequest {
|
||||
// client ID of track, to match it when RTC track is received
|
||||
string cid = 1;
|
||||
@@ -50,6 +51,7 @@ message AddTrackRequest {
|
||||
|
||||
message TrickleRequest {
|
||||
string candidateInit = 1;
|
||||
SignalTarget target = 2;
|
||||
}
|
||||
|
||||
message MuteTrackRequest {
|
||||
@@ -65,6 +67,7 @@ message JoinResponse {
|
||||
Room room = 1;
|
||||
ParticipantInfo participant = 2;
|
||||
repeated ParticipantInfo other_participants = 3;
|
||||
string server_version = 4;
|
||||
}
|
||||
|
||||
message TrackPublishedResponse {
|
||||
@@ -72,10 +75,6 @@ message TrackPublishedResponse {
|
||||
TrackInfo track = 2;
|
||||
}
|
||||
|
||||
message NegotiationResponse {
|
||||
// empty
|
||||
}
|
||||
|
||||
message SessionDescription {
|
||||
string type = 1; // "answer" | "offer" | "pranswer" | "rollback"
|
||||
string sdp = 2;
|
||||
|
||||
@@ -32,6 +32,7 @@ func TestMultiNodeRouting(t *testing.T) {
|
||||
c1 := createRTCClient("c1", defaultServerPort)
|
||||
c2 := createRTCClient("c2", secondServerPort)
|
||||
waitUntilConnected(t, c1, c2)
|
||||
defer stopClients(c1, c2)
|
||||
|
||||
// c1 publishing, and c2 receiving
|
||||
t1, err := c1.AddStaticTrack("audio/opus", "audio", "webcam")
|
||||
@@ -54,9 +55,6 @@ func TestMultiNodeRouting(t *testing.T) {
|
||||
return true
|
||||
})
|
||||
|
||||
c1.Stop()
|
||||
c2.Stop()
|
||||
|
||||
// TODO: delete room explicitly and ensure it's closed
|
||||
//
|
||||
//// ensure that room is closed
|
||||
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
package version
|
||||
|
||||
const Version = "0.3.4"
|
||||
const Version = "0.4.0"
|
||||
|
||||
Reference in New Issue
Block a user