The writer is an engineer at WebRTC Ventures. At RTC 2018, senior software engineers from WebRTC Ventures will share their experience on WebRTC development. Welcome to the RTC developer community to share your experience with more WebRTC developers.



An easy way to see how WebRTC works is by learning how to build a video conferencing App using WebRTC and Kurento Media Server. Although WebRTC was originally intended to establish peer-to-peer connections, media servers are useful for adding features such as recording and multi-party calls. We will use Kurento, an open source media server, to support the connection of our App with more than two users. Next, let’s review the overall process. We break the process of establishing a connection through WebRTC into three steps:

1. The browser obtains media devices (such as cameras and microphones). 2. Each peer exchanges information with all other peers. 3. Once the information is exchanged, peers can be connected via the media server and start communication.

Note that we still need a signaling server for exchanging messages and a STUN or TURN server for NAT penetration. In addition, we have added a media server to direct the stream to the peers.

Our App includes a login screen where the user enters his name and the number of the room he wants to join and talk to, where he can see other participants in the video conference.

The code for this tutorial is available in a public directory on Github, and you can clone it to your local location and use it, or follow the step-by-step instructions in this article. If you choose the latter, download adapter.js and kurento-utils.min.js, which we will use later.

We use JavaScript as the programming language and Node.js as the runtime engine, so you’ll need to install Node if you don’t have it. We will also use Docker to run the media server locally.

Let’s start by creating a new folder, which will be the project folder.

Create a folder inside it called Public, and now copy the downloaded Library there. Using the command line, navigate to the project folder and enter the following commands to install the required environment. An Internet connection is required to download the Library.

Also, to start the media server, enter the following command on the command line.

To start, we need to create an HTML file containing two DIVs, one for login and one for actual communication. Also, we add kurento-utils Library, which requires adapter.js, socket. IO client library and client.js files.

Using your favorite text editor, create a new folder, paste the following code and save it in the project folder. Name it index.html in the public folder.

Good, now let’s create the JS file on the client side. We start by getting references for web elements and variables that declare customer usernames and room numbers. We also need to declare a variable to store a list of meeting participants. Then, just like the one-to-one version of the app, we connect to the signaling server using socket. IO and register a click event that sends the first message to the server, which is a “join the room” message. Instead of using the socket.emit() function directly this time, we’ll use a sendMessage() function that is defined at the bottom of the file. We also need to declare the handlers for the server information.

Use a text editor to create the client.js file and save it in the public folder of your project.

Next, we create the server. We first add the required Node packages. We then declare a pair of variables to store Kurento client references and a queue to store the ICE candidates received before the Kurento breakpoint is established.

Next, set the URL of App and Kurento server to AS_URI and WS_URI. Note that at run time, we use package as little as possible to provide support for setting these values on the command line.

We then set up a static host to the public folder and define the handlers for events received through socket. IO. Finally we set up a function to get the Kurento client reference from the media server and set the App listener to port 3000.

Use your favorite text editor to create the server.js file and save it in the project folder.

Now to continue the conversation process, on the server side, after we receive the message from the client to join the room, we call the joinRoom function, which uses the getRoom function to manage the room.

In the getRoom function, when the first customer arrives, we create a new room, and a new Kurento MediaPipeline. The pipeline is split with the room and a list of empty participants. When another customer arrives, we don’t need to create a new pipeline, so we just add the customer to the room.

Back in the joinRoom function, after we get the room, we create a Kurento WebRTC breakpoint, which is assigned to the user. Then if there are any ice candidates in the queue, it will be added via the addIceCandidate function that calls the breakpoint, and we set up the onIceCandidate event.

The function ends by sending two messages: one to notify other users in the room that they have a new actor, and another to notify the current user of the existing actor. Add the following function to server.js.

On the client side, two functions manage the server to send the newParticipantArrived and existingParticipants events, they are the receiveVideo and onExistingParticipants functions.

In the onNewParticipants function, we first establish video elements to present the flow and create a user as the current participant. The user object will store the newly created video element and an rtcPeer field.

After storing the user object into the global participant array, we implement Kurento’s API object, assign it to rtcPeer filed, and prepare a request to start the sending process. End the function by calling the receiveVideo function.

Each function has its own internal function for the onOffer and onIceCandidate events, which are fired by the rtcPeer object and, when ready, are responsible for sending the actual request and the ICE request to the server, Send receiveVideoFrom and candidate information. Add the following code to client.js.

So far, we have completed the first step and started the mailing process.

On the server side, receiveVideoFrom and candidate events are handled by the receiveVideoFrom and addIceCandidate functions. A third function called getEndpointForUser is also used to restore Kurento WebRTC breakpoints associated with each user.

The ReceiveVideoFrom function is very simple; when it gets the appropriate breakpoint, it processes the request, generates a reply, sends it to the client and begins collecting the ICE candidates. In the same way, the addIceCandidate function receives the ICE Candidate and adds it to the appropriate breakpoint. GetEndpointForUser gets the correct breakpoint to receive the video. Add the following code to server.js.

Then on the client side we need to handle the receiveVideoAnswer and the candidates events sent by the server, which we do by using the onReceiveVideoAnswer and addIceCandidate functions. Add them to the client.js file.

Using the code above, we complete the sending process, and step 2 is complete.

When we use the Kurento-utils library on the client side, there is no additional action for the client. Therefore, Step 3 is automatically completed.

Now it’s time to start the App, from the command line, go to the project folder and type the following command

node server.js

Then, using Google Chrome or Mozilla Firefox, open http://localhost:3000 in three or more tabs, enter a different participant name and the same room number, and click enter.