WebRTC is used for peer-to-peer networking on the web, what does that mean? That means your browser, for example, can connect to another browser and share different types of data between them, like video, audio stream or just some JSON data fragments … For today’s example, we will learn how WebRTC works.
Divide & Conquer
WebRTC contains many classes and objects such as MediaStream, RTCPeerConnection, RTCDataChannel, etc. There are also some difficult words like NATS, Stunt, Signaling Server …
MediaStream
Before we start streaming video from one browser to another, the first thing we have to do is use the webcam data somehow. Because, we will be using the MediaStream API MediaStream API which provides the ability to capture microphone or webcam streaming on the device. Even if the data is not being sent, we can still display the webcam view inside the web page. All we have to do is ask our users if we want to give us that kind of permission, here’s how we do it using javascript.
1 2 3 4 5 6 7 8 9 10 11 12 | //we call getUserMedia to get stream navigator.getUserMedia({ video: true, audio: false },function(stream) { //Here we are atttaching our incoming stream //to the video element inside our web page var video = dcument.querySelector('video'); //inserting our stream to the video tag video.src = window.URL.createObjectURL(stream); }, function (err) {}); } |
Whenever we call this function. The browser will pop up a warning popup saying the app is trying to access the camera.
And if the user accepts, then we take the stream of using the camera session and integrate it into the web browser. So we can watch the video immediately.
RTCPeerConnection
After we have the public camera session in place, we can now send that session to any other browser, but how do we do that? We will use RTCPeerConnection for that Before explaining how RTCPeerConnection works, first we need to know a few points after the following line:
Signaling Servers
We cannot avoid some servers, even when the browsers are communicating with each other.
First of all, the browser needs to find another browser somehow to start talking to each other, that’s where the Signaling Server is.
This is a simplified version of starting to communicate with webRTC.
Suppose we want to stream video from Browser “Darth Vader” to browser “luke skywalker”, this is how the conversation will start Darth Vader hey Signaling Server, I want to connect with someone I know, you can also grant my Unique Identifier? (we call createOffer method)
Signaling Server
hey Darth Vader, sure i can give you a unique identifier, here’s one (this method will return a unique identifier number)
Darth Vader
thank you Signaling Server I have set this unique identifier for my “local descriptor” so It becomes my Unique Identifier (call the setLocalDescription method with the createOffer response returned)
Hello Luke skywalker, I am trying to start WebRTC connection with you, this is my Unique Identifier (currently we are sending this Unique Identifier to Luke skywalker browser, we can send the way we want, we can send it over the socket.the problem, the important part is that Luke skywalker somehow gets this data)
Luke skywalker
Hello Dad (Darth Vader), I heard you want to pass some data with me. I already have your unique ID, I will put that code in my remote descriptor so you know who I’m talking to (call setRemoteDescription with Darth Vaders’s unique identifier)
Hi Signaling Server, I want to accept an offer from my dad and I also want a Unique Identifier so my dad can find me (call the “generate answer” method)
Hello, Luke skywalker, sure you can get a unique Identifier below.
Thanks Luke skywalker, Signaling Server, I’ll put it in my local descriptor (call the setLocalDescriptor method with the response “createAnswer”).
Hey dad, it’s my unique identifier (send identifier in the same way).
Darth Vader
great son, i have cached, i will put it in my remote descriptor (call setRemoteDescriptor with Unique Identifier)
Now we can finally share our stream
Let’s do it together
Here is how we can implement the communication with the above description as follows
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | //this function is used to send some data via socket. to web server function send(message, dataToSend) { //sending logic HERE } //this function is used to listen to some messages from web server //via socket again function on(message, callback) { // recieve Logic here } //here we are configurating our RTCPeerConnection //we have to set some Signaling Server for it //on this case it's googles signaling server var configuration = { iceServers: [{ urls: "stun:stun.1.google.com:19302" }] }; // we create connection var darthWaderPc = new webkitRTCPeerConnection(configuration); console.log("RTCPeerConnection object was created"); console.log(darthWaderPc); //first we get our webcam stream //and set it to our rpcConnection navigator.getUserMedia({ video: true, audio: false }, function(stream) { //so you have 1 stream and can have multiple tracks //for example here we have only 1 track it's and video track // but we could also have audio track stream.getTracks().forEach(t=>darthWaderPc.addTrack(t)); }, function(err) { alert("Not stream found"); } ); //now we have to create offer //create offer asks signaling server to get some unique identifier darthWaderPc.createOffer().then(offer => { //We set our unique identifier to local descriptor darthWaderPc.setLocalDescription(offer); //now we have to send this unique identifier to another client //we send it to the web server first via socket and then web server will //send it to another client send("OFFER", offer); }); //here we have the second client initiated var lukeSkywalkerPc= new webkitRTCPeerConnection(configuration); //so when we finally connect two clients //this method will be called and will catch stream here //so we can for example attach it to our video element inside our page lukeSkywalkerPc.ontrack = (event)=>{ let stream = event.streams[0]; } //when the offer will arive to another client //it will set unique identifier to remoteDescription //and start to create answer and then send his unique identifier //to the first client on("OFFER", offer => { lukeSkywalkerPc.setRemoteDescription(offer); lukeSkywalkerPc.createAnswer().then(answer => { lukeSkywalkerPc.setLocalDescription(answer); send("ANSWER", answer); }); }); //finally when the first client gets answer everything is set up //so they first client can share stream with another client on("ANSWER", answer => { darthWaderPc.setLocalDescription(answer); }); |
So we have 2 instances of RTCPeerConnection and they are just sharing their unique identifier with each other.
summary
WebRTC may seem intimidating, but it’s really nothing but starting a chat with two browsers that have a unique identifier. The joy you’ll get when you first share some video streams between two browsers is really worth spending a few hours or days learning it.
You can read more about webrtc through this course: https://www.tutorialspoint.com/webrtc/index.htm