Multiparty Video Conferencing feature overview
ConnectyCube Multiparty Video Conferencing API is built on top of WebRTC protocol and based on top of WebRTC SFU architecture.
Max people per Conference call is 12.
Video Conferencing is available starting from Advanced plan.
To get a difference between P2P calling and Conference calling please read our ConnectyCube Calling API comparison blog page.
Features supported
- Video/Audio Conference with up to 12 people
- Join-Rejoin video room functionality (like Skype)
- Guest rooms
- Mute/Unmute audio/video streams
- Display bitrate
- Switch video input device (camera)
Config
ConferenceConfig class introduces new setting for Conference - conference endpoint.
ConferenceConfig.companion.url = ""
CYBCallConfig class introduces new setting for Conference - conference endpoint.
To set a specific conference endpoint use this method.
+ (void)setConferenceEndpoint:(NSString *)conferenceEndpoint;
Note
Endpoint should be a correct ConnectyCube Conference server endpoint.
Use this method to get a current conference endpoint (default is nil):
ConferenceConfig.companion.url
+ (NSString *)conferenceEndpoint;
Conference client
Conference module has its own client which is described in current part.
Conference client delegate
Conference client delegate is inherited from base client delegate and has all of its protocol methods implemented as well.
Base client delegate protocol methods
All protocol methods below have their own explanation inlined and are optional.
/** * Called when session state has been changed. * * @param session P2PSession instance * @param state session state * */func onStateChanged(session: BaseSession<AnyObject>, state: BaseSessionRTCSessionState) {}
/** * Called in case when connection with opponent is established * * @param session P2PSession instance * @param userId ID of opponent */func onConnectedToUser(session: BaseSession<AnyObject>, userId: Int32) {}
/** * * Called in case when connection failed with user * * @param session P2PSession instance * @param userId ID of opponent */func onDisconnectedFromUser(session: BaseSession<AnyObject>, userId: Int32) {}
/** * * Called in case when connection is closed for user * * @param session P2PSession * @param userId ID of opponent */func onConnectionClosedForUser(session: BaseSession<AnyObject>, userId: Int32) {}
/** * * Called when received remote video track from user * * @param videoTrack ConnectycubeVideoTrack instance * @param userId ID of user */func onRemoteVideoTrackReceive(session: BaseSession<AnyObject>, videoTrack: ConnectycubeVideoTrack, userId: Int32) {}
/** * * Called when received remote audio track from user * * @param videoTrack ConnectycubeAudioTrack instance * @param userId ID of user */func onRemoteAudioTrackReceive(session: BaseSession<AnyObject>, audioTrack: ConnectycubeAudioTrack, userId: Int32) {}
/** * Called by timeout with updated stats report for user ID. * * @param session CYBCallSession instance * @param report CYBCallStatsReport instance * @param userID user ID * * @remark Configure time interval with [CYBCallConfig setStatsReportTimeInterval:timeInterval]. */- (void)session:(__kindof CYBCallBaseSession *)session updatedStatsReport:(CYBCallStatsReport *)report forUserID:(NSNumber *)userID;
/** * Called when session state has been changed. * * @param session CYBCallSession instance * @param state session state * * @discussion Use this to track a session state. As SDK 2.3 introduced states for session, you can now manage your own states based on this. */- (void)session:(__kindof CYBCallBaseSession *)session didChangeState:(CYBCallSessionState)state;
/** * Called when received remote audio track from user. * * @param audioTrack CYBCallAudioTrack instance * @param userID ID of user */- (void)session:(__kindof CYBCallBaseSession *)session receivedRemoteAudioTrack:(CYBCallAudioTrack *)audioTrack fromUser:(NSNumber *)userID;
/** * Called when received remote video track from user. * * @param videoTrack CYBCallVideoTrack instance * @param userID ID of user */- (void)session:(__kindof CYBCallBaseSession *)session receivedRemoteVideoTrack:(CYBCallVideoTrack *)videoTrack fromUser:(NSNumber *)userID;
/** * Called when connection is closed for user. * * @param session CYBCallSession instance * @param userID ID of user */- (void)session:(__kindof CYBCallBaseSession *)session connectionClosedForUser:(NSNumber *)userID;
/** * Called when connection is initiated with user. * * @param session CYBCallSession instance * @param userID ID of user */- (void)session:(__kindof CYBCallBaseSession *)session startedConnectingToUser:(NSNumber *)userID;
/** * Called when connection is established with user. * * @param session CYBCallSession instance * @param userID ID of user */- (void)session:(__kindof CYBCallBaseSession *)session connectedToUser:(NSNumber *)userID;
/** * Called when disconnected from user. * * @param session CYBCallSession instance * @param userID ID of user */- (void)session:(__kindof CYBCallBaseSession *)session disconnectedFromUser:(NSNumber *)userID;
/** * Called when connection failed with user. * * @param session CYBCallSession instance * @param userID ID of user */- (void)session:(__kindof CYBCallBaseSession *)session connectionFailedForUser:(NSNumber *)userID;
/** * Called when session connection state changed for a specific user. * * @param session CYBCallSession instance * @param state state - @see CYBCallConnectionState * @param userID ID of user */- (void)session:(__kindof CYBCallBaseSession *)session didChangeConnectionState:(CYBCallConnectionState)state forUser:(NSNumber *)userID;
Conference client delegate protocol methods
All protocol methods below are conference client specific, optional to be implemented and have their own explanation inlined.
/** * Called when some publisher (user) joined to the video room */func onPublisherLeft(userId: KotlinInt?) {}
/** *Called when some publisher left room */func onPublishersReceived(publishers: [KotlinInt]?) {}
/** *Called when media - audio or video type, is received */func onMediaReceived(type: String?, success\_ success: Bool) {}
/** * Called when slowLink is received. SlowLink with uplink=true means you notified several missing packets from server, while uplink=false means server is not receiving all your packets. */func onSlowLinkReceived(uplink: Bool, lost: Int32) {}
/** * Called when received errors from server */func onError(ex\_ ex: WsException?) {}
/** * Called when ConferenceSession is closed */func onSessionClosed(session: ConferenceBaseSession) {}
/** * Called when session was created on server. * * @param session CYBCallConferenceSession instance * * @discussion When this method is called, session instance that was already created by CYBCallConferenceClient * will be assigned valid session ID from server. * * @see CYBCallConferenceSession, CYBCallConferenceClient */- (void)didCreateNewSession:(CYBCallConferenceSession *)session;
/** * Called when join to session is performed and acknowledged by server. * * @param session CYBCallConferenceSession instance * @param chatDialogID chat dialog ID * @param publishersList array of user IDs, that are currently publishers * * @see CYBCallConferenceSession */- (void)session:(CYBCallConferenceSession *)session didJoinChatDialogWithID:(NSString *)chatDialogID publishersList:(NSArray <NSNumber *> *)publishersList;
/** * Called when new publisher did join. * * @param session CYBCallConferenceSession instance * @param userID new publisher user ID * * @see CYBCallConferenceSession */- (void)session:(CYBCallConferenceSession *)session didReceiveNewPublisherWithUserID:(NSNumber *)userID;
/** * Called when publisher did leave. * * @param session CYBCallConferenceSession instance * @param userID publisher that left user ID * * @see CYBCallConferenceSession */- (void)session:(CYBCallConferenceSession *)session publisherDidLeaveWithUserID:(NSNumber *)userID;
/** * Called when session did receive error from server. * * @param session CYBCallConferenceSession instance * @param error received error from server * * @note Error doesn't necessarily means that session is closed. Can be just a minor error that can be fixed/ignored. * * @see CYBCallConferenceSession */- (void)session:(CYBCallConferenceSession *)session didReceiveError:(NSError *)error;
/** * Called when slowlink was received. * * @param session CYBCallConferenceSession instance * @param uplink whether the issue is uplink or not * @param nacks number of nacks * * @discussion this callback is triggered when serber reports trouble either sending or receiving media on the * specified connection, typically as a consequence of too many NACKs received from/sent to the user in the last * second: for instance, a slowLink with uplink=true means you notified several missing packets from server, * while uplink=false means server is not receiving all your packets. * * @note useful to figure out when there are problems on the media path (e.g., excessive loss), in order to * possibly react accordingly (e.g., decrease the bitrate if most of our packets are getting lost). * * @see CYBCallConferenceSession */- (void)session:(CYBCallConferenceSession *)session didReceiveSlowlinkWithUplink:(BOOL)uplink nacks:(NSNumber *)nacks;
/** * Called when media receiving state was changed on server. * * @param session CYBCallConferenceSession instance * @param mediaType media type * @param receiving whether media is receiving by server * * @see CYBCallConferenceSession, CYBCallConferenceMediaType */- (void)session:(CYBCallConferenceSession *)session didChangeMediaStateWithType:(CYBCallConferenceMediaType)mediaType receiving:(BOOL)receiving;
/** * Session did initiate close request. * * @param session CYBCallConferenceSession instance * * @discussion 'sessionDidClose:withTimeout:' will be called after server will close session with callback * * @see CYBCallConferenceSession */- (void)sessionWillClose:(CYBCallConferenceSession *)session;
/** * Called when session was closed completely on server. * * @param session CYBCallConferenceSession instance * @param timeout whether session was closed due to timeout on server * * @see CYBCallConferenceSession */- (void)sessionDidClose:(CYBCallConferenceSession *)session withTimeout:(BOOL)timeout;
Conference client interface
ConferenceCalls is a singleton based class which is used to create and operate with conference sessions.
//MARK: ConferenceCallbacklet conferenceType = CallType.video
ConnectyCube().conferenceCalls.createSession(userId: userId, callType: conferenceType, callback: self)
extension YourClass: ConferenceCallback { func onSuccess(result: Any?) { let conferenceSession = result as! ConferenceSession }
func onError(ex: WsException) { }
}
In order to create new conference session you should use method below:
class ConferenceCallbackJoinDialog: ConferenceCallback { func onSuccess(result: Any?) { let userIds: [Int] = result as! [Int] }
func onError(ex: WsException) { }}
conferenceSession.joinDialog(dialogId: dialogId, conferenceRole: conferenceRole, callback: ConferenceCallbackJoinDialog())
CYBCallConferenceClient is a singleton based class which is used to create and operate with conference sessions. It has observer (delegates) manager, which can be activated/deactivated with two simple methods:
/** * Add delegate to the observers list. * * @param delegate delegate that conforms to CYBCallConferenceClientDelegate protocol * * @see CYBCallConferenceClientDelegate */- (void)addDelegate:(id<CYBCallConferenceClientDelegate>)delegate;
/** * Remove delegate from the observers list. * * @param delegate delegate that conforms to CYBCallConferenceClientDelegate protocol * * @see CYBCallConferenceClientDelegate */- (void)removeDelegate:(id<CYBCallConferenceClientDelegate>)delegate;
Delegate should conform to CYBCallConferenceClientDelegate protocol, which is inherited from base client delegate.
In order to create new conference session you should use method below:
/** * Send create session request. * * @note Returns session without ID. When session will be created on server * ID will be assigned and session will be returned in 'didCreateNewSession:' callback. * * @see CYBCallConferenceClientDelegate * * @param chatDialogID chat dialog ID */- (CYBCallConferenceSession *)createSessionWithChatDialogID:(NSString *)chatDialogID;
It will create session locally first, without session ID, until server will perform a didCreateNewSession:
callback in CYBCallConferenceClientDelegate protocol, where session ID will be assigned and session will receive its CYBCallSessionStateNew state. After that you can join or leave (destroy) it, etc. Conference session is explained in the following paragraph.
Conference session
ConferenceSession is inherited from base session class, and has all of its basics, such as state
, currentUserId
, localMediaStream
, ability to get remote audio and video tracks for a specific user IDs.
You can subscribe and unsubscribe from publishers using methods below.
conferenceSession.subscribeToPublisher(publisherId: publisherId)
conferenceSession.unsubscribeFromPublisher(publisherId: publisherId)
And in order to close/leave session you can perform the following method:
conferenceSession.leave()
Note
You do not need to be joined as publisher in order to perform subscription based operations in session.
CYBCallConferenceSession is inherited from base session class, and has all of its basics, such as state
, currentUserID
, localMediaStream
, ability to get remote audio and video tracks for a specific user IDs:
/** * Remote audio track with opponent user ID. * * @param userID opponent user ID * * @return CYBCallAudioTrack audio track instance */- (CYBCallAudioTrack *)remoteAudioTrackWithUserID:(NSNumber *)userID;
/** * Remote video track with opponent user ID. * * @param userID opponent user ID * * @return CYBCallVideoTrack video track instance */- (CYBCallVideoTrack *)remoteVideoTrackWithUserID:(NSNumber *)userID;
and ability to get a connection state for a specific user ID if his connection is opened:
/** * Connection state for opponent user ID. * * @param userID opponent user ID * * @return CYBCallConnectionState connection state for opponent user ID */- (CYBCallConnectionState)connectionStateForUser:(NSNumber *)userID;
See CYBCallBaseSession class for more inline documentation. As for conference specific methods, conference session ID is NSNumber. Each conference session is tied to a specific ConnectyCube dialog ID (NSString).
It also has a publishers list property. But publisher list will be only valid if you perform join to that session as publisher using method below:
/** * Perform join room as publisher. * * @discussion 'session:didJoinChatDialogWithID:publishersList:' will be called upon successful join. * * @see CYBCallConferenceClientDelegate */- (void)joinAsPublisher;
This method joins session and will publish your feed (make you an active publisher in room). Everyone in room will be able to subscribe and receive your feed.
Note
Only can be used when session has a valid session ID, e.g. is created on server and notified to you with
didCreateNewSession:
callback from CYBCallConferenceClientDelegate protocol.
You can subscribe and unsubscribe from publishers using methods below.
Note
You do not need to be joined as publisher in order to perform subscription based operations in session.
/** * Subscribe to publisher's with user ID feed. * * @param userID active publisher's user ID * * @discussion If you want to receive publishers feeds, you need to subscribe to them. * * @note User must be an active publisher. */- (void)subscribeToUserWithID:(NSNumber *)userID;
/** * Unsubscribe from publisher's with user ID feed. * * @param userID active publisher's user ID * * @discussion Do not need to be used when publisher did leave room, in that case unsibscribing will be performing automatically. Use if you need to unsubscribe from active publisher's feed. * * @note User must be an active publisher. */- (void)unsubscribeFromUserWithID:(NSNumber *)userID;
Note
These methods can also be used only when session has a valid session ID, e.g. is created on server and notified to you with
didCreateNewSession:
callback from CYBCallConferenceClientDelegate protocol.
And in order to close/leave session you can perform the following method:
/** * Leave chat room and close session. * * @discussion 'sessionWillClose:' will be called when all connection are closed, 'sessionDidClose:withTimeout:' will be called when session will be successfully closed by server. */- (void)leave;
Note
This method can be called in any state of the session and will always close it no matter what.
Examples and implementations
sample-videochat-conference-objc is a great example of our ConnectyCubeCalls Conference module, classes to look at: CallViewController.