Skip to content

Participant

Participant holds what the local and the remote participants have in common. You never create one: the local user is Room.localParticipant, and everyone you are in a call with is a RemoteParticipant in Room.remoteParticipants, keyed by friend ID. A few properties only have a value on a RemoteParticipant; see Only on a remote participant.

Identity

Property Meaning
Participant.identity The friend ID. It never changes and is never empty.
Participant.name The display name, or nil when there is none.
Participant.statusMessage The status message the user set, or nil when there is none.
Participant.userStatus Available (UserStatus.none), UserStatus.away or UserStatus.busy.

Tracks

Participant.trackPublications holds every track the participant publishes, keyed by publication ID. Participant.videoTracks and Participant.audioTracks return the same publications, filtered by kind.

Three shortcuts return the first track of one source:

Property Returns
Participant.firstCameraVideoTrack The camera track.
Participant.firstScreenShareVideoTrack The screen share track.
Participant.firstAudioTrack The first audio track.

Still returned while muted

Participant.firstCameraVideoTrack, Participant.firstScreenShareVideoTrack and Participant.firstAudioTrack keep returning the track when the participant mutes it. They return nil only when there is no such track. Check isMuted on the track before you show it: while it is muted, the participant is not sending real video or sound.

To show a camera, set the track on a VideoView only when it is not muted, and show your own placeholder otherwise. Run the same check again when your delegate receives didUpdateIsMuted for that participant (see Events).

import RevueSDK

/// Show a participant's camera in their tile, or the App's placeholder when the camera is muted.
/// firstCameraVideoTrack still returns the track while the participant is muted, so check isMuted.
/// Call this again from didUpdateIsMuted.
func showCamera(of friendId: String, in videoView: VideoView) -> Bool {
    let camera = Room.shared.remoteParticipants[friendId]?.firstCameraVideoTrack
    guard let camera, !camera.isMuted else {
        videoView.track = nil
        return false  // show the placeholder
    }
    videoView.track = camera
    return true
}

Participant.isCameraEnabled(), Participant.isMicrophoneEnabled() and Participant.isScreenShareEnabled() answer the same question in one call: true when the participant has that track and it is not muted.

Speaking

Property Meaning
Participant.isSpeaking Whether the participant is speaking now.
Participant.audioLevel The current volume, from 0.0 to 1.0. It is 0 when the participant is not speaking.
Participant.lastSpokeAt When the participant last started speaking. It does not change while they keep talking.

The SDK updates them every 400 ms, for the local participant too. See Events for the speaking events.

Only on a remote participant

These properties are declared on Participant, but only a RemoteParticipant fills them in. On Room.localParticipant they never change.

Property On a RemoteParticipant On the LocalParticipant
Participant.joinedAt When the participant connected to you, set at participantDidConnect. Always nil.
Participant.connectionQuality How good your connection to that participant is, rated every second. Always ConnectionQuality.unknown.

Only a RemoteParticipant has a value

Participant.joinedAt and Participant.connectionQuality only have a value on a RemoteParticipant. Read them from Room.remoteParticipants, not from Room.localParticipant.

import RevueSDK
import Foundation

/// How long a participant has been in the call. joinedAt only has a value on a RemoteParticipant,
/// so read it from Room.shared.remoteParticipants, not from the local participant.
func timeInCall(of friendId: String) -> TimeInterval? {
    guard let joinedAt = Room.shared.remoteParticipants[friendId]?.joinedAt else { return nil }
    return Date().timeIntervalSince(joinedAt)
}

See Connection state for the quality levels.