let clientState = streamVideo.state
let callState = call.state
let participants = call.state.participants
Call & Participant State
Video Call State
When you join a call, we’ll automatically expose observable objects in 3 different places:
Call State
The call state is kept in sync (updates are received) only when you join the call.
Here’s an example of how you can access the call state:
let call = streamVideo.call(callType: "default", callId: "mycall")
let joinResult = try await call.join(create: true)
// state is now available at
let state = call.state
The following fields are available on the call:
Attribute | Description |
---|---|
participants | For calls with less than 250 participants, the property contains all participants. For calls with more than 250 participants, the property contains the first 250 participants. |
participantsMap | A dictionary mapping participant IDs to CallParticipant objects. |
localParticipant | The current user’s participant object. |
remoteParticipants | List of participants other than the current user. |
activeSpeakers | List of participants who are actively speaking. |
dominantSpeaker | The participant recognized as the dominant speaker. |
members | The list of call members. |
screenSharingSession | Information about the active screen sharing session, if any. |
recordingState | The current recording state of the call. |
blockedUserIds | A set of user IDs that are blocked in the call. |
settings | The call settings fetched from the backend. |
ownCapabilities | The capabilities the current user has in the call. |
capabilitiesByRole | A map of role to allowed capabilities. |
backstage | Indicates whether the call is in backstage mode. |
broadcasting | Whether the call is broadcasting (e.g., via RTMP or HLS). |
createdAt | The date when the call was created. |
updatedAt | The date when the call was last updated. |
startsAt | The scheduled start time of the call, if any. |
startedAt | The actual time the call started. |
endedAt | The time when the call ended. |
endedBy | The user who ended the call. |
custom | Custom data associated with the call. |
team | Team restriction on the call, if any. |
createdBy | The user who created the call. |
ingress | RTMP ingress configuration if active. |
permissionRequests | List of pending permission requests. |
transcribing | Indicates if transcriptions are active. |
captioning | Indicates if closed captions are active. |
egress | Information about egress (recording, broadcasting) of the call. |
session | The session information for the ongoing call. |
reconnectionStatus | The current reconnection status of the call. |
anonymousParticipantCount | Number of anonymous participants. |
participantCount | Total number of participants (connected and anonymous). |
isInitialized | Indicates whether the call has been initialized. |
callSettings | The call settings currently active. |
isCurrentUserScreensharing | Indicates if the current user is sharing their screen. |
duration | Duration of the current session in seconds. |
statsReport | Periodic stats report updated at regular intervals. |
closedCaptions | List of active closed caption entries. |
statsCollectionInterval | Interval at which call stats are collected, in seconds. |
incomingVideoQualitySettings | Incoming video policy applied for the session. |
disconnectionError | Error describing the reason for a disconnection, if any. |
Participant State
The CallParticipant
is the most essential component used to render a participant in a call. It contains all of the information to render a participant, such as audio & video tracks, availabilities of audio & video, the screen sharing session, reactions, and etc. Here’s how you can subscribe to participants updates:
// all participants
let cancellable = call.state.$participants.sink { participants in
// ..
}
Filtering of the participants is also supported. You can get all the participants with the role “host”, with the following code:
var hosts: [CallParticipant] {
call.state.participants.filter { $0.roles.contains("host") }
}
When you join a call with many participants, maximum of 250 participants are returned in the join response. The list of participants is updated dynamically when there are join call events.
The participants that are publishing video, audio or screensharing are prioritized over the other participants in the list.
The total number of participants is updated realtime via health check events. This value is available from the call state’s participantCount
property.
You can get the current user with the following code:
let localParticipant: CallParticipant? = call.state.localParticipant
The following fields are available on the participant:
Attribute | Description |
---|---|
user | The User object for the participant. |
id | The unique call id of the participant. |
roles | The user’s roles in the call. |
trackLookupPrefix | The id of the track that’s connected to the participant. |
hasVideo | Returns whether the participant has video. |
hasAudio | Returns whether the participant has audio. |
isScreensharing | Returns whether the participant is screen sharing. |
track | Returns the participant’s video track. |
trackSize | Returns the size of the track for the participant. |
screenshareTrack | Returns the screensharing track for the participant. |
showTrack | Returns whether the track should be shown. |
isSpeaking | Returns whether the participant is speaking. |
isDominantSpeaker | Returns whether the participant is a dominant speaker. |
sessionId | Returns the session id of the participant. |
connectionQuality | The participant’s connection quality. |
joinedAt | Returns the date when the user joined the call. |
audioLevel | The audio level for the user. |
audioLevels | A list of the last 10 audio levels. Convenient for audio visualizations. |
pin | Holds pinning information. |
isPinned | Returns whether the user is pinned. |
pausedTracks | The set of media track types currently paused for this participant. |
Participants Sorting
If you want to change the default sorting of the participants, you can use the Call
object’s method updateParticipantsSorting
.
Here’s an example that will sort participants alphabetically, by their name:
let nameComparator: StreamSortComparator<CallParticipant> = {
comparison($0, $1, keyPath: \.name)
}
let call = streamVideo.call(callType: callType, callId: callId)
call.updateParticipantsSorting(with: [nameComparator])
Client State
// client state is available on the client object
let state = streamVideo.state
And contains these fields:
Attribute | Description |
---|---|
user | The user you’re currently authenticated as. |
connection | The connection state. See ConnectionState. |
activeCall | The call you’ve currently joined. |
ringingCall | Contains the call if you’re calling someone or someone is calling you. |
- I'm working with the Stream Video IOS SDK and would like to ask questions about this documentation page: https://getstream.io/video/docs/ios/guides/call-and-participant-state.md
- View as markdown
- Open in ChatGPT
- Open in Claude