Skip to main content

Joining and Creating Calls

Creating Calls

To create a call, we first call the makeCall function on the StreamVideo class and pass it the call type and ID. The most common call type is default, which enables full audio and video transmission. However, there are multiple call types (and even custom types) from which you can choose based on your use case.

Call typeNameShort overview
defaultDefaultsimple 1-1 calls for larger group video calling with sensible defaults
audio_roomAudiopre-configured for a workflow around requesting permissions in audio settings (speaking, etc.)
livestreamLivestreamaccess to calls is granted to all authenticated users, useful in one-to-many settings (such as livestreaming)
developmentDevelopmentshould only be used for testing, permissions are open and everything is enabled (use carefully)

You can read more about call types here.

final call = StreamVideo.instance.makeCall(callType: StreamCallType.defaultType(), id: 'Your-call-ID');
await call.getOrCreate();

Calling makeCall returns a Call object for us to work with. However, it neither connects nor starts transmitting data automatically. To create and join the call, we must then invoke getOrCreate on the returned object which creates the call if it doesn't exist and returns the existing call if it does.

For the call ID there are a few things to note:

  • You can reuse the same call multiple times.
  • If you have a unique id for the call we recommend passing that as the id.
  • If you don't have a unique id you can leave it empty and we'll generate one for you.

As an example, if you're building a telemedicine app, calls will be connected to an appointment. Using your own appointment id as the Call ID makes it easy to find the call later.

Managing Members and Ringing Calls

You can pass certain arguments to the call.getOrCreate() method used in the previous example:

  1. members: Upon creation, we can supply a list of user IDs we would like to immediately add to the call.
  2. ringing: If ringing is set to true, Stream will send a VoIP notification to the users on the call, triggering the platform call screen on iOS and Android.
  3. video: When ringing, the notification will indicate whether it's a video call or an audio-only call, depending on whether you set the video parameter to true or false.
  4. custom: Any custom data associated with the call.
  5. team: A team is a part of Stream Video multi-tenancy support. You can separate different groups of videos and calls using this argument.
  6. notify If notify is set to true, Stream will send a standard non-VoIP push notification to all the users in the call.
note

By default, calling getOrCreate() assigns admin permission to each user who is supplied during creation. Depending on call permissions settings, call member may have different permissions than other users joining the call. For example, call can be configured so only members can join. See here for more information.

When call is already active you can still manage members:

final call = client.makeCall(callType: StreamCallType.defaultType(), id: 'my-call-id');
call.getOrCreate(memberIds: ['alice', 'bob']);

// grant access to more users
await call.updateCallMembers(updateMembers: [const UserInfo(id: 'charlie', role: 'call_member')]);
// or
await call.addMembers([const UserInfo(id: 'charlie', role: 'call_member')]);

// remove access from some users
await call.updateCallMembers(removeIds: ['charlie']);
// or
await call.removeMembers(['charlie']);

Call CRUD Operations

With calls, we make it easy to perform basic create, read, update, and delete (CRUD) operations on calls providing the user has sufficient permissions.

For example, once a call is created a user can call.update the information on the call by adding custom metadata such as a name, description, or any other arbitrary Map<String, Object> to the call before getOrCreate is invoked.

call.update(custom: {'name': 'My first Call'});
await call.getOrCreate();

Using the update method, a variety of settings can also be applied before the call is created such as:

  • Ring
  • Audio
  • Video
  • ScreenShare
  • Recording
  • Transcription
  • Backstage
  • Geofencing

Joining Calls

To join a call that already exists, you must first know two things:

  • The callType of the existing call
  • The ID of the existing call

Similar to the flow of creating a call, we can use makeCall to construct a Call class for us to perform operations on.

final call = StreamVideo.instance.makeCall(callType: StreamCallType.defaultType(), id: 'My-existing-call-ID');
await call.getOrCreate();

Next, with our class instantiated, we can connect to the call and SFU by invoking join.

await call.join();

Unlike the call creation flow and functions, the user must have sufficient permissions to join the call or a VideoError will be returned. All users connected via the join() function have the permission type of user by default and are limited in the actions they can perform.

Backstage setup

The backstage feature makes it easy to build a use-case where you and your co-hosts can setup your camera before going live. Only after you call call.goLive() the regular users be allowed to join the livestream.

However, you can also specify a joinAheadTimeSeconds, which allows regular users to join the livestream before it is live, in the specified join time before the stream starts.

Here's an example how to do that:

final call = StreamVideo.instance.makeCall(callType: StreamCallType.livestream(), id: 'my-call-id');

const backstageSetting = StreamBackstageSettings(
enabled: true,
joinAheadTimeSeconds: 300,
);

await call.getOrCreate(
memberIds: ['alice', 'bob'],
startsAt: DateTime.now().add(const Duration(seconds: 500)),
backstage: backstageSetting,
);

await call.join();

In the code snippet above, we are creating a call that starts 500 seconds from now. We are also enabling backstage mode, with a joinAheadTimeSeconds of 300 seconds. That means that regular users will be able to join the call 200 seconds from now.

Restricting access

You can restrict access to a call by tweaking the Call Type permissions and roles. A typical use case is to restrict access to a call to a specific set of users -> call members.

Step 1: Set up the roles and permissions

​ On our dashboard, navigate to the Video & Audio -> Roles & Permissions section and select the appropriate role and scope. In this example, we will use my-call-type scope.

By default, all users unless specified otherwise, have the user role.

We start by removing the JoinCall permission from the user role for the my-call-type scope. It will prevent regular users from joining a call of this type.

Revoke JoinCall

Next, let's ensure that the call_member role has the JoinCall permission for the my-call-type scope. It will allow users with the call_member role to join a call of this type.

Grant JoinCall

Once this is set, we can proceed with setting up a call instance.

Did you find this page helpful?