Remote Participants·续
Use the useRealtimeKitClient hook to access the meeting object:
import { useRealtimeKitClient } from "@cloudflare/realtimekit-react";
const [meeting] = useRealtimeKitClient();
// Set the view mode to paginated
await meeting.participants.setViewMode("PAGINATED");
// Set the view mode to active grid
await meeting.participants.setViewMode("ACTIVE_GRID");
Android SDK uses active grid mode by default on page 0. If you switch to the next page, it automatically switches to paginated mode.
iOS SDK uses active grid mode by default on page 0. If you switch to the next page, it automatically switches to paginated mode.
// Set the view mode to paginated
await meeting.participants.setViewMode("PAGINATED");
// Set the view mode to active grid
await meeting.participants.setViewMode("ACTIVE_GRID");
Set page in paginated mode
// Switch to second page
await meeting.participants.setPage(2);
import { useRealtimeKitClient } from "@cloudflare/realtimekit-react";
const [meeting] = useRealtimeKitClient();
// Switch to second page
await meeting.participants.setPage(2);
// Switch to first page
meeting.participants.setPage(1)
// Switch to first page
meeting.participants.setPage(1)
// Switch to second page
await meeting.participants.setPage(2);
Monitor view mode
const viewMode = meeting.participants.viewMode;
const currentPage = meeting.participants.currentPage;
const viewMode = useRealtimeKitSelector((m) => m.participants.viewMode);
const currentPage = useRealtimeKitSelector((m) => m.participants.currentPage);
Monitoring view mode is not available on this platform.
const viewMode = useRealtimeKitSelector((m) => m.participants.viewMode);
const currentPage = useRealtimeKitSelector((m) => m.participants.currentPage);
Host Controls
The participant object allows the host several controls. These can be selected while creating the host preset.
Media controls
With the correct permissions, the host can disable media for remote participants.
const participant = meeting.participants.joined.get(participantId);
// Disable a participant's video stream
participant.disableVideo();
// Disable a participant's audio stream
participant.disableAudio();
// Kick a participant from the meeting
participant.kick();
import { useRealtimeKitClient } from "@cloudflare/realtimekit-react";
const [meeting] = useRealtimeKitClient();
const participant = meeting.participants.joined.get(participantId);
// Disable a participant's video stream
participant.disableVideo();
// Disable a participant's audio stream
participant.disableAudio();
// Kick a participant from the meeting
participant.kick();
val participant = meeting.participants.joined.firstOrNull { it.id == participantId }
participant?.let { pcpt ->
// Disable a participant's video stream
val videoError = pcpt.disableVideo()
// Disable a participant's audio stream
val audioError = pcpt.disableAudio()
// Kick a participant from the meeting
val kickError = pcpt.kick()
}
if let participant = meeting.participants.joined.first(where: { $0.id == participantId }) {
// Disable a participant's video stream
let videoError: HostError? = participant.disableVideo()
// Disable a participant's audio stream
let audioError: HostError? = participant.disableAudio()
// Kick a participant from the meeting
let kickError: HostError? = participant.kick()
}
const participant = meeting.participants.joined.get(participantId);
// Disable a participant's video stream
participant.disableVideo();
// Disable a participant's audio stream
participant.disableAudio();
// Kick a participant from the meeting
participant.kick();
Waiting room controls
The waiting room allows the host to control which users can join your meeting and when. They can either choose to accept or reject the request.
You can also automate this flow so that users join the meeting automatically when the host joins the meeting, using presets.
Accept waiting room request
await meeting.participants.acceptWaitingRoomRequest(participantId);
import { useRealtimeKitClient } from "@cloudflare/realtimekit-react";
const [meeting] = useRealtimeKitClient();
await meeting.participants.acceptWaitingRoomRequest(participantId);
meeting.participants.acceptWaitingRoomRequest(participantId)
meeting.participants.acceptWaitingRoomRequest(id: participantId)
await meeting.participants.acceptWaitingRoomRequest(participantId);
Reject waiting room request
await meeting.participants.rejectWaitingRoomRequest(participantId);
import { useRealtimeKitClient } from "@cloudflare/realtimekit-react";
const [meeting] = useRealtimeKitClient();
await meeting.participants.rejectWaitingRoomRequest(participantId);
meeting.participants.rejectWaitingRoomRequest(participantId)
meeting.participants.rejectWaitingRoomRequest(participantId)
await meeting.participants.rejectWaitingRoomRequest(participantId);
Pin participants
The host can choose to pin or unpin participants to the grid.
const participant = meeting.participants.joined.get(participantId);
// Pin a participant
await participant.pin();
// Unpin a participant
await participant.unpin();
import { useRealtimeKitClient } from "@cloudflare/realtimekit-react";
const [meeting] = useRealtimeKitClient();
const participant = meeting.participants.joined.get(participantId);
// Pin a participant
await participant.pin();
// Unpin a participant
await participant.unpin();
val participant = meeting.participants.joined.firstOrNull { it.id == participantId }
participant?.let { pcpt ->
// Pin a participant
val pinError = pcpt.pin()
// Unpin a participant
val unpinError = pcpt.unpin()
}
if let participant = meeting.participants.joined.first(where: { $0.id == participantId }) {
// Pin a participant
let pinError: HostError? = participant.pin()
// Unpin a participant
let unpinError: HostError? = participant.unpin()
}
const participant = meeting.participants.joined.get(participantId);
// Pin a participant
await participant.pin();
// Unpin a participant
await participant.unpin();
Update participant permissions
The host can modify the permissions for a participant. Permissions for a participant are defined by their preset.
Note
When the host updates the permissions for a participant, the preset is not modified and the permission changes are limited to the duration of the meeting.
Updating participant permissions is not available on this platform.
First, find the participant(s) you want to update.
const participantIds = meeting.participants.joined
.toArray()
.filter((e) => e.name.startsWith("John"))
.map((p) => p.id);
Use the updatePermissions method to modify the permissions for the participant.
// Allow file upload permissions in public chat
const newPermissions = {
chat: {
public: {
files: true,
},
},
};
meeting.participants.updatePermissions(participantIds, newPermissions);
The following permissions can be modified:
interface UpdatedPermissions {
polls?: {
canCreate?: boolean;
canVote?: boolean;
};
plugins?: {
canClose?: boolean;
canStart?: boolean;
};
chat?: {
public?: {
canSend?: boolean;
text?: boolean;
files?: boolean;
};
private?: {
canSend?: boolean;
text?: boolean;
files?: boolean;
};
};
}
Display participant videos
To play a participant's video track on a <video> element:
<video class="participant-video" id="participant-video"></video>
// Get the video element
const videoElement = document.getElementById("participant-video");
// Get the participant
const participant = meeting.participants.joined.get(participantId);
// Register the video element
participant.registerVideoElement(videoElement);
For local user preview (video not sent to other users):
meeting.self.registerVideoElement(videoElement, true);
Clean up when the video element is no longer needed:
participant.deregisterVideoElement(videoElement);
To play a participant's video track on a <video> element:
import { useRealtimeKitClient } from "@cloudflare/realtimekit-react";
const [meeting] = useRealtimeKitClient();
// Get the video element
const videoElement = document.getElementById("participant-video");
// Get the participant
const participant = meeting.participants.joined.get(participantId);
// Register the video element
participant.registerVideoElement(videoElement);
// Clean up when the video element is no longer needed
participant.deregisterVideoElement(videoElement);
For local user preview (video not sent to other users):
meeting.self.registerVideoElement(videoElement, true);
Call participant.getVideoView() which returns a View that renders the participant's video stream:
// Get video view of a given participant
val videoView = participant.getVideoView()
// Get screen share video view
val screenShareView = participant.getScreenShareVideoView()
Call participant.getVideoView() which returns a UIView that renders the participant's video stream:
// Get video view of a given participant
let videoView = participant.getVideoView()
// Get screen share video view
let screenShareView = participant.getScreenShareVideoView()
Use useRealtimeKitSelector to get the video track and render it with RTCView:
import { useRealtimeKitSelector } from "@cloudflare/realtimekit-react-native";
import { MediaStream, RTCView } from "@cloudflare/react-native-webrtc";
function VideoView() {
const { videoTrack } = useRealtimeKitSelector((m) =>
m.participants.active.toArray(),
)[0];
const stream = new MediaStream(undefined);
stream.addTrack(videoTrack);
return (
<RTCView
objectFit="cover"
style={{ flex: 1 }}
streamURL={stream.toURL()}
mirror={true}
zOrder={1}
/>
);
}
Was this helpful?
YesNo
On this page
{"@context":"https://schema.org","@type":"WebPage","@id":"https://developers.cloudflare.com/realtime/realtimekit/humans/core/remote-participants/#page","headline":"Remote Participants","description":"Access participant data, display videos, and handle events for remote participants in RealtimeKit.","url":"https://developers.cloudflare.com/realtime/realtimekit/humans/core/remote-participants/","inLanguage":"en","image":"https://developers.cloudflare.com/realtime/realtimekit/humans/core/remote-participants/og.png?v=56dbd553429232da","dateModified":"2026-10-19","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
description: Events emitted by RealtimeKit participants for join, leave, pin, and grid changes. title: Events image: https://developers.cloudflare.com/realtime/realtimekit/humans/core/remote-participants/events/og.png?v=dcd0b2d5addfa5ab
Documentation Index
Fetch the complete documentation index at: https://developers.cloudflare.com/realtime/llms.txt
Use this file to discover all available pages before exploring further.
Docs