Skip to content

Need clarification on Kurento’s API to connect webRTCEndpoint to RTPEndpoint

I am attempting to use Kurento’s bridging of webRTCendpoint to RTPendpoint. The webRTCendpoint client is a Chrome browser. The RTPendpoint client is a SIP server (proxy/B2BUA). Here is the basic code or pseudo-code I have (I am using Kurento-client.js in my app server):

//On receipt of offer from the WebRTC Browser-Peer
mySignalling.on('sdpOffer', function(sdpOffer) { //Action starts!
  //Create Mediapipeline so that endpoints can be created
  kurentoClient.create('MediaPipeline', function(error, pipeline) {
    pipeline.create('webRtcEndpoint', function(error, myWebrtcEndpoint)  {
      //Get ICE Candidates from webRTC endpoint to send to browser
      mySignalling.on('candidate', function(candidate) {
      myWebrtcEndpoint.on('OnIceCandidate', function(event) {
        var candidate = kurento.register.complexTypes.IceCandidate(event.candidate);
        mySignalling.send(candidate); //Send ICE candidate to webRTC browser peer
      pipeline.create('rtpEndpoint', function(error,myRtpEndpoint) {
        myWebrtcEndpoint.connect(myrtpEndpoint,function(error){ });
        myWebrtcEndpoint.processOffer(sdpOffer, function(error, sdpAnswer) {
          mySignalling.send(sdpAnswer);  //Send answersdp to browser
          myRtpEndpoint.getLocalSessionDescriptor(function(error, sdpRTP) {
            mySignalling2.send(sdpRTP); //Send SDP to Asterisk as part of SIP INVITE

I have several questions:

  1. Is the overall structure correct?
  2. What is the use of webRTCEndpoint.gatherCandidates? The documentation says that it must be called after processOffer. Why? How is it connected to the addIceCandidate method?
  3. The RTPendpoint gets connected to the webrtcEndpoint but how do I control the RTP profile to be generated by the RTPEndpoint generateOffer? I mean, how do I, for example, get a RTP/AVPF and not RTP/AVP from the RTPEndpoint? If not, and the AVPF has to be mapped to AVP, will Kurento handle the “F” in the AVPF while bridging from AVPF to AVP.

I have not added, for simplicity, error processing, OnIceGatheringDone event handling, provision for multiple-users/sessions, etc.

As a side, I am constructing my own SIP requests in the app server and processing the SIP responses. I will be changing, if required, the SDPs generated by the RTPEndpoint.generateOffer, if required. Will come to that point, when I get over this initial hurdle!


1) It looks fine. You can finish the WebRtcEndpoint negotiation before creating the RtpEndpoint, if you’d like. Also, you’re missing the call to gatherCandidates, which is covered in your next question.

2) gatherCandidates is used to signal de WebRtcEndpoint to start harvesting ICE candidates. That’s trickle ICE, and it’s an optimisation of the ICE protocol: candidates are emitted when discovered, and sent to the other peer for probing. This speeds up connection times, as a valid candidate can be found before all are harvested (which can take up to 20 seconds or more). The WebRtcEndpoint needs to send the candidates to the remote peer, while the candidates received from the remote peer are processed with the addIceCandidate method. If you call gatherCandidates before processing the offer or generating the answer, those candidates will be added to the SDP offer or answer, and you’ll be using Vanilla ICE.

3) If you are going to use the RtpEndpoint for emitting only, I’d recommend providing a mangled SDP with the options you need, and having the endpoint process that offer. If you are going to send to Wowza, for instance, you can fix the IP and port where the Wowza Media Server expects the RTP flow.