void startSharing() {
// Checks to ensure the user can share their screen.
final canShare = call.hasPermission(CallPermission.screenshare);
if (canShare) {
// Set screensharing to enabled
call.setScreenShareEnabled(enabled: true);
}
}
Screen Sharing
Introduction
During the duration of a call, participants may want to share either a portion of their screen, application or their entire screen to other users on the call. Stream Video makes it easy to support screensharing to other users natively on both Android and iOS devices.
In this guide, we will look at the steps required to configure screensharing on both platforms. If you are interested in screensharing for just one platform, you can skip to the Android or iOS section using this link.
iOS
Starting with iOS, there are two main options for screensharing from an iOS device. These are:
- in-app screensharing - In this mode, the app’s screen is only shared while the app is active or in the foreground. If the app is not in the foreground, screensharing is paused.
- broadcasting - Using broadcasting mode allows the app to share the contents of the screen even when the application goes into the background.
Both of these options use Apple’s framework ReplayKit (via flutter_webrtc) for broadcasting the user’s screen.
Before a user can share their screen, the call must have the screensharing capability configured via the Dashboard.
In-app sharing
In-app screensharing only shares the application’s screens. While in a call, screensharing can be enabled by calling call.setScreenShareEnabled(enabled: true)
method.
If you use our UI components you can also add ToggleScreenShareOption
as one of StreamCallControls
option.
When the method is invoked, ReplayKit will ask for the user’s consent that their screen will be shared. Only after the permission is granted, the screensharing starts.
Broadcasting
In most cases, you would need to share your screen while the app is in the background, to be able to open other apps. For this, you need to create a Broadcast Upload Extension.
Toggle screen sharing with broadcast mode
If you want to start screen sharing in broadcast mode on iOS you will need to toggle it by setting useiOSBroadcastExtension
flag to true in ScreenShareConstraints
. You can set the constraints inside ToggleScreenShareOption
or when you use call.setScreenShareEnabled()
directly.
const constraints = ScreenShareConstraints(
useiOSBroadcastExtension: true,
);
...
ToggleScreenShareOption(
...
screenShareConstraints: constraints,
),
//or
call.setScreenShareEnabled(enabled: true, constraints: constraints);
Add Broadcast Upload Extension
iOS requires the use of Broadcast Upload Extensions to facilitate screen sharing when your app is in the background. This extension provides the necessary framework to handle capturing and broadcasting the screen content.
Now add the extension, without UI, to your project in Xcode:
Make sure the deployment target for both your app and broadcast extension is set to iOS 14 or newer.
After you create the extension, there should be a class called SampleHandler
, that implements the RPBroadcastSampleHandler
protocol. Remove the protocol conformance and the methods, import our stream_video_screen_sharing
, and make the SampleHandler
a subclass of our class called BroadcastSampleHandler
, that internally handles the broadcasting.
To have access to our Handler implementation add stream_video_screen_sharing
package to your app’s pubspec.yaml
file:
dependencies:
stream_video_screen_sharing: ^<latest_version>
Then for native code to see it, add it as a dependency manually for the extension target in the Podfile file:
target 'YOUR_EXTENSION_NAME' do
use_frameworks!
pod 'stream_video_screen_sharing', :path => File.join('.symlinks', 'plugins', 'stream_video_screen_sharing', 'ios')
end
Replace YOUR_EXTENSION_NAME
with the name of the extension you created.
Setup app groups
Add your extension to an app group by going to your extension’s target in the project. In the Signings & Capabilities tab, click the + button in the top left and add App Groups. If you haven’t done so already, add App Groups to your main app as well, ensuring that the App Group identifier is the same for both.
Update Info.plist
Finally, you should add a new entries in the Info.plist
files.
In both the app and the broadcast extension, add a key RTCAppGroupIdentifier
with a value of the app group id and RTCScreenSharingExtension
key with a value of a bundle id of your extension.
With that, the setup for the broadcast upload extension is done.
Android
The Stream Video SDK has support for screen sharing from an Android device. The SDK is using the Android Media Projection API for the capture. To initiate screen sharing, user consent is mandatory.
When using the ToggleScreenShareOption
within thestream_video_flutter
package, permission handling is seamlessly integrated. However, if you opt to initiate screen sharing via the setScreenShareEnabled()
method on the Call
object, you will be responsible for securing the necessary permissions and initiating a foreground service. The foreground service is essential for displaying a notification to the user while screen sharing is active.
It is required to start media projection foreground service from Android version 10 onward.
From Android 14 onward, it is also required to actively ask users for a permission to share their screen. You can do this by calling call.requestScreenSharePermission()
method.
Below is an example snippet that demonstrates how to use our built in StreamBackgroundService
class to manage these requirements:
void startScreemSharing() {
if (CurrentPlatform.isAndroid) {
// Check if the user has granted permission to share their screen
if (!await call.requestScreenSharePermission()) {
return;
}
// Start the screen sharing notification service
await StreamBackgroundService()
.startScreenSharingNotificationService(call);
}
// Enable screen sharing
final result = await call.setScreenShareEnabled(
enabled: true,
);
// Stop the screen sharing notification service if the operation failed
if (CurrentPlatform.isAndroid && result.isFailure) {
await StreamBackgroundService()
.stopScreenSharingNotificationService();
}
}
Remember to stop the foreground service when the screen sharing is disabled:
void stopScreenSharing() async {
final result = await call.setScreenShareEnabled(
enabled: false,
);
if (CurrentPlatform.isAndroid) {
await StreamBackgroundService()
.stopScreenSharingNotificationService();
}
}
You can customize the notification content and behavior by initiating StreamBackgroundService
:
StreamBackgroundService.init(
StreamVideo.instance,
onNotificationClick: (call) async {
//TODO navigate to call
},
onButtonClick: (call, type, serviceType) async {
switch (serviceType) {
case ServiceType.call:
call.end();
case ServiceType.screenSharing:
StreamVideoFlutterBackground.stopService(ServiceType.screenSharing);
call.setScreenShareEnabled(enabled: false);
}
},
);
Screen sharing settings
You can customize the screen sharing behavior by providing ScreenShareConstraints
to the ToggleScreenShareOption
widget or setScreenShareEnabled()
method.
You can specify the following settings:
useiOSBroadcastExtension
- Set totrue
to enable broadcast mode on iOS.captureScreenAudio
- Set totrue
to capture audio from the screen.sourceId
- The device ID of an audio source, if you want to capture audio from a specific source.maxFrameRate
- The maximum frame rate for the screen sharing video.params
- The video parameters for the screen sharing video.
For params
you can use one of our predefined presets in RtcVideoParametersPresets
.