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
Decentralized Finance (DeFi) – what is it?

Oleksandra Bilokrys

Decentralized Finance (DeFi) – what is it?

Decentralized Finance, in short DeFi, is a concept which enables entrepreneurs who choose to take advantage of blockchain technology and traditional financial instruments in a decentralized architecture. Two examples of DeFi applications are Bitcoin and Etherum. They are both controlled by big networks of computers and not central authorities. What does that mean and why is DeFi becoming more and […]

What are smart contracts and what is their potential for business?

Are you interested in blockchain technology, and you are wondering what its business potential is? To understand the possible application in your industry, you first need to learn how it works. One of the most useful tools associated with blockchain is smart contracts. They enable transferring not only fiat currency and cryptocurrencies but also other resources. Smart contracts are applications […]

What are smart contracts and what is their potential for business?


Substantive support - Oleksandra Bilokrys

How to augment your software development team? Staff augmentation in practice.


Substantive support - Oleksandra Bilokrys

How to augment your software development team? Staff augmentation in practice.

Do you need high-quality software for your company? In some situations only high-quality, custom solutions can solve certain business problems, but how to develop the right software? No one better than you knows what exactly you need to become more efficient and thus, more competitive. If you do not have enough experienced employees for such a big IT undertaking in […]

Hiring the best machine learning developer – what do you need to know?

Finding and hiring specialists for your IT department is never easy, especially when your company is taking advantage of quite complex IT solutions for business. Do you need to employ the best machine learning developer available on the market? A deep understanding of the IT field – which is a data-based science – is crucial for HR experts and managers […]

Hiring the best machine learning developer – what do you need to know?


Substantive support - Oleksandra Bilokrys

Get a free estimation

Need a successful project?