Change Role

Role is a powerful concept that takes a lot of complexity away in handling permissions and supporting features like breakout rooms.

Each HMSPeer instance has a role property which returns an HMSRole instance. You can use this property to do the following:

  1. Check what this Role is allowed to publish, that is, can it publish a video (and at what resolution)? Can it publish audio? Can it share a screen? Who can this role subscribe to?

    For example, a Student Role can only see the Teacher's video. This is can be discovered by checking publishSettings and subscribeSettings properties.

  2. Check what actions this Role can perform. i.e can it change someone else's current Role, End the Meeting, or remove someone from the room? This is can be discovered by checking the permissions property.

In certain scenarios, you may want to change someone's role.

Imagine an audio room with 2 roles speaker and listener. Only someone with a speaker role can publish audio to the room while a listener can only subscribe.

Now at some point, the speaker may decide to nominate some listener to become a speaker.

This is where Change Role capabilities come into play.

You may choose to do either:

  1. Single Peer Role Change: Change the role of a single peer to a specified one using the changeRoleOfPeer API

  2. Bulk Role Change: Change the role of all peers with a certain role, to a specified one using the changeRoleOfPeersWithRoles API

Single Peer Role Change

Note: 🔑 changeRoleOfPeer is the same as changeRole but we have deprecated changeRole and it will be removed in future releases. So, Please use changeRoleOfPeer.

class Meeting implements HMSUpdateListener, HMSActionResultListener{ ... void changeRoleOfPeer({required HMSPeer peer,required HMSRole roleName,bool forceChange}) { ///[peer]: peer whose role needs to be changed ///[toRole]: the role which we want the peer to be in(destination role). ///[forceChange]: it indicates whether to change the role of a peer forcefully ///If set to `true` then the role will be changed without asking permission from the [peer] ///In case of `false` permissions will be asked and the role will be changed only after the request is accepted. ///[hmsActionResultListener]: an instance of a class which implements HMSActionResultListener //Here this is an instance of a class that implements HMSActionResultListener that is Meeting hmsSDK.changeRoleOfPeer( forPeer: peer, toRole: roleName, force: forceChange, hmsActionResultListener: this); } void onSuccess( {HMSActionResultListenerMethod methodType = HMSActionResultListenerMethod.unknown, Map<String, dynamic>? arguments}) { switch (methodType) { ... case HMSActionResultListenerMethod.changeRoleOfPeer: //Here we will receive the success callback break; ... } } void onException( {HMSActionResultListenerMethod methodType = HMSActionResultListenerMethod.unknown, Map<String, dynamic>? arguments, required HMSException hmsException}) { switch (methodType) { ... case HMSActionResultListenerMethod.changeRoleOfPeer: // Check the HMSException object for details about the error break; ... } } }

To invoke this method we will need 4 parameters.

  • forPeer: An instance of HMSPeer of the peer whose role you want to change.

  • toRole: The HMSRole instance for the target role.

  • force: Whether you want to change their role without asking them or give them a chance to accept/reject.

  • hmsActionResultListener: The HMSActionResultListener will get a success or failure callback depending on the result of the request.

How to handle it at receiver side if force is false.Check it out here

Note: success doesn't mean that the role was changed, just that the server accepted the request as valid.

If the changeRole was succeeded you will get an update in the onPeerUpdate with roleUpdatedas update type, With the same peer, you passed as forPeer and an HMSPeerUpdate.roleUpdated update type.

class Meeting implements HMSUpdateListener, HMSActionResultListener{ ... void onPeerUpdate({required HMSPeer peer, required HMSPeerUpdate update}) async { switch (update) { ... case HMSPeerUpdate.roleUpdated: //Here we will get the update with peer being the same as the `forPeer` we sent in changeRole break; ... } } }

Bulk Role Change

Bulk Role Change is used when we want to change the role of peers with a specific role to another role.

For example, if peers join a room with a waiting role and now you want to change all these peers to viewer role then use the changeRoleOfPeersWithRoles method.

class Meeting implements HMSUpdateListener, HMSActionResultListener{ ... void changeRoleOfPeersWithRoles( {required HMSRole toRole, required List<HMSRole> ofRoles, HMSActionResultListener? hmsActionResultListener}) { ///[toRole]: the role you wish to move peers into(destination role) ///[ofRoles]: List of roles whose role needs to be changed ///[hmsActionResultListener]: an instance of a class which implements HMSActionResultListener //Here this is an instance of a class that implements HMSActionResultListener that is Meeting hmsSDK.changeRoleOfPeersWithRoles( toRole: toRole, ofRoles: ofRoles, hmsActionResultListener: this); } void onSuccess( {HMSActionResultListenerMethod methodType = HMSActionResultListenerMethod.unknown, Map<String, dynamic>? arguments}) { switch (methodType) { case HMSActionResultListenerMethod.changeRoleOfPeer: break; case HMSActionResultListenerMethod.changeRoleOfPeersWithRoles: //Here we will receive the success callback break; ... } } void onException( {HMSActionResultListenerMethod methodType = HMSActionResultListenerMethod.unknown, Map<String, dynamic>? arguments, required HMSException hmsException}) { switch (methodType) { case HMSActionResultListenerMethod.changeRoleOfPeer: break; case HMSActionResultListenerMethod.changeRoleOfPeersWithRoles: // Check the HMSException object for details about the error break; ... } } }

Edge cases with bulk role change

  1. Note that if an empty list is sent to ofRoles, no roles will be changed. This is to avoid accidentally changing roles you may not have intended such as the bots that provide recording and streaming with the roles beam.

  2. Also, Bulk Role Changes are always forced, that is, no option will be given for the peer to accept it, they will just be changed immediately.

Let's have a look at an example of bulk role change

Here's how the method could be called to change all waiting and guest roles to host:

// fetch all available Roles in the room List<HMSRole> roles = await hmsSDK.getRoles(); // get the Host Role object HMSRole toHostRole = roles.firstWhere((element) => element.name == "host"); // get a list of Roles to be updated - in this case, "Waiting" and "Guest" Roles roles.retainWhere((element) => ((element.name == "waiting") || (element.name == "guest"))); // now perform Role Change of all peers in "Waiting" and "Guest" Roles to the "Host" Role hmsSDK.changeRoleOfPeersWithRoles( toRole: toHostRole, ofRoles: roles, hmsActionResultListener: hmsActionResultListener);

Bulk Role Change Errors

You may get the following errors for bulk role change:

MessageMeaning
invalid roleA role in the list of roles to change does not exist in this room.
target role clash with requested rolesthe 'toRole' is also listed as one to change to 'toRole'
role does not have required permissionPeer does not have role change permission.
peer leftThe peer who's role was to be changed has left.
role invalidThe 'toRole' is invalid.

Accept Role change Request

When a peer wishes to change the role of another peer it calls changeRoleOfPeer with a parameter force. The force parameter in changeRoleOfPeer,

  • when true role is directly changed and the peer receives an onPeerUpdate with method type as roleUpdated.
  • when false, is a polite request: "Would you like to change your role from listener to speaker?" Which can be ignored by the peer. The way it works is the other peer will first receive an onRoleChangeRequest callback in HMSUpdateListener:

Let's understand this with a diagram:

accept-change-role

Now let's do it step-by-step:

PeerA calls changeRoleOfPeer with force as false

//Assuming that HMSActionResultListener is implemented in the class where this function is being called hmsSDK.changeRoleOfPeer( forPeer: peerB, toRole: new-role, force: false, hmsActionResultListener: this);

PeerB receives onRoleChangeRequest

PeerB receives onRoleChangeRequest in the class wherever HMSUpdateListener is implemented.

class Meeting implements HMSUpdateListener, HMSActionResultListener{ ... void onRoleChangeRequest({required HMSRoleChangeRequest roleChangeRequest}) { //Show some popup asking for permissions } }

At this point, the app should show a prompt to the user asking for permission to accept or deny role change.

How to extract info from HMSRoleChangeRequest to show popups for permission

HMSRoleChangeRequest is a class that contains info about the role change request. It contains two attributes:

  • suggestedRole -> This is an HMSRole object which contains info about the destination role
  • suggestedBy -> This is an HMSPeer object which contains info about the peer who performed a role change

To get information like role name and peer who performed role change we can do it like :

class Meeting implements HMSUpdateListener, HMSActionResultListener{ ... void onRoleChangeRequest({required HMSRoleChangeRequest roleChangeRequest}) { String? peerWhoPerformedRoleChange = roleChangeRequest.suggestedBy?.name; String? destinationRole = roleChangeRequest.suggestedRole.name } }

PeerB calls acceptChangeRole

If the user wants to accept the request, the app should invoke acceptChangeRole on HMSSDK instance:

//roleChangeRequest: this is the same request which we received in onRoleChangeRequest hmsSDK.acceptChangeRole(hmsRoleChangeRequest: roleChangeRequest, hmsActionResultListener: hmsActionResultListener);

All the peers receive onPeerUpdate with type as roleUpdated

Now, all peers in the room will receive an HMSPeerUpdate.roleUpdated callback so that they can do the necessary UI updates. PeerB will have all the permissions of new role.

Case with changeRoleOfPeer with

Now let's imagine the newly nominated speaker is not behaving nicely and we want to move him back to the listener without a prompt. This is where the force parameter comes in.

When it is set to true the other party will not receive a confirmation roleChangeRequest but instead will straight away receive a new set of updated permissions and stop publishing.

HMSPeerUpdate.roleUpdated callback will still be fired so that the app can update the user's UI state.

Preview For Role

Preview for role is a feature that allows you to preview the camera/mic states of the new role in which you are transitioning to. This is useful when you want to check if your camera/mic is working before you transition to a new role. This provides two methods:

  • previewForRole
  • cancelPreview

previewForRole

This returns an object of Future<dynamic> which can be either of HMSException type or a List<HMSTrack> type based on whether method execution is completed successfully or not. It takes a HMSRole as a parameter which is the role in which you want to preview.

void previewForRole({required String role}) async { HMSLocalVideoTrack? previewForRoleVideoTrack; HMSLocalAudioTrack? previewForRoleAudioTrack; ///hmsSDK is the instance of HMSSDK var result = await hmsSDK.previewForRole(role: role); if (result is HMSException) { //Handle the exception here } else{ ///Here we find the index of video track from the result list var indexForVideoTrack = (result as List<HMSTrack>).indexWhere( (element) => element.kind == HMSTrackKind.kHMSTrackKindVideo && element.source == "REGULAR"); if (indexForVideoTrack != -1) { ///We will use this track to display video preview previewForRoleVideoTrack = result[indexForVideoTrack] as HMSLocalVideoTrack; } ///Here we find the index of audio track from the result list var indexForAudioTrack = result.indexWhere( (element) => element.kind == HMSTrackKind.kHMSTrackKindAudio); if (indexForAudioTrack != -1) { previewForRoleAudioTrack = result[indexForAudioTrack] as HMSLocalAudioTrack; } } }

cancelPreview

If a [previewForRole] call was performed previously then calling this method clears the tracks created anticipating a change of role. This method only needs to be called if the user declined the request for role change.

This returns an object of Future<dynamic> which can be either of HMSException type or a boolean value [true] based on whether method execution is completed successfully or not.

Future<dynamic> cancelPreview() async { ///hmsSDK is the instance of HMSSDK var result = await hmsSDK.cancelPreview(); ///If the result is of type HMSException then handle the exception if (result is HMSException) { //Handle the exception here } else{ ///If the result is of type bool then check if it is true if(result){ ///Preview cancelled successfully } } }

Have a suggestion? Recommend changes ->

Was this helpful?

1234