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

Remote Participants·续 - 图1Docs

{"@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


Skip to content

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.