Multiparty: Subscribe to Every Remote Stream
Each remote client appears as a Stream. Implement onStreamReceived / onStreamDropped:
- For each new stream, build a
Subscriber, callsession.subscribe(subscriber), then attachsubscriber.viewto a dedicated cell in your layout.
This sample uses a fixed number of slots (maxSubscribers): parallel arrays for Subscriber?, optional stream IDs, and FrameLayout? cells. The next free index gets the new participant; if all slots are full, ignore or replace according to your product rules.
private val maxSubscribers = 4
private val subscribers = arrayOfNulls<Subscriber>(maxSubscribers)
private val subscriberContainers = arrayOfNulls<FrameLayout>(maxSubscribers)
private val subscriberStreamIds = arrayOfNulls<String>(maxSubscribers)
override fun onStreamReceived(session: Session, stream: Stream) {
val subscriber = Subscriber.Builder(this@MainActivity, stream).build()
session.subscribe(subscriber)
addSubscriber(subscriber)
}
private fun addSubscriber(subscriber: Subscriber) {
val index = subscribers.indexOfFirst { it == null }
if (index == -1) {
Toast.makeText(
this,
"New subscriber ignored, maxSubscribers limit reached",
Toast.LENGTH_LONG
).show()
return
}
subscribers[index] = subscriber
subscriberStreamIds[index] = subscriber.stream.streamId
subscriber.setStyle(BaseVideoRenderer.STYLE_VIDEO_SCALE, BaseVideoRenderer.STYLE_VIDEO_FILL)
subscriber.subscribeToAudio = true
runOnUiThread {
subscriberContainers[index]?.removeAllViews()
subscriberContainers[index]?.addView(subscriber.view)
}
subscriberAudioEnabled[index] = true
subscriberVisible[index] = true
}
- When a stream ends, remove that subscriber’s view and free the slot.
override fun onStreamDropped(session: Session, stream: Stream) {
val index = subscriberStreamIds.indexOfFirst { it == stream.streamId }
if (index == -1) return
val subscriber = subscribers[index] ?: return
runOnUiThread {
subscriberContainers[index]?.removeView(subscriber.view)
}
subscribers[index] = null
subscriberStreamIds[index] = null
subscriberVisible[index] = false
subscriberAudioEnabled[index] = true
}
Toggle remote audio with subscriber.subscribeToAudio = enabled. Toggle your outgoing A/V with publisher.publishAudio / publisher.publishVideo.
Tear Down Cleanly
On exit, unsubscribe each subscriber, unpublish the publisher, then session.disconnect(). Doing this avoids leaked sessions and blocked cameras/mics on some devices.
Simple Multiparty
Learn how to use the Vonage Android SDK for a multi-party call. The application publishes audio/video from a device and can connect to multiple subscribers.