Video Conference

Learn how to add video conference calls to your app.

🚧

This feature is available for customers on the Enterprise plan only. Take advantage of Enterprise features to unlock new value and opportunities for users. For more information and if you want to request a Demo, please contact us by mail: [email protected].

QuickBlox provides a Multiparty Video Conferencing solution allowing to set up a video conference between 10-12 people. It is built on top of WebRTC SFU technologies.

Features supported:

- Video/Audio Conference with 10-12 people.
- Join/Rejoin video room functionality (like Skype).
- Mute/Unmute audio/video stream (own and opponents).
- Display bitrate.
- Switch video input device (camera).

Dependencies for browser

​For the library to work, you need to include a webrtc-adapter in your html before quickblox-multiparty-video-conferencing-client-0.8.6.min.js.

<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
<script src="quickblox-multiparty-video-conferencing-client-0.8.6.min.js"></script>

Initialize

In order to start working with Multiparty Video Conferencing API, you need to initialize a client.

const config = {
  server: "wss://...",
  debug: true, // optional
  iceServers: [], // optional
};
const client = new QBVideoConferencingClient(config);

Set the following fields using the config object:

FieldRequiredDescription
serveryesA conference server endpoint or array of endpoints.
debugnoEnables logging. true is enabled. false is disabled.
iceServersnoA list of ICE servers.

📘

To request your server endpoint, contact us by mail: [email protected].

Create session

Once the library has been initialized, you can start creating a session. Typically, each browser tab will need a single session with the server. Once the session is created, you can interact with a Video Conferencing API.

client
  .createSession()
  .then(() => {
    // session created
  })
  .catch((error) => {
    // some error occurred
  });

Attach video conferencing plugin

Video conferencing allows you to exploit features of the plugin to manipulate the media sent and/or received by peer connection on your web page. This method will create a plugin handle that you can subscribe to and handle events. You also have to attach the plugin to each remote user.

const isRemote = remoteUser ? true : false;
const userId = remoteUser ? remoteUser.id : null;
client
  .attachVideoConferencingPlugin(isRemote, userId)
  .then((plugin) => {
    const eventHandler = console.log; // use your own event handler(s)
    Object.keys(plugin.events).forEach((key) =>
      plugin.on(plugin.events[key], eventHandler)
    );
  })
  .catch((error) => {
    // some error occurred
  });

📘

To attach the plugin to a local user plugin, set userId to null and isRemote to false.

The following code lists the supported events of the video conferencing plugin as well as shows how to add the listener.

function consentDialog(on) {}

function mediaState(media, receiving) {}

function webrtcState(on, reason) {}

function slowLink(uplink, lost) {}

function iceState(state) {}

function detached() {}

function cleanup() {}

plugin.addListener(plugin.events.CONSENT_DIALOG, consentDialog);
plugin.addListener(plugin.events.MEDIA_STATE, mediaState);
plugin.addListener(plugin.events.WEBRTC_STATE, webrtcState);
plugin.addListener(plugin.events.SLOW_LINK, slowLink);
plugin.addListener(plugin.events.ICE_STATE, iceState);
plugin.addListener(plugin.events.DETACHED, detached);
plugin.addListener(plugin.events.CLEANUP, cleanup);
EventDescription
plugin.events.CONSENT_DIALOGThis event is triggered just before the getUserMedia() method is called and after it is completed. This means it can be used to modify the UI accordingly. For example, to prompt the user to accept the device access requests.
plugin.events.MEDIA_STATEThis event is triggered when the media server starts or stops receiving your media. For example, a mediaState with type=audio and on=true means that the media server started receiving your audio stream or started getting it again after a pause of more than a second. A mediaState with type=video and on=false means that the media server hasn't received any video from you in the last second after a start. This event is useful to figure out when the media server actually started handling your media, or to detect problems on the media path (e.g., media never started, or stopped at some point of time time).
plugin.events.WEBRTC_STATEThis event is triggered with a true value when the PeerConnection associated with a handle becomes active (so ICE, DTLS and everything else succeeded) from the media server perspective. A false value is triggered when the PeerConnection goes down instead. This event is useful to figure out when WebRTC is actually up and running between you and the media server. In case of the false value, a reason of the String type may be present as an optional parameter.
plugin.events.SLOW_LINKThis event is triggered when the media server reports trouble associated with either sending or receiving media on the specified PeerConnection. Typically, it is triggered as a consequence of too many NACKs received from/sent to the user in the last second. For example, a slowLink with uplink=true means you notified several missing packets from the media server, while uplink=false means the media server is not receiving all your packets. This event is useful to figure out when there are problems on the media path (e.g., excessive loss), in order to react accordingly (e.g., decrease the bitrate if most of our packets are getting lost).
plugin.events.ICE_STATEThis event is triggered when the ICE state for the PeerConnection associated with the handle changes. Thus, the argument of the callback is a new state of the String type (e.g., "connected" or "failed").
plugin.events.DETACHEDThe plugin handle has been detached by the plugin itself, and so should not be used anymore.
plugin.events.CLEANUPThe WebRTC peer connection with the plugin was closed.

Join video room

To jump into a video conference room, join it using the join() method.

const joinParams = {
  roomId: "room_123",
  userId: 12345,
  display: "John Doe",
  onlyAudio: false,
  role: "publisher",
  video: "stdres",
};

client
  .join(joinParams)
  .then(() => {
    // joined successfully
  })
  .catch((error) => {
    // handle error
  });

Set the following fields using the joinParams object:

FieldRequiredDescription
roomIdyesA room ID, should be of String type.
userIdyesA user ID, should be of Number type.
displaynoA name to be shown to other participants, should be of String type.
onlyAudionoSpecifies whether to use the audio only. A Boolean parameter.
Default: false.
rolenoA user role. Possible values are "subscriber" or "publisher". Default: publisher.
videonoA video property. Default: lowres. See this section for more information.

To check the current video room you are joined to, use the following property of the QBVideoConferencingClient.

client.currentRoomId

The QBVideoConferencingClient has the following properties:

PropertyDescription
connectedReturns a boolean indicating whether the client is connected to the server or not.
pluginIdReturns a unique plugin ID for the current user.
sessionIdReturns a current session ID indicating if there is a session.
currentRoomIdReturns a current room ID.

List online participants

To list online users in a video conference room, use the listOnlineParticipants() method.

client
  .listOnlineParticipants(roomId)
  .then((participants) => {
    // handle as necessary
  })
  .catch((error) => {
    // handle error
  });

Events

There is a number of events you can subscribe to. You can inspect the property events to check the list of supported events. To assign an event handler, you can use the same API as for NodeJS EventEmitter.

client.on(client.events.PARTICIPANT_JOINED, (userId, userDisplayName) => {});

client.on(client.events.PARTICIPANT_LEFT, (userId, userDisplayName) => {});

client.on(client.events.LOCAL_STREAM, (stream) => {
  const localVideo = document.querySelector("video#local");
  QBVideoConferencingClient.attachMediaStream(localVideo, stream);
});

client.on(client.events.REMOTE_STREAM, (stream, userId) => {
  const remoteVideo = document.querySelector("video#remote" + userId);
  QBVideoConferencingClient.attachMediaStream(remoteVideo, stream);
});

client.on(client.events.SESSION_DESTROYED, () => {});

client.on(client.events.ERROR, (error) => {
  // handle error
});
EventDescription
client.events.PARTICIPANT_JOINEDA participant has joined a conference room.
client.events.PARTICIPANT_LEFTA participant has left a conference room.
client.events.LOCAL_STREAMA local MediaStream is available and ready to be displayed.
client.events.REMOTE_STREAMA remote MediaStream is available and ready to be displayed.
client.events.SESSION_DESTROYEDA conference session has been destroyed.

To remove all listeners the following code can be used.

Object.keys(client.events).forEach(key =>
  client.removeAllListeners(client.events[key])
);

Mute remote audio

You also can mute/unmute a remote user's audio.

const muted = client.toggleRemoteAudioMute(userId);
console.info("Now remote audio is muted=" + muted);

Disable local video

You can enable/disable your own video.

const muted = client.toggleVideoMute();
console.info("Now video is muted=" + muted);

Disable remote video

You also can enable/disable a remote user's video.

const muted = client.toggleRemoteVideoMute(userId);
console.info("Now remote video is muted=" + muted);

Display bitrate

There is a way to show a video bitrate of a remote user. It will start updating the innerText of the video element every second with the bitrate in 'kbps' for the remote user (if found by userId). Thus, the following string will be shown in the video element: 180 kbits/sec.

const userId = 12344;
const bitrateNode = document.getElementById("bitrate");
client.showBitrate(userId, bitrateNode);

In order to stop displaying the video bitrate of the remote user, use the code snippet below. It will clear innerText of the video element and stop updating the bitrate.

const userId = 12344;
const bitrateNode = document.getElementById("bitrate");
client.hideBitrate(userId, bitrateNode);

List video input devices

To get a list of all video input devices (cameras), use the following code snippet.

QBVideoConferencingClient
  .listVideoInputDevices()
  .then(videoInputDevices => {
    // handle as necessary
  });

List audio input devices

To get a list of all audio input devices (microphones), use the following code snippet.

QBVideoConferencingClient
  .listAudioInputDevices()
  .then(audioInputDevices => {
    // handle as necessary
  });

Switch video input device

In order to switch a video camera, you have to obtain a list of currently plugged video cameras with listVideoInputDevices() method. See this section to learn how to list video input devices. Then, call the switchVideoInput().

var deviceId = "...";
client
  .switchVideoInput(mediaDeviceId)
  .then(() => {
    // switched successfully
  })
  .catch((error) => {
    // handle error
  });

Switch audio input device

In order to switch a microphone, you have to obtain a list of currently plugged microphones with the listAudioInputDevices() method. See this section to learn how to list audio input devices. Then, call the switchAudioInput().

var deviceId = "...";
client
  .switchAudioInput(mediaDeviceId)
  .then(() => {
    // switched successfully
  })
  .catch((error) => {
    // handle error
  });

Screen sharing

​In order to start sharing your screen call the toggleScreenSharing() method.

client
  .toggleScreenSharing()
  .then(() => {
    // sharing your screen
  })
  .catch((error) => {
    // some error occurred
  });

To check if the screen sharing is enabled, call the screenSharingEnabled() method.

const enabled = client.screenSharingEnabled()

ICE Restart

Initiate ICE restart for a peer. This is typically needed whenever something in your network changes. For example, you move from Wi-Fi to a mobile or a different Wi-Fi but want to keep the conversation going. In this case, an ICE restart needs to take place, as peers need to exchange new candidates they can be reached on.

const userId = remoteUser
  ? // restart ICE for remote user
    remoteUser.id
  : // or restart ICE for local (current) user
    null;
client
  .iceRestart(userId)
  .then(() => {
    /* success */
  })
  .catch((error) => {
    /* some error occurred */
  });

Leave video room

To leave the video room, use the leave() method.

client
  .leave()
  .then(() => {
    // left room successfully
  })
  .catch((error) => {
    // handle error
  });

Detach video conferencing plugin

When the job is done, you should detach the video conferencing plugin. The detachVideoConferencingPlugin() method detaches the plugin and destroys the handle tearing down to the related peer connection if it exists.

client
  .detachVideoConferencingPlugin()
  .then(() => {
    // successfully detached
  })
  .catch((error) => {
    // handle error
  });

Destroy session

To destroy a session, use the destroySession() method.

client
  .destroySession()
  .then(() => {
    // success
  })
  .catch((error) => {
    // handle error
  });

Camera resolution

Set a camera resolution when joining a video room using the video property of the joinParams object.

const joinParams = {
  roomId: "room_123",
  userId: 12345,
  display: "John Doe",
  onlyAudio: false,
  role: "publisher",
  video: "stdres",
};

client
  .join(joinParams)
  .then(() => {
    // joined successfully
  })
  .catch((error) => {
    // handle error
  });

The allowed values for the video property are the following:

PropertyDescription
videoA video property. Default: lowres. The possible values are:

For a small resolution
lowres (240 x 320)
lowres-16:9 (180 x 320)

For a normal resolution
stdres (480 x 640)
stdres-16:9 (360 x 640)

For a High(HD) resolution
hires, hires-16:9, hdres (720 x 1280). High(HD) resolution is only 16:9.

For a full HD resolution
fhdres (1080 x 1920). Full HD resolution is only 16:9.

For a 4K resolution
4kres (2160 x 3840). 4K resolution is only 16:9.

What’s Next