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.
- Switch video input device (camera).
Initialize
In order to start working with Multiparty Video Conferencing API, you need to initialize the conference module by calling the init()
method. The conference module allows to process conference calls. If the module is not initialized, it will not be able to create the session and process calls consequently.
You must call the
init()
method before calling any other methods. If you attempt to call a method without initializing the module, the error is returned.
try {
String conferenceServer = "your_conference_server";
await QB.conference.init(conferenceServer);
} on PlatformException catch (e) {
// Some error occurred, look at the exception message for more details
}
Argument | Required | Description |
---|---|---|
conferenceServer | yes | A conference server endpoint. |
Manage calls
To process events such as a received video track, you should subscribe to an event(s) first and assign an event handler. If you've subscribed to the event(s), you receive StreamSubscription
that you should unsubscribe when you need, for example, in the dispose()
method.
You can subscribe to several events at the same time. However, you should handle these events as different subscriptions. For example, if you subscribe to three events, you should call three subscribeConferenceEvent()
methods. And if you need to unsubscribe from these three events, you should have the same number of unsubscriptions.
// Conference Events
// QBConferenceEventTypes.CONFERENCE_VIDEO_TRACK_RECEIVED
// QBConferenceEventTypes.CONFERENCE_PARTICIPANT_RECEIVED
// QBConferenceEventTypes.CONFERENCE_PARTICIPANT_LEFT
// QBConferenceEventTypes.CONFERENCE_ERROR_RECEIVED
// QBConferenceEventTypes.CONFERENCE_CLOSED
// QBConferenceEventTypes.CONFERENCE_STATE_CHANGED
StreamSubscription? _someSubscription;
// Unsubscribe
@override
void dispose() {
if(_someSubscription != null) {
_someSubscription!.cancel();
_someSubscription = null;
}
}
// Subscribe
String event = QBConferenceEventTypes.CONFERENCE_CLOSED;
try {
someSubscription = await QB.conference.subscribeConferenceEvent(event ,(data) {
String sessionId = data["payload"]["sessionId"];
});
} on PlatformException catch (e) {
// Some error occured, look at the exception message for more details
}
The table below lists all supported conference session events.
Event | Description |
---|---|
QBConferenceEventTypes. CONFERENCE_VIDEO_TRACK_RECEIVED | A remote video track has been received by the remote participant. |
QBConferenceEventTypes. CONFERENCE_PARTICIPANT_RECEIVED | A new participant has joined a conference session. |
QBConferenceEventTypes. CONFERENCE_PARTICIPANT_LEFT | A participant has left a conference session. |
QBConferenceEventTypes. CONFERENCE_ERROR_RECEIVED | An error was received. |
QBConferenceEventTypes. CONFERENCE_CLOSED | A conference session was closed. |
QBConferenceEventTypes. CONFERENCE_STATE_CHANGED | A conference session state has been changed. |
Create session
To be able to interact with the Video Conferencing API, you need to create a conference session by calling the create()
method. Each conference session is tied to a specific dialogId
taken from the QuickBlox Chat. See this section for more information about dialogs.
It is important to store the current session in the
session
variable to be able to interact with the current conference session. For example, if you don't store the current session, you won't be able to hang up or reject a call.
// Session Types
// QBConferenceSessionTypes.VIDEO
// QBConferenceSessionTypes.AUDIO
...
QBConferenceRTCSession? _session;
...
String dialogId = "1148462029";
String sessionType = QBConferenceSessionTypes.VIDEO;
try {
_session = await QB.conference.create(dialogId, sessionType);
int sessionId = session!.id;
} on PlatformException catch (e) {
// Some error occurred, look at the exception message for more details
}
Argument | Required | Description |
---|---|---|
sessionType | yes | Conference session type: QBConferenceSessionTypes.VIDEO , QBConferenceSessionTypes.AUDIO . |
dialogId | yes | ID of the dialog. Taken from the QuickBlox Chat. |
Join video room
Once a conference session is created, you need to establish a call. To establish a call, you need to join an already-created conference session by calling the joinAsPublisher()
method. This method joins the session and publishes your feed making you an active publisher in the room. Everyone in the room will be able to subscribe and receive your feed. Once the room is joined, you receive an array of participants' IDs.
Make sure to subscribe to each participant to be able to receive video/audio tracks from them. If you don't subscribe, you won't receive audio and video of the participant joined to the room. See this section for more information.
String sessionId = "114846dfsJKJDdls8dsfj2029";
try {
List<int?> participants = await QB.conference.joinAsPublisher(sessionId);
for (int i = 0; i < participants.length; i++) {
int userId = participants[i]!;
subscribeToParticipant(sessionId, userId);
}
} on PlatformException catch (e) {
// Some error occurred, look at the exception message for more details
}
Argument | Required | Description |
---|---|---|
sessionId | yes | Conference session ID. Received from the QBConferenceRTCSession object that is returned in the response to the create() method. |
Subscribe
Use the subscribeToParticipant()
method to subscribe to a participant.
String sessionId = "114846dfsJKJDdls8dsfj2029";
int userid = 567527986;
try {
await QB.conference.subscribeToParticipant(sessionId, userId);
} on PlatformException catch (e) {
// Some error occurred, look at the exception message for more details
}
Argument | Required | Description |
---|---|---|
sessionId | yes | Conference session ID. |
userId | yes | User ID. Taken from the array of participants' IDs received in the responce to the joinAsPublisher() method. |
Unsubscribe
Use the unsubscribeFromParticipant()
method to unsubscribe from the participant's audio/video track.
String sessionId = "114846dfsJKJDdls8dsfj2029";
int userid = 567527986;
try {
await QB.conference.unsubscribeFromParticipant(sessionId, userId);
} on PlatformException catch (e) {
// Some error occurred, look at the exception message for more details
}
Argument | Required | Description |
---|---|---|
sessionId | yes | Conference session ID. |
userId | yes | User ID. Taken from the array of participants' IDs received in the responce to the joinAsPublisher() mthod. |
Set up video view
Set up the ConferenceVideoView
for remote and local video tracks to be able to show the video. The ConferenceVideoView
allows displaying the video stream while the ConferenceVideoViewController
allows to control the video view. Thus, you can play, release the video stream from video view.
- A remote video track represents a remote peer video stream from a remote camera app. Specify the initial value to
ConferenceVideoView
-RTCVideoViewController
for the remote camera app of the remote peer. There can be multiple remote video tracks in the conference call. In this case, you should set up theConferenceVideoView
for each remote video track individually. - A local video track represents a local peer video stream from a local camera app. Specify the initial value to
ConferenceVideoView
-RTCVideoViewController
for the local camera app of the remote peer. There can be only one local video track in the conference call.
...
ConferenceVideoViewController? _localVideoViewController
ConferenceVideoViewController? _remoteVideoViewController
// Some widgets code
...
child: new Container(
margin: EdgeInsets.fromLTRB(10.0, 10.0, 10.0, 10.0),
width: 160.0,
height: 160.0,
child: ConferenceVideoView(
onVideoViewCreated: onRemoteVideoViewCreated,
),
decoration: BoxDecoration(color: Colors.black54),
)
child: Container(
margin: EdgeInsets.fromLTRB(10.0, 10.0, 10.0, 10.0),
width: 160.0,
height: 160.0,
child: ConferenceVideoView(
onVideoViewCreated: onLocalVideoViewCreated,
),
decoration: BoxDecoration(color: Colors.black54),
)
...
void onRemoteVideoViewCreated(ConferenceVideoViewController controller) {
_remoteVideoViewController = controller;
}
void onLocalVideoViewCreated(ConferenceVideoViewController controller) {
_localVideoViewController = controller;
}
...
Subscribe to the QBConferenceEventTypes.CONFERENCE_VIDEO_TRACK_RECEIVED
event. Thus, once the SDK receives data that a remote video track was received, it creates the event of CONFERENCE_VIDEO_TRACK_RECEIVED
type with userId
and sessionId
properties. See this section to learn how to subscribe the event.
After this, invoke method play()
and pass sessionId
and userId
parameters to it. If the userId
matches with the one in properties, the video starts playing.
...
String sessionId = "114846dfsJKJDdls8dsfj2029";
int opponentId = 2182763;
Future<void> startRenderingRemote() async {
try {
await remoteVideoViewController.play(sessionId, opponentId);
} on PlatformException catch (e) {
// Some error occurred, look at the exception message for more details
}
}
String sessionId = "114846dfsJKJDdls8dsfj2029";
int opponentId = 2182763;
Future<void> startRenderingLocal() async {
try {
await localVideoViewController.play(sessionId, userId);
} on PlatformException catch (e) {
// Some error occurred, look at the exception message for more details
}
}
Argument | Required | Description |
---|---|---|
sessionId | yes | Conference session ID. |
userId | yes | The ID of the local peer. |
opponentId | yes | The ID of the remote peer. |
Mute local audio
You can mute/unmute your own audio by using the enableAudio()
method.
String sessionId = "114846dfsJKJDdls8dsfj2029";
bool enable = true;
try {
await QB.conference.enableAudio(sessionId, enable: enable);
} on PlatformException catch (e) {
// Some error occurred, look at the exception message for more details
}
Argument | Required | Description |
---|---|---|
sesssionId | yes | Conference session ID. |
enabled | no | Boolean parameter. Allows to enable/disable a local audio. |
Disable local video
You can enable/disable your own video by using the enableVideo()
method.
String sessionId = "114846dfsJKJDdls8dsfj2029";
bool enable = true;
try {
await QB.conference.enableVideo(sessionId, enable: enable);
} on PlatformException catch (e) {
// Some error occurred, look at the exception message for more details
}
Argument | Required | Description |
---|---|---|
sessionId | yes | Conference session ID. |
enabled | no | Boolean parameter. Allows to enable/disable a local video. |
Switch video input device
You can switch a video input to the rear or front camera. The SDK automatically finds all cameras and chooses the two cameras with the highest video quality. Call the switchCamera()
method to switch between the two cameras.
String sessionId = "114846dfsJKJDdls8dsfj2029";
try {
await QB.conference.switchCamera(sessionId);
} on PlatformException catch (e) {
// Some error occurred, look at the exception message for more details
}
Argument | Required | Description |
---|---|---|
sessionId | yes | Conference session ID. |
Switch audio output device
You can switch an audio output. Call the switchAudioOutput()
method and pass the type of the audio device to it.
You can switch the audio input only after calling the
create()
method.
// Audio output
// EARSPEAKER = 0
// LOUDSPEAKER = 1
// HEADPHONES = 2
// BLUETOOTH = 3
int output = QBConferenceAudioOutputTypes.LOUDSPEAKER;
try {
await QB.conference.switchAudioOutput(output);
} on PlatformException catch (e) {
// Some error occurred, look at the exception message for more details
}
Argument | Required | Description |
---|---|---|
output | yes | Type of the audio device:QBConferenceAudioOutputTypes.EARSPEAKER ,QBConferenceAudioOutputTypes.LOUDSPEAKER ,QBConferenceAudioOutputTypes.HEADPHONES ,QBConferenceAudioOutputTypes.BLUETOOTH . |
Leave video room
To leave the video room, use the leave()
method. After calling this method, the current session is deleted from SDK and you can't access this session any more.
String sessionId = "114846dfsJKJDdls8dsfj2029";
try {
await QB.conference.leave(sessionId);
} on PlatformException catch (e) {
// Some error occurred, look at the exception message for more details
}
Argument | Required | Description |
---|---|---|
sessionId | yes | Conference session ID. |
Release resource
If you don't want to receive and process video calls, for example, when a user is logged out or the ConferenceVideoView
is going to close, you have to release the conference module. Call the release()
method that allows to unregister the conference module from receiving any video conference events and closes existing signaling channels.
If you want to create another conference session after the release()
method, you should call the init()
method first to initialize the conference module. After the module is initialized, you can create another conference session by calling the create()
method.
...
ConferenceVideoViewController? _localVideoViewController;
ConferenceVideoViewController? _remoteVideoViewController;
...
try {
await QB.conference.release();
// Release video views
await _localVideoViewController!.release();
await _remoteVideoViewController!.release();
} on PlatformException catch (e) {
// Some error occurred, look at the exception message for more details
}
The
release()
method should be called when a video track is no more valid. If you don't call this method, you will get a memory leak.
Updated almost 2 years ago