logo
On this page

Screen sharing

What's screen sharing?

Screen sharing refers to the process of broadcasting the contents of one screen to another device or multiple devices in a video call or interactive video scene.

Starts screen sharingScreen shared by mobile appsScreen shared by web appsLandscape mode

Prerequisites

Before you begin, make sure you complete the follow the integration steps by referring to the Quick start or Quick start with co-hosting.

Implementation

Use the screen sharing

Screen sharing is only supported in the gallery layout. To share your screen, you will need to set the layout inside the ZegoUIKitPrebuiltLiveStreamingConfig to Gallery first.

To decide whether to use the full-screen mode by default during screen sharing, you will need to configure the showNewScreenSharingViewInFullscreenMode inside the ZegoLayoutGalleryConfig. Set it to true (default setting), meaning that the shared screen will automatically be in full screen when the screen sharing starts.

Meanwhile, the full-screen mode button is customizable, you can decide the way how it shows. To set it, configure the showScreenSharingFullscreenModeToggleButtonRules inside the ZegoLayoutGalleryConfig:

  • showWhenScreenPressed: (default setting) shows the full-screen mode button when clicking the shared screen.
  • alwaysShow: always shows the full-screen mode button.
  • alwaysHide: always hides the full-screen mode button.

Add/customize the buttons

To start the screen sharing, add the ZegoMenuBarButtonName.toggleScreenSharingButton config to the bottomMenuBarConfig to let the screen sharing button show.

Here is the reference code:

Untitled
class LivePage extends StatelessWidget {
  const LivePage({Key? key, required this.liveID, this.isHost = false})
      : super(key: key);

  final String liveID;
  final bool isHost;

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: ZegoUIKitPrebuiltLiveStreaming(
          appID: YourSecret.appID,
          appSign: YourSecret.appSign,
          userID: userID,
          userName: 'user_$userID',
          liveID: liveID,

          // Modify your custom configurations here.
          config: isHost
              ? (ZegoUIKitPrebuiltLiveStreamingConfig.host()
                    ..layout = ZegoLayout.gallery(
                        showScreenSharingFullscreenModeToggleButtonRules:
                            ZegoShowFullscreenModeToggleButtonRules.alwaysShow,
                        showNewScreenSharingViewInFullscreenMode:
                            false) //  Set the layout to gallery mode. and configure the [showNewScreenSharingViewInFullscreenMode] and [showScreenSharingFullscreenModeToggleButtonRules].
                    ..bottomMenuBar =
                        ZegoLiveStreamingBottomMenuBarConfig(hostButtons: [
                      ZegoMenuBarButtonName.toggleScreenSharingButton,
                      ZegoMenuBarButtonName.toggleMicrophoneButton,
                      ZegoMenuBarButtonName.toggleCameraButton
                    ]) // Add a screen sharing toggle button.
                  )
              : (ZegoUIKitPrebuiltLiveStreamingConfig.audience()
                ..layout = ZegoLayout.gallery(
                    showScreenSharingFullscreenModeToggleButtonRules:
                        ZegoShowFullscreenModeToggleButtonRules.alwaysShow,
                    showNewScreenSharingViewInFullscreenMode:
                        false) // Set the layout to gallery mode. and configure the [showNewScreenSharingViewInFullscreenMode] and [showScreenSharingFullscreenModeToggleButtonRules].
                ..bottomMenuBar =
                    ZegoLiveStreamingBottomMenuBarConfig(hostButtons: [
                  ZegoMenuBarButtonName.toggleScreenSharingButton,
                  ZegoMenuBarButtonName.coHostControlButton
                ]) // Add a screen sharing toggle button.
              )),
    );
  }
}
1
Copied!

To customize the UI of the full-screen mode button, configure the foregroundBuilder. To decide whether to show the shared screen in full-screen mode, use the ZegoUIKitPrebuiltLiveStreamingController().screenSharing.showViewInFullscreenMode inside the custom foregroundBuilder.

Here is the reference code:

Untitled
class _LivePageState extends State<LivePage> {
  // this indicates whether the current state is full screen.
  bool isFullscreen = true;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: ZegoUIKitPrebuiltLiveStreaming(
        appID: YourSecret.appID /*input your AppID*/,
        appSign: YourSecret.appSign /*input your AppSign*/,
        userID: userID,
        userName: 'user_$userID',
        liveID: widget.liveID,
        config: widget.isHost
            ? ZegoUIKitPrebuiltLiveStreamingConfig.host()
            : ZegoUIKitPrebuiltLiveStreamingConfig.audience()
          ..audioVideoView.foregroundBuilder =
              (context, size, user, extraInfo) {
            // Here is the full-screen mode button.
            return Container(
              child: OutlinedButton(
                  onPressed: () {
                    isFullscreen = !isFullscreen;
                    ZegoUIKitPrebuiltLiveStreamingController()
                        .screenSharing
                        .showViewInFullscreenMode(
                          user?.id ?? '',
                          isFullscreen,
                        ); // Call this to decide whether to
                    // show the shared screen in full-screen mode.
                  },
                  child: const Text('full screen')),
            );
          },
      ),
    );
  }
}
1
Copied!

Add the screen sharing permission (for android only)

Note

Before sharing the screen, a dialog will prompt the user to allow the app to share the screen.

The user needs to manually grant the permission.

The screen sharing feature relies on foreground service to keep the app alive. Therefore, navigate to the "app/src/main" directory, open the "AndroidManifest.xml" file, and add the following permissions:

  • If the Android SDK version is lower than version 34.0.0, you need to declare the FOREGROUND_SERVICE permission.

    app/src/main/AndroidManifest.xml
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
    
    1
    Copied!
  • If the Android SDK version is 34.0.0 or later, you need to declare the FOREGROUND_SERVICE and FOREGROUND_SERVICE_MEDIA_PROJECTION permission.

    app/src/main/AndroidManifest.xml
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION"/>
    
    1
    Copied!

Create a Broadcast Upload Extension (for iOS only)

Note

The memory limit of the Broadcast Upload Extension is 50 MB, make sure the memory usage of the Extension for screen sharing does not exceed 50 MB.

  1. Open your project in Xcode, select File > New > Target.
  1. In the following window, select the Broadcast Upload Extension, and click Next.
  1. Fill in items or choose options for your new target, such as filling in the Product Name as ScreenShare, and choose options for the Team, Language, and other required information, and then click Finish.
Note

Don't need to check the Include UI Extension option.

  1. Set screen sharing target minimum support version. The minimum support version needs to be greater than or equal to 12. If your phone's system version is lower than this minimum support version, screen sharing function will not be available.
  1. After you created the Broadcast Upload Extension, you will see a folder for this Extension in your project with a structure similar to the following. This folder is used to store the implementation codes for the screen sharing feature:
  1. Add the ZegoExpressEngine.xcframework dependency.
  • Run the cd command in the Terminal to navigate to your iOS project directory, and run the pod install to install the ZegoExpressEngine library.
  • Click the + button as shown in the following figure.
  • Select and add the ZegoExpressEngine.xcframework.
  • Set Embed to Do Not Embed.
  1. Replace the code in the SampleHandler file with the following code:
Untitled
import ReplayKit
import ZegoExpressEngine

class SampleHandler: RPBroadcastSampleHandler, ZegoReplayKitExtHandler {

    override func broadcastStarted(withSetupInfo setupInfo: [String : NSObject]?) {
        // User has requested to start the broadcast. Setup info from the UI extension can be supplied but optional.
        ZegoReplayKitExt.sharedInstance().setup(withDelegate: self)
    }
    
    override func broadcastPaused() {
        // User has requested to pause the broadcast. Samples will stop being delivered.
    }
    
    override func broadcastResumed() {
        // User has requested to resume the broadcast. Samples delivery will resume.
    }
    
    override func broadcastFinished() {
        // User has requested to finish the broadcast.
        ZegoReplayKitExt.sharedInstance().finished()
    }
    
    override func processSampleBuffer(_ sampleBuffer: CMSampleBuffer, with sampleBufferType: RPSampleBufferType) {
        
        ZegoReplayKitExt.sharedInstance().send(sampleBuffer, with: sampleBufferType)
        
        switch sampleBufferType {
        case RPSampleBufferType.video:
            // Handle video sample buffer
            break
        case RPSampleBufferType.audioApp:
            // Handle audio sample buffer for app audio
            break
        case RPSampleBufferType.audioMic:
            // Handle audio sample buffer for mic audio
            break
        @unknown default:
            // Handle other sample buffer types
            fatalError("Unknown type of sample buffer")
        }
    }

    func broadcastFinished(_ broadcast: ZegoReplayKitExt, reason: ZegoReplayKitExtReason) {
        switch reason {
        case .hostStop:
            let userInfo = [NSLocalizedDescriptionKey: "Host app stopped screen capture"]
            let error = NSError(domain: NSCocoaErrorDomain, code: 0, userInfo: userInfo)
            finishBroadcastWithError(error)

        case .connectFail:
            let userInfo = [NSLocalizedDescriptionKey: "Connect host app failed; need to startScreenCapture in host app"]
            let error = NSError(domain: NSCocoaErrorDomain, code: 0, userInfo: userInfo)
            finishBroadcastWithError(error)

        case .disconnect:
            let userInfo = [NSLocalizedDescriptionKey: "Disconnected from host app"]
            let error = NSError(domain: NSCocoaErrorDomain, code: 0, userInfo: userInfo)
            finishBroadcastWithError(error)

        default:
            let userInfo = [NSLocalizedDescriptionKey: "Unknown reason for broadcast finish"]
            let error = NSError(domain: NSCocoaErrorDomain, code: 0, userInfo: userInfo)
            finishBroadcastWithError(error)
        }
    }
}
1
Copied!