← Cloudflare Realtime / realtime / realtimekit / core / remote-participants
События
На этой странице представлен обзор событий, генерируемых meeting.participants и связанные карты участников, которые можно использовать для синхронизации интерфейса с такими изменениями, как присоединение или выход участников, обновления закрепления, смена активного спикера, а также изменения режима сетки или страницы.
События сетки
Эти события позволяют отслеживать изменения сетки.
Изменение режима отображения
Срабатывает, когда режим отображения переключается между ACTIVE_GRID и PAGINATED.
meeting.participants.on(
"viewModeChanged",
({ viewMode, currentPage, pageCount }) => {
console.log("view mode changed", viewMode);
},
);Срабатывает, когда режим отображения переключается между ACTIVE_GRID и PAGINATED.
const viewMode = useRealtimeKitSelector((m) => m.participants.viewMode);Или используйте обработчик события:
meeting.participants.on(
"viewModeChanged",
({ viewMode, currentPage, pageCount }) => {
console.log("view mode changed", viewMode);
},
);Это событие недоступно на данной платформе.
Срабатывает, когда режим отображения переключается между ACTIVE_GRID и PAGINATED.
const viewMode = useRealtimeKitSelector((m) => m.participants.viewMode);Или используйте обработчик события:
meeting.participants.on(
"viewModeChanged",
({ viewMode, currentPage, pageCount }) => {
console.log("view mode changed", viewMode);
},
);Изменение страницы
Срабатывает, когда меняется страница в постраничном режиме.
meeting.participants.on(
"pageChanged",
({ viewMode, currentPage, pageCount }) => {
console.log("page changed", currentPage);
},
);Срабатывает, когда меняется страница в постраничном режиме.
const currentPage = useRealtimeKitSelector((m) => m.participants.currentPage);
const pageCount = useRealtimeKitSelector((m) => m.participants.pageCount);Это событие недоступно на данной платформе.
Срабатывает, когда меняется страница в постраничном режиме.
const currentPage = useRealtimeKitSelector((m) => m.participants.currentPage);
const pageCount = useRealtimeKitSelector((m) => m.participants.pageCount);Активный спикер
Срабатывает, когда участник начинает говорить.
meeting.participants.on("activeSpeaker", (participant) => {
console.log(`${participant.id} is currently speaking`);
});const activeSpeaker = useRealtimeKitSelector(
(m) => m.participants.lastActiveSpeaker,
);Или используйте обработчик события:
meeting.participants.on("activeSpeaker", (participant) => {
console.log(`${participant.id} is currently speaking`);
});meeting.addParticipantsEventListener(object : RtkParticipantsEventListener {
override fun onActiveSpeakerChanged(participant: RtkRemoteParticipant?) {
participant?.let {
println("${it.id} is currently speaking")
}
}
})extension MeetingViewModel: RtkParticipantsEventListener {
func onActiveSpeakerChanged(participant: RtkRemoteParticipant?) {
if let participant = participant {
print("\(participant.id) is currently speaking")
}
}
}
meeting.addParticipantsEventListener(self)const activeSpeaker = useRealtimeKitSelector(
(m) => m.participants.lastActiveSpeaker,
);Или используйте обработчик события:
meeting.participants.on("activeSpeaker", (participant) => {
console.log(`${participant.id} is currently speaking`);
});События карты участников
Эти события позволяют отслеживать изменения в картах удалённых участников. Используйте их, чтобы получать уведомления о том, что участник присоединился к встрече или покинул её, был закреплён или переместился за пределы сетки.
Участник присоединился
Срабатывает, когда любой участник присоединяется к встрече.
meeting.participants.joined.on("participantJoined", (participant) => {
console.log(`A participant with id "${participant.id}" has joined`);
});const joinedParticipants = useRealtimeKitSelector((m) => m.participants.joined);Или используйте обработчик события:
meeting.participants.joined.on("participantJoined", (participant) => {
console.log(`A participant with id "${participant.id}" has joined`);
});meeting.addParticipantsEventListener(object : RtkParticipantsEventListener {
override fun onParticipantJoin(participant: RtkRemoteParticipant) {
println("A participant with id ${participant.id} has joined")
}
})extension MeetingViewModel: RtkParticipantsEventListener {
func onParticipantJoin(participant: RtkRemoteParticipant) {
print("A participant with id \(participant.id) has joined")
}
}
meeting.addParticipantsEventListener(self)const joinedParticipants = useRealtimeKitSelector((m) => m.participants.joined);Или используйте обработчик события:
meeting.participants.joined.on("participantJoined", (participant) => {
console.log(`A participant with id "${participant.id}" has joined`);
});Участник покинул встречу
Срабатывает, когда любой участник покидает встречу.
meeting.participants.joined.on("participantLeft", (participant) => {
console.log(`A participant with id "${participant.id}" has left the meeting`);
});const joinedParticipants = useRealtimeKitSelector((m) => m.participants.joined);Или используйте обработчик события:
meeting.participants.joined.on("participantLeft", (participant) => {
console.log(`A participant with id "${participant.id}" has left the meeting`);
});meeting.addParticipantsEventListener(object : RtkParticipantsEventListener {
override fun onParticipantLeave(participant: RtkRemoteParticipant) {
println("A participant with id ${participant.id} has left the meeting")
}
})extension MeetingViewModel: RtkParticipantsEventListener {
func onParticipantLeave(participant: RtkRemoteParticipant) {
print("A participant with id \(participant.id) has left the meeting")
}
}
meeting.addParticipantsEventListener(self)const joinedParticipants = useRealtimeKitSelector((m) => m.participants.joined);Или используйте обработчик события:
meeting.participants.joined.on("participantLeft", (participant) => {
console.log(`A participant with id "${participant.id}" has left the meeting`);
});Изменение активных участников
Каждый participant map генерирует participantJoined и participantLeft события:
// Listen for when a participant gets pinned
meeting.participants.pinned.on("participantJoined", (participant) => {
console.log(`Participant ${participant.name} got pinned`);
});
// Listen for when a participant gets unpinned
meeting.participants.pinned.on("participantLeft", (participant) => {
console.log(`Participant ${participant.name} got unpinned`);
});meeting.addParticipantsEventListener(object : RtkParticipantsEventListener {
override fun onActiveParticipantsChanged(active: List<RtkRemoteParticipant>) {
// Called when active participants change
}
})extension MeetingViewModel: RtkParticipantsEventListener {
func onActiveParticipantsChanged(active: [RtkRemoteParticipant]) {
// Called when active participants change
}
}
meeting.addParticipantsEventListener(self)Участник закреплён
Срабатывает, когда участник закрепляется.
meeting.participants.joined.on("pinned", (participant) => {
console.log(`Participant with id "${participant.id}" was pinned`);
});const pinnedParticipants = useRealtimeKitSelector((m) => m.participants.pinned);Или используйте обработчик события:
meeting.participants.joined.on("pinned", (participant) => {
console.log(`Participant with id "${participant.id}" was pinned`);
});meeting.addParticipantsEventListener(object : RtkParticipantsEventListener {
override fun onParticipantPinned(participant: RtkRemoteParticipant) {
println("Participant with id ${participant.id} was pinned")
}
})extension MeetingViewModel: RtkParticipantsEventListener {
func onParticipantPinned(participant: RtkRemoteParticipant) {
print("Participant with id \(participant.id) was pinned")
}
}
meeting.addParticipantsEventListener(self)const pinnedParticipants = useRealtimeKitSelector((m) => m.participants.pinned);Или используйте обработчик события:
meeting.participants.joined.on("pinned", (participant) => {
console.log(`Participant with id "${participant.id}" was pinned`);
});Участник откреплён
Срабатывает, когда с участника снимается закрепление.
meeting.participants.joined.on("unpinned", (participant) => {
console.log(`Participant with id "${participant.id}" was unpinned`);
});const pinnedParticipants = useRealtimeKitSelector((m) => m.participants.pinned);Или используйте обработчик события:
meeting.participants.joined.on("unpinned", (participant) => {
console.log(`Participant with id "${participant.id}" was unpinned`);
});meeting.addParticipantsEventListener(object : RtkParticipantsEventListener {
override fun onParticipantUnpinned(participant: RtkRemoteParticipant) {
println("Participant with id ${participant.id} was unpinned")
}
})extension MeetingViewModel: RtkParticipantsEventListener {
func onParticipantUnpinned(participant: RtkRemoteParticipant) {
print("Participant with id \(participant.id) was unpinned")
}
}
meeting.addParticipantsEventListener(self)const pinnedParticipants = useRealtimeKitSelector((m) => m.participants.pinned);Или используйте обработчик события:
meeting.participants.joined.on("unpinned", (participant) => {
console.log(`Participant with id "${participant.id}" was unpinned`);
});События участника
Вы можете отслеживать изменения конкретного участника с помощью следующих событий.
Обновление видео
Срабатывает, когда любой участник включает или выключает видео.
meeting.participants.joined.on("videoUpdate", (participant) => {
console.log(
`A participant with id "${participant.id}" updated their video track`,
);
if (participant.videoEnabled) {
// Use participant.videoTrack
} else {
// Handle stop video
}
});// Check for one participant
const videoEnabled = useRealtimeKitSelector(
(m) => m.participants.joined.get(participantId)?.videoEnabled,
);
// All video enabled participants
const videoEnabledParticipants = useRealtimeKitSelector((m) =>
m.participants.joined.toArray().filter((p) => p.videoEnabled),
);meeting.addParticipantEventListener(object : RtkParticipantEventListener {
override fun onVideoUpdate(participant: RtkRemoteParticipant, isEnabled: Boolean) {
println("Participant ${participant.id} video is now ${if (isEnabled) "enabled" else "disabled"}")
}
})extension MeetingViewModel: RtkParticipantEventListener {
func onVideoUpdate(participant: RtkRemoteParticipant, isEnabled: Bool) {
print("Participant \(participant.id) video is now \(isEnabled ? "enabled" : "disabled")")
}
}
meeting.addParticipantEventListener(self)// Check for one participant
const videoEnabled = useRealtimeKitSelector(
(m) => m.participants.joined.get(participantId)?.videoEnabled,
);
// All video enabled participants
const videoEnabledParticipants = useRealtimeKitSelector((m) =>
m.participants.joined.toArray().filter((p) => p.videoEnabled),
);Обновление аудио
Срабатывает, когда любой участник включает или выключает звук.
meeting.participants.joined.on("audioUpdate", (participant) => {
console.log(
`A participant with id "${participant.id}" updated their audio track`,
);
if (participant.audioEnabled) {
// Use participant.audioTrack
} else {
// Handle stop audio
}
});// Check for one participant
const audioEnabled = useRealtimeKitSelector(
(m) => m.participants.joined.get(participantId)?.audioEnabled,
);
// All audio enabled participants
const audioEnabledParticipants = useRealtimeKitSelector((m) =>
m.participants.joined.toArray().filter((p) => p.audioEnabled),
);meeting.addParticipantEventListener(object : RtkParticipantEventListener {
override fun onAudioUpdate(participant: RtkRemoteParticipant, isEnabled: Boolean) {
println("Participant ${participant.id} audio is now ${if (isEnabled) "enabled" else "disabled"}")
}
})extension MeetingViewModel: RtkParticipantEventListener {
func onAudioUpdate(participant: RtkRemoteParticipant, isEnabled: Bool) {
print("Participant \(participant.id) audio is now \(isEnabled ? "enabled" : "disabled")")
}
}
meeting.addParticipantEventListener(self)// Check for one participant
const audioEnabled = useRealtimeKitSelector(
(m) => m.participants.joined.get(participantId)?.audioEnabled,
);
// All audio enabled participants
const audioEnabledParticipants = useRealtimeKitSelector((m) =>
m.participants.joined.toArray().filter((p) => p.audioEnabled),
);Обновление демонстрации экрана
Срабатывает, когда любой участник начинает или прекращает демонстрацию экрана.
meeting.participants.joined.on("screenShareUpdate", (participant) => {
console.log(
`A participant with id "${participant.id}" updated their screen share`,
);
if (participant.screenShareEnabled) {
// Use participant.screenShareTracks
} else {
// Handle stop screen share
}
});// Check for one participant
const screensharingParticipant = useRealtimeKitSelector((m) =>
m.participants.joined.toArray().find((p) => p.screenShareEnabled),
);
// All screen sharing participants
const screenSharingParticipants = useRealtimeKitSelector((m) =>
m.participants.joined.toArray().filter((p) => p.screenShareEnabled),
);meeting.addParticipantEventListener(object : RtkParticipantEventListener {
override fun onScreenShareUpdate(participant: RtkRemoteParticipant, isEnabled: Boolean) {
println("Participant ${participant.id} screen share is now ${if (isEnabled) "enabled" else "disabled"}")
}
})extension MeetingViewModel: RtkParticipantEventListener {
func onScreenShareUpdate(participant: RtkRemoteParticipant, isEnabled: Bool) {
print("Participant \(participant.id) screen share is now \(isEnabled ? "enabled" : "disabled")")
}
}
meeting.addParticipantEventListener(self)// Check for one participant
const screensharingParticipant = useRealtimeKitSelector((m) =>
m.participants.joined.toArray().find((p) => p.screenShareEnabled),
);
// All screen sharing participants
const screenSharingParticipants = useRealtimeKitSelector((m) =>
m.participants.joined.toArray().filter((p) => p.screenShareEnabled),
);Оценка качества сети
Отслеживайте качество сети участника с помощью mediaScoreUpdate событие.
meeting.participants.joined.on(
"mediaScoreUpdate",
({ participantId, kind, isScreenshare, score, scoreStats }) => {
if (kind === "video") {
console.log(
`Participant ${participantId}'s ${isScreenshare ? "screenshare" : "video"} quality score is`,
score,
);
}
if (kind === "audio") {
console.log(
`Participant ${participantId}'s audio quality score is`,
score,
);
}
if (score < 5) {
console.log(`Participant ${participantId}'s media quality is poor`);
}
},
);Отслеживайте качество сети участника с помощью mediaScoreUpdate событие.
import { useEffect } from "react";
// Use event listener for media score updates
useEffect(() => {
if (!meeting) return;
const handleMediaScoreUpdate = ({
participantId,
kind,
isScreenshare,
score,
scoreStats,
}) => {
if (kind === "video") {
console.log(
`Participant ${participantId}'s ${isScreenshare ? "screenshare" : "video"} quality score is`,
score,
);
}
if (score < 5) {
console.log(`Participant ${participantId}'s media quality is poor`);
}
};
meeting.participants.joined.on("mediaScoreUpdate", handleMediaScoreUpdate);
return () => {
meeting.participants.joined.off("mediaScoreUpdate", handleMediaScoreUpdate);
};
}, [meeting]);Это событие недоступно на данной платформе.
Отслеживайте качество сети участника с помощью mediaScoreUpdate событие.
import { useEffect } from "react";
// Use event listener for media score updates
useEffect(() => {
if (!meeting) return;
const handleMediaScoreUpdate = ({
participantId,
kind,
isScreenshare,
score,
scoreStats,
}) => {
if (kind === "video") {
console.log(
`Participant ${participantId}'s ${isScreenshare ? "screenshare" : "video"} quality score is`,
score,
);
}
if (score < 5) {
console.log(`Participant ${participantId}'s media quality is poor`);
}
};
meeting.participants.joined.on("mediaScoreUpdate", handleMediaScoreUpdate);
return () => {
meeting.participants.joined.off("mediaScoreUpdate", handleMediaScoreUpdate);
};
}, [meeting]);Прослушивайте события участников
Каждый объект участника является генератором событий:
meeting.participants.joined
.get(participantId)
.on("audioUpdate", ({ audioEnabled, audioTrack }) => {
console.log(
"The participant with id",
participantId,
"has toggled their mic to",
audioEnabled,
);
});Как вариант, отслеживайте карту участников, чтобы видеть всех участников:
meeting.participants.joined.on(
"audioUpdate",
(participant, { audioEnabled, audioTrack }) => {
console.log(
"The participant with id",
participant.id,
"has toggled their mic to",
audioEnabled,
);
},
);import { useRealtimeKitClient } from "@cloudflare/realtimekit-react";
import { useEffect } from "react";
function ParticipantAudioListener({ participantId }) {
const [meeting] = useRealtimeKitClient();
useEffect(() => {
if (!meeting) return;
const handleAudioUpdate = ({ audioEnabled, audioTrack }) => {
console.log(
"The participant with id",
participantId,
"has toggled their mic to",
audioEnabled,
);
};
const participant = meeting.participants.joined.get(participantId);
participant.on("audioUpdate", handleAudioUpdate);
return () => {
participant.off("audioUpdate", handleAudioUpdate);
};
}, [meeting, participantId]);
}Или используйте селектор для конкретных свойств:
const audioEnabled = useRealtimeKitSelector(
(m) => m.participants.joined.get(participantId)?.audioEnabled,
);Реализуйте RtkParticipantEventListener интерфейс для получения обновлений событий участников:
meeting.addParticipantEventListener(object : RtkParticipantEventListener {
override fun onVideoUpdate(participant: RtkRemoteParticipant, isEnabled: Boolean) {
// Called when participant's video state changes
}
override fun onAudioUpdate(participant: RtkRemoteParticipant, isEnabled: Boolean) {
// Called when participant's audio state changes
}
override fun onScreenShareUpdate(participant: RtkRemoteParticipant, isEnabled: Boolean) {
// Called when participant's screen share state changes
}
})Реализуйте RtkParticipantEventListener протокол для получения обновлений событий участников:
extension MeetingViewModel: RtkParticipantEventListener {
func onVideoUpdate(participant: RtkRemoteParticipant, isEnabled: Bool) {
// Called when participant's video state changes
}
func onAudioUpdate(participant: RtkRemoteParticipant, isEnabled: Bool) {
// Called when participant's audio state changes
}
func onScreenShareUpdate(participant: RtkRemoteParticipant, isEnabled: Bool) {
// Called when participant's screen share state changes
}
}
meeting.addParticipantEventListener(self)import { useRealtimeKitClient } from "@cloudflare/realtimekit-react-native";
import { useEffect } from "react";
function ParticipantAudioListener({ participantId }) {
const [meeting] = useRealtimeKitClient();
useEffect(() => {
if (!meeting) return;
const handleAudioUpdate = ({ audioEnabled, audioTrack }) => {
console.log(
"The participant with id",
participantId,
"has toggled their mic to",
audioEnabled,
);
};
const participant = meeting.participants.joined.get(participantId);
participant.on("audioUpdate", handleAudioUpdate);
return () => {
participant.off("audioUpdate", handleAudioUpdate);
};
}, [meeting, participantId]);
}Или используйте селектор для конкретных свойств:
const audioEnabled = useRealtimeKitSelector(
(m) => m.participants.joined.get(participantId)?.audioEnabled,
);