mirror of
https://github.com/livekit/livekit.git
synced 2026-08-28 07:14:12 +00:00
binding to buffer and correctly forwarding
This commit is contained in:
+116
-81
@@ -12,13 +12,11 @@ import (
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/pion/webrtc/v3"
|
||||
"github.com/pkg/errors"
|
||||
"google.golang.org/protobuf/encoding/protojson"
|
||||
"google.golang.org/protobuf/proto"
|
||||
|
||||
"github.com/livekit/livekit-server/pkg/logger"
|
||||
"github.com/livekit/livekit-server/pkg/rtc"
|
||||
"github.com/livekit/livekit-server/pkg/rtc/types"
|
||||
"github.com/livekit/livekit-server/proto/livekit"
|
||||
)
|
||||
|
||||
@@ -39,6 +37,7 @@ type RTCClient struct {
|
||||
// pending actions to start after connected to peer
|
||||
pendingCandidates []*webrtc.ICECandidate
|
||||
pendingTrackWriters []*TrackWriter
|
||||
OnConnected func()
|
||||
|
||||
// navigate log ring buffer. saving the last N entries
|
||||
writer *ring.Ring
|
||||
@@ -78,9 +77,10 @@ func NewRTCClient(conn *websocket.Conn) (*RTCClient, error) {
|
||||
reader: logRing,
|
||||
writer: logRing,
|
||||
PeerConn: peerConn,
|
||||
me: &webrtc.MediaEngine{},
|
||||
}
|
||||
c.ctx, c.cancel = context.WithCancel(context.Background())
|
||||
|
||||
c.me.RegisterDefaultCodecs()
|
||||
peerConn.OnICECandidate(func(ic *webrtc.ICECandidate) {
|
||||
if ic == nil {
|
||||
return
|
||||
@@ -102,24 +102,14 @@ func NewRTCClient(conn *websocket.Conn) (*RTCClient, error) {
|
||||
|
||||
peerConn.OnTrack(func(track *webrtc.TrackRemote, rtpReceiver *webrtc.RTPReceiver) {
|
||||
c.AppendLog("track received", "label", track.StreamID(), "id", track.ID())
|
||||
r := rtc.NewReceiver(nil, rtpReceiver, track)
|
||||
c.lock.Lock()
|
||||
c.receivers = append(c.receivers, r)
|
||||
go c.consumeReceiver(track.ID(), r)
|
||||
c.lock.Unlock()
|
||||
go c.consumeReceiver(track)
|
||||
})
|
||||
|
||||
peerConn.OnNegotiationNeeded(func() {
|
||||
// do nothing
|
||||
//c.AppendLog("negotiate needed")
|
||||
//if !c.connected {
|
||||
// c.AppendLog("not yet connected, skipping negotiate")
|
||||
// return
|
||||
//}
|
||||
//err := c.Negotiate()
|
||||
//if err != nil {
|
||||
// c.AppendLog("error negotiating", "err", err)
|
||||
//}
|
||||
if !c.iceConnected {
|
||||
return
|
||||
}
|
||||
c.requestNegotiation()
|
||||
})
|
||||
|
||||
peerConn.OnDataChannel(func(channel *webrtc.DataChannel) {
|
||||
@@ -137,8 +127,13 @@ func NewRTCClient(conn *websocket.Conn) (*RTCClient, error) {
|
||||
}
|
||||
}
|
||||
|
||||
initialConnect := !c.iceConnected
|
||||
c.pendingTrackWriters = nil
|
||||
c.iceConnected = true
|
||||
|
||||
if initialConnect && c.OnConnected != nil {
|
||||
go c.OnConnected()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -157,7 +152,7 @@ func (c *RTCClient) Run() error {
|
||||
})
|
||||
|
||||
// create a data channel, in order to work
|
||||
dc, err := c.PeerConn.CreateDataChannel("default", nil)
|
||||
dc, err := c.PeerConn.CreateDataChannel("_private", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -204,21 +199,7 @@ func (c *RTCClient) Run() error {
|
||||
|
||||
defer c.PeerConn.Close()
|
||||
case *livekit.SignalResponse_Answer:
|
||||
c.AppendLog("connected to remote, setting desc")
|
||||
// remote answered the offer, establish connection
|
||||
err = c.PeerConn.SetRemoteDescription(rtc.FromProtoSessionDescription(msg.Answer))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.connected = true
|
||||
|
||||
// add all the pending items
|
||||
c.lock.Lock()
|
||||
for _, ic := range c.pendingCandidates {
|
||||
c.SendIceCandidate(ic)
|
||||
}
|
||||
c.pendingCandidates = nil
|
||||
c.lock.Unlock()
|
||||
c.handleAnswer(rtc.FromProtoSessionDescription(msg.Answer))
|
||||
case *livekit.SignalResponse_Offer:
|
||||
c.AppendLog("received server offer",
|
||||
"type", msg.Offer.Type)
|
||||
@@ -226,6 +207,8 @@ func (c *RTCClient) Run() error {
|
||||
if err := c.handleOffer(desc); err != nil {
|
||||
return err
|
||||
}
|
||||
case *livekit.SignalResponse_Negotiate:
|
||||
c.negotiate()
|
||||
case *livekit.SignalResponse_Trickle:
|
||||
candidateInit := rtc.FromProtoTrickle(msg.Trickle)
|
||||
c.AppendLog("adding remote candidate", "candidate", candidateInit.Candidate)
|
||||
@@ -314,39 +297,6 @@ func (c *RTCClient) SendIceCandidate(ic *webrtc.ICECandidate) error {
|
||||
})
|
||||
}
|
||||
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
|
||||
// if we received an offer, we'd have to answer
|
||||
if desc.Type == webrtc.SDPTypeOffer {
|
||||
// create media engine
|
||||
c.me = &webrtc.MediaEngine{}
|
||||
if err := c.me.RegisterDefaultCodecs(); err != nil {
|
||||
return errors.Wrapf(err, "could not parse SDP")
|
||||
}
|
||||
|
||||
answer, err := c.PeerConn.CreateAnswer(nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := c.PeerConn.SetLocalDescription(answer); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// send remote an answer
|
||||
return c.SendRequest(&livekit.SignalRequest{
|
||||
Message: &livekit.SignalRequest_Answer{
|
||||
Answer: rtc.ToProtoSessionDescription(answer),
|
||||
},
|
||||
})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *RTCClient) AddTrack(path string, id string, label string) error {
|
||||
// determine file mime
|
||||
mime, ok := extMimeMapping[filepath.Ext(path)]
|
||||
@@ -354,7 +304,7 @@ func (c *RTCClient) AddTrack(path string, id string, label string) error {
|
||||
return fmt.Errorf("%s has an unsupported extension", filepath.Base(path))
|
||||
}
|
||||
|
||||
logger.GetLogger().Infow("adding track",
|
||||
c.AppendLog("adding track",
|
||||
"mime", mime,
|
||||
)
|
||||
|
||||
@@ -367,6 +317,15 @@ func (c *RTCClient) AddTrack(path string, id string, label string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
trackType := livekit.TrackType_AUDIO
|
||||
if strings.HasPrefix(mime, "video") {
|
||||
trackType = livekit.TrackType_VIDEO
|
||||
}
|
||||
|
||||
if err := c.SendAddTrack(id, label, trackType); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
c.localTracks = append(c.localTracks, track)
|
||||
@@ -385,12 +344,7 @@ func (c *RTCClient) AddTrack(path string, id string, label string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
trackType := livekit.TrackType_AUDIO
|
||||
if strings.HasPrefix(mime, "video") {
|
||||
trackType = livekit.TrackType_VIDEO
|
||||
}
|
||||
|
||||
return c.SendAddTrack(id, label, trackType)
|
||||
return nil
|
||||
}
|
||||
|
||||
// send AddTrack command to server to initiate server-side negotiation
|
||||
@@ -406,6 +360,80 @@ func (c *RTCClient) SendAddTrack(cid string, name string, trackType livekit.Trac
|
||||
})
|
||||
}
|
||||
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
|
||||
// if we received an offer, we'd have to answer
|
||||
answer, err := c.PeerConn.CreateAnswer(nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := c.PeerConn.SetLocalDescription(answer); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// send remote an answer
|
||||
c.AppendLog("sending answer")
|
||||
return c.SendRequest(&livekit.SignalRequest{
|
||||
Message: &livekit.SignalRequest_Answer{
|
||||
Answer: rtc.ToProtoSessionDescription(answer),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func (c *RTCClient) handleAnswer(desc webrtc.SessionDescription) error {
|
||||
c.AppendLog("handling server answer")
|
||||
// remote answered the offer, establish connection
|
||||
err := c.PeerConn.SetRemoteDescription(desc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !c.connected {
|
||||
c.connected = true
|
||||
|
||||
// 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 {
|
||||
c.AppendLog("requesting negotiation")
|
||||
return c.SendRequest(&livekit.SignalRequest{
|
||||
Message: &livekit.SignalRequest_Negotiate{
|
||||
Negotiate: &livekit.NegotiationRequest{},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func (c *RTCClient) negotiate() error {
|
||||
c.AppendLog("starting negotiation")
|
||||
offer, err := c.PeerConn.CreateOffer(nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := c.PeerConn.SetLocalDescription(offer); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.SendRequest(&livekit.SignalRequest{
|
||||
Message: &livekit.SignalRequest_Offer{
|
||||
Offer: rtc.ToProtoSessionDescription(offer),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
type logEntry struct {
|
||||
msg string
|
||||
args []interface{}
|
||||
@@ -443,11 +471,22 @@ func (c *RTCClient) logLoop() {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *RTCClient) consumeReceiver(trackId string, r types.Receiver) {
|
||||
func (c *RTCClient) consumeReceiver(track *webrtc.TrackRemote) {
|
||||
lastUpdate := time.Time{}
|
||||
peerId, trackId := rtc.UnpackTrackId(trackId)
|
||||
peerId, trackId := rtc.UnpackTrackId(track.ID())
|
||||
numBytes := 0
|
||||
for pkt := range r.RTPChan() {
|
||||
for {
|
||||
pkt, _, err := track.ReadRTP()
|
||||
if c.ctx.Err() != nil {
|
||||
break
|
||||
}
|
||||
if rtc.IsEOF(err) {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
c.AppendLog("error reading RTP", "err", err)
|
||||
continue
|
||||
}
|
||||
numBytes += pkt.MarshalSize()
|
||||
if time.Now().Sub(lastUpdate) > 30*time.Second {
|
||||
c.AppendLog("consumed from peer",
|
||||
@@ -455,9 +494,5 @@ func (c *RTCClient) consumeReceiver(trackId string, r types.Receiver) {
|
||||
"size", numBytes)
|
||||
lastUpdate = time.Now()
|
||||
}
|
||||
|
||||
if c.ctx.Err() != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,11 +112,14 @@ func joinRoom(c *cli.Context) error {
|
||||
// add tracks if needed
|
||||
audioFile := c.String("audio")
|
||||
videoFile := c.String("video")
|
||||
if audioFile != "" {
|
||||
rc.AddTrack(audioFile, "audio", filepath.Base(audioFile))
|
||||
}
|
||||
if videoFile != "" {
|
||||
rc.AddTrack(videoFile, "video", filepath.Base(videoFile))
|
||||
rc.OnConnected = func() {
|
||||
// add after connection, since we need proper publish track APIs
|
||||
if audioFile != "" {
|
||||
rc.AddTrack(audioFile, "audio", filepath.Base(audioFile))
|
||||
}
|
||||
if videoFile != "" {
|
||||
rc.AddTrack(videoFile, "video", filepath.Base(videoFile))
|
||||
}
|
||||
}
|
||||
|
||||
// start loop to detect input
|
||||
|
||||
@@ -35,6 +35,7 @@ var (
|
||||
Aliases: []string{"r"},
|
||||
Usage: "name of the room to join, empty to allow joining all rooms",
|
||||
},
|
||||
devFlag,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -36,6 +36,10 @@ var (
|
||||
EnvVars: []string{"LK_API_SECRET"},
|
||||
Required: true,
|
||||
}
|
||||
devFlag = &cli.BoolFlag{
|
||||
Name: "dev",
|
||||
Usage: "enables dev mode, longer expiration for tokens",
|
||||
}
|
||||
)
|
||||
|
||||
func PrintJSON(obj interface{}) {
|
||||
@@ -60,9 +64,14 @@ func accessToken(c *cli.Context, grant *auth.VideoGrant, identity string) (value
|
||||
return
|
||||
}
|
||||
|
||||
isDev := c.Bool("dev")
|
||||
|
||||
at := auth.NewAccessToken(apiKey, apiSecret).
|
||||
AddGrant(grant).
|
||||
SetIdentity(identity).
|
||||
SetValidFor(time.Hour * 24)
|
||||
SetIdentity(identity)
|
||||
if isDev {
|
||||
fmt.Println("creating dev token")
|
||||
at.SetValidFor(time.Hour * 24 * 30)
|
||||
}
|
||||
return at.ToJWT()
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ require (
|
||||
github.com/manifoldco/promptui v0.8.0
|
||||
github.com/maxbrunsfeld/counterfeiter/v6 v6.3.0
|
||||
github.com/pion/ion-log v1.0.0
|
||||
github.com/pion/ion-sfu v1.7.2
|
||||
github.com/pion/ion-sfu v1.7.7
|
||||
github.com/pion/rtcp v1.2.6
|
||||
github.com/pion/rtp v1.6.2
|
||||
github.com/pion/stun v0.3.5
|
||||
|
||||
@@ -316,6 +316,8 @@ github.com/pion/ion-log v1.0.0 h1:2lJLImCmfCWCR38hLWsjQfBWe6NFz/htbqiYHwvOP/Q=
|
||||
github.com/pion/ion-log v1.0.0/go.mod h1:jwcla9KoB9bB/4FxYDSRJPcPYSLp5XiUUMnOLaqwl4E=
|
||||
github.com/pion/ion-sfu v1.7.2 h1:jW59IxIQtcGotK/BYlTqOF1Vsp/UqM4BoRD6MMnYw1Y=
|
||||
github.com/pion/ion-sfu v1.7.2/go.mod h1:61HfTCWVx6rTpYCc7kmvnTToEpyBoMwDhOyvMiUtNhk=
|
||||
github.com/pion/ion-sfu v1.7.7 h1:qbBOsUJrU8ZlFUC8Gmz8P3FBfZ5rzr6X/FErt87dioA=
|
||||
github.com/pion/ion-sfu v1.7.7/go.mod h1:D6Qnd7GHbYiRI1ye5a1IHst6cbbATawCb8fDs0oLxEI=
|
||||
github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY=
|
||||
github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms=
|
||||
github.com/pion/mdns v0.0.4 h1:O4vvVqr4DGX63vzmO6Fw9vpy3lfztVWHGCQfyw0ZLSY=
|
||||
|
||||
@@ -55,7 +55,7 @@ func (t *AccessToken) ToJWT() (string, error) {
|
||||
|
||||
validFor := defaultValidDuration
|
||||
if t.validFor > 0 {
|
||||
t.validFor = validFor
|
||||
validFor = t.validFor
|
||||
}
|
||||
|
||||
cl := jwt.Claims{
|
||||
|
||||
@@ -21,7 +21,7 @@ type RTCConfig struct {
|
||||
StunServers []string `yaml:"stun_servers"`
|
||||
UseExternalIP bool `yaml:"use_external_ip"`
|
||||
|
||||
MaxBandwidth uint64 `yaml:"max_bandwidth"`
|
||||
MaxBitrate uint64 `yaml:"max_bandwidth"`
|
||||
MaxBufferTime int `yaml:"max_buffer_time"`
|
||||
}
|
||||
|
||||
|
||||
+4
-5
@@ -11,12 +11,11 @@ import (
|
||||
type WebRTCConfig struct {
|
||||
Configuration webrtc.Configuration
|
||||
SettingEngine webrtc.SettingEngine
|
||||
|
||||
receiver ReceiverConfig
|
||||
Receiver ReceiverConfig
|
||||
}
|
||||
|
||||
type ReceiverConfig struct {
|
||||
maxBandwidth uint64
|
||||
maxBitrate uint64
|
||||
maxBufferTime int
|
||||
}
|
||||
|
||||
@@ -48,8 +47,8 @@ func NewWebRTCConfig(conf *config.RTCConfig, externalIP string) (*WebRTCConfig,
|
||||
return &WebRTCConfig{
|
||||
Configuration: c,
|
||||
SettingEngine: s,
|
||||
receiver: ReceiverConfig{
|
||||
maxBandwidth: conf.MaxBandwidth,
|
||||
Receiver: ReceiverConfig{
|
||||
maxBitrate: conf.MaxBitrate,
|
||||
maxBufferTime: conf.MaxBufferTime,
|
||||
},
|
||||
}, nil
|
||||
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
|
||||
"github.com/livekit/livekit-server/pkg/logger"
|
||||
"github.com/livekit/livekit-server/pkg/rtc/types"
|
||||
"github.com/livekit/livekit-server/pkg/utils"
|
||||
"github.com/livekit/livekit-server/proto/livekit"
|
||||
)
|
||||
|
||||
@@ -30,10 +29,10 @@ type DataTrack struct {
|
||||
subscribers map[string]*DownDataChannel
|
||||
}
|
||||
|
||||
func NewDataTrack(participantId string, dc *webrtc.DataChannel) *DataTrack {
|
||||
func NewDataTrack(trackId, participantId string, dc *webrtc.DataChannel) *DataTrack {
|
||||
t := &DataTrack{
|
||||
//ctx: context.Background(),
|
||||
id: utils.NewGuid(utils.TrackPrefix),
|
||||
id: trackId,
|
||||
name: dc.Label(),
|
||||
participantId: participantId,
|
||||
dataChannel: dc,
|
||||
|
||||
+6
-5
@@ -3,9 +3,10 @@ package rtc
|
||||
import "errors"
|
||||
|
||||
var (
|
||||
ErrRoomIdMissing = errors.New("room is not passed in")
|
||||
ErrInvalidRoomName = errors.New("room must have a unique name")
|
||||
ErrRoomNotFound = errors.New("requested room does not exist")
|
||||
ErrPermissionDenied = errors.New("no permissions to access the room")
|
||||
ErrUnexpectedOffer = errors.New("expected answer SDP, received offer")
|
||||
ErrRoomIdMissing = errors.New("room is not passed in")
|
||||
ErrInvalidRoomName = errors.New("room must have a unique name")
|
||||
ErrRoomNotFound = errors.New("requested room does not exist")
|
||||
ErrPermissionDenied = errors.New("no permissions to access the room")
|
||||
ErrUnexpectedOffer = errors.New("expected answer SDP, received offer")
|
||||
ErrUnexpectedNegotiation = errors.New("client negotiation has not been granted")
|
||||
)
|
||||
|
||||
+50
-8
@@ -16,7 +16,6 @@ import (
|
||||
"github.com/livekit/livekit-server/pkg/logger"
|
||||
"github.com/livekit/livekit-server/pkg/rtc/types"
|
||||
"github.com/livekit/livekit-server/pkg/sfu"
|
||||
"github.com/livekit/livekit-server/pkg/utils"
|
||||
"github.com/livekit/livekit-server/proto/livekit"
|
||||
)
|
||||
|
||||
@@ -54,10 +53,10 @@ type MediaTrack struct {
|
||||
lastPLI time.Time
|
||||
}
|
||||
|
||||
func NewMediaTrack(pId string, rtcpCh chan []rtcp.Packet, track *webrtc.TrackRemote, receiver types.Receiver) *MediaTrack {
|
||||
func NewMediaTrack(trackId string, pId string, rtcpCh chan []rtcp.Packet, track *webrtc.TrackRemote, receiver types.Receiver) *MediaTrack {
|
||||
t := &MediaTrack{
|
||||
ctx: context.Background(),
|
||||
id: utils.NewGuid(utils.TrackPrefix),
|
||||
id: trackId,
|
||||
participantId: pId,
|
||||
ssrc: track.SSRC(),
|
||||
name: track.StreamID(),
|
||||
@@ -135,7 +134,7 @@ func (t *MediaTrack) AddSubscriber(participant types.Participant) error {
|
||||
t.handleRTCP(outTrack, pkt)
|
||||
})
|
||||
}
|
||||
//go sub.sendStreamDownTracksReports(recv.Name())
|
||||
//go t.scheduleDownTrackBindingReports(recv.Name())
|
||||
})
|
||||
outTrack.OnCloseHandler(func() {
|
||||
t.lock.Lock()
|
||||
@@ -188,26 +187,69 @@ func (t *MediaTrack) RemoveAllSubscribers() {
|
||||
t.downtracks = make(map[string]types.DownTrack)
|
||||
}
|
||||
|
||||
// forwardRTPWorker reads from the receiver and writes to each sender
|
||||
//func (t *MediaTrack) scheduleDownTrackBindingReports(streamId string) {
|
||||
// var sd []rtcp.SourceDescriptionChunk
|
||||
//
|
||||
// p.lock.RLock()
|
||||
// dts := p.subscribedTracks[streamId]
|
||||
// for _, dt := range dts {
|
||||
// if !dt.IsBound() {
|
||||
// continue
|
||||
// }
|
||||
// chunks := dt.CreateSourceDescriptionChunks()
|
||||
// if chunks != nil {
|
||||
// sd = append(sd, chunks...)
|
||||
// }
|
||||
// }
|
||||
// p.lock.RUnlock()
|
||||
//
|
||||
// pkts := []rtcp.Packet{
|
||||
// &rtcp.SourceDescription{Chunks: sd},
|
||||
// }
|
||||
//
|
||||
// go func() {
|
||||
// batch := pkts
|
||||
// i := 0
|
||||
// for {
|
||||
// if err := p.peerConn.WriteRTCP(batch); err != nil {
|
||||
// logger.GetLogger().Debugw("error sending track binding reports",
|
||||
// "participant", p.id,
|
||||
// "err", err)
|
||||
// }
|
||||
// if i > 5 {
|
||||
// return
|
||||
// }
|
||||
// i++
|
||||
// time.Sleep(20 * time.Millisecond)
|
||||
// }
|
||||
// }()
|
||||
//}
|
||||
|
||||
// b reads from the receiver and writes to each sender
|
||||
func (t *MediaTrack) forwardRTPWorker() {
|
||||
defer func() {
|
||||
logger.GetLogger().Debugw("stopping forward RTP worker")
|
||||
t.RemoveAllSubscribers()
|
||||
// TODO: send unpublished events?
|
||||
t.nackWorker.Stop()
|
||||
}()
|
||||
|
||||
for pkt := range t.receiver.RTPChan() {
|
||||
//logger.GetLogger().Debugw("read packet from remoteTrack",
|
||||
// "participant", t.participantId,
|
||||
// "track", t.ID())
|
||||
// when track is muted, it's "disabled" on the client side, and will still be sending black frames
|
||||
// when our metadata is updated as such, we shortcircuit forwarding of black frames
|
||||
if t.muted {
|
||||
continue
|
||||
}
|
||||
|
||||
//logger.GetLogger().Debugw("read packet from remoteTrack",
|
||||
// "participantId", t.participantId,
|
||||
// "remoteTrack", t.remoteTrack.ID())
|
||||
t.lock.RLock()
|
||||
for dstId, dt := range t.downtracks {
|
||||
//logger.GetLogger().Debugw("read packet from remoteTrack",
|
||||
// "srcParticipant", t.participantId,
|
||||
// "destParticipant", dstId,
|
||||
// "track", t.ID())
|
||||
err := dt.WriteRTP(pkt)
|
||||
if IsEOF(err) {
|
||||
// this participant unsubscribed, remove it
|
||||
|
||||
+108
-38
@@ -2,7 +2,6 @@ package rtc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"sync"
|
||||
"time"
|
||||
@@ -25,10 +24,17 @@ const (
|
||||
negotiationFrequency = 100 * time.Millisecond
|
||||
)
|
||||
|
||||
const (
|
||||
negotiationStateNone = iota
|
||||
negotiationStateClient
|
||||
negotiationStateServer
|
||||
)
|
||||
|
||||
type ParticipantImpl struct {
|
||||
id string
|
||||
peerConn types.PeerConnection
|
||||
sigConn types.SignalConnection
|
||||
receiverConfig ReceiverConfig
|
||||
ctx context.Context
|
||||
cancel context.CancelFunc
|
||||
mediaEngine *webrtc.MediaEngine
|
||||
@@ -39,7 +45,10 @@ type ParticipantImpl struct {
|
||||
// publishedTracks that participant is publishing
|
||||
publishedTracks map[string]types.PublishedTrack
|
||||
// client intended to publish, yet to be reconciled
|
||||
pendingTracks map[string]*livekit.TrackInfo
|
||||
pendingTracks map[string]*livekit.TrackInfo
|
||||
|
||||
negotiationCond *sync.Cond
|
||||
negotiationState int
|
||||
debouncedNegotiate func(func())
|
||||
|
||||
lock sync.RWMutex
|
||||
@@ -63,7 +72,7 @@ func NewPeerConnection(conf *WebRTCConfig) (*webrtc.PeerConnection, error) {
|
||||
return api.NewPeerConnection(conf.Configuration)
|
||||
}
|
||||
|
||||
func NewParticipant(pc types.PeerConnection, sc types.SignalConnection, name string) (*ParticipantImpl, error) {
|
||||
func NewParticipant(pc types.PeerConnection, sc types.SignalConnection, name string, receiverConfig ReceiverConfig) (*ParticipantImpl, error) {
|
||||
me := &webrtc.MediaEngine{}
|
||||
me.RegisterDefaultCodecs()
|
||||
|
||||
@@ -73,12 +82,14 @@ func NewParticipant(pc types.PeerConnection, sc types.SignalConnection, name str
|
||||
name: name,
|
||||
peerConn: pc,
|
||||
sigConn: sc,
|
||||
receiverConfig: receiverConfig,
|
||||
ctx: ctx,
|
||||
cancel: cancel,
|
||||
rtcpCh: make(chan []rtcp.Packet, 10),
|
||||
subscribedTracks: make(map[string][]*sfu.DownTrack),
|
||||
state: livekit.ParticipantInfo_JOINING,
|
||||
lock: sync.RWMutex{},
|
||||
negotiationCond: sync.NewCond(&sync.Mutex{}),
|
||||
publishedTracks: make(map[string]types.PublishedTrack, 0),
|
||||
pendingTracks: make(map[string]*livekit.TrackInfo),
|
||||
mediaEngine: me,
|
||||
@@ -86,7 +97,6 @@ func NewParticipant(pc types.PeerConnection, sc types.SignalConnection, name str
|
||||
}
|
||||
|
||||
log := logger.GetLogger()
|
||||
pc.ConnectionState()
|
||||
pc.OnTrack(participant.onMediaTrack)
|
||||
|
||||
pc.OnICECandidate(func(c *webrtc.ICECandidate) {
|
||||
@@ -119,9 +129,18 @@ func NewParticipant(pc types.PeerConnection, sc types.SignalConnection, name str
|
||||
}
|
||||
})
|
||||
|
||||
// TODO: handle data channel
|
||||
pc.OnDataChannel(participant.onDataChannel)
|
||||
|
||||
// only set after answered
|
||||
pc.OnNegotiationNeeded(func() {
|
||||
if participant.state != livekit.ParticipantInfo_JOINED && participant.state != livekit.ParticipantInfo_ACTIVE {
|
||||
// ignore negotiation requests before connected
|
||||
return
|
||||
}
|
||||
logger.GetLogger().Debugw("negotiation needed", "participantId", participant.ID())
|
||||
participant.scheduleNegotiate()
|
||||
})
|
||||
|
||||
return participant, nil
|
||||
}
|
||||
|
||||
@@ -173,6 +192,12 @@ func (p *ParticipantImpl) OnClose(callback func(types.Participant)) {
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
if err = p.peerConn.SetRemoteDescription(sdp); err != nil {
|
||||
return
|
||||
}
|
||||
@@ -188,11 +213,13 @@ func (p *ParticipantImpl) Answer(sdp webrtc.SessionDescription) (answer webrtc.S
|
||||
return
|
||||
}
|
||||
|
||||
// only set after answered
|
||||
p.peerConn.OnNegotiationNeeded(func() {
|
||||
logger.GetLogger().Debugw("negotiation needed", "participantId", p.ID())
|
||||
p.scheduleNegotiate()
|
||||
})
|
||||
// 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()
|
||||
|
||||
err = p.sigConn.WriteResponse(&livekit.SignalResponse{
|
||||
Message: &livekit.SignalResponse_Answer{
|
||||
@@ -211,21 +238,29 @@ func (p *ParticipantImpl) AddTrack(clientId, name string, trackType livekit.Trac
|
||||
p.lock.Lock()
|
||||
defer p.lock.Unlock()
|
||||
|
||||
p.pendingTracks[clientId] = &livekit.TrackInfo{
|
||||
ti := &livekit.TrackInfo{
|
||||
Type: trackType,
|
||||
Name: name,
|
||||
Sid: utils.NewGuid(utils.TrackPrefix),
|
||||
}
|
||||
p.pendingTracks[clientId] = ti
|
||||
|
||||
p.scheduleNegotiate()
|
||||
p.sigConn.WriteResponse(&livekit.SignalResponse{
|
||||
Message: &livekit.SignalResponse_TrackPublished{
|
||||
TrackPublished: &livekit.TrackPublishedResponse{
|
||||
Cid: clientId,
|
||||
Track: ti,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func (p *ParticipantImpl) RemoveTrack(sid string) error {
|
||||
p.lock.Lock()
|
||||
defer p.lock.Unlock()
|
||||
|
||||
//
|
||||
// TODO: handle removal properly
|
||||
|
||||
p.scheduleNegotiate()
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -237,9 +272,31 @@ func (p *ParticipantImpl) HandleAnswer(sdp webrtc.SessionDescription) error {
|
||||
if err := p.peerConn.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() {
|
||||
// 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()
|
||||
p.sigConn.WriteResponse(&livekit.SignalResponse{
|
||||
Message: &livekit.SignalResponse_Negotiate{
|
||||
Negotiate: &livekit.NegotiationResponse{},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// AddICECandidate adds candidates for remote peer
|
||||
func (p *ParticipantImpl) AddICECandidate(candidate webrtc.ICECandidateInit) error {
|
||||
if err := p.peerConn.AddICECandidate(candidate); err != nil {
|
||||
@@ -346,9 +403,9 @@ func (p *ParticipantImpl) AddDownTrack(streamId string, dt *sfu.DownTrack) {
|
||||
p.lock.Lock()
|
||||
p.subscribedTracks[streamId] = append(p.subscribedTracks[streamId], dt)
|
||||
p.lock.Unlock()
|
||||
dt.OnBind(func() {
|
||||
go p.scheduleDownTrackBindingReports(streamId)
|
||||
})
|
||||
//dt.OnBind(func() {
|
||||
// go p.scheduleDownTrackBindingReports(streamId)
|
||||
//})
|
||||
}
|
||||
|
||||
func (p *ParticipantImpl) RemoveDownTrack(streamId string, dt *sfu.DownTrack) {
|
||||
@@ -368,7 +425,16 @@ func (p *ParticipantImpl) scheduleNegotiate() {
|
||||
p.debouncedNegotiate(p.negotiate)
|
||||
}
|
||||
|
||||
// initiates server-driven negotiation by creating an offer
|
||||
func (p *ParticipantImpl) negotiate() {
|
||||
p.negotiationCond.L.Lock()
|
||||
for p.negotiationState != negotiationStateNone {
|
||||
p.negotiationCond.Wait()
|
||||
p.negotiationState = negotiationStateServer
|
||||
}
|
||||
p.negotiationCond.L.Unlock()
|
||||
|
||||
logger.GetLogger().Debugw("starting negotiation", "participant", p.ID())
|
||||
offer, err := p.peerConn.CreateOffer(nil)
|
||||
if err != nil {
|
||||
logger.GetLogger().Errorw("could not create offer", "err", err)
|
||||
@@ -415,13 +481,18 @@ func (p *ParticipantImpl) updateState(state livekit.ParticipantInfo_State) {
|
||||
|
||||
// when a new remoteTrack is created, creates a Track and adds it to room
|
||||
func (p *ParticipantImpl) onMediaTrack(track *webrtc.TrackRemote, rtpReceiver *webrtc.RTPReceiver) {
|
||||
logger.GetLogger().Debugw("remoteTrack added", "participantId", p.ID(), "remoteTrack", track.ID())
|
||||
logger.GetLogger().Debugw("mediaTrack added", "participantId", p.ID(), "remoteTrack", track.ID())
|
||||
|
||||
ti := p.popPendingTrack(track.ID())
|
||||
if ti == nil {
|
||||
return
|
||||
}
|
||||
|
||||
// create ReceiverImpl
|
||||
receiver := NewReceiver(p.rtcpCh, rtpReceiver, track)
|
||||
mt := NewMediaTrack(p.id, p.rtcpCh, track, receiver)
|
||||
receiver := NewReceiver(p.rtcpCh, rtpReceiver, track, p.receiverConfig)
|
||||
mt := NewMediaTrack(ti.Sid, p.id, p.rtcpCh, track, receiver)
|
||||
|
||||
p.handleTrackPublished(track.ID(), mt)
|
||||
p.handleTrackPublished(mt)
|
||||
}
|
||||
|
||||
func (p *ParticipantImpl) onDataChannel(dc *webrtc.DataChannel) {
|
||||
@@ -430,38 +501,37 @@ func (p *ParticipantImpl) onDataChannel(dc *webrtc.DataChannel) {
|
||||
}
|
||||
logger.GetLogger().Debugw("dataChannel added", "participantId", p.ID(), "label", dc.Label())
|
||||
|
||||
dt := NewDataTrack(p.id, dc)
|
||||
p.lock.Lock()
|
||||
p.publishedTracks[dt.id] = dt
|
||||
p.lock.Unlock()
|
||||
// data channels have numeric ids, so we use its label to identify
|
||||
ti := p.popPendingTrack(dc.Label())
|
||||
if ti == nil {
|
||||
return
|
||||
}
|
||||
|
||||
dt.Start()
|
||||
dt := NewDataTrack(ti.Sid, p.id, dc)
|
||||
|
||||
cid := fmt.Sprintf("%d", dc.ID())
|
||||
p.handleTrackPublished(cid, dt)
|
||||
p.handleTrackPublished(dt)
|
||||
}
|
||||
|
||||
func (p *ParticipantImpl) handleTrackPublished(clientId string, track types.PublishedTrack) {
|
||||
// fill in
|
||||
func (p *ParticipantImpl) popPendingTrack(clientId string) *livekit.TrackInfo {
|
||||
p.lock.Lock()
|
||||
defer p.lock.Unlock()
|
||||
ti := p.pendingTracks[clientId]
|
||||
if ti == nil {
|
||||
logger.GetLogger().Errorw("track info not published prior to track", "clientId", clientId)
|
||||
} else {
|
||||
track.SetName(ti.Name)
|
||||
delete(p.pendingTracks, clientId)
|
||||
}
|
||||
return ti
|
||||
}
|
||||
|
||||
func (p *ParticipantImpl) handleTrackPublished(track types.PublishedTrack) {
|
||||
// fill in
|
||||
p.lock.Lock()
|
||||
defer p.lock.Unlock()
|
||||
p.publishedTracks[track.ID()] = track
|
||||
|
||||
track.Start()
|
||||
|
||||
// confirm publication
|
||||
p.sigConn.WriteResponse(&livekit.SignalResponse{
|
||||
Message: &livekit.SignalResponse_TrackPublished{
|
||||
TrackPublished: ToProtoTrack(track),
|
||||
},
|
||||
})
|
||||
if p.onTrackPublished != nil {
|
||||
go p.onTrackPublished(p, track)
|
||||
}
|
||||
@@ -492,7 +562,7 @@ func (p *ParticipantImpl) scheduleDownTrackBindingReports(streamId string) {
|
||||
i := 0
|
||||
for {
|
||||
if err := p.peerConn.WriteRTCP(batch); err != nil {
|
||||
logger.GetLogger().Debugw("Sending track binding reports",
|
||||
logger.GetLogger().Debugw("error sending track binding reports",
|
||||
"participant", p.id,
|
||||
"err", err)
|
||||
}
|
||||
|
||||
+6
-1
@@ -23,7 +23,7 @@ type ReceiverImpl struct {
|
||||
rtcpChan chan []rtcp.Packet
|
||||
}
|
||||
|
||||
func NewReceiver(rtcpCh chan []rtcp.Packet, rtpReceiver *webrtc.RTPReceiver, track *webrtc.TrackRemote) *ReceiverImpl {
|
||||
func NewReceiver(rtcpCh chan []rtcp.Packet, rtpReceiver *webrtc.RTPReceiver, track *webrtc.TrackRemote, config ReceiverConfig) *ReceiverImpl {
|
||||
r := &ReceiverImpl{
|
||||
rtpReceiver: rtpReceiver,
|
||||
rtcpChan: rtcpCh,
|
||||
@@ -43,6 +43,11 @@ func NewReceiver(rtcpCh chan []rtcp.Packet, rtpReceiver *webrtc.RTPReceiver, tra
|
||||
// TODO: figure out how to handle this
|
||||
})
|
||||
|
||||
r.buffer.Bind(rtpReceiver.GetParameters(), buffer.Options{
|
||||
BufferTime: config.maxBufferTime,
|
||||
MaxBitRate: config.maxBitrate,
|
||||
})
|
||||
|
||||
// received sender updates
|
||||
r.rtcpReader.OnPacket(func(bytes []byte) {
|
||||
pkts, err := rtcp.Unmarshal(bytes)
|
||||
|
||||
+7
-2
@@ -68,7 +68,8 @@ func (r *Room) Join(participant types.Participant) error {
|
||||
// it's important to set this before connection, we don't want to miss out on any publishedTracks
|
||||
participant.OnTrackPublished(r.onTrackAdded)
|
||||
participant.OnStateChange(func(p types.Participant, oldState livekit.ParticipantInfo_State) {
|
||||
log.Debugw("participant state changed", "state", p.State(), "participant", p.ID())
|
||||
log.Debugw("participant state changed", "state", p.State(), "participant", p.ID(),
|
||||
"oldState", oldState)
|
||||
r.broadcastParticipantState(p)
|
||||
|
||||
if oldState == livekit.ParticipantInfo_JOINING && p.State() == livekit.ParticipantInfo_JOINED {
|
||||
@@ -140,10 +141,14 @@ func (r *Room) onTrackAdded(participant types.Participant, track types.Published
|
||||
// skip publishing participant
|
||||
continue
|
||||
}
|
||||
if existingParticipant.State() != livekit.ParticipantInfo_JOINED {
|
||||
if existingParticipant.State() != livekit.ParticipantInfo_JOINED && existingParticipant.State() != livekit.ParticipantInfo_ACTIVE {
|
||||
// not fully joined. don't subscribe yet
|
||||
continue
|
||||
}
|
||||
logger.GetLogger().Debugw("subscribing to new track",
|
||||
"srcParticipant", participant.ID(),
|
||||
"remoteTrack", track.ID(),
|
||||
"dstParticipant", existingParticipant.ID())
|
||||
if err := track.AddSubscriber(existingParticipant); err != nil {
|
||||
logger.GetLogger().Errorw("could not subscribe to remoteTrack",
|
||||
"srcParticipant", participant.ID(),
|
||||
|
||||
+4
-2
@@ -85,7 +85,7 @@ func (s *RTCService) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
writeJSONError(w, http.StatusInternalServerError, "could not create peerConnection", err.Error())
|
||||
return
|
||||
}
|
||||
participant, err := rtc.NewParticipant(pc, signalConn, pName)
|
||||
participant, err := rtc.NewParticipant(pc, signalConn, pName, s.manager.Config().Receiver)
|
||||
if err != nil {
|
||||
writeJSONError(w, http.StatusInternalServerError, "could not create participant", err.Error())
|
||||
return
|
||||
@@ -149,6 +149,8 @@ func (s *RTCService) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
// 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 {
|
||||
log.Errorw("cannot trickle before peer offer", "participant", participant.ID())
|
||||
@@ -185,7 +187,7 @@ func (s *RTCService) handleOffer(participant types.Participant, offer *livekit.S
|
||||
|
||||
func (s *RTCService) handleTrickle(participant types.Participant, trickle *livekit.TrickleRequest) error {
|
||||
candidateInit := rtc.FromProtoTrickle(trickle)
|
||||
logger.GetLogger().Debugw("adding peer candidate", "participant", participant.ID())
|
||||
//logger.GetLogger().Debugw("adding peer candidate", "participant", participant.ID())
|
||||
if err := participant.AddICECandidate(candidateInit); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
+395
-173
@@ -37,6 +37,7 @@ type SignalRequest struct {
|
||||
// *SignalRequest_AddTrack
|
||||
// *SignalRequest_Mute
|
||||
// *SignalRequest_RemoveTrack
|
||||
// *SignalRequest_Negotiate
|
||||
Message isSignalRequest_Message `protobuf_oneof:"message"`
|
||||
}
|
||||
|
||||
@@ -121,6 +122,13 @@ func (x *SignalRequest) GetRemoveTrack() *RemoveTrackRequest {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *SignalRequest) GetNegotiate() *NegotiationRequest {
|
||||
if x, ok := x.GetMessage().(*SignalRequest_Negotiate); ok {
|
||||
return x.Negotiate
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type isSignalRequest_Message interface {
|
||||
isSignalRequest_Message()
|
||||
}
|
||||
@@ -151,6 +159,11 @@ type SignalRequest_RemoveTrack struct {
|
||||
RemoveTrack *RemoveTrackRequest `protobuf:"bytes,6,opt,name=remove_track,json=removeTrack,proto3,oneof"`
|
||||
}
|
||||
|
||||
type SignalRequest_Negotiate struct {
|
||||
// when client needs to negotiate
|
||||
Negotiate *NegotiationRequest `protobuf:"bytes,7,opt,name=negotiate,proto3,oneof"`
|
||||
}
|
||||
|
||||
func (*SignalRequest_Offer) isSignalRequest_Message() {}
|
||||
|
||||
func (*SignalRequest_Answer) isSignalRequest_Message() {}
|
||||
@@ -163,6 +176,8 @@ func (*SignalRequest_Mute) isSignalRequest_Message() {}
|
||||
|
||||
func (*SignalRequest_RemoveTrack) isSignalRequest_Message() {}
|
||||
|
||||
func (*SignalRequest_Negotiate) isSignalRequest_Message() {}
|
||||
|
||||
type SignalResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@@ -175,6 +190,7 @@ type SignalResponse struct {
|
||||
// *SignalResponse_Trickle
|
||||
// *SignalResponse_Update
|
||||
// *SignalResponse_TrackPublished
|
||||
// *SignalResponse_Negotiate
|
||||
Message isSignalResponse_Message `protobuf_oneof:"message"`
|
||||
}
|
||||
|
||||
@@ -252,13 +268,20 @@ func (x *SignalResponse) GetUpdate() *ParticipantUpdate {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *SignalResponse) GetTrackPublished() *TrackInfo {
|
||||
func (x *SignalResponse) GetTrackPublished() *TrackPublishedResponse {
|
||||
if x, ok := x.GetMessage().(*SignalResponse_TrackPublished); ok {
|
||||
return x.TrackPublished
|
||||
}
|
||||
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()
|
||||
}
|
||||
@@ -290,7 +313,12 @@ type SignalResponse_Update struct {
|
||||
|
||||
type SignalResponse_TrackPublished struct {
|
||||
// sent to the participant when their track has been published
|
||||
TrackPublished *TrackInfo `protobuf:"bytes,6,opt,name=track_published,json=trackPublished,proto3,oneof"`
|
||||
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() {}
|
||||
@@ -305,15 +333,17 @@ func (*SignalResponse_Update) isSignalResponse_Message() {}
|
||||
|
||||
func (*SignalResponse_TrackPublished) isSignalResponse_Message() {}
|
||||
|
||||
func (*SignalResponse_Negotiate) isSignalResponse_Message() {}
|
||||
|
||||
type AddTrackRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
Type TrackType `protobuf:"varint,2,opt,name=type,proto3,enum=livekit.TrackType" json:"type,omitempty"`
|
||||
// client ID of track, to match it when RTC track is received
|
||||
Cid string `protobuf:"bytes,3,opt,name=cid,proto3" json:"cid,omitempty"`
|
||||
Cid string `protobuf:"bytes,1,opt,name=cid,proto3" json:"cid,omitempty"`
|
||||
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
|
||||
Type TrackType `protobuf:"varint,3,opt,name=type,proto3,enum=livekit.TrackType" json:"type,omitempty"`
|
||||
}
|
||||
|
||||
func (x *AddTrackRequest) Reset() {
|
||||
@@ -348,6 +378,13 @@ func (*AddTrackRequest) Descriptor() ([]byte, []int) {
|
||||
return file_rtc_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *AddTrackRequest) GetCid() string {
|
||||
if x != nil {
|
||||
return x.Cid
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *AddTrackRequest) GetName() string {
|
||||
if x != nil {
|
||||
return x.Name
|
||||
@@ -362,13 +399,6 @@ func (x *AddTrackRequest) GetType() TrackType {
|
||||
return TrackType_AUDIO
|
||||
}
|
||||
|
||||
func (x *AddTrackRequest) GetCid() string {
|
||||
if x != nil {
|
||||
return x.Cid
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type TrickleRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@@ -463,17 +493,17 @@ func (x *RemoveTrackRequest) GetSid() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
type SessionDescription struct {
|
||||
type MuteTrackRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` // "answer" | "offer" | "pranswer" | "rollback"
|
||||
Sdp string `protobuf:"bytes,2,opt,name=sdp,proto3" json:"sdp,omitempty"`
|
||||
Sid string `protobuf:"bytes,1,opt,name=sid,proto3" json:"sid,omitempty"`
|
||||
Muted bool `protobuf:"varint,2,opt,name=muted,proto3" json:"muted,omitempty"`
|
||||
}
|
||||
|
||||
func (x *SessionDescription) Reset() {
|
||||
*x = SessionDescription{}
|
||||
func (x *MuteTrackRequest) Reset() {
|
||||
*x = MuteTrackRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_rtc_proto_msgTypes[5]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
@@ -481,13 +511,13 @@ func (x *SessionDescription) Reset() {
|
||||
}
|
||||
}
|
||||
|
||||
func (x *SessionDescription) String() string {
|
||||
func (x *MuteTrackRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*SessionDescription) ProtoMessage() {}
|
||||
func (*MuteTrackRequest) ProtoMessage() {}
|
||||
|
||||
func (x *SessionDescription) ProtoReflect() protoreflect.Message {
|
||||
func (x *MuteTrackRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_rtc_proto_msgTypes[5]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
@@ -499,23 +529,61 @@ func (x *SessionDescription) ProtoReflect() protoreflect.Message {
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use SessionDescription.ProtoReflect.Descriptor instead.
|
||||
func (*SessionDescription) Descriptor() ([]byte, []int) {
|
||||
// Deprecated: Use MuteTrackRequest.ProtoReflect.Descriptor instead.
|
||||
func (*MuteTrackRequest) Descriptor() ([]byte, []int) {
|
||||
return file_rtc_proto_rawDescGZIP(), []int{5}
|
||||
}
|
||||
|
||||
func (x *SessionDescription) GetType() string {
|
||||
func (x *MuteTrackRequest) GetSid() string {
|
||||
if x != nil {
|
||||
return x.Type
|
||||
return x.Sid
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *SessionDescription) GetSdp() string {
|
||||
func (x *MuteTrackRequest) GetMuted() bool {
|
||||
if x != nil {
|
||||
return x.Sdp
|
||||
return x.Muted
|
||||
}
|
||||
return ""
|
||||
return false
|
||||
}
|
||||
|
||||
type NegotiationRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
}
|
||||
|
||||
func (x *NegotiationRequest) Reset() {
|
||||
*x = NegotiationRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_rtc_proto_msgTypes[6]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *NegotiationRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*NegotiationRequest) ProtoMessage() {}
|
||||
|
||||
func (x *NegotiationRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_rtc_proto_msgTypes[6]
|
||||
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 NegotiationRequest.ProtoReflect.Descriptor instead.
|
||||
func (*NegotiationRequest) Descriptor() ([]byte, []int) {
|
||||
return file_rtc_proto_rawDescGZIP(), []int{6}
|
||||
}
|
||||
|
||||
type JoinResponse struct {
|
||||
@@ -531,7 +599,7 @@ type JoinResponse struct {
|
||||
func (x *JoinResponse) Reset() {
|
||||
*x = JoinResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_rtc_proto_msgTypes[6]
|
||||
mi := &file_rtc_proto_msgTypes[7]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -544,7 +612,7 @@ func (x *JoinResponse) String() string {
|
||||
func (*JoinResponse) ProtoMessage() {}
|
||||
|
||||
func (x *JoinResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_rtc_proto_msgTypes[6]
|
||||
mi := &file_rtc_proto_msgTypes[7]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -557,7 +625,7 @@ func (x *JoinResponse) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use JoinResponse.ProtoReflect.Descriptor instead.
|
||||
func (*JoinResponse) Descriptor() ([]byte, []int) {
|
||||
return file_rtc_proto_rawDescGZIP(), []int{6}
|
||||
return file_rtc_proto_rawDescGZIP(), []int{7}
|
||||
}
|
||||
|
||||
func (x *JoinResponse) GetRoom() *RoomInfo {
|
||||
@@ -581,32 +649,32 @@ func (x *JoinResponse) GetOtherParticipants() []*ParticipantInfo {
|
||||
return nil
|
||||
}
|
||||
|
||||
type MuteTrackRequest struct {
|
||||
type TrackPublishedResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Sid string `protobuf:"bytes,1,opt,name=sid,proto3" json:"sid,omitempty"`
|
||||
Muted bool `protobuf:"varint,2,opt,name=muted,proto3" json:"muted,omitempty"`
|
||||
Cid string `protobuf:"bytes,1,opt,name=cid,proto3" json:"cid,omitempty"`
|
||||
Track *TrackInfo `protobuf:"bytes,2,opt,name=track,proto3" json:"track,omitempty"`
|
||||
}
|
||||
|
||||
func (x *MuteTrackRequest) Reset() {
|
||||
*x = MuteTrackRequest{}
|
||||
func (x *TrackPublishedResponse) Reset() {
|
||||
*x = TrackPublishedResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_rtc_proto_msgTypes[7]
|
||||
mi := &file_rtc_proto_msgTypes[8]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *MuteTrackRequest) String() string {
|
||||
func (x *TrackPublishedResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*MuteTrackRequest) ProtoMessage() {}
|
||||
func (*TrackPublishedResponse) ProtoMessage() {}
|
||||
|
||||
func (x *MuteTrackRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_rtc_proto_msgTypes[7]
|
||||
func (x *TrackPublishedResponse) 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 {
|
||||
@@ -617,23 +685,116 @@ func (x *MuteTrackRequest) ProtoReflect() protoreflect.Message {
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use MuteTrackRequest.ProtoReflect.Descriptor instead.
|
||||
func (*MuteTrackRequest) Descriptor() ([]byte, []int) {
|
||||
return file_rtc_proto_rawDescGZIP(), []int{7}
|
||||
// Deprecated: Use TrackPublishedResponse.ProtoReflect.Descriptor instead.
|
||||
func (*TrackPublishedResponse) Descriptor() ([]byte, []int) {
|
||||
return file_rtc_proto_rawDescGZIP(), []int{8}
|
||||
}
|
||||
|
||||
func (x *MuteTrackRequest) GetSid() string {
|
||||
func (x *TrackPublishedResponse) GetCid() string {
|
||||
if x != nil {
|
||||
return x.Sid
|
||||
return x.Cid
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *MuteTrackRequest) GetMuted() bool {
|
||||
func (x *TrackPublishedResponse) GetTrack() *TrackInfo {
|
||||
if x != nil {
|
||||
return x.Muted
|
||||
return x.Track
|
||||
}
|
||||
return false
|
||||
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[9]
|
||||
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[9]
|
||||
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{9}
|
||||
}
|
||||
|
||||
type SessionDescription struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` // "answer" | "offer" | "pranswer" | "rollback"
|
||||
Sdp string `protobuf:"bytes,2,opt,name=sdp,proto3" json:"sdp,omitempty"`
|
||||
}
|
||||
|
||||
func (x *SessionDescription) Reset() {
|
||||
*x = SessionDescription{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_rtc_proto_msgTypes[10]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *SessionDescription) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*SessionDescription) ProtoMessage() {}
|
||||
|
||||
func (x *SessionDescription) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_rtc_proto_msgTypes[10]
|
||||
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 SessionDescription.ProtoReflect.Descriptor instead.
|
||||
func (*SessionDescription) Descriptor() ([]byte, []int) {
|
||||
return file_rtc_proto_rawDescGZIP(), []int{10}
|
||||
}
|
||||
|
||||
func (x *SessionDescription) GetType() string {
|
||||
if x != nil {
|
||||
return x.Type
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *SessionDescription) GetSdp() string {
|
||||
if x != nil {
|
||||
return x.Sdp
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type ParticipantUpdate struct {
|
||||
@@ -647,7 +808,7 @@ type ParticipantUpdate struct {
|
||||
func (x *ParticipantUpdate) Reset() {
|
||||
*x = ParticipantUpdate{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_rtc_proto_msgTypes[8]
|
||||
mi := &file_rtc_proto_msgTypes[11]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -660,7 +821,7 @@ func (x *ParticipantUpdate) String() string {
|
||||
func (*ParticipantUpdate) ProtoMessage() {}
|
||||
|
||||
func (x *ParticipantUpdate) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_rtc_proto_msgTypes[8]
|
||||
mi := &file_rtc_proto_msgTypes[11]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -673,7 +834,7 @@ func (x *ParticipantUpdate) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use ParticipantUpdate.ProtoReflect.Descriptor instead.
|
||||
func (*ParticipantUpdate) Descriptor() ([]byte, []int) {
|
||||
return file_rtc_proto_rawDescGZIP(), []int{8}
|
||||
return file_rtc_proto_rawDescGZIP(), []int{11}
|
||||
}
|
||||
|
||||
func (x *ParticipantUpdate) GetParticipants() []*ParticipantInfo {
|
||||
@@ -688,7 +849,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, 0xe7, 0x02, 0x0a, 0x0d, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75,
|
||||
0x6f, 0x22, 0xa4, 0x03, 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,
|
||||
@@ -710,69 +871,86 @@ var file_rtc_proto_rawDesc = []byte{
|
||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x52,
|
||||
0x65, 0x6d, 0x6f, 0x76, 0x65, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x48, 0x00, 0x52, 0x0b, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x54, 0x72, 0x61, 0x63, 0x6b,
|
||||
0x42, 0x09, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0xde, 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, 0x3d, 0x0a, 0x0f, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x5f, 0x70, 0x75, 0x62, 0x6c,
|
||||
0x69, 0x73, 0x68, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6c, 0x69,
|
||||
0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 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,
|
||||
0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e,
|
||||
0x61, 0x6d, 0x65, 0x12, 0x26, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 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, 0x12, 0x10, 0x0a, 0x03, 0x63,
|
||||
0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x63, 0x69, 0x64, 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, 0x26, 0x0a, 0x12, 0x52, 0x65, 0x6d, 0x6f, 0x76, 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, 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, 0xba, 0x01, 0x0a, 0x0c, 0x4a, 0x6f,
|
||||
0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x04, 0x72, 0x6f,
|
||||
0x6f, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b,
|
||||
0x69, 0x74, 0x2e, 0x52, 0x6f, 0x6f, 0x6d, 0x49, 0x6e, 0x66, 0x6f, 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, 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, 0x51, 0x0a, 0x11, 0x50, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e,
|
||||
0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x3c, 0x0a, 0x0c, 0x70, 0x61, 0x72, 0x74, 0x69,
|
||||
0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e,
|
||||
0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x50, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70,
|
||||
0x61, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0c, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69,
|
||||
0x70, 0x61, 0x6e, 0x74, 0x73, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e,
|
||||
0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2f, 0x6c, 0x69, 0x76, 0x65,
|
||||
0x6b, 0x69, 0x74, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x2f, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
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, 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, 0x26, 0x0a,
|
||||
0x12, 0x52, 0x65, 0x6d, 0x6f, 0x76, 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, 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, 0xba, 0x01, 0x0a, 0x0c, 0x4a, 0x6f, 0x69, 0x6e,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x04, 0x72, 0x6f, 0x6f, 0x6d,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74,
|
||||
0x2e, 0x52, 0x6f, 0x6f, 0x6d, 0x49, 0x6e, 0x66, 0x6f, 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, 0x32, 0x18, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b,
|
||||
0x69, 0x74, 0x2e, 0x50, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x49, 0x6e,
|
||||
0x66, 0x6f, 0x52, 0x0c, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x73,
|
||||
0x42, 0x31, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c,
|
||||
0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2f, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2d, 0x73,
|
||||
0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x6c, 0x69, 0x76, 0x65,
|
||||
0x6b, 0x69, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -787,45 +965,51 @@ func file_rtc_proto_rawDescGZIP() []byte {
|
||||
return file_rtc_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_rtc_proto_msgTypes = make([]protoimpl.MessageInfo, 9)
|
||||
var file_rtc_proto_msgTypes = make([]protoimpl.MessageInfo, 12)
|
||||
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
|
||||
(*RemoveTrackRequest)(nil), // 4: livekit.RemoveTrackRequest
|
||||
(*SessionDescription)(nil), // 5: livekit.SessionDescription
|
||||
(*JoinResponse)(nil), // 6: livekit.JoinResponse
|
||||
(*MuteTrackRequest)(nil), // 7: livekit.MuteTrackRequest
|
||||
(*ParticipantUpdate)(nil), // 8: livekit.ParticipantUpdate
|
||||
(*TrackInfo)(nil), // 9: livekit.TrackInfo
|
||||
(TrackType)(0), // 10: livekit.TrackType
|
||||
(*RoomInfo)(nil), // 11: livekit.RoomInfo
|
||||
(*ParticipantInfo)(nil), // 12: livekit.ParticipantInfo
|
||||
(*SignalRequest)(nil), // 0: livekit.SignalRequest
|
||||
(*SignalResponse)(nil), // 1: livekit.SignalResponse
|
||||
(*AddTrackRequest)(nil), // 2: livekit.AddTrackRequest
|
||||
(*TrickleRequest)(nil), // 3: livekit.TrickleRequest
|
||||
(*RemoveTrackRequest)(nil), // 4: livekit.RemoveTrackRequest
|
||||
(*MuteTrackRequest)(nil), // 5: livekit.MuteTrackRequest
|
||||
(*NegotiationRequest)(nil), // 6: livekit.NegotiationRequest
|
||||
(*JoinResponse)(nil), // 7: livekit.JoinResponse
|
||||
(*TrackPublishedResponse)(nil), // 8: livekit.TrackPublishedResponse
|
||||
(*NegotiationResponse)(nil), // 9: livekit.NegotiationResponse
|
||||
(*SessionDescription)(nil), // 10: livekit.SessionDescription
|
||||
(*ParticipantUpdate)(nil), // 11: livekit.ParticipantUpdate
|
||||
(TrackType)(0), // 12: livekit.TrackType
|
||||
(*RoomInfo)(nil), // 13: livekit.RoomInfo
|
||||
(*ParticipantInfo)(nil), // 14: livekit.ParticipantInfo
|
||||
(*TrackInfo)(nil), // 15: livekit.TrackInfo
|
||||
}
|
||||
var file_rtc_proto_depIdxs = []int32{
|
||||
5, // 0: livekit.SignalRequest.offer:type_name -> livekit.SessionDescription
|
||||
5, // 1: livekit.SignalRequest.answer:type_name -> livekit.SessionDescription
|
||||
10, // 0: livekit.SignalRequest.offer:type_name -> livekit.SessionDescription
|
||||
10, // 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
|
||||
7, // 4: livekit.SignalRequest.mute:type_name -> livekit.MuteTrackRequest
|
||||
5, // 4: livekit.SignalRequest.mute:type_name -> livekit.MuteTrackRequest
|
||||
4, // 5: livekit.SignalRequest.remove_track:type_name -> livekit.RemoveTrackRequest
|
||||
6, // 6: livekit.SignalResponse.join:type_name -> livekit.JoinResponse
|
||||
5, // 7: livekit.SignalResponse.answer:type_name -> livekit.SessionDescription
|
||||
5, // 8: livekit.SignalResponse.offer:type_name -> livekit.SessionDescription
|
||||
3, // 9: livekit.SignalResponse.trickle:type_name -> livekit.TrickleRequest
|
||||
8, // 10: livekit.SignalResponse.update:type_name -> livekit.ParticipantUpdate
|
||||
9, // 11: livekit.SignalResponse.track_published:type_name -> livekit.TrackInfo
|
||||
10, // 12: livekit.AddTrackRequest.type:type_name -> livekit.TrackType
|
||||
11, // 13: livekit.JoinResponse.room:type_name -> livekit.RoomInfo
|
||||
12, // 14: livekit.JoinResponse.participant:type_name -> livekit.ParticipantInfo
|
||||
12, // 15: livekit.JoinResponse.other_participants:type_name -> livekit.ParticipantInfo
|
||||
12, // 16: livekit.ParticipantUpdate.participants:type_name -> livekit.ParticipantInfo
|
||||
17, // [17:17] is the sub-list for method output_type
|
||||
17, // [17:17] is the sub-list for method input_type
|
||||
17, // [17:17] is the sub-list for extension type_name
|
||||
17, // [17:17] is the sub-list for extension extendee
|
||||
0, // [0:17] is the sub-list for field type_name
|
||||
6, // 6: livekit.SignalRequest.negotiate:type_name -> livekit.NegotiationRequest
|
||||
7, // 7: livekit.SignalResponse.join:type_name -> livekit.JoinResponse
|
||||
10, // 8: livekit.SignalResponse.answer:type_name -> livekit.SessionDescription
|
||||
10, // 9: livekit.SignalResponse.offer:type_name -> livekit.SessionDescription
|
||||
3, // 10: livekit.SignalResponse.trickle:type_name -> livekit.TrickleRequest
|
||||
11, // 11: livekit.SignalResponse.update:type_name -> livekit.ParticipantUpdate
|
||||
8, // 12: livekit.SignalResponse.track_published:type_name -> livekit.TrackPublishedResponse
|
||||
9, // 13: livekit.SignalResponse.negotiate:type_name -> livekit.NegotiationResponse
|
||||
12, // 14: livekit.AddTrackRequest.type:type_name -> livekit.TrackType
|
||||
13, // 15: livekit.JoinResponse.room:type_name -> livekit.RoomInfo
|
||||
14, // 16: livekit.JoinResponse.participant:type_name -> livekit.ParticipantInfo
|
||||
14, // 17: livekit.JoinResponse.other_participants:type_name -> livekit.ParticipantInfo
|
||||
15, // 18: livekit.TrackPublishedResponse.track:type_name -> livekit.TrackInfo
|
||||
14, // 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
|
||||
}
|
||||
|
||||
func init() { file_rtc_proto_init() }
|
||||
@@ -896,30 +1080,6 @@ func file_rtc_proto_init() {
|
||||
}
|
||||
}
|
||||
file_rtc_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*SessionDescription); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_rtc_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*JoinResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_rtc_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*MuteTrackRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -931,7 +1091,67 @@ func file_rtc_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_rtc_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*NegotiationRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_rtc_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*JoinResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_rtc_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*TrackPublishedResponse); 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.(*NegotiationResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_rtc_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*SessionDescription); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_rtc_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ParticipantUpdate); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -951,6 +1171,7 @@ func file_rtc_proto_init() {
|
||||
(*SignalRequest_AddTrack)(nil),
|
||||
(*SignalRequest_Mute)(nil),
|
||||
(*SignalRequest_RemoveTrack)(nil),
|
||||
(*SignalRequest_Negotiate)(nil),
|
||||
}
|
||||
file_rtc_proto_msgTypes[1].OneofWrappers = []interface{}{
|
||||
(*SignalResponse_Join)(nil),
|
||||
@@ -959,6 +1180,7 @@ func file_rtc_proto_init() {
|
||||
(*SignalResponse_Trickle)(nil),
|
||||
(*SignalResponse_Update)(nil),
|
||||
(*SignalResponse_TrackPublished)(nil),
|
||||
(*SignalResponse_Negotiate)(nil),
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
@@ -966,7 +1188,7 @@ func file_rtc_proto_init() {
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_rtc_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 9,
|
||||
NumMessages: 12,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
|
||||
+28
-10
@@ -15,6 +15,8 @@ message SignalRequest {
|
||||
AddTrackRequest add_track = 4;
|
||||
MuteTrackRequest mute = 5;
|
||||
RemoveTrackRequest remove_track = 6;
|
||||
// when client needs to negotiate
|
||||
NegotiationRequest negotiate = 7;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,15 +33,17 @@ message SignalResponse {
|
||||
// sent when participants in the room has changed
|
||||
ParticipantUpdate update = 5;
|
||||
// sent to the participant when their track has been published
|
||||
TrackInfo track_published = 6;
|
||||
TrackPublishedResponse track_published = 6;
|
||||
// sent to participant when they should initiate negotiation
|
||||
NegotiationResponse negotiate = 7;
|
||||
}
|
||||
}
|
||||
|
||||
message AddTrackRequest {
|
||||
string name = 1;
|
||||
TrackType type = 2;
|
||||
// client ID of track, to match it when RTC track is received
|
||||
string cid = 3;
|
||||
string cid = 1;
|
||||
string name = 2;
|
||||
TrackType type = 3;
|
||||
}
|
||||
|
||||
message TrickleRequest {
|
||||
@@ -50,9 +54,13 @@ message RemoveTrackRequest {
|
||||
string sid = 1;
|
||||
}
|
||||
|
||||
message SessionDescription {
|
||||
string type = 1; // "answer" | "offer" | "pranswer" | "rollback"
|
||||
string sdp = 2;
|
||||
message MuteTrackRequest {
|
||||
string sid = 1;
|
||||
bool muted = 2;
|
||||
}
|
||||
|
||||
message NegotiationRequest {
|
||||
// empty
|
||||
}
|
||||
|
||||
message JoinResponse {
|
||||
@@ -61,11 +69,21 @@ message JoinResponse {
|
||||
repeated ParticipantInfo other_participants = 3;
|
||||
}
|
||||
|
||||
message MuteTrackRequest {
|
||||
string sid = 1;
|
||||
bool muted = 2;
|
||||
message TrackPublishedResponse {
|
||||
string cid = 1;
|
||||
TrackInfo track = 2;
|
||||
}
|
||||
|
||||
message NegotiationResponse {
|
||||
// empty
|
||||
}
|
||||
|
||||
message SessionDescription {
|
||||
string type = 1; // "answer" | "offer" | "pranswer" | "rollback"
|
||||
string sdp = 2;
|
||||
}
|
||||
|
||||
|
||||
message ParticipantUpdate {
|
||||
repeated ParticipantInfo participants = 1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user