Participant properties, roles, and track management
The JitsiParticipant class represents a participant (member) in a conference, containing information about their identity, role, tracks, and custom properties.
constructor( jid: string, // Conference XMPP JID conference: JitsiConference, displayName: string, hidden: boolean, // True for hidden participants (e.g., recorder) statsID?: string, // Optional statistics ID status?: string, // Initial status identity?: object, // XMPP identity from JWT context isReplacing?: boolean, // Whether replacing another participant isReplaced?: boolean, // Whether being replaced isSilent?: boolean // Whether joined without audio) { this._jid = jid; this._id = Strophe.getResourceFromJid(jid); // Extract endpoint ID this._conference = conference; this._displayName = displayName; this._role = 'none'; this._tracks = []; this._properties = new Map(); this._features = new Set(); this._sources = new Map();}
The participant ID (_id) is extracted from the resource part of the JID using Strophe.getResourceFromJid(). This is an 8-character hexadecimal string used as the endpoint ID.
// Get all participants (excluding local)const participants = conference.getParticipants();// Get specific participant by IDconst participant = conference.getParticipantById(participantId);// Get participant countconst count = conference.getParticipantCount();
// Get participant ID (endpoint ID)const id = participant.getId();// Get display nameconst displayName = participant.getDisplayName();// Get full JIDconst jid = participant.getJid();// Get statistics ID const statsID = participant.getStatsID();// Get statusconst status = participant.getStatus();
// Get connection JID (bridge connection)const connectionJid = participant.getConnectionJid();// Get bot type (if participant is a bot)const botType = participant.getBotType();
Participants can be moderators or regular participants:
// Get roleconst role = participant.getRole(); // 'moderator' or 'none'// Check if moderatorconst isModerator = participant.isModerator();// Listen for role changesconference.on(JitsiConferenceEvents.USER_ROLE_CHANGED, (id, role) => { console.log(`Participant ${id} role changed to ${role}`);});
From JitsiParticipant.ts:227-231 and JitsiParticipant.ts:309-312:
// Get all tracksconst tracks = participant.getTracks();// Get tracks by media typeconst audioTracks = participant.getTracksByMediaType(MediaType.AUDIO);const videoTracks = participant.getTracksByMediaType(MediaType.VIDEO);// Check track countconsole.log('Participant has', tracks.length, 'tracks');
Participants can have multiple sources (tracks) of the same media type:From JitsiParticipant.ts:10-13 and JitsiParticipant.ts:98-109:
interface ISourceInfo { muted: boolean; // Source mute state videoType: string; // 'camera' or 'desktop'}// Source structure:// Map<mediaType, Map<sourceName, ISourceInfo>>// Example: Map<'video', Map<'participant-v0', { muted: false, videoType: 'camera' }>>const sources = participant.getSources();// Iterate over sourcesfor (const [mediaType, sourceMap] of sources) { console.log(`Media type: ${mediaType}`); for (const [sourceName, sourceInfo] of sourceMap) { console.log(` Source: ${sourceName}`); console.log(` Muted: ${sourceInfo.muted}`); console.log(` Video type: ${sourceInfo.videoType}`); }}
Source information is updated through the signaling layer when participants add, remove, or modify their tracks. The PARTICIPANT_SOURCE_UPDATED event fires when sources change.
// Get all featuresconst features = await participant.getFeatures();// Check if feature is supportedconst supportsFeature = participant.hasFeature('feature-name');// Common features:// - 'urn:xmpp:jingle:apps:dtls:0' - DTLS support// - 'urn:ietf:rfc:5888' - Audio/video grouping// - Application-specific features
From JitsiParticipant.ts:188-193 and JitsiParticipant.ts:273-280:
Some participants may be hidden (e.g., recording bots):
// Check if participant is hiddenconst isHidden = participant.isHidden();// Check if hidden from recorderconst isHiddenFromRecorder = participant.isHiddenFromRecorder();
// Check if this participant is replacing anotherconst isReplacing = participant.isReplacing();// Check if this participant will be replacedconst isReplaced = participant.isReplaced();
conference.on(JitsiConferenceEvents.USER_ROLE_CHANGED, (id, role) => { const participant = conference.getParticipantById(id); if (participant.isModerator()) { console.log(`${participant.getDisplayName()} is now a moderator`); showModeratorBadge(id); } else { console.log(`${participant.getDisplayName()} is no longer a moderator`); hideModeratorBadge(id); }});