Ask tech team
From QuickBlox Developers (API docs, code samples, SDK)
Jump to: navigation, search


Deprecation notice

Deprecation notice

This documentation is outdated, the newest version of the documentation is now maintained at


Project homepage on GIT:

Clone source code via Terminal (the way we recommend):

git clone

or download ZIP:


The WebRTC VideoChat code sample allows you easily add video calling features into your Web app. Enable a video call function similar to Skype using this code sample as a basis.

It is built on top of the WebRTC technology.

Browsers support of WebRTC


  • Chrome (latest)
  • Firefox (latest)
  • Opera (latest)


  • Android Browser (latest)
  • Opera Mobile (latest)
  • Chrome for Android (latest)
  • Firefox for Android (latest)

Unfortunately, these features are unsupported in IE and Safari, and iOS mobile browsers.
You can find more info here -

Note: Opera mini for Android, which has minimal functionality, does not work with this technology either.

Prepare your application for Javascript SDK

Preparation includes the following steps:

  • Create QuickBlox account
  • Register an application in Dashboard
  • Integrate QuickBlox SDK into application

Register a QuickBlox account

Create application in the Admin panel

In addition, there is helpful 5 minute guide.

Connect the SDK and configure

Integrate video calling to your application

Transition guide from 1.7 to 2.0 version

This migration guide will provide guidance to upgrade your existing application to SDK version 2.0:

  1. Now methods as getUserMedia, attachMediaStream, detachMediaStream, call, accept, reject, stop, update, mute, unmute, snapshot are encapsulated in session object. You can obtain it via var session = QB.webrtc.createNewSession(calleesIds, typeOfCall);
  2. Added a callback to close a session - onSessionCloseListener.
  3. Renamed the callback onSessionStateChangedListener to onSessionConnectionStateChangedListener

More detailed info on these updates find in guide below.

Connect to chat

You have to connect to the Chat because the QuickBlox Video calling SDK exchanges signaling messages over XMPP protocol via own signaling mechanism.{userId: 4355, password: "geremy67df"}, function(err, roster) {

More detailed info about connection to Chat you can find on Chat code sample page.

Create video session

In order to use Video calling API you have to create a session object - choose your opponents with whom you would like to have a video chat and a type of session (VIDEO or AUDIO):

var calleesIds = [56, 76, 34]; // User's ids 
var sessionType = QB.webrtc.CallType.VIDEO; // AUDIO is also possible
var callerID = 25; // Your user ID (optional, will be defined from chat connection)
var additionalOptions = {"bandwith": 512}; // The video bandwith (number, optional, 0 = unlimited)
var session = QB.webrtc.createNewSession(calleesIds, sessionType, callerID, additionalOptions);

Get local Media Stream

Access local media stream

In order to have a video chat session you have to get access to the user's devices (webcam / microphone):

var mediaParams = {
  audio: true,
  video: true,
  options: {
    muted: true,
    mirror: true
  elemId: 'localVideo'
session.getUserMedia(mediaParams, function(err, stream) {
  if (err){

This method lets the browser asks the user for permission to use devices. The appearance of the popup varies between browsers.




You should allow this dialog to access the stream. Otherwise, the browser can't obtain access and will throw an error for the getUserMedia callback function.


You can use following parameters with getUserMedia

Param Required Type Value Example Description
audio Yes* Boolean true / false audio stream from microphone
video Yes* Boolean true / false video stream from webcam
elemId Optional String 'localVideo' ID of audio/video DOM element to attach a video stream to.
options[muted] Optional** Boolean true / false disable local audio stream for user

Note: is useful to reduce echo cancellation
and noises in the audio/video chat

options[mirror] Optional** Boolean true / false mirrored rotate the video stream

* audio or/and video are required
** the options object will work only if elemId exists

Localhost and the secure HTTP protocol

The request for webrtc permissions is a security measure in browsers. Note also that getUserMedia() must be used solely when on the server, not the local file system, otherwise media streaming will not work.

Also you have to use HTTPS protocol to make it works - Chrome will block it on HTTP.

Code snippets

Get only audio stream from microphone

session.getUserMedia({audio: true}, function(err, stream) {
  // callback

Get only video stream from webcam

session.getUserMedia({video: true}, function(err, stream) {
  // callback

Get both streams

session.getUserMedia({audio: true, video: true}, function(err, stream) {
  // callback

Get stream and automatically attach it to video element on the page

session.getUserMedia({audio: true, video: true, elemId: 'localVideo'}, function(err, stream) {
  // callback

Get stream and automatically attach, mute and mirrored rotate it

var options = {
  muted: true,
  mirror: true
session.getUserMedia({audio: true, video: true, elemId: 'localVideo', options: options}, function(err, stream) {
  // callback

Advanced settings

It's also possible to set custom video resolution using getUserMedia constraints.

Example of HD camera resolution constraints, i.e. minWidth: 1280, minHeight: 720:

var contraints = {       
      audio: true,
      video: {
            optional: {
              minWidth: 1280,
              maxWidth: 1280,
              minHeight: 720,
              maxHeight: 720
session.getUserMedia(contraints, function(err, stream) {
  // callback

Here is a good code sample from WebRTC team how to work with getUserMedia constraints:

Attach stream on the page

You can also attach your local media stream to HTML video element lately if you don't pass the elemId key in parameters to getUserMedia.

To do this use the following steps:

  • create any audio / video element in html
  • call session.attachMediaStream(id, stream, options)

Param Required Type Value Example Description
id Yes String 'localVideo' ID of audio/video DOM element
stream Yes Object [stream from browser] Media Stream Object received via getUserMedia
options[muted] Optional Boolean true / false disable the audio stream for DOM element
options[mirror] Optional Boolean true / false mirrored rotate the video stream

This method attaches Media Stream Object to your DOM element and auto plays it

session.attachMediaStream('videoElement', stream);

The same method is used for remote stream, received from your opponents.

Note on Debugging

If you try to download and open sample in your browser, you will likely run into Cross-Origin Resource Sharing (CORS) errors since the browser will block your requests to use video and microphone features.

To test a sample locally we recommend you setup a simple server using Python.

To do this, open your terminal and change directories into your sample and depending on your version of Python, run one of the following commands:

# Python 2
python -m SimpleHTTPServer <portNo>
# Python 3
python -m http.server <portNo>

For example,

python -m SimpleHTTPServer 8002

Now you can go to http://localhost:8002/index.html to debug your app.

Make a call

Make a call with this method:

var extension = {};, function(error) {

The extension is used to pass any extra parameters in the request to your opponents.

After this call the opponents will get an incoming call request in onCallListener callback:

QB.webrtc.onCallListener = function(session, extension) {

If the opponent is offline at the moment then onUserNotAnswerListener callback will be fired on caller's side:

QB.webrtc.onUserNotAnswerListener = function(session, userId) {

Settings & configuration

Session settings

There are a set of pre defined Video calling settings that you can update for your purpose:

var CONFIG = {
  webrtc: {
    answerTimeInterval: 60, // Max answer time after that the 'QB.webrtc.onUserNotAnswerListener' callback will be fired.
    dialingTimeInterval: 5,  // The interval between call requests produced by
    disconnectTimeInterval: 30 // If an opponent lost a connection then after this time the caller will now about it via 'QB.webrtc.onSessionConnectionStateChangedListener' callback.
    statsReportTimeInterval: false // Allows access to the statistical information about a peer connection. You can set amount of seconds you can get statistic information after.
QB.init(3477, 'ChRnwEJ3WzxH9O4', 'AS546kpUQ2tfbvv', CONFIG);

We recommend you to create config.js configuration file in your js-application and insert your custom video calling settings into it.

ICE servers

Also you can customise a list of ICE servers (via iceServers key).

We use 3 TURN servers: in North Virginia, in Asia and in Europe

How does WebRTC select which TURN server to use if multiple options are given? During the connectivity checking phase, WebRTC will choose the TURN relay with the lowest round-trip time. Thus, setting multiple TURN servers allows your application to scale-up in terms of bandwidth and number of users.

Here is a list with default settings that we use, you can customise all of them or only some particular:

var CONFIG = {
  webrtc: {
    iceServers: [
        'url': ''
        'url': '',
        'username': 'quickblox',
        'credential': 'baccb97ba2d92d71e26eb9886da5f1e0'
        'url': '',
        'username': 'quickblox',
        'credential': 'baccb97ba2d92d71e26eb9886da5f1e0'
        'url': '',
        'username': 'quickblox',
        'credential': 'baccb97ba2d92d71e26eb9886da5f1e0'
QB.init(3477, 'ChRnwEJ3WzxH9O4', 'AS546kpUQ2tfbvv', CONFIG);
Test your settings

Google has another great analysis tool –

You open the settings, insert your own STUN and TURN server configuration – and start the test.

It will then check the system and network connections to give you a nice view of what the browser is experiencing – something you can later use to understand the environment you operate in.

Accept a call

Use accept method to accept the incoming call:

var extension = {};

After this call the opponent will get a confirmation in onAcceptCallListener callback:

QB.webrtc.onAcceptCallListener = function(session, userId, extension) {

Next, caller will get also remote media stream from the opponent in onRemoteStreamListener function

QB.webrtc.onRemoteStreamListener = function(session, userID, remoteStream) {
  // attach the remote stream to DOM element
  session.attachMediaStream('remoteVideo', remoteStream);

From this point you have a working ready to go real-time videochat!

Reject a call

Use the reject method to decline an incoming call:

var extension = {};

After this call the opponent will get a reject signal in onRejectCallListener callback:

QB.webrtc.onRejectCallListener = function(session, userId, extension) {

End a call

Either participant can end the call anytime with the following method:

var extension = {};

After this call the opponent will get a stop signal in onStopCallListener callback:

QB.webrtc.onStopCallListener = function(session, userId, extension) {

Track session state

There is a callback function to track the session state:

QB.webrtc.onSessionConnectionStateChangedListener = function(session, userID, connectionState) {

The possible values of connectionState are those of an enum of type QB.webrtc.SessionConnectionState:

  • QB.webrtc.SessionConnectionState.UNDEFINED
  • QB.webrtc.SessionConnectionState.CONNECTING
  • QB.webrtc.SessionConnectionState.CONNECTED
  • QB.webrtc.SessionConnectionState.FAILED
  • QB.webrtc.SessionConnectionState.DISCONNECTED
  • QB.webrtc.SessionConnectionState.CLOSED
  • QB.webrtc.SessionConnectionState.COMPLETED

Also, SDK does not support multiple active sessions. If the user already has an active session, the SDK will send the auto-reject. To track an incoming call during a busy session, use the callback onInvalidEventsListener.

QB.webrtc.onInvalidEventsListener= function onInvalidEventsListener(nameAction, sessionID, userID, userInfo) {
  if(nameAction === 'onCall') //handle the second active session

The nameAction means an event where an incorrect behavior occurred. Possible events: 'onCall', 'onAccept', 'onStop'.

Notify opponents about any updates

Sometimes you make changes on the client side (e.g. changing the camera feed orientation from portrait to landscape) that need to be fed to the opponents and updated. For this, you can use the update function to send instructions to the opponents on how to update the UI.

var extension = {
  "userInfo": {
    "param1": "value1",
    "param2": "value2"

After this call the opponent will get a signal in onUpdateCallListener callback:

QB.webrtc.onUpdateCallListener = function(session, userId, extension) {

Mute the stream

You can disable some of your local media stream at any time with mute(type) method:


Naturally, you can unmute the stream with the following methods:


Stats reporting

You are able to observe stats provided by WebRTC.

To start collecting report information do the following on config:

var CONFIG = {
  webrtc: {
    statsReportTimeInterval: true

And listen for stats reports in callback:

QB.webrtc.onCallStatsReport = function onCallStatsReport(session, userId, stats, error) {

More info on stats keys is here