Skip to main content
Version: 0.1.x

Manage Participants - Android

1. Local Participant (self)

Local participant is used to consume your video & audio streams. it contains information about local participant such as displayName, id, quality and streams Map.

You can acces localParticipant from the meeting object.

Participant object properties

Property NameTypeDescription
idstringUnique id of the participant.
displayNamestringThe name you define during the meeting initialization.
localbooleanIndicates the participant is local or not.
qualitystringIndicates the participant streams quality.
StreamsMap of StreamReturns Video & Audio Streams.

Stream Object properties

Property NameTypeDescription
idstringUnique id
codecstringVideo/Audio codec.
kindstringStream Kind.
trackstringMediaStreamTrack

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

activity_main.xml
  <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" />
info
  • Here the participant's video is displayed using VideoView, but you may also use SurfaceViewRender for the same.
  • For VideoView, SDK version should be 0.1.13 or higher.
  • To know more about VideoView, please visit here
MainActivity.kt
  import live.videosdk.rtc.android.VideoView
import 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
localView.addTrack(videoTrack)
}
}
}
)
}

private fun displayRemoteParticipants() {
val rvParticipants = findViewById<RecyclerView>(R.id.rvParticipants)
rvParticipants.layoutManager = GridLayoutManager(this, 2)
rvParticipants.adapter = ParticipantAdapter(meeting!!)
}

item_remote_peer.xml
<?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>
ParticipantAdapter.kt

class ParticipantAdapter(meeting: Meeting) : RecyclerView.Adapter<ParticipantAdapter.PeerViewHolder>() {
private val participants: MutableList<Participant> = ArrayList()
private var containerHeight = 0

init {
participants.add(meeting.localParticipant)
meeting.addEventListener(object : MeetingEventListener() {
override fun onParticipantJoined(participant: Participant) {
participants.add(participant)
notifyItemInserted(participants.size - 1)
}

override fun onParticipantLeft(participant: Participant) {
// 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

for ((_, stream) in participant.streams) {
if (stream.kind.equals("video", ignoreCase = true)) {
val videoTrack = stream.track as VideoTrack
holder.participantView.addTrack(videoTrack)
break
}
}

participant.addEventListener(object : ParticipantEventListener() {
override fun onStreamEnabled(stream: Stream) {
if (stream.kind.equals("video", ignoreCase = true)) {
val videoTrack = stream.track as VideoTrack
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)
}
}

Please refer the example code on Github for more details.

  1. onParticipantJoined - Whenever any new participant join the meeting, onParticipantJoined event will trigger. For example, the meeting is running with Alice and Bob, then Eve join that meeting, after that onParticipantJoined event trigger and return the participant object.

  2. onParticipantLeft - Whenever any participant leave/exit the meeting, onParticipantLeft event will trigger.For example, the meeting is running with Alice and Bob, then Bob leave that meeting, after that onParticipantLeft event trigger and return the participant object

  3. onPresenterChanged - Whenever any participant present/screenshare their screen/window in meeting, onPresenterChanged event will trigger and return the presenter participantId.

  4. onStreamEnabled - Whenever any participant enabled mic/webcam in meeting, onStreamEnabled event will trigger and return Stream.

  5. onStreamDisabled - Whenever any participant disabled mic/webcam in meeting, onStreamDisabled event will trigger and return 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) {
Toast.makeText(this@MainActivity, participant.displayName + " left", Toast.LENGTH_SHORT).show()
}

override fun onPresenterChanged(presenterId: String) {
Toast.makeText(this@MainActivity, presenterId + " started presenting", Toast.LENGTH_SHORT).show()
}
})

Got a Question? Ask us on discord