Skip to main content
Version: 5.x.x

Manage On-Screen Participants - Flutter

It is important that only the necessary person are present on the screen when livestream is on. To handle this, we will be using the pin and unpin methods of the Participant object.

note

To ensure only the hosts/speakers are shown in the grid, you should use the SPOTLIGHT layout and pin as the priority when starting the interactive livestream.

Let us first explore two methods that we will be using to manage on-screen participats.

pin()​

With these method you can pin any participant's Camera, Screen Share or both. This can be useful to identify the participants based on which you can perform rendering participant grid.

unpin()​

With these methods you can unpin any participant's Camera, Screen Share or both. This can be useful to reset pin state of the participant.

Both methods return a Future that throws a VideoSDKError when the pin state cannot be changed.

info

Important Changes Flutter SDK in Version v1.3.0

  • The following modes have been deprecated:
    • CONFERENCE has been replaced by SEND_AND_RECV
    • VIEWER has been replaced by SIGNALLING_ONLY

Please update your implementation to use the new modes.

⚠️ Compatibility Notice:
To ensure a seamless meeting experience, all participants must use the same SDK version.
Do not mix version v1.3.0 + with older versions, as it may cause significant conflicts.

Managing On-Screen Participants​

  1. If you want to pin all the hosts/speakers automatically, you can do it by listenting to the Events.roomJoined callback and Events.participantModeChanged, where you can pin and unpin based on the mode. participant.mode is already updated when participantModeChanged fires, so read it there.
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:videosdk/videosdk.dart';

class RoomScreen extends StatefulWidget {
...
}

class _RoomScreenState extends State<RoomScreen> {
late Room room;

@override
void initState() {
...

setupRoomEventListener();
}

@override
Widget build(BuildContext context) {
return YourRoomWidget();
}

void setupRoomEventListener() {
room.on(Events.roomJoined, () {
//We will pin the participant if mode is SEND_AND_RECV
if (room.localParticipant.mode == Mode.SEND_AND_RECV) {
setPinned(true);
}
});

room.on(Events.participantModeChanged, (Map<String, dynamic> data){
//We will pin the participant if mode is SEND_AND_RECV else unpin him
if (data['participantId'] == room.localParticipant.id) {
setPinned(room.localParticipant.mode == Mode.SEND_AND_RECV);
}
});
}

Future<void> setPinned(bool pinned) async {
try {
if (pinned) {
await room.localParticipant.pin();
} else {
await room.localParticipant.unpin();
}
} on VideoSDKError catch (error) {
log("Could not update the pin: ${error.code} ${error.name}");
}
}
}
  1. When rendering the participant grid on the Speaker side, make sure to show only the participants who are in SEND_AND_RECV mode. You can filter the participants as shown in below examples. room.participants holds the remote participants only, so add room.localParticipant once the room is joined.
import 'package:flutter/material.dart';
import 'package:videosdk/videosdk.dart';

class RoomScreen extends StatefulWidget {
...
}

class _RoomScreenState extends State<RoomScreen> {
late Room room;
bool _joined = false;

Map<String, Participant> _speakers = {};

@override
void initState() {
...

updateSpeakers();

setupRoomEventListener();
}

@override
Widget build(BuildContext context) {
return YourRoomWidget();
}

void updateSpeakers(){
Map<String, Participant> speakers = {};
// room.participants holds remote participants only, so add yourself.
final everyone = [
if (_joined) room.localParticipant,
...room.participants.values,
];
everyone.forEach((participant) {
if (participant.mode == Mode.SEND_AND_RECV) {
speakers.putIfAbsent(participant.id, () => participant);
}
});
setState(()=>_speakers = speakers);
}

void setupRoomEventListener() {
room.on(Events.roomJoined, () {
_joined = true;
updateSpeakers();
});

room.on(Events.participantModeChanged, (Map<String, dynamic> data){
updateSpeakers();
});

room.on(Events.participantJoined, (Participant participant) {
updateSpeakers();
});


room.on(Events.participantLeft, (Participant participant, LeaveReason reason) {
updateSpeakers();
});
}
}

API Reference​

The API references for all the methods utilized in this guide are provided below.

Got a Question? Ask us on discord