Manage participants during a call with actions like muting, pausing video, and pinning. These features help maintain order in group calls and highlight important speakers.
By default, all participants who join a call have moderator access and can perform these actions. Implementing role-based moderation (e.g., restricting actions to hosts only) is the responsibility of the app developer based on their use case.
Mute a Participant
Mute a specific participant’s audio. This affects the participant for all users in the call.
CallSession.shared.muteParticipant(participantId: participant.pid)
[[CallSession shared] muteParticipantWithParticipantId:participant.pid];
Pause Participant Video
Pause a specific participant’s video. This affects the participant for all users in the call.
CallSession.shared.pauseParticipantVideo(participantId: participant.pid)
[[CallSession shared] pauseParticipantVideoWithParticipantId:participant.pid];
Pin a Participant
Pin a participant to keep them prominently displayed regardless of who is speaking. Useful for keeping focus on a presenter or important speaker.
// Pin a participant
CallSession.shared.pinParticipant()
// Unpin (returns to automatic speaker highlighting)
CallSession.shared.unPinParticipant()
// Pin a participant
[[CallSession shared] pinParticipant];
// Unpin (returns to automatic speaker highlighting)
[[CallSession shared] unPinParticipant];
Pinning a participant only affects your local view. Other participants can pin different users independently.
Listen for Participant Events
Monitor participant state changes using ParticipantEventListener:
class CallViewController: UIViewController, ParticipantEventListener {
override func viewDidLoad() {
super.viewDidLoad()
CallSession.shared.addParticipantEventListener(self)
}
deinit {
CallSession.shared.removeParticipantEventListener(self)
}
func onParticipantJoined(participant: Participant) {
print("\(participant.name ?? "") joined the call")
updateParticipantList()
}
func onParticipantLeft(participant: Participant) {
print("\(participant.name ?? "") left the call")
updateParticipantList()
}
func onParticipantListChanged(participants: [Participant]) {
print("Participant count: \(participants.count)")
refreshParticipantList(participants)
}
func onParticipantAudioMuted(participant: Participant) {
print("\(participant.name ?? "") was muted")
updateMuteIndicator(participant, muted: true)
}
func onParticipantAudioUnmuted(participant: Participant) {
print("\(participant.name ?? "") was unmuted")
updateMuteIndicator(participant, muted: false)
}
func onParticipantVideoPaused(participant: Participant) {
print("\(participant.name ?? "") video paused")
showParticipantAvatar(participant)
}
func onParticipantVideoResumed(participant: Participant) {
print("\(participant.name ?? "") video resumed")
showParticipantVideo(participant)
}
func onDominantSpeakerChanged(participant: Participant) {
print("\(participant.name ?? "") is now speaking")
highlightActiveSpeaker(participant)
}
// Other callbacks...
func onParticipantHandRaised(participant: Participant) {}
func onParticipantHandLowered(participant: Participant) {}
func onParticipantStartedScreenShare(participant: Participant) {}
func onParticipantStoppedScreenShare(participant: Participant) {}
func onParticipantStartedRecording(participant: Participant) {}
func onParticipantStoppedRecording(participant: Participant) {}
}
@interface CallViewController () <ParticipantEventListener>
@end
@implementation CallViewController
- (void)viewDidLoad {
[super viewDidLoad];
[[CallSession shared] addParticipantEventListener:self];
}
- (void)dealloc {
[[CallSession shared] removeParticipantEventListener:self];
}
- (void)onParticipantJoinedWithParticipant:(Participant *)participant {
NSLog(@"%@ joined the call", participant.name);
[self updateParticipantList];
}
- (void)onParticipantLeftWithParticipant:(Participant *)participant {
NSLog(@"%@ left the call", participant.name);
[self updateParticipantList];
}
- (void)onParticipantListChangedWithParticipants:(NSArray<Participant *> *)participants {
NSLog(@"Participant count: %lu", (unsigned long)participants.count);
[self refreshParticipantList:participants];
}
- (void)onParticipantAudioMutedWithParticipant:(Participant *)participant {
NSLog(@"%@ was muted", participant.name);
}
- (void)onParticipantAudioUnmutedWithParticipant:(Participant *)participant {
NSLog(@"%@ was unmuted", participant.name);
}
- (void)onDominantSpeakerChangedWithParticipant:(Participant *)participant {
NSLog(@"%@ is now speaking", participant.name);
}
// Other callbacks...
@end
Participant Object
The Participant object contains information about each call participant:
| Property | Type | Description |
|---|
uid | String | Unique identifier (CometChat user ID) |
name | String | Display name |
avatar | String | URL of avatar image |
pid | String | Participant ID for this call session |
role | String | Role in the call |
audioMuted | Bool | Whether audio is muted |
videoPaused | Bool | Whether video is paused |
isPinned | Bool | Whether pinned in layout |
isPresenting | Bool | Whether screen sharing |
raisedHandTimestamp | Int | Timestamp when hand was raised (0 if not raised) |
To hide the participant list button in the call UI:
let sessionSettings = CometChatCalls.sessionSettingsBuilder
.hideParticipantListButton(true)
.build()
SessionSettings *sessionSettings = [[[CometChatCalls sessionSettingsBuilder]
hideParticipantListButton:YES]
build];