Preview

The preview screen is a frequently used UX element that allows users to check if their input devices are working properly and set the initial state (mute/unmute) of their audio and video tracks before joining.

100ms SDKs provide an easy-to-use API to back this feature. Additionally, the SDK will try to establish a connection to the 100ms server to verify there are no network issues and that the auth credentials are valid so that if everything is in order the subsequent room join will be much faster.

Let's look at the flow of HMSSDK with a preview

preview-join-flow

Let's follow the steps of joining a room with a preview:

Initialize HMSSDK

late HMSSDK hmsSDK; HMSSDK hmsSDK = HMSSDK();

Call build method on HMSSDK instance

await hmsSDK.build(); // ensure to await while invoking the `build` method

Attach preview listeners and call preview method

Let's see the complete implementation till now:

class Preview implements HMSPreviewListener{ late HMSSDK hmsSDK; Preview(){ initHMSSDK(); } void initHMSSDK() async { hmsSDK = HMSSDK(); await hmsSDK.build(); // ensure to await while invoking the `build` method HMSConfig config = HMSConfig( userName: "John Doe", authToken: "eyJH5c", // client-side token generated from your token service ); //Here this is an instance of a class that implements HMSPreviewListener, that is, Preview hmsSDK.addPreviewListener(listener:this); hmsSDK.preview(config: config); } void onPreview( {required HMSRoom room, required List<HMSTrack> localTracks}) { /// We will get the callback here if the preview succeeds } void onHMSError({required HMSException error}) { //Error updates: https://www.100ms.live/docs/flutter/v2/features/error-handling#hms-exception } void onRoomUpdate( {required HMSRoom room, required HMSRoomUpdate update}) { /// Only sent when Preview Room State is enabled. /// Room updates: https://www.100ms.live/docs/flutter/v2/features/update-listener-enums#hms-room-update } void onPeerUpdate( {required HMSPeer peer, required HMSPeerUpdate update}) async { /// Only sent when Preview Room State is enabled. /// Peer updates: https://www.100ms.live/docs/flutter/v2/features/update-listener-enums#hms-peer-update } void onAudioDeviceChanged( {HMSAudioDevice? currentAudioDevice, List<HMSAudioDevice>? availableAudioDevice}) { /// Get notified when the audio device is changed: https://www.100ms.live/docs/flutter/v2/features/audio-output-routing#adding-audio-device-change-event-listener-android-only } }

After calling preview your app will be provided an update from the 100ms SDK.

If successful, the onPreview({required HMSRoom room, required List<HMSTrack> localTracks}) method of HMSPreviewListener will be invoked with information about the room encapsulated in the HMSRoom object.

If failure, the onHMSError({required HMSException error}) method will be invoked with exact failure reason.

Render Preview

In case of success onPreview provides an array of local tracks in the parameter localTracks that you can display to the user (see Render Video and Mute sections for more details).

  • Fetching the track in onPreview callback:
class Preview implements HMSPreviewListener{ ... List<HMSVideoTrack> videoTracks = []; void onPreview({required HMSRoom room, required List<HMSTrack> localTracks}) { for (var track in localTracks) { if (track.kind == HMSTrackKind.kHMSTrackKindVideo) { isVideoOn = !(track.isMute); videoTracks.add(track as HMSVideoTrack); } if (track.kind == HMSTrackKind.kHMSTrackKindAudio) { isAudioOn = !(track.isMute); } } } }
  • Display the track using HMSVideoView:
//videoTracks is the List<HMSVideoTrack> which we have set above HMSVideoView( scaleType: ScaleType.SCALE_ASPECT_FILL, track:videoTracks[0],//setting the first track from videoTracks list to render on screen setMirror: true, matchParent: false, )

Check how we have implemented the preview in our sample app here

Remove HMSPreviewListener before calling join

class Preview implements HMSPreviewListener{ ... void removePreviewListener(){ //Here this is an instance of a class that implements HMSPreviewListener, that is, Preview hmsSDK.removePreviewListener(this); } }

After calling removePreviewListener to remove HMSPreviewListener call join by passing the same HMSSDK instance and HMSConfig.

Call join method and attach HMSUpdateListener

class Meeting implements HMSUpdateListener{ late HMSSDK hmsSDK; Meeting({required HMSSDK hmsSDKFromPreview,HMSConfig configFromPreview}){ hmsSDK = hmsSDKFromPreview; hmsSDK.addUpdateListener(listener: this); hmsSDK.join(config: configFromPreview); } void onJoin({required HMSRoom room}) async { // User Joined successfully. } ... }

In this way, a room can be joined with Preview. The rest of the functions and their implementation is same as we do in the case of direct join.

Get onPeerUpdate and onRoomUpdate while in Preview Mode

To enable onPeerUpdate & onRoomUpdate in the Preview, we need to enable Room State from the 100ms Dashboard. This can be enabled by selecting a Template and then navigating to Advanced Settings.

By default, Room State in Preview Mode is Disabled. So onPeerUpdate & onRoomUpdate events will not be received if these are not Enabled from Dashboard.

Advanced settings

These options are available in advanced settings:

Room State in preview

What if you leave the call after preview

In the event that a user exits the room after initiating the preview but before proceeding to join, it is recommended to invoke the leave method to guarantee proper cleanup.

class Preview implements HMSUpdateListener{ late HMSSDK hmsSDK; ... ///Call leave method when a user leaves after preview ///The execution of the 'leave' method should also be triggered when the user presses the back button in the application. void leave(){ hmsSDK.leave(); } }

Supplementary bytes

Now, let's take a look at the listener class in detail.

///[HMSPreviewListener] listens to updates when you preview. /// ///Just implement it and get the preview updates. /// /// Check out the [Sample App] to know about how we are implementing it: https://github.com/100mslive/100ms-flutter. abstract class HMSPreviewListener { ///when an error is caught [onError] will be called /// /// - Parameters: /// - error: error which you get. void onHMSError({required HMSException error}); ///when you want to preview listen to this callback /// /// - Parameters: /// - room: the room which was joined /// - localTracks: local audio/video tracks list void onPreview({required HMSRoom room, required List<HMSTrack> localTracks}); /// This is called when there is a change in any property of the Room. /// Only sent when Preview Room State is enabled. /// /// - Parameters: /// - room: the room which was joined /// - update: the triggered update type. Should be used to perform different UI Actions void onRoomUpdate({required HMSRoom room, required HMSRoomUpdate update}); /// This will be called whenever there is an update on an existing peer /// or a new peer got added/existing peer is removed. /// Only sent when Preview Room State is enabled. /// /// This callback can be used to keep a track of all the peers in the room /// - Parameters: /// - peer: the peer who joined/left or was updated /// - update: the triggered update type. Should be used to perform different UI Actions void onPeerUpdate({required HMSPeer peer, required HMSPeerUpdate update}); ///whenever a new audio device is plugged in or the audio output is changed we ///get the onAudioDeviceChanged update ///This callback is only fired on Android devices. On iOS, this callback will not be triggered. /// - Parameters: /// - currentAudioDevice: Current audio output route /// - availableAudioDevice: List of available audio output devices void onAudioDeviceChanged( {HMSAudioDevice? currentAudioDevice, List<HMSAudioDevice>? availableAudioDevice}); }

Have a suggestion? Recommend changes ->

Was this helpful?

1234