From 9575b808933e1a0330f83b10f611ce3846a2acf7 Mon Sep 17 00:00:00 2001 From: Juliusz Chroboczek Date: Thu, 21 May 2020 22:30:31 +0200 Subject: [PATCH] Use mids instead of track ids for indexing labels. It turns out that track ids are not necessarily the same on the local and remote sides. Thanks to Ines Klimann for noticing the issue. --- client.go | 37 ++++++++++++++++++++++++++++++++++--- group.go | 14 ++++++++++++-- static/sfu.js | 23 +++++++++++++++++++++-- 3 files changed, 67 insertions(+), 7 deletions(-) diff --git a/client.go b/client.go index faff8c3..9b5713e 100644 --- a/client.go +++ b/client.go @@ -346,9 +346,28 @@ func addUpConn(c *client, id string) (*upConnection, error) { c.mu.Unlock() return } + + mid := getUpMid(pc, remote) + if mid == "" { + log.Printf("Couldn't get track's mid") + c.mu.Unlock() + return + } + + label, ok := u.labels[mid] + if !ok { + log.Printf("Couldn't get track's label") + isvideo := remote.Kind() == webrtc.RTPCodecTypeVideo + if isvideo { + label = "video" + } else { + label = "audio" + } + } + track := &upTrack{ track: remote, - label: u.labels[remote.ID()], + label: label, cache: packetcache.New(96), rate: estimator.New(time.Second), jitter: jitter.New(remote.Codec().ClockRate), @@ -957,8 +976,20 @@ func negotiate(c *client, down *downConnection) error { } labels := make(map[string]string) - for _, t := range down.tracks { - labels[t.track.ID()] = t.remote.label + for _, t := range down.pc.GetTransceivers() { + var track *webrtc.Track + if t.Sender() != nil { + track = t.Sender().Track() + } + if track == nil { + continue + } + + for _, tr := range down.tracks { + if tr.track == track { + labels[t.Mid()] = tr.remote.label + } + } } return c.write(clientMessage{ diff --git a/group.go b/group.go index 421f411..1827944 100644 --- a/group.go +++ b/group.go @@ -96,11 +96,21 @@ type upConnection struct { labels map[string]string } +func getUpMid(pc *webrtc.PeerConnection, track *webrtc.Track) string { + for _, t := range pc.GetTransceivers() { + if t.Receiver() != nil && t.Receiver().Track() == track { + return t.Mid() + } + } + return "" +} + func (up *upConnection) complete() bool { - for id, _ := range up.labels { + for mid, _ := range up.labels { found := false for _, t := range up.tracks { - if t.track.ID() == id { + m := getUpMid(up.pc, t.track) + if m == mid { found = true break } diff --git a/static/sfu.js b/static/sfu.js index f89f6cd..e801c1f 100644 --- a/static/sfu.js +++ b/static/sfu.js @@ -41,6 +41,7 @@ function Connection(id, pc) { this.pc = pc; this.stream = null; this.labels = {}; + this.labelsByMid = {}; this.iceCandidates = []; this.timers = []; this.audioStats = {}; @@ -647,12 +648,18 @@ async function gotOffer(id, labels, offer) { }; c.pc.ontrack = function(e) { + let label = e.transceiver && c.labelsByMid[e.transceiver.mid]; + if(label) { + c.labels[e.track.id] = label; + } else { + console.error("Couldn't find label for track"); + } c.stream = e.streams[0]; setMedia(id); }; } - c.labels = labels; + c.labelsByMid = labels; await c.pc.setRemoteDescription(offer); await addIceCandidates(c); @@ -1066,10 +1073,22 @@ async function negotiate(id) { if(!offer) throw(new Error("Didn't create offer")); await c.pc.setLocalDescription(offer); + + // mids are not known until this point + c.pc.getTransceivers().forEach(t => { + if(t.sender && t.sender.track) { + let label = c.labels[t.sender.track.id]; + if(label) + c.labelsByMid[t.mid] = label; + else + console.error("Couldn't find label for track"); + } + }); + send({ type: 'offer', id: id, - labels: c.labels, + labels: c.labelsByMid, offer: offer, }); }