Working with Individual Participants
Each remote participant in a RealtimeKit meeting is represented by an RtkRemoteParticipant instance that provides access to
their properties, media states, and participant-specific controls.
The RtkRemoteParticipant object provides the following properties:
id: Session-specific identifier generated when the participant joins meeting session (also known aspeerId). A single user joining from multiple devices or tabs will have differentidvalues for each connection.userId: Permanent identifier of the participant generated when adding the participant to a meeting. This remains unchanged across multiple connections, sessions, or devices.name: Display name of the participantpicture: String URL to the participant's display picture (if any).isHost: Boolean value whether this participant has host privilegescustomParticipantId: Custom identifier that can be set while adding participant to a meeting by customervideoEnabled: Whether the participant's camera is currently enabledaudioEnabled: Whether the participant's microphone is currently unmutedscreenshareEnabled:stageStatus: Indicates the participant's current stage status (applicable only in stage-enabled meetings)isPinned: Whether this participant is currently pinned in the meetingpresetName: Name of the preset applied to this participant while adding to meeting
// Example: Access participant properties
final participant = meeting.participants.joined[0];
print('Participant: ${participant.name} (ID: ${participant.id})');
print('Audio: ${participant.audioEnabled ? "On" : "Off"}');
print('Video: ${participant.videoEnabled ? "On" : "Off"}');
Finding Specific Participants
You can search for specific participants using standard Dart list operations:
// Find a participant by peer ID
final participant = meeting.participants.joined
.where((p) => p.id == "<peerId>")
.firstOrNull;
Displaying Participant Video
To display a participant's video stream in your UI, use the video view methods which return a Widget that you can place directly in your UI hierarchy.
// Create a widget to display the participant's camera video
final cameraView = VideoView(meetingParticipant: participant);
// Create a widget to display the participant's screen share
final screenShareView = ScreenshareView(meetingParticipant: participant);
Host Controls
If your local user has the necessary host permissions, you can perform the following actions on individual remote participants:
Disabling Media
// Disable a remote participant's video
participant.disableVideo(onResult: (e) {
// handle error if any
});
// Disable a remote participant's audio
participant.disableAudio(onResult: (e) {
// handle error if any
});
Removing Participant
// Remove the participant from the meeting
participant.kick();
Required Permission: permissions.host.canDisableVideo, permissions.host.canDisableAudio must be true
Pin-Unpin Participant
// Pin a remote participant
participant.pin();
// Unpin a previously pinned participant
participant.unpin();
Required Permission: permissions.host.canPinParticipant must be true
For operations that affect all participants at once, see the Participants Host Controls documentation.
Individual Participant Events
To receive updates about a specific participant's state changes, implement the RtkParticipantUpdateListener interface and add the listener on that participant using participant.addParticipantEventsListener().
Available event callbacks:
onAudioUpdate: Called when the participant's audio state changesonVideoUpdate: Called when the participant's video state changesonPinned: Called when the participant is pinnedonUnpinned: Called when the participant is unpinnedonScreenShareUpdate: Called when the participant's screen sharing state changesonUpdate: Called whenever any property of the participant changes
// Create a listener class
class ParticipantUpdateHandler extends RtkParticipantUpdateListener {
void onVideoUpdate(RtkRemoteParticipant participant, bool isEnabled) {
print("${participant.name}'s video is now ${isEnabled ? 'on' : 'off'}");
}
void onAudioUpdate(RtkRemoteParticipant participant, bool isEnabled) {
print("${participant.name}'s audio is now ${isEnabled ? 'on' : 'off'}");
}
void onPinned(RtkRemoteParticipant participant) {
print("${participant.name} was pinned");
}
void onUnpinned(RtkRemoteParticipant participant) {
print("${participant.name} was unpinned");
}
void onScreenShareUpdate(RtkRemoteParticipant participant, bool isEnabled) {
print("${participant.name}'s screen-share is now ${isEnabled ? 'on' : 'off'}");
}
void onUpdate(RtkRemoteParticipant participant) {
print("${participant.name} was updated");
}
}
// Register the listener with a specific participant
final listener = ParticipantUpdateHandler();
participant.addParticipantUpdateListener(listener);
// When you're done listening to events, remove the listener
participant.removeParticipantUpdateListener(listener);
For events that apply to all participants collectively, see all Participants Events documentation.