Skip to main content
Version: 4.x.x

Participant Class Events - iOS

  • Participant events are delivered to a ParticipantEventListener. Add your listener to each participant with addEventListener(), for example in onParticipantJoined(), and to room.localParticipant for your own streams.
  • Every callback has an empty default implementation, so implement only the ones you need. Callbacks run on the main thread.
extension RoomViewController: RoomEventListener {
func onParticipantJoined(_ participant: Participant) {
participant.addEventListener(self)
}
}

extension RoomViewController: ParticipantEventListener {
func onStreamEnabled(_ stream: RTCStream, forParticipant participant: Participant) {
// a stream of the participant is now available
}
}

onStreamEnabled​

  • onStreamEnabled is a callback which gets triggered whenever a participant's video, audio or screen share stream is enabled.
  • It is also triggered for your own streams, on the local participant. For a remote participant, it is triggered only for the streams that this device receives.

Event callback parameters​

  • stream: RTCStream - use stream.kind to tell audio, video and share streams apart.
  • participant: Participant - the participant the stream belongs to.

Example​

func onStreamEnabled(_ stream: RTCStream, forParticipant participant: Participant) {
switch stream.kind {
case .video:
// participantVideoView is your RTCMTLVideoView
if let videoTrack = stream.track as? RTCVideoTrack {
videoTrack.add(participantVideoView)
}
case .audio:
print("\(participant.displayName) turned on their mic")
case .share:
print("\(participant.displayName) started sharing their screen")
@unknown default:
break
}
}

onStreamDisabled​

  • onStreamDisabled is a callback which gets triggered whenever a participant's video, audio or screen share stream is disabled.

Event callback parameters​

  • stream: RTCStream - the stream that was disabled.
  • participant: Participant - the participant the stream belongs to.

Example​

func onStreamDisabled(_ stream: RTCStream, forParticipant participant: Participant) {
if stream.kind == .video, let videoTrack = stream.track as? RTCVideoTrack {
videoTrack.remove(participantVideoView)
}
}

onStreamPaused​

  • onStreamPaused is a callback which gets triggered when this device stops receiving one of the participant's streams because the server paused it, for example after you call enableAdaptiveSubscription() on the room. To know more, see the Scalability Guide.
  • The callback does not include the participant. It is delivered to the listeners added to the participant whose stream was paused.

Event callback parameters​

  • kind: StreamKind? - .AUDIO, .VIDEO or .SHARE; nil for screen-share audio.
  • reason: String - why the stream was paused, for example muted or leastDominance with adaptive subscription. It can be empty.

Example​

func onStreamPaused(kind: StreamKind?, reason: String) {
print("\(String(describing: kind)) stream paused: \(reason)")
}

onStreamResumed​

  • onStreamResumed is a callback which gets triggered when a paused stream of the participant is received again.
  • Like onStreamPaused, it is delivered to the listeners added to that participant.

Event callback parameters​

  • kind: StreamKind? - .AUDIO, .VIDEO or .SHARE; nil for screen-share audio.
  • reason: String - why the stream was resumed, for example adaptiveSubscriptionsDisabled or networkStable with adaptive subscription. It can be empty.

Example​

func onStreamResumed(kind: StreamKind?, reason: String) {
print("\(String(describing: kind)) stream resumed: \(reason)")
}

onE2EEStateChanged​

  • onE2EEStateChanged is a callback which gets triggered when the end-to-end encryption state of one of the participant's streams changes.
  • It reports a success state when encryption or decryption of the stream starts. Decryption failures are not reported, so a wrong or removed key raises no event.

Event callback parameters​

  • participant: Participant - the participant whose stream changed.
  • state: E2EEState
    • .EncryptionSuccess: encryption of the stream started.
    • .DecryptionSuccess: decryption of the stream started.
    • .EncryptionFailed: encryption failed.
    • .DecryptionFailed: not reported.
    • .InternalError: an unexpected encryption error.
  • stream: RTCStream - the stream whose state changed.

Example​

func onE2EEStateChanged(forParticipant participant: Participant, state: E2EEState, _ stream: RTCStream) {
print("\(participant.id) \(stream.kind.rawValue): \(state.rawValue)")
}

onAgentStateChanged​

  • onAgentStateChanged is a callback which gets triggered when an AI agent moves between idle, listening, thinking and speaking.
  • It is triggered on agent participants, the ones whose isAgent() returns true. Add your listener to the agent.

Event callback parameters​

  • state: AgentState - .IDLE, .LISTENING, .THINKING or .SPEAKING.
  • participant: Participant - the agent.

Example​

func onAgentStateChanged(_ state: AgentState, forParticipant participant: Participant) {
print("\(participant.displayName) is \(state.rawValue)")
}

onAgentTranscriptionReceived​

  • onAgentTranscriptionReceived is a callback which gets triggered for each transcript segment of the conversation with an AI agent.
  • It is triggered on every agent participant in the room. Add your listener to the agent, and read participant to see who spoke.

Event callback parameters​

  • segment: TranscriptionSegment - text (String) is the transcribed text, and timestamp (Int) is when the agent created the segment, in epoch milliseconds. It is 0 when the agent sent no time, or one that cannot be read.
  • participant: Participant? - the participant who spoke. It can be you or the agent. It is nil when the SDK can't find that participant.

Example​

func onAgentTranscriptionReceived(_ segment: TranscriptionSegment, forParticipant participant: Participant?) {
print("\(participant?.displayName ?? "Unknown"): \(segment.text)")
}

onAgentMetrics​

  • onAgentMetrics is a callback which gets triggered on an agent participant after each turn of the conversation, with metrics and speech data for that turn.

Event callback parameters​

  • metrics: [String: Any] - contains latency and speech. The first turn also contains providers and systemInstructions. A key can be missing, so read each value as an optional.
  • participant: Participant - the agent.

Example​

func onAgentMetrics(_ metrics: [String: Any], forParticipant participant: Participant) {
if let latency = metrics["latency"] {
print("Latency: \(latency)")
}
}

Got a Question? Ask us on discord