Webrtc adding ice candidate to remote peer - javascript

Below is the sample webrtc peer to peer connection code from google webrtc tutorilal. this link. I couldn't understand properly ,how addIceCandidate() add its Ice candidate to its remote peer using onIceCandidate(). what does event.candidate means here. A clear explanation would be appreciated
function onIceCandidate(pc, event) { //pc1.onicecandidate
if (event.candidate) {
getOtherPc(pc).addIceCandidate(
new RTCIceCandidate(event.candidate)
).then(
function() {
onAddIceCandidateSuccess(pc);
},
function(err) {
onAddIceCandidateError(pc, err);
}
);

When peer A has discovered an ICE candidate (a potential route which could be used to communicate), it needs to send this ICE candidate to peer B (and vice versa). Peer B then adds that ICE candidate to its connection. Both peers exchange ICE candidates this way until they have found the optimal route that both are able to use to communicate with each other directly.
In that simple sample, peer A and B seem to be in the same machine, so the (dummy) getOtherPc function can get a handle of "the other peer" and you can directly use its addIceCandidate method. In practice however you will have to send that ICE candidate using a signalling server; some other way in which the peer can exchange the information across a network. Typically that signalling server will use a websocket connection via which information can be relayed in near-realtime.

Related

what triggers the webRTC API to connect to stun server

Don't know if this example is correct
The process, call new RTCPeerConnection() then createOffer() then setLocalDescription()
Then I wait for onicecandidate take what it gives and first send the offer and second the icecandidates through the signal server to the other peer
Then the other peer takes the received offer into setRemoteDescription(offer) then the received icecandidates into addIceCandidate(icecandidates) then calls createAnswer() this gives an answer to put in setLocalDescription(answer) this triggers onicecandidate take these icecandidates with the answer=offer and send them back to the other peer
The other peer takes the answer into setRemoteDescription(answer) then the received icecandidates into addIceCandidate(icecandidates)
I think in this example the connection will work when testing inside local network but what if it doesn't because its not a local network, at what step in this example will the API call the STUN server and what other functions do I need to call if it does call the STUN server?
I've found that one way to generate BIND requests to be sent to the STUN server right away is to set the iceCandidatePoolSize option in the configuration to be > 0.
config = {iceServers: [{urls:stun:stunserver.stunprotocol.org}], iceCandidatePoolSize: 1};
peerConnection = new RTCPeerConnection(config); // pretty much starts to resolve the DNS name and sends BIND requests right away.
Hope this helps.
Also: this link is chock-full of great suggestions to troubleshoot webrtc connections.
You need to specify a STUN server in the peer connection's configuration. E.g.:
pc = new RTCPeerConnection({iceServers: [{urls: "stun:stun.1.google.com:19302"}]});
There are no other methods to call, provided it works on a LAN already. You should see additional calls to onicecandidate from this, compared to before. That's it.
Note that a couple of the things you describe happen in parallel, but in short, what triggers the browser to connect to the STUN server is setLocalDescription. It causes the browser's built-in ICE agent to kick off its candidate gathering process for this connection, and STUN is part of that.

Both WebRTC peers initiate ICE restart simultaneously

I am fairly new to webRTC. The problem pertains to ICE restart. Let's say there are 2 peers connected using webRTC and one of them loses connection. Now, the peer connection will first go into "disconnected" state. And shortly after, if there is still no connection, goes into "failed" state.
Now, I understand once this failed state is reached, I have to perform an ICE restart. The problem is that even though one peer loses connection, both peers will report "failed" state and try to perform ICE restart, which I believe should be problematic. Here is a snippet of the code:
if (peer.localConnection.iceConnectionState == "failed") {
// create an offer
peer.localConnection.createOffer({
iceRestart : true
}).then(function(offer) {
peer.localConnection.setLocalDescription(offer);
// forward the offer to the signaling server
var msg = createMsg("OFFER", myId, peerId, offer);
sendToSignallingServer(msg);
}, function(error) {
//error
});
}
I understand that upon finding that there are now two offers, one of the peers should perform a "rollback" using RTCSessionDescription("rollback"). But I am confused whether this will work or not since both the peers might try to perform rollback.
How I can I make sure that only one peer performs a rollback?
One way to avoid the situation (as rollback is not widely implemented yet) is to only do the ice restart when your side of the connection sent the initial offer.

Audio/Voice over webRTC

I am trying to implement a one directional voice transmission with webRTC and php as a server side.
Looking at the samples, I fail to understand the webRTC mechanism.
The way I see it, the flow should look like this:
Caller and recipient register on server
Recipient listens for incoming calls
Caller asks server for recipient's IP
Server sends IP to caller
Caller connects to recipient directly
However the sample code, (that runs on a local machine)
function call() {
trace('Starting call');
var servers = null;
var pcConstraints = {
'optional': []
};
pc1 = new RTCPeerConnection(servers, pcConstraints);
trace('Created local peer connection object pc1');
pc1.onicecandidate = iceCallback1;
pc2 = new RTCPeerConnection(servers, pcConstraints);
trace('Created remote peer connection object pc2');
pc2.onicecandidate = iceCallback2;
pc2.onaddstream = gotRemoteStream;
trace('Requesting local stream');
navigator.mediaDevices.getUserMedia({
audio: true,
video: false
})
.then(gotStream)
.catch(function(e) {
alert('getUserMedia() error: ' + e.name);
});
}
Does not use ip address or any kind of identification token that could be translated into IP.
How could that be ?
To get started you will need to provide some kind of signaling channel between your clients. Most people are using some protocol (typically JSON based or SIP) over WebSockets to something like Node.js, SIP server or message broker on the backend which can then bridge between the two clients. You can pretty much send blobs of data that are pulled directly from the WebRTC PeerConnection. This includes SDPs, ICE candidates, etc. The PeerConnection can directly consume the data generated from the other peer so you don't have to deal with formatting the data. Just pack it into a JSON object and send it to Node over a WebSockets and let Node send it out to the other side. Its up to you to design how registered endpoints find each other and create this bridge.
We used MQTT over WebSockets to do this. In our model each client subscribes on their own MQTT topic and each side can publish messages to the other client on those topics. Clients register these topics with a back end service that is subscribed on a topic as well or you can use retained messages to let the MQTT broker manage the topics. You can read more about our approach here: http://www.wasdev.net/webrtc. We open sourced the signaling protocol and you can use any open MQTT broker for this. We also created SDKs including an AngularJS module you can play with here: http://angular-rtcomm.wasdev.developer.ibm.com/

Getting WebRTC IceCandidates before createOffer or createAnswer

During establishing the video call ice candidates gathereing is started after the call to createOffer or createAnswer. I'd like to get all local ice candidates for the local peer before I call createOffer or createAnswer. This way I'll have all of them set in sdp description and there will be no need to send them separately to remote peer as they will go all together in sdp. Is it possible?
UPD:
All I want is to gather Ice candidates and keep them. After I want to create offers and asnwers but without of waiting for gathering of candidates will fininsh. Also How to add Ice candidates to description manually? And Is it possible to disabale Ice candidates gathering without recreating RTCPeerConnection?
Candidate gathering only starts when you call setLocalDescription.
If you want an SDP with all the candidates, wait for the onicecandidate event without a candidate and inspect the peerconnection's localDescription.sdp which contains all candidates gathered so far.
You can reduce the delay by setting icecandidatepoolsize - then the browser will try and pre-gather candidates before Offer/Answer.
see:
https://github.com/pipe/two/blob/master/index.html#L181
According to https://developer.mozilla.org/zh-CN/docs/Web/API/RTCPeerConnection/onicecandidate
When onicecandidate event in callback is null, issue that the peer connection has gather ice candidate complete. So at that time Create offer to other peer connection and the Offer's SDP info will contain 'a=candidate' attribute.
Reference: https://aggresss.github.io/webrtc-samples/src/content/peerconnection/pc1-mod/

WebRTC: How to add stream after offer and answer?

I am working on webRTC video calling. I got datachannel successfully implemented. Now I would like to add video stream to the same peer connection.
I have read that stream should be added before answer and offer. Is there a way to add stream after answer or offer?
In case I have added stream before offer or answer, how could I stop streaming and start it again when needed?
Could there be any issues in maintaining so many streams?
To add stream after creating complete signalling, the Peer connection should renegotiate with stream.
pc1.addstream(stream)
Then once again create offer and send it to other Peer.
Remote peer will add stream and send answer SDP.
To stop streams:
stream.stop();
pc1.removeStream(stream);
In my experience, what Konga Raju advised didn't work. I couldn't send an "updated offer" and have the video streaming actually happen.
I found that this sequence of events works for my case, in which I wish to stream video from peer 1 to peer 2.
set up some way for the peers to exchange messages. (The variance in how people accomplish this is what makes different WebRTC code samples so incommensurable, sadly.)
On each side, set up handlers for the important signalling events. (Some folks have reported that you need to create these handlers at special times, but I haven't found that to be the case.
) There are 3 basic events:
an ice candidate sent from the other side ==> call addIceCandidate with it
an offer message ==> SetRemoteDescription & make an answer & send it
an answer message ===> SetRemoteDescription
On each side, create the peerconnection object with the event handlers we care about: onicecandidate, onremovestream, onaddstream, etc.
ice candidate pops out of the peerconnection object ===> send it to other side
When both peers are present and all the handlers are in place, peer 1 gets a trigger message of some kind to start video capture (the getUserMedia call)
Once getUserMedia succeeds, we have a stream. Call addStream on the peer connection object.
Then peer 1 makes an offer
Due to the handlers we set up earlier, peer 2 sends an answer
Concurrently with this (and rather opaquely), the peer connection object starts producing ice candidates. They get sent back and forth between the two peers and handled (steps 2 & 3 above)
Streaming starts by itself, opaquely, as a result of 2 conditions:
offer/answer exchange
ice candidates received, exchanged, and handled
I haven't found a way to add video after step 9. When I want to change something, I go back to step 3.
MediaStream should be added to peerconnection first only then exchange of offer, answer ,candidates should be done. If the onAddStream() is called ,that mean you are receiving the remote video.

Categories

Resources