import { useCallStateHooks } from "@stream-io/video-react-native-sdk";
const { useOwnCapabilities } = useCallStateHooks();
const ownCapabilities = useOwnCapabilities();
Permissions & Moderation
In many types of calls, there is a requirement for providing different users with certain permissions and capabilities. A typical example is a webinar where the host wants to control who can speak or who can share their video or screen.
The Stream Video SDK provides a certain set of permissions and capabilities that can be used to control the behavior of participants in a call.
Conceptual overview
Roles
The Stream Video API allows assigning roles to users. Each user has a global role, and they will also have a call-level role for each call they join. The Stream Video API provides a set of predefined roles, but it’s also possible to create your own roles.
Call types
Call types also allow for a more granular control system:
- you can enable/disable certain features on a call type level
- you can configure how each call-level role works on a call type level
Capabilities
Based on a user’s roles and the call type settings, we can determine which actions are allowed for a user joined to a specific call.
The capabilities of the local user live in the state of the call
instance.
In our React Native Video SDK, you can use the useOwnCapabilities
hook.
Permissions
As soon as you join a call, the Call
instance would allow you to check the permissions of the local user
or perform some permission-related actions:
Check permissions
import { OwnCapability } from "@stream-io/video-react-native-sdk";
const call = streamVideoClient.call(type, id);
const canSendAudio = call.permissionsContext.hasPermission(
OwnCapability.SEND_AUDIO,
);
In our React Native Video SDK, you can use the useHasPermissions
hook to check for permissions.
import {
useCallStateHooks,
OwnCapability,
} from "@stream-io/video-react-native-sdk";
const { useHasPermissions } = useCallStateHooks();
const canSendAudio = useHasPermissions(OwnCapability.SEND_AUDIO);
Request permissions
Every user may request permission to perform certain actions depending on the call type and call settings.
For example, in an audio-room call type, only the hosts have send-audio
permission by default.
Other users should request this permission before they can start sending audio if the call settings allow it.
import { OwnCapability } from "@stream-io/video-react-native-sdk";
const call = streamVideoClient.call(type, id);
if (!call.permissionsContext.canRequest(OwnCapability.SEND_AUDIO)) {
console.log("The host has disabled the ability to request this permission");
return;
}
await call.requestPermissions({
permissions: [OwnCapability.SEND_AUDIO],
});
Approving permission requests
Call hosts and moderators can approve permission requests from other users.
Whenever a user requests a certain permission, a call.permission_request
event will be emitted on the Call
instance.
You can listen to this event and approve the request.
import {
PermissionRequestEvent,
StreamCallEvent,
} from "@stream-io/video-react-native-sdk";
const call = streamVideoClient.call(type, id);
call.on("call.permission_request", async (event: StreamCallEvent) => {
const request = event as PermissionRequestEvent;
if (shouldApproveRequest(request)) {
await call.grantPermissions(request.user.id, request.permissions);
}
});
Moderation
At any time, a moderator or host can decide to either grant or revoke certain permission to any participant.
import { OwnCapability } from "@stream-io/video-react-native-sdk";
const call = streamVideoClient.call(type, id);
await call.updateUserPermissions({
user_id: "demo-user",
grant_permission: [OwnCapability.SEND_AUDIO, OwnCapability.SEND_VIDEO],
revoke_permissions: [OwnCapability.SCREENSHARE],
});
// alternate API for granting user permissions:
await call.grantPermissions("demo-user", [
OwnCapability.SEND_AUDIO,
OwnCapability.SEND_VIDEO,
]);
// alternate API for revoking user permissions:
await call.revokePermissions("demo-user", [OwnCapability.SCREENSHARE]);
The end user would get notified via a WebSocket event with a type: call.permissions_updated
.
In the case of revoked permissions, the SDK would automatically stop publishing the appropriate tracks.
Ending call for everyone
In some cases, a moderator or host may want to end the call for everyone.
const call = streamVideoClient.call(type, id);
await call.endCall();
This operation will emit call.ended
event to every participant in the call.
The SDK would automatically stop publishing any tracks and leave the call.
Ended calls can’t be re-joined.
Users
Blocking and Unblocking
In some cases, a moderator or host may want to block a participant from joining the call.
const call = client.call(type, id);
await call.blockUser("user-id");
// to unblock
await call.unblockUser("user-id");
Kicking
Kicking a participant is a softer version of blocking. The participant will be disconnected from the call, but they will be able to re-join the call.
const call = client.call(type, id);
await call.kickUser({ user_id: "user-id" });
// you can use this shortcut to block the user from re-joining the call:
await call.kickUser({ user_id: "user-id", block: true });
Muting
In addition to granting or revoking permissions, a moderator or host can also mute a participant. This is a common scenario as quite often, participants may be a source of unwanted noise or distraction.
const call = client.call(type, id);
await call.muteUser("demo-user-id", "audio");
await call.muteUser("demo-user-id", "video");
await call.muteUser("demo-user-id", "screenshare");
// or, mute in bulk
await call.muteUser(["demo-user-id", "demo-user-id-2"], "audio");
// or, muting self
await call.muteSelf("audio");
// or, muting others
await call.muteOthers("audio");
// or, mute all, including self.
await call.muteAllUsers("audio");
This operation doesn’t revoke any permission, and the user would still be able to un-mute itself.