100ms Logo

100ms

Docs

Search docs
/

Render Video - VideoView

At the very least for rendering video you'll need an instance of HMSVideoView and a HMSVideoTrack instance from a peer.

Adding HMSVideoView dependency

The latest HMSVideoView SDK version is:

build.gradle
dependencies { def hmsVersion = "x.x.x" implementation "live.100ms:android-sdk:$hmsVersion" // Essential base sdk implementation "live.100ms:video-view:$hmsVersion" // HMSVideoView }

Minimum Requirements

  • SDK version 2.5.3 or higher

In XML layouts it would look like

<live.hms.videoview.HMSVideoView android:id="@+id/peer_video" android:layout_width="match_parent" android:layout_height="wrap_content" />

The peer's video is in hmsPeer.videoTrack and their ScreenShare video will be an instance of HMSVideoTrack in the list hmsPeer.auxiliaryTracks.

You would get them like so:

val hmsVideoTrack : HMSVideoTrack? = hmsPeer.videoTrack

Getting HMSVideoView

Get an instance of the HMSVideoView.

val hmsVideoView : HMSVideoView = findViewById(R.id.peer_video)

Set the scaling to whatever you prefer. Aspect Fit is recommended for common use cases. See more scale types here.

hmsVideoView.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FIT)

Adding a video to the HMSVideoView

Each time you want to add a video to the HMSVideoView, you'll just need to update addTrack().

val hmsVideoTrack : HMSVideotrack = hmsPeer.videoTrack hmsVideoView.addTrack(hmsVideoTrack)

It's also important to remove it when done.

Removing a video from the HMSVideoView

It's very important to remove the video when you're done showing it.

hmsVideoView.removeTrack()

Until you call removeTrack() the video frame is being streamed over the device's data.

Capture Video Frame

You can get a bitmap object of the frame getting rendered on the HMSVideoView

In case you are calling this API on a videoView which is rendering localVideoTrack, it will return a bitmap whose resolution would be equal to the resolution at which this peer is supposed to publish.

hmsVideoView.captureBitmap(onBitmap: (Bitmap?) -> Unit, scale: Float = 1.0f)

Disabling Auto Simulcast

HMSVideoView has an automatic simulcast layer selection capability which is enabled if adaptive bitrate is enabled. You can check more about it here

It will select a layer that best matches the current view frame size and reacts to frame updates. In case manual layer selection is preferred set disableAutoSimulcastLayerSelect property to true. By default, the track layer is set to high.

hmsVideoView.disableAutoSimulcastLayerSelect(true)

Special cases for videos in RecyclerViews

If you're going to be using a RecyclerView to display multiple videos in a grid there are specific places where you should do these operations.

Currently the best known way is in the ViewHolder to have a method for binding items, a method to start the HMSVideoView addTrack() and a method to removeTrack() the hmsVideoView.

Two additional Adapter methods are overloaded. onViewAttachedToWindow and onViewDetachedFromWindow which will call HMSVideoView adding and removing video track respectively.

Complete source code is available here.

PeerViewHolder

init Video-Scale type can be set here.

startHMSVideoView will add the video track.

stopHMSVideoView will remove the attched video track.

PeerViewHolder.kt
class PeerViewHolder(view: View, private val getItem: (Int) -> TrackPeerMap) : RecyclerView.ViewHolder(view) { init { itemView.findViewById<HMSVideoView>(R.id.peer_video).apply { setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FIT) } } fun startHMSVideoView() { itemView.findViewById<HMSVideoView>(R.id.peer_video).apply { getItem(adapterPosition).videoTrack?.let { hmsVideoTrack -> hmsVideoTrack.addTrack(this) } } } fun stopHMSVideoView() { itemView.findViewById<HMSVideoView>(R.id.peer_video).apply { if (adapterPosition != -1) { getItem(adapterPosition).videoTrack?.let { hmsVideoTrack -> hmsVideoTrack.removeTrack() } } } } fun bind(peer: TrackPeerMap) { itemView.findViewById<HMSVideoView>(R.id.peer_video).apply { setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FIT) } ... itemView.findViewById<TextView>(R.id.peerName).text = peer.peer.name } }

PeerAdapter

PeerAdapter.kt
override fun onBindViewHolder(holder: PeerViewHolder, position: Int) { getItem(position)?.let { holder.stopHMSVideoView() holder.bind(it) } } override fun onViewAttachedToWindow(holder: PeerViewHolder) { super.onViewAttachedToWindow(holder) holder.startHMSVideoView() } override fun onViewDetachedFromWindow(holder: PeerViewHolder) { super.onViewDetachedFromWindow(holder) holder.stopHMSVideoView() } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PeerViewHolder { val view = LayoutInflater.from(parent.context).inflate(R.layout.layout_peer_item, parent, false) return PeerViewHolder(view, ::getItem) }

Have a suggestion? Recommend changes ->

Was this helpful?

1234