INTEGRITY Документация

События

На этой странице представлен обзор событий, генерируемых 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,
);