How to NOT use Trickle ICE in the browser? (kurento utils js)

801 views
Skip to first unread message

sergei

unread,
Nov 10, 2017, 6:08:24 AM11/10/17
to kurento
That would be a strange wish, so I'll explain why I need it first.

I started with "kurento-tutorial-java/kurento-one2many-call" demo project and it works fine.  
Then I added code to support multiple broadcasters (each with its own pipeline and stream id), it's also fine.
Then I needed to modify the server app to fetch video from Flashphoner, and it didn't work. It had to work differently with it though, because Flashphoner needs to receive SDP first (but the tutorials always generate SDP in browser first) and it also doesn't use Trickle ICE (candidates must be sent inside SDP offer/answer).

From there I decided that I must test if the same SDP negotiation scheme would work with browsers (to get an idea of the source of the problem). Therefore I need to modify the browser-side js code so that it would:  
• answer to SDP offer received from server, instead of making the offer in the browser
• not use Trickle ICE — it must receive and send ICE candidates inside SDP payloads.

This is where I got stuck. Because while the docs/comments for KMS Java API are quite good, I found the documentation for kurento js utils very sparse, and as I don't really know js and all front-end stuff, it's really difficult to infer it from the source code.

So, how can I bundle ICE candidates into SDP answer in the browser when using kurento js library?

phom...@gmail.com

unread,
Nov 10, 2017, 7:54:21 AM11/10/17
to kur...@googlegroups.com

Do-Able!  Don't send answers/offers or ice candidates.  Wait for ice done event and send the sdp, then use that as offer or answer.

That's a vague answer, let me know if you need more information,

--
You received this message because you are subscribed to the Google Groups "kurento" group.
To unsubscribe from this group and stop receiving emails from it, send an email to kurento+u...@googlegroups.com.
To post to this group, send email to kur...@googlegroups.com.
Visit this group at https://groups.google.com/group/kurento.
To view this discussion on the web visit https://groups.google.com/d/msgid/kurento/731eddf1-01dc-40d5-bff8-15c950e90261%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

sergei

unread,
Nov 10, 2017, 8:28:34 AM11/10/17
to kurento
But how can I wait for ice done event?

I've checked available methods in `WebRtcPeerSendonly` in chrome debugger, and there's nothing similarly named.
I guess if I simply answer to SDP as soon as it comes from the server by using webRtcPeer.processOffer, the resulting SDP answer won't contain ICE candidates?

phom...@gmail.com

unread,
Nov 10, 2017, 11:33:17 AM11/10/17
to kur...@googlegroups.com

You do it in the icecandidates handler.  If it is not a candidate, it must be done (I think)

Mine looks like this.  I send it all to the backend and let java figure out what to do when by 'connectionType'


    function iceCandidateEventHandler(event) {
        time = new Date();
        if(! event.candidate) {          
            console.log("[" + time.toLocaleTimeString() + "] " + "iceCandidateEventHandler done"+":"+cid);
            myPeerConnection.addIceCandidate(event.candidate);
            myMessage = {
                'mydetv':mydetv,
                verb : 'iceCandidatesDone',
                connectionType: connectionType,
                role: role,
                cid: cid,
                sdp: myPeerConnection.localDescription
            };
            sendMessage(myMessage);
            return;
        }
        else {
            console.log("[" + time.toLocaleTimeString() + "] " + "iceCandidateEventHandler candidate:"+event.candidate);
                myMessage = {
                    'mydetv':mydetv,
                    verb : 'iceCandidate',
                    connectionType: connectionType,
                    role: role,
                    cid: cid,
                    candidate: event.candidate
                };
                sendMessage(myMessage);
        }
    }

sergei

unread,
Nov 13, 2017, 3:52:52 AM11/13/17
to kurento
Thanks for the idea. This looks a bit strange though. What is the point in "myPeerConnection.

addIceCandidate(event.candidate);" line, if it's inside the branch where it's not a candidate? And, regardless, it should be used for ICE candidates from the remote endpoint, not the locally discovered ones, isn't it?

Does this code actually work for you?

phom...@gmail.com

unread,
Nov 13, 2017, 4:07:24 AM11/13/17
to kur...@googlegroups.com
Works great.  I admit I have much more code than I need: much more is being sent to the backend to sort out.  I'm proficient in java programming but not in javascript.

My application does browser<->browser AND kurento<->browser.  Sometimes I do trickle ice (process answer/offer), sometimes I don't (process iceCandidatesDone);

Does this answer the question 'What is the point in myPeerConnectionaddIceCandidate(event.candidate)'

var myPeerConnection = new RTCPeerConnection(myRTCPeerConnectionConfig);
myPeerConnection.onicecandidate             = iceCandidateEventHandler;

That event is for the locally created candidates AFAIK, correct me if I am wrong.  The remote candidates are sent via websockets from the other side and looks like this:

    function iceCandidate(message) {   
        time = new Date();
        myIceCandidate = message.iceCandidate;     
        rtcIceCandidate = new RTCIceCandidate(myIceCandidate);   
        myPeerConnection.addIceCandidate(rtcIceCandidate)
            .catch(function(err) {
                console.log("[" + time.toLocaleTimeString() + "] " + "iceCandidate error "+err.name+":"+err.message);
            });    
       }

Paul

sergei

unread,
Nov 13, 2017, 4:09:59 AM11/13/17
to kurento
I thought you don't need to add locally created candidates because they are already known to the webrtc implementation. Not sure if this is 100% correct.
Thanks for the explanation, I think I should try this.

phom...@gmail.com

unread,
Nov 13, 2017, 4:13:35 AM11/13/17
to kur...@googlegroups.com
This helped me.  The problem with most examples is

1) they don't have the signaling shown

2) they do both sides sending/receiving video (like this example) when
you are trying to focus on just one way

https://developer.mozilla.org/en-US/docs/Web/API/WebRTC_API/Signaling_and_video_calling


sergei

unread,
Nov 13, 2017, 4:27:16 AM11/13/17
to kurento
I tested this approach within chrome debugger and, unfortunately, the `onicecandidate` callback is always called with real candidates, there is nothing telling that there are no more candidates.
So the question "how to detect ICE done event" is still open…

phom...@gmail.com

unread,
Nov 13, 2017, 4:36:49 AM11/13/17
to kur...@googlegroups.com
I forgot to mention: the other problem with examples
#3 they are old and not really relevant anymore.

Your statement is true and my code still works without myPeerConnection.addIceCandidate(event.candidate);

I've tested this every which way, and I always get an iceCandidatesDone event on the backend.  I don't always use it, but I see it come from the browser no matter what.  Did you test this on something that is working, or something that is not?  If the implementation is not working then you are probably also getting ice failed which I wrote as such:

    function iceConnectionStateChangeEventHandler() {
        time = new Date();
        console.log("[" + time.toLocaleTimeString() + "] " + "*** ICE connection state changed to: "+myPeerConnection.iceConnectionState+":"+cid);

        switch(myPeerConnection.iceConnectionState) {
            case "closed":
                break;
            case "failed":
                myMessage = {
                    'mydetv':mydetv,
                    verb : 'iceFailed',

                    connectionType: connectionType,
                    role: role,
                    cid: cid,
                    sdp: myPeerConnection.localDescription
                };
                sendMessage(myMessage);
                break;
            case "disconnected":
                break;
            default:
                break;
        }
    }


Paul
--
You received this message because you are subscribed to the Google Groups "kurento" group.
To unsubscribe from this group and stop receiving emails from it, send an email to kurento+u...@googlegroups.com.
To post to this group, send email to kur...@googlegroups.com.
Visit this group at https://groups.google.com/group/kurento.

sergei

unread,
Nov 13, 2017, 4:45:05 AM11/13/17
to kurento
I simply looked at `onicecandidate` parameter values in working js code which is almost unchanged kurento example. The parameter in `onicecandidate` is always a `RTCIceCandidate` object, so it can't be used to detect if ICE search is completed.
And how do you use this `iceConnectionStateChangeEventHandler` function? (which code should call it)

btw, looking at the source at https://doc-kurento.readthedocs.io/en/stable/_static/langdoc/jsdoc/kurento-utils-js/WebRtcPeer.js.html#line220, there might be another parameter in options: `oncandidategatheringdone` maybe this is what's really should be used. Gonna try it now…
Reply all
Reply to author
Forward
0 new messages