本页面提供了 meeting.participants 及相关参与者映射触发的事件概览,您可以使用这些事件来使您的 UI 与变化保持同步,例如参与者加入或离开、置顶更新、活跃发言者更改,以及网格视图模式或页面更改。
这些事件允许您监控网格的变化。
当视图模式在 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)class ParticipantsNotifier extends RtkParticipantsEventListener {
@override
void onActiveSpeakerChanged(RtkRemoteParticipant? participant) {
if (participant != null) {
print('${participant.id} is currently speaking');
}
}
}
meeting.addParticipantsEventListener(ParticipantsNotifier());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)class ParticipantsNotifier extends RtkParticipantsEventListener {
@override
void onParticipantJoin(RtkRemoteParticipant participant) {
print('A participant with id ${participant.id} has joined');
}
}
meeting.addParticipantsEventListener(ParticipantsNotifier());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)class ParticipantsNotifier extends RtkParticipantsEventListener {
@override
void onParticipantLeave(RtkRemoteParticipant participant) {
print('A participant with id ${participant.id} has left the meeting');
}
}
meeting.addParticipantsEventListener(ParticipantsNotifier());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`);
});每个参与者映射都会触发 participantJoined 和 participantLeft 事件:
// 监听何时置顶了参与者
meeting.participants.pinned.on("participantJoined", (participant) => {
console.log(`Participant ${participant.name} got pinned`);
});
// 监听何时取消置顶了参与者
meeting.participants.pinned.on("participantLeft", (participant) => {
console.log(`Participant ${participant.name} got unpinned`);
});meeting.addParticipantsEventListener(object : RtkParticipantsEventListener {
override fun onActiveParticipantsChanged(active: List<RtkRemoteParticipant>) {
// 当活动参与者发生变化时调用
}
})extension MeetingViewModel: RtkParticipantsEventListener {
func onActiveParticipantsChanged(active: [RtkRemoteParticipant]) {
// 当活动参与者发生变化时调用
}
}
meeting.addParticipantsEventListener(self)class ParticipantsNotifier extends RtkParticipantsEventListener {
@override
void onActiveParticipantsChanged(List<RtkRemoteParticipant> active) {
// 当活动参与者发生变化时调用
}
}
meeting.addParticipantsEventListener(ParticipantsNotifier());当参与者被置顶时触发。
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)class ParticipantsNotifier extends RtkParticipantsEventListener {
@override
void onParticipantPinned(RtkRemoteParticipant participant) {
print('Participant with id ${participant.id} was pinned');
}
}
meeting.addParticipantsEventListener(ParticipantsNotifier());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)class ParticipantsNotifier extends RtkParticipantsEventListener {
@override
void onParticipantUnpinned(RtkRemoteParticipant participant) {
print('Participant with id ${participant.id} was unpinned');
}
}
meeting.addParticipantsEventListener(ParticipantsNotifier());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) {
// 使用 participant.videoTrack
} else {
// 处理停止视频
}
});// 检查单个参与者
const videoEnabled = useRealtimeKitSelector(
(m) => m.participants.joined.get(participantId)?.videoEnabled,
);
// 所有启用了视频的参与者
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)class ParticipantUpdateHandler extends RtkParticipantUpdateListener {
@override
void onVideoUpdate(RtkRemoteParticipant participant, bool isEnabled) {
print('Participant ${participant.id} video is now ${isEnabled ? "enabled" : "disabled"}');
}
}
participant.addParticipantUpdateListener(ParticipantUpdateHandler());// 检查单个参与者
const videoEnabled = useRealtimeKitSelector(
(m) => m.participants.joined.get(participantId)?.videoEnabled,
);
// 所有启用了视频的参与者
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) {
// 使用 participant.audioTrack
} else {
// 处理停止音频
}
});// 检查单个参与者
const audioEnabled = useRealtimeKitSelector(
(m) => m.participants.joined.get(participantId)?.audioEnabled,
);
// 所有启用了音频的参与者
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)class ParticipantUpdateHandler extends RtkParticipantUpdateListener {
@override
void onAudioUpdate(RtkRemoteParticipant participant, bool isEnabled) {
print('Participant ${participant.id} audio is now ${isEnabled ? "enabled" : "disabled"}');
}
}
participant.addParticipantUpdateListener(ParticipantUpdateHandler());// 检查单个参与者
const audioEnabled = useRealtimeKitSelector(
(m) => m.participants.joined.get(participantId)?.audioEnabled,
);
// 所有启用了音频的参与者
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) {
// 使用 participant.screenShareTracks
} else {
// 处理停止屏幕共享
}
});// 检查单个参与者
const screensharingParticipant = useRealtimeKitSelector((m) =>
m.participants.joined.toArray().find((p) => p.screenShareEnabled),
);
// 所有共享屏幕的参与者
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)class ParticipantUpdateHandler extends RtkParticipantUpdateListener {
@override
void onScreenShareUpdate(RtkRemoteParticipant participant, bool isEnabled) {
print('Participant ${participant.id} screen share is now ${isEnabled ? "enabled" : "disabled"}');
}
}
participant.addParticipantUpdateListener(ParticipantUpdateHandler());// 检查单个参与者
const screensharingParticipant = useRealtimeKitSelector((m) =>
m.participants.joined.toArray().find((p) => p.screenShareEnabled),
);
// 所有共享屏幕的参与者
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";
// 使用事件监听器获取媒体评分更新
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";
// 使用事件监听器获取媒体评分更新
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) {
// 当参与者的视频状态发生变化时调用
}
override fun onAudioUpdate(participant: RtkRemoteParticipant, isEnabled: Boolean) {
// 当参与者的音频状态发生变化时调用
}
override fun onScreenShareUpdate(participant: RtkRemoteParticipant, isEnabled: Boolean) {
// 当参与者的屏幕共享状态发生变化时调用
}
})实现 RtkParticipantEventListener 协议以接收参与者事件更新:
extension MeetingViewModel: RtkParticipantEventListener {
func onVideoUpdate(participant: RtkRemoteParticipant, isEnabled: Bool) {
// 当参与者的视频状态发生变化时调用
}
func onAudioUpdate(participant: RtkRemoteParticipant, isEnabled: Bool) {
// 当参与者的音频状态发生变化时调用
}
func onScreenShareUpdate(participant: RtkRemoteParticipant, isEnabled: Bool) {
// 当参与者的屏幕共享状态发生变化时调用
}
}
meeting.addParticipantEventListener(self)实现 RtkParticipantUpdateListener 接口并在参与者上添加监听器:
class ParticipantUpdateHandler extends RtkParticipantUpdateListener {
@override
void onVideoUpdate(RtkRemoteParticipant participant, bool isEnabled) {
print("${participant.name}'s video is now ${isEnabled ? 'on' : 'off'}");
}
@override
void onAudioUpdate(RtkRemoteParticipant participant, bool isEnabled) {
print("${participant.name}'s audio is now ${isEnabled ? 'on' : 'off'}");
}
@override
void onPinned(RtkRemoteParticipant participant) {
print("${participant.name} was pinned");
}
@override
void onUnpinned(RtkRemoteParticipant participant) {
print("${participant.name} was unpinned");
}
@override
void onScreenShareUpdate(RtkRemoteParticipant participant, bool isEnabled) {
print("${participant.name}'s screen-share is now ${isEnabled ? 'on' : 'off'}");
}
@override
void onUpdate(RtkRemoteParticipant participant) {
print("${participant.name} was updated");
}
}
// 向特定参与者注册监听器
final listener = ParticipantUpdateHandler();
participant.addParticipantUpdateListener(listener);
// 听取完毕后,移除监听器
participant.removeParticipantUpdateListener(listener);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,
);