Manage Participants - Android
1. Local Participant (self)
The local participant is you: it sends your video and audio streams. It contains information about the local participant such as displayName, id, quality and streams Map.
You can access localParticipant from the meeting object.
Participant object properties
| Property Name | Type | Description |
|---|---|---|
| id | String | Unique id of the participant. |
| displayName | String | The name you define during the meeting initialization. |
| isLocal | Boolean | Indicates the participant is local or not. |
| quality | String | Indicates the participant streams quality. |
| streams | Map<String, Stream> | Returns Video & Audio Streams. |
Stream Object properties
| Property Name | Type | Description |
|---|---|---|
| id | String | Unique id |
| kind | String | Stream Kind: audio, video, share or shareAudio. |
| track | MediaStreamTrack? | The videosdk.org.webrtc track. For video and share, it is a VideoTrack. |
2. Other Participants (Except You)
Other participants Map is used to get all the participants (except you) in the meeting at any given time.
Other participants Map contains same properties as LocalParticipant.
Local And Other Participants
<live.videosdk.rtc.android.VideoView
android:id="@+id/localView"
android:layout_width="80dp"
android:layout_height="100dp"
android:layout_gravity="end" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvParticipants"
android:layout_width="match_parent"
android:layout_height="match_parent" />
- Here the participant's video is displayed using
VideoView. Render video tracks withVideoView.addTrack(). - Your own camera is shown in one
VideoViewat a time. If you add your video track to a secondVideoView, the first one stops updating. - The SDK does not bring in
RecyclerView. Addandroidx.recyclerview:recyclerviewto your app's dependencies. - To know more about
VideoView, please visit here
import live.videosdk.rtc.android.VideoView
import videosdk.org.webrtc.VideoTrack
private fun displayLocalParticipant() {
var localView: VideoView = findViewById(R.id.localView)
// display local video when stream available
meeting!!.localParticipant.addEventListener(
object : ParticipantEventListener() {
override fun onStreamEnabled(stream: Stream) {
if (stream.kind.equals("video", ignoreCase = true)) {
val videoTrack = stream.track as? VideoTrack ?: return
localView.addTrack(videoTrack)
}
}
}
)
}
private fun displayRemoteParticipants() {
val rvParticipants = findViewById<RecyclerView>(R.id.rvParticipants)
rvParticipants.layoutManager = GridLayoutManager(this, 2)
rvParticipants.adapter = ParticipantAdapter(meeting!!)
}
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<live.videosdk.rtc.android.VideoView
android:id="@+id/participantView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
import videosdk.org.webrtc.VideoTrack
class ParticipantAdapter(meeting: Meeting) : RecyclerView.Adapter<ParticipantAdapter.PeerViewHolder>() {
private val participants: MutableList<Participant> = ArrayList()
private var containerHeight = 0
init {
meeting.addEventListener(object : MeetingEventListener() {
override fun onParticipantJoined(participant: Participant) {
participants.add(participant)
notifyItemInserted(participants.size - 1)
}
override fun onParticipantLeft(participant: Participant, reason: LeaveReason) {
// remove participant from grid
}
})
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PeerViewHolder {
containerHeight = parent.height
return PeerViewHolder(
LayoutInflater.from(parent.context)
.inflate(R.layout.item_remote_peer, parent, false)
)
}
override fun onBindViewHolder(holder: PeerViewHolder, position: Int) {
val participant = participants[position]
val layoutParams = holder.itemView.layoutParams
layoutParams.height = containerHeight / 3
holder.itemView.layoutParams = layoutParams
// Also called right away for each stream the participant already has
participant.addEventListener(object : ParticipantEventListener() {
override fun onStreamEnabled(stream: Stream) {
if (stream.kind.equals("video", ignoreCase = true)) {
val videoTrack = stream.track as? VideoTrack ?: return
holder.participantView.addTrack(videoTrack)
}
}
})
}
override fun getItemCount(): Int {
return participants.size
}
class PeerViewHolder(view: View) : RecyclerView.ViewHolder(view) {
var participantView: VideoView = view.findViewById(R.id.participantView)
}
}
3. Participant Related Events
-
onParticipantJoined - Whenever a new participant joins the meeting, the
onParticipantJoinedevent is triggered. For example, the meeting is running with Alice and Bob, then Eve joins that meeting, after that theonParticipantJoinedevent is triggered and returns the participant object. -
onParticipantLeft - Whenever a participant leaves the meeting, the
onParticipantLeftevent is triggered. For example, the meeting is running with Alice and Bob, then Bob leaves that meeting, after that theonParticipantLeftevent is triggered and returns the participant object and aLeaveReason. -
onPresenterChanged - Whenever a participant starts sharing their screen in the meeting, the
onPresenterChangedevent is triggered and returns the presenterparticipantId. It returnsnullwhen the screen share stops. -
onStreamEnabled - Whenever a participant enables their mic or webcam in the meeting, the
onStreamEnabledevent is triggered and returns Stream. -
onStreamDisabled - Whenever a participant disables their mic or webcam in the meeting, the
onStreamDisabledevent is triggered and returns Stream.
meeting!!.addEventListener(object : MeetingEventListener() {
override fun onParticipantJoined(participant: Participant) {
participant.addEventListener(object : ParticipantEventListener() {
override fun onStreamEnabled(stream: Stream) {
if (stream.kind.equals("video", ignoreCase = true)) {
// participant video enabled
} else if (stream.kind.equals("audio", ignoreCase = true)) {
// participant mic enabled
}
}
override fun onStreamDisabled(stream: Stream) {
if (stream.kind.equals("video", ignoreCase = true)) {
// participant video disabled
} else if (stream.kind.equals("audio", ignoreCase = true)) {
// participant mic disabled
}
}
})
}
override fun onParticipantLeft(participant: Participant, reason: LeaveReason) {
Toast.makeText(this@MainActivity, participant.displayName + " left", Toast.LENGTH_SHORT).show()
}
override fun onPresenterChanged(presenterId: String?) {
if (presenterId != null) {
Toast.makeText(this@MainActivity, presenterId + " started presenting", Toast.LENGTH_SHORT).show()
}
}
})
Got a Question? Ask us on discord

