Skip to main content
Version: 2.x.x

Screen Share - Flutter

This feature enables hosts to start or stop sharing their screen with other hosts and audience members during the live stream. Only hosts (in SEND_AND_RECV mode) can broadcast their screen, while audience members (in RECV_ONLY mode) can view it in real time.

enableScreenShare()​

  • By using enableScreenShare() function of Room object, host can share his/her screen or window to other host and audience member.

  • Screen Share stream of the participant can be accessed from the streams property of Participant object.

  • To enable Screenshare in Android devices, you need to provide the following permissions in AndroidManifest.xml

AndroidManifest.xml
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
//For Android devices versioned 14 and above.
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION" />

disableScreenShare()​

  • By using disableScreenShare() function of Room object, host can stop sharing his/her screen or window to other host or audience member.

Events associated with enableScreenShare​

Events associated with disableScreenShare​

import 'package:flutter/material.dart';
import 'package:videosdk/videosdk.dart';

class LiveStreamScreen extends StatefulWidget {
...
}

class _LiveStreamScreenState extends State<LiveStreamScreen> {
late Room _room;

@override
void initState() {
_initStreamListeners();
}
//Change state according to the events received
_initStreamListeners() {
widget.participant.on(Events.streamEnabled, (Stream stream) {
if (stream.kind == 'share') {
//Screen share Turned On
}
});

widget.participant.on(Events.streamDisabled, (Stream stream) {
if (stream.kind == 'share') {
//Screen Share Turned Off
}
});
}
@override
Widget build(BuildContext context) {
return Column(
children:[
ElevatedButton(
onPressed:(){
_room.enableScreenShare();
},
child: const Text("Enable Screen Share"),
),
ElevatedButton(
onPressed:(){
_room.disableScreenShare();
},
child: const Text("Disable Screen Share"),
),
]
);
}
}
class LiveStreamScreen extends StatefulWidget {
...
}

class _LiveStreamScreenState extends State<LiveStreamScreen> {
late Room room;

@override
void initState() {
...

setupRoomEventListener();
}

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

void setupRoomEventListener() {

room.on(Events.presenterChanged, (String? presenterId) {
//Room screen presenter has changed
//Participant ID of current presenter is presenterId
});
}
}

iOS Setup​

note

For Flutter iOS Screen Share feature, you need to follow this guide Flutter iOS Screen Share

Rendering Screen Share Stream​

  1. To render the screenshare, you will need the participantId who is presenting the screen, which can be found from the presenterId property of Room object.

We will listen for the Events.presenterChanged on Room object to check if some other participant starts screen share, Events.streamEnabled and Events.streamDisabled on the localParticipant's object to identify if the local participant is presenting or not.

LiveStreamScreen.dart
import 'package:flutter/material.dart';
import 'package:videosdk/videosdk.dart';
import './screen_share_view.dart';

class LiveStreamScreen extends StatefulWidget {
final String liveStreamId;
final String token;

const LiveStreamScreen(
{super.key, required this.liveStreamId, required this.token});

@override
State<LiveStreamScreen> createState() => _LiveStreamScreenState();
}

class _LiveStreamScreenState extends State<LiveStreamScreen> {
late Room _room;
String? _presenterId;


@override
void initState() {
// create room
_room = VideoSDK.createRoom(
roomId: widget.liveStreamId,
token: widget.token,
displayName: "John Doe",
micEnabled: true,
camEnabled: true,
defaultCameraIndex:
1, // Index of MediaDevices will be used to set default camera
);

setLivestreamEventListener();

// Join room
_room.join();

super.initState();
}

// listening to livestream events
void setLivestreamEventListener() {
_room.on(Events.roomLeft, () {
participants.clear();
Navigator.popUntil(context, ModalRoute.withName('/'));
});
//Listening if remote participant starts presenting
_room.on(Events.presenterChanged, (String? presenterId) {
setState(() => {_presenterId = presenterId});
});

//Listening if local participant starts presenting
_room.localParticipant.on(Events.streamEnabled, (Stream stream) {
if (stream.kind == "share") {
setState(() => {_presenterId = _room.localParticipant.id});
}
});

_room.localParticipant.on(Events.streamDisabled, (Stream stream) {
if (stream.kind == "share") {
setState(() => {_presenterId = null});
}
});
}

// onbackButton pressed leave the room
Future<bool> _onWillPop() async {
_room.leave();
return true;
}

@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () => _onWillPop(),
child: Scaffold(
appBar: AppBar(
title: const Text('VideoSDK QuickStart'),
),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
Text(widget.liveStreamId),
//we will render the screenshare view if the presenterId is not null
if (_presenterId != null)
ScreenShareView(
participant: _presenterId == _room.localParticipant.id
? _room.localParticipant
: _room.participants[_presenterId],
),
ElevatedButton(
onPressed: () {
if (_presenterId != null) {
_room.disableScreenShare();
} else {
_room.enableScreenShare();
}
},
child: const Text('Toggle Screnshare')),
],
),
),
),
);
}
}

  1. Now that we know if there is an active presenter, let us get the screen share stream from the Participant object and render it.
screen_share_view.dart
import 'package:flutter/material.dart';
import 'package:videosdk/videosdk.dart';

class ScreenShareView extends StatelessWidget {
final Participant? participant;

ScreenShareView({super.key, required this.participant}) {
//intialize the shareStream
participant?.streams.forEach((key, value) {
if (value.kind == "share") {
shareStream = value;
}
});
}
Stream? shareStream;

@override
Widget build(BuildContext context) {
return Container(
color: Colors.grey.shade800,
height: 300,
width: 200,
//show the screen share stream
child: shareStream != null
? RTCVideoView(
shareStream?.renderer as RTCVideoRenderer,
objectFit: RTCVideoViewObjectFit.RTCVideoViewObjectFitCover,
)
: null,
);
}
}

API Reference​

The API references for all the methods and events utilised in this guide are provided below.

Got a Question? Ask us on discord