diff --git a/relay.go b/relay.go index 56a6389..a2ce897 100644 --- a/relay.go +++ b/relay.go @@ -9,6 +9,7 @@ import ( "fmt" "io" "log" + "sync" "time" "github.com/pion/rtcp" @@ -186,6 +187,10 @@ func newCall(mainOffer receivedSignal, r activeRelay) { log.Printf("Starting new call: %s", mainOffer.callHash) + // Ice candidates mutex + var candidatesMux sync.Mutex + pendingCandidates := make([]*webrtc.ICECandidate, 0) + // Since we are answering use PayloadTypes declared by offerer mediaEngine := webrtc.MediaEngine{} err := mediaEngine.PopulateFromSDP(mainOffer.sdp) @@ -195,8 +200,13 @@ func newCall(mainOffer receivedSignal, r activeRelay) { return } + // Enable trickling + s := webrtc.SettingEngine{} + s.SetTrickle(true) + // Create the API object with the MediaEngine - api := webrtc.NewAPI(webrtc.WithMediaEngine(mediaEngine)) + api := webrtc.NewAPI(webrtc.WithMediaEngine(mediaEngine), + webrtc.WithSettingEngine(s)) // Setup config peerConnectionConfig := webrtc.Configuration{ @@ -214,6 +224,28 @@ func newCall(mainOffer receivedSignal, r activeRelay) { // Close peer connection defer mainPeerConnection.Close() + // Forward ice candidates + mainPeerConnection.OnICECandidate(func(c *webrtc.ICECandidate) { + if c == nil || r.closed { + return + } + + // Lock the list of candidates + candidatesMux.Lock() + defer candidatesMux.Unlock() + + desc := mainPeerConnection.RemoteDescription() + + if desc == nil { + // Add the signal to the pending list + pendingCandidates = append(pendingCandidates, c) + } else { + // Send the signal directly + sendSignal(mainOffer.callHash, mainOffer.peerID, c.ToJSON()) + } + + }) + // Allow us to receive 1 audio & 1 video track if _, err = mainPeerConnection.AddTransceiverFromKind(webrtc.RTPCodecTypeVideo, webrtc.RtpTransceiverInit{Direction: webrtc.RTPTransceiverDirectionRecvonly}); err != nil { @@ -316,16 +348,19 @@ func newCall(mainOffer receivedSignal, r activeRelay) { return } - // Forward ice candidates - mainPeerConnection.OnICECandidate(func(c *webrtc.ICECandidate) { - if c != nil { - sendSignal(mainOffer.callHash, mainOffer.peerID, c.ToJSON()) - } - }) - // Send anwser if !r.closed { sendSignal(mainOffer.callHash, mainOffer.peerID, answer) + + // Warning ! Do not put this outside a specific block + candidatesMux.Lock() + + // Send pending ice candidates + for _, val := range pendingCandidates { + sendSignal(mainOffer.callHash, mainOffer.peerID, val) + } + + candidatesMux.Unlock() } // Keep a list of active tracks @@ -401,6 +436,7 @@ func newCall(mainOffer receivedSignal, r activeRelay) { // Send ice candidates newPeerConnection.OnICECandidate(func(c *webrtc.ICECandidate) { if c != nil { + println("new ice candidate 2") sendSignal(r.callHash, newMessage.peerID, c.ToJSON()) } })