Skip to main content
Version: Android SDK v1.2.1

Viewing UI Controls

Regardless of the StreamViewer implementation that you are using, the user must be presented with UI controls to control the streamer behavior. Similar to what happens in all other modules, we offer a default UI implementation called io.video.videokit.live.viewer.ui.controls.StreamViewerControls.

With fragments

If you are using StreamViewerFragment, a StreamViewerControls view will be automatically added to the hierarchy and it is managed by the fragment itself, so there's nothing you should do.

When creating the fragment, you also have the option to pass a more generic layout resource that contains your overlays. If the view contains a StreamViewerControls instance anywhere in the hierarchy, the recorder will find it and set it up.

val options = StreamViewerControls.build {
overlay(R.layout.stream_viewer_overlay) // customize overlays
overlay(null) // disable default controls
}

By default, the overlay() layout contains a single StreamViewerControls view. Your overlays can contain a richer hierarchy or you can leverage a layout file to customize controls with the XML attributes listed below. You can also pass null to disable the default controls.

With other StreamViewer implementations

When using other StreamViewer implementations, the controls can be added to your view hierarchy as an overlay to the viewer. For example, in case of StreamViewerView, you can simply using a frame layout:

<!-- Part of your UI... -->
<FrameLayout>

<!-- Add StreamViewerView here: -->
<io.video.videokit.live.viewer.ui.StreamViewerView
android:id="@+id/viewer_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>

<!-- Then add controls: -->
<io.video.videokit.live.viewer.ui.controls.StreamViewerControls
android:id="@+id/viewer_controls"
android:layout_width="match_parent"
android:layout_height="match_parent"/>

</FrameLayout>

At runtime, the controls should be bound to the viewer using StreamViewerControls.setStreamViewer(). Once this is done, the controls class will start listening to the recorder events and update the interface accordingly.

val streamViewerView: StreamViewerView = findViewById(R.id.viewer_view)
val streamViewerControls: StreamViewerControls = findViewById(R.id.viewer_controls)
streamViewerControls.setStreamViewer(streamViewerView)

Customizing controls

The StreamViewerControls class offers many APIs to control the controls appearance, both through XML attributes and programmatically.

APIXML AttributeDescriptionDefault
showErrorsapp:streamViewerControlsShowErrorsIf true, a toast is shown whenever we detect a playback error.true
showSpinnerapp:streamViewerControlsShowSpinnerIf true, a loading spinner is shown when the stream is being loaded or buffered.true
showLiveapp:streamViewerControlsShowLiveIf true, shows an indicator of the live status, shown in WATCHING and BUFFERING states.true
liveDrawableapp:streamViewerControlsLiveDrawableControls the drawable for the live status indicator.LiveDrawable()
showAbortapp:streamViewerControlsShowAbortIf true, shows a close icon to abort the stream viewer.true
showMuteapp:streamViewerControlsShowMuteIf true, the mute / unmute button will be shown.true
muteDrawableapp:streamViewerControlsMuteDrawableControls the drawable for the mute control. Set to @empty to avoid showing a drawable at all.-
unmuteDrawableapp:streamViewerControlsUnmuteDrawableControls the drawable for the unmute control. Set to @empty to avoid showing a drawable at all.-
showPlayapp:streamViewerControlsShowPlayIf true, the play / pause button will be shown.true
playDrawableapp:streamViewerControlsPlayDrawableControls the drawable for the play state. Set to @empty to avoid showing a drawable at all.-
pauseDrawableapp:streamViewerControlsPauseDrawableControls the drawable for the pause state. Set to @empty to avoid showing a drawable at all.-

You can also have full control over the UI by passing your own layout resource to app:streamViewerControlsLayout.

Touch controls

The controls view is able to react to simple touch events and perform actions accordingly. You can configure the touch behavior with the singleTapAction API, both in XML and programmatically.

val controls: StreamViewerControls = findViewById(R.id.controls)
controls.singleTapAction = SingleTapAction.NONE // do nothing
controls.singleTapAction = SingleTapAction.TOGGLE_PLAYBACK // pause if playing, plays if paused
controls.singleTapAction = SingleTapAction.TOGGLE_VISIBILITY // shows or hides the controls