Your free e-book!

See when it is not worth using Scrum.
"Why Scrum Doesn't Work" Download

Real time communication – WebRTC tutorial

Web Real-Time Communication in the browser – WebRTC tutorial

How many of your friends are still using Skype or any kind of native software to have a video chat? In the era of Google Hangouts, Meet or Discord you don’t need any other application than the browser of your choice. The reason is that our browsers became powerful platforms that can, besides of showing formatted texts, render graphics, access your devices and stream data using complex network protocols. Today it’s better to provide a single native platform, than many specialised applications for different needs.

One of such functionalities built-in the browser is Web Real-Time Communication (WebRTC) module, that allows you to build skype-like web apps. They can use your mic and camera to stream data between other browsers bidirectionally. In this article we’re going to get familiar with basics of WebRTC and build simple video chat application.

WebRTC – in detail

Web Real-Time Communication is an open source C++ framework that allows real-time communications in the web. It’s integrated in the most of the web browsers like e.g. Chrome, Opera or Firefox and it’s standardized in WebRTC API maintained by W3C. It’s ready to use by web developers. WebRTC is built of many smart technologies around network protocols and audio/video processing. The most problematic part of such communication is transferring data directly between the browsers in the web. As the computers are hidden behind network address translation units (NAT), it’s not trivial to send data directly to another PC. WebRTC uses Interactive Connectivity Establishment (ICE) technique that uses STUN or (more advanced) TURN] protocol to determine the optimal path for network packets. Data being send over the network cables should also be properly compressed and optimized. Browsers are also supplied with the best audio/video codecs that allow to prepare such media streams efficiently.

WebRTC architecture –

Let’s build the simple chat application


Some parts of WebRTC API are incompatible between different browsers. To provide a generic solution we can use a polyfill package called adapter.

For simplification, in our examples we will use a small index.html file with a few video elements in the body:

<video playsinline autoplay></video>

and adapter script dependency:

<script src=””></script>

You can also use the package from npm or bower repository to build your source package with webpack or other module bundler.

Javascript calls can be triggered from browser’s console (hit F12) or your .js source file.

Accessing peripherals (ex.1)

First of all, we need access to the peripherals – microphone, speaker and camera. To achieve this, we can use MediaDevices.getUserMedia() function. It returns a Promise that resolves to a MediaStream object, that includes audio and video tracks. This action requires user permission to access the devices. getUserMedia() takes constraints object specifying the media types requested – we can choose audio, video or both.

const video = document.querySelector('video');
navigator.mediaDevices.getUserMedia({audio: true, video: true}).then(stream => video.srcObject = stream).catch(err => console.log(err));

Hello! With this two lines, you should be able to see yourself in the browser window.

It’s also possible to configure audio/video tracks, by passing configuration properties instead of boolean values in the constraints object.

Full example can be found here in the online editor.

Streaming data (ex.2)

Having access to media devices is crucial for audio/video communication. Now, it’s the time to “send” data between the browsers. In this tutorial, we won’t send anything through the network – for the needs of testing the communication will be placed on the same machine.

WebRTC API provides RTCPeerConnection interface that stands for connection between local and remote computer.

In this example we’ll use two video elements – for remote and local peers. As both elements are displayed on the same page, we don’t have to use signaling server to negotiate the session.

Get MediaStream from devices

Firstly, we need to access media devices (just like in the previous example):

navigator.mediaDevices.getUserMedia({ audio: true, video: true })
.then(stream => {
local.srcObject = stream;
localStream = stream;
.catch(err => console.log(err));

The only difference is that we are storing MediaStream object in a local variable.

Establish peer connection

Our call() function – used for establishing connection between the peers – is a bit elaborated, so let’s take a step-by-step analysis.

pc1 and pc2 variables stand for our local and remote RTCPeerConnection objects.

      1. Create RTCPeerConnection objects (should be called on both sides – remote and local).
        const pc1 = new RTCPeerConnection();
        pc1.onicecandidate = e => pc2.addIceCandidate(e.candidate);
        const pc2 = new RTCPeerConnection();
        pc2.onicecandidate = e => pc1.addIceCandidate(e.candidate);

        In a real world, setting ICE candidate should be handled by signalling server. This is our first “Hey! I’m here”. Normally it’s not possible to set candidate on the other side peer just like that, as it should be send by network. However we can make some shortcuts to keep this example clear.

      2. Set remote peer ontrack callback.
        pc2.ontrack = e => {
        remote.srcObject = e.streams[0];

        When the remote peer adds a track, this callback function is executed. So that, we can set our video element to display the MediaStream – notice that they may be more than one stream in the event.

      3. Add local tracks to send them over peer connection.
        localStream.getTracks().forEach(track => pc1.addTrack(track, localStream));

        With this line we’re adding our local stream tracks (audio and video) to the list of tracks being sent over the network.

      4. Create offer – start the magic.With createOffer API method, we can get Session Description Protocol object with all of necessary information about the real-time communication that’s going to be invoked. It takes RTCOfferOptions object, that can be used to adjust the offer.
        pc1.createOffer().then(description => {
        pc2.createAnswer().then(description => {

    As a result of this method, we’ll get the Promise that resolves to SDP object that has to be properly assigned on both local and remote sides. For pc2 description object resolved with createOffer contains remote peer connection details. Finally, to make the communication work, remote peer has to answer with it’s own SDP description – again, description object should be properly assigned on both of the sides.

    It works! Data stream from our local device is being sent over WebRTC and received properly in our simulated remote peer.
    You may find full example here.

  • Software Engineers - development team

  • WebRTC Tutorial – What’s next?

    This tutorial was meant to show you basic usages and concepts around Web Real-Time Communication. We’ve built a simple app that uses whole set of protocols and native browser modules to send audio/video stream over from one peer to another.

    Next step would be making this work between browser pages (e.g. with a use of
    localStorage to simulate socket connection) or even two machines. We could write our own signaling server, to make such basic connection work with session negotiation over the network. For production usage, it’s mostly recommended to use one of dedicated media servers that acts as Multipoint Conferencing Unit (MCU). With this we can built multi-endpoint connection (like group video chat) or mix audio and video streams from multiple sources. One of such media servers is Kurento, which provides advanced tools for building rich real-time audio/video communications over the network.

    So, everyone – go ahead and do it yourself!

    Tomasz Niedziela – Brach



cto - Chris Gibas

Free 30-minute consultation with our CTO

Chris Gibas - our CTO will be happy to discuss your project! Let's talk!

More blog posts
Behind the scenes of Python closure function

Kamil Kolodziej

Behind the scenes of Python closure function

In this article, we will learn what python closure is, how to use it and what it can be used for. Also, we will explain some extra terms like nonlocal and free variables, what a scope for variables is and what nested and first-class functions are. First, let’s look at the definition from Wikipedia: (…) closure, (…) is a technique […]

Frontend development technologies – how to choose?

You may sometimes find misleading articles about the best frontend languages. There are plenty of technologies used for frontend development of an application, although there are only three languages used for that purpose: JavaScript, HTML and CSS. From this article, you will learn what the difference between a language and a framework is, what is important when developing the client-side […]

Frontend development technologies – how to choose?


Substantive support - Julianna Sykutera

How does robotic process automation change the healthcare industry?


Substantive support - Julianna Sykutera

How does robotic process automation change the healthcare industry?

Healthcare companies deal with a significant amount of repetitive and manual tasks that have to be carried out in their systems. These processes can impact the quality of medical services, if they are performed inefficiently. Improvement within this area is crucial, considering that there are lives at stake.  Robotic process automation (RPA) solution suits the needs of even the most […]

What AI-based solutions can you apply in your business?

Companies all around the world are investing in innovations not only to improve the efficiency of internal processes but also to serve their customers better and surprise them with unique solutions implemented in applications and websites. What do you need to know about Artificial Intelligence, and how can you leverage this technology to make your company more competitive?  Could your […]

What AI-based solutions can you apply in your business?


Substantive support - Julianna Sykutera

Get a free estimation

Need a successful project?