The browser used is Chrome... I have the caller and receiver code to generate SDP and ICE candidates. I get the caller code to generate proper SDP and ICE candidates with sd
(It sounds from comments that you're caching ICE candidates. Don't do that. I also suspect timing issues may be behind loss of some candidates.)
The whole point of Trickle ICE is to trickle candidates, that is, send candidates as soon as they become available.
With WebRTC, your app is responsible for signaling between peers, which is time-sensitive. So:
pc.localDescription
no later than in the setLocalDescription
success callback.pc.onicecandidate
to start firing immediately after that callback. Send them.This is true on both sides (for offer and answer). What you want to see on the wire is:
offer, candidate, candidate, candidate
and the other way:
answer, candidate, candidate, candidate
What not to do:
setRemoteDescription
when an offer comes in on the receiving end for any reason, or it wont be ready to receive candidates.Update 2:
Your sdp says a=recvonly
and not a=sendrecv
, which means the receiver is resigned to receive only, without send anything in return. One of two things can cause this:
offerToReceiveVideo:false
and/or offerToReceiveAudio:false
.pc.addStream
in time for (before) pc.setLocalDescription
.The second can happen if there's a race between getUserMedia
and receiving an offer.
Update 3:
If all else fails, compare to working code. I've shared a cross-tab demo before in other answers, but it only sent video, didn't receive any.
Here's a modified version of that demo that only receives video from the remote camera instead. As usual, open it in two tabs in the same browser.
Note that in Firefox, after you hit Call
, you have to physically focus the other tab before it allows access to the camera.
What you are dealing with is called bundeling. Offerer and answerer agree to bundle all ICE transports into a single ICE transport. Therefore you only get a single ICE candidate for the first m-section.
The offerer is still giving you all these ICE candidates for the video m-section, because it does not know if the answerer is going to agree to use bundle.
As AlexD points out in his answer you can influence this behavior on the offerer side via the "bundlePolicy". "maxBundle" as policy will for example result in the offerer assuming the answerer is going to understand bundleling and therefore only create ICE candidates for a single transport.
But as long as the offerer is offering bundle the answerer is going to use it if it supports it.
I was able to solve this by setting:
rtcConfiguration.bundlePolicy = "max-compat"
See: http://w3c.github.io/webrtc-pc/#dom-rtcbundlepolicy-max-compat