iOS Screen Share

Screen sharing during video meetings is designed to provide a collaboration environment for meeting participants. On iOS, when the video app runs in the background, an extension is broadcasted in user's app for a continued broadcast screen.

Note:* This feature is supported with iOS 12+.

Live Broadcast using ReplayKit Library

Using the ReplayKit library, users can build app extensions for live broadcasting.

Class: RPSystemBroadcastPickerView

  1. Add the broadcast extension. Go to Project > File > Target > Broadcast Upload Extension.

  1. Set a unique bundle ID for Broadcast targets com.companyName.Appname.Broadcast.extension

Note: After adding the broadcast extension, you must add the correct bundle id for your broadcast extension and the app.

  1. Open the Broadcast Extension through RPSystemBroadcastPickerView.

    1. Add the below code and run the application. The broadcast opens and you receive the sample buffer.

      RPSystemBroadcastPickerView *pickerView = [[RPSystemBroadcastPickerView alloc]initWithFrame:CGRectMake(0, 0, 50, 50)];
      pickerView.translatesAutoresizingMaskIntoConstraints = false;
      pickerView.autoresizingMask = (UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleRightMargin);
      NSURL *url = [[NSBundle mainBundle] URLForResource:@"BroadCastExtension" withExtension:@"Appex" subdirectory:@"PlugIns"];
      if(url != nil){
      NSBundle *bundle = [NSBundle bundleWithURL:url];
      if(bundle != nil){
      pickerView.preferredExtension= bundle.bundleIdentifier;
      }
      }
      pickerView.hidden = true;
      pickerView.showsMicrophoneButton = false;
      SEL buttonPress = NSSelectorFromString(@"buttonPressed:");
      if ([pickerView respondsToSelector:buttonPress]){
      [pickerView performSelector:buttonPress withObject:nil];
      }
      [self.view addSubview:pickerView];
      [self.view bringSubviewToFront:pickerView];
      pickerView.center = self.view.center;
      [self.extensionContext loadBroadcastingApplicationInfoWithCompletion:^(NSString* _Nonnull bundleID,NSString *_Nonnull displayName, UIImage *_Nullable AppIcon){
      if(AppIcon != nil){
      }
      }];

      (buffer frame of your image).

    2. The sample buffer in the Sample Handler broadcast class is sent through a delegate method.

Class Sample Handler
Delegate Method (void)processSampleBuffer:(CMSampleBufferRef)sampleBuffer withType:(RPSampleBufferType)sampleBufferType; get buffer frame

Other delegated methods are listed below.

- (void)broadcastFinished If the broadcast has stopped/finished
- (void)broadcastPaused If the broadcast has paused
-(void)broadcastResumed To resume the broadcast

Broadcast the Device Screen to EnableX Server

The EnableX iOS SDK leverages the broadcast extension to broadcast your device screen and publishes it on the EnableX server.

To broadcast your device screen:

  1. Add the app group capabilities to the application. It enables data exchange from the app to the broadcast extension and vice versa. To add an app group to your application:

    1. Go to Testing > TARGETS and select your application
    2. To add the app group capabilities for your application, select Capability > App Groups

  1. To add the app group to your broadcast extension:

    1. Go to Testing > TARGETS and select your broadcast
    2. To add the app group capabilities to your broadcast, select Capability > App Groups

  1. Join EnableX Conference through your application, and store your RoomID through NSUserDefaults or any other storage that you want to use to obtain the same RoomID in the broadcast extension.
NSUserDefaults *userDaf = [[NSUserDefaults alloc]initWithSuiteName:@"group.com.enx.Videocall"];
[userDaf setObject:[@"your roomID through which you have joined EnableX Room" objectForKey:@"RoomId"] forKey:@"RoomId"];
[userDaf synchronize];
  1. Obtain your ClientID and store it in NSUserDefaults after successfully joining the EnableX Room.
NSUserDefaults *userDefault = [[NSUserDefaults alloc]initWithSuiteName:@"group.com.enx.Videocall"];
[userDefault setObject:_remoteRoom.clientId forKey:@"ClientID"];
[userDefault synchronize];
  1. Pass the app group key to EnableX SDK.
[[EnxUtilityManager shareInstance] setAppGroupsName:@"group.com.enx.Videocall" withUserKey:@"ClientID"];
  1. Start the broadcast through RPSystemBroadcastPickerView after sharing the RoomID and the ClientID.

  2. Use the class SampleHandler class to broadcast the extension in RPSystemBroadcastPickerView. This class notifies the user of all the events.

    Add another class to obtain an update from SampleHandler and pass it to the EnableX iOS SDK.

Note: The user needs to join the EnableX room with the help of the same RoomID shared through the main application.

Connect to the Broadcast Extension

The SampleHandler initiates the helper class (the class that you have created inside the broadcast extension). On a successful connection to the broadcast extension, you receive a delegated method in SampleHandler.

(void)broadcastStartedWithSetupInfo:(NSDictionary< NSString *,NSObject * > *)setupInfo

  1. Connect to the EnableX room with the same RoomID and pass through the main application.

  2. Get the same RoomID stored in UserDefault

NSUserDefaults *userDefault = [[NSUserDefaults alloc] initWithSuiteName:@"group.com.enx.Videocall"];
NSString *roomId = [userDefault objectForKey:@"RoomId"];
  1. Pass the stored app group name to the EnableX SDK at the same time
[[EnxUtilityManager shareInstance] setAppGroupsName:@"group.com.enx.Videocall" withUserKey:@"ClientID"];
  1. Create an EnableX token and connect with the room after getting RoomID
EnxRoom *remoteRooml = [[EnxRoom alloc]init];
[remoteRooml connectWithScreenshare:respinseDict[@"token"] withScreenDelegate:self];

User receives a callback from EnableX iOS SDK when the room is successfully connected:

  • (void)broadCastConnected;

If the connection fails due to any reason, the user receives the below failure callback through the EnableX iOS SDK:

  • (void)failedToConnectWithBroadCast:(NSArray *)reason

Start Screen Sharing

The EnxRoom.startScreenShare() method creates a screen-sharing stream @6fps to publish in the room. The EnableX SDK organizes and publishes the screen sharing over the EnableX media channel. Once the screen sharing is successfully published, the broadcast extension class receives a callback method, and the application receives an acknowledgment method for starting the screen sharing.

Class: EnxRoom

MethodsDescription
[enxRoom startScreenShare];Not Applicable
(void)didStartBroadCast:(NSArray *)dataReceived by the broadcast extension class after the shared screen stream is published.
(void)room:(EnxRoom *)room didStartScreenShareACK:(NSArray *)DataReceived by the application for starting the screen sharing.

Send the Video Buffer Frame to EnableX Room

  1. Once you are connected to the room and have started screen sharing, start sending your video buffer frame to the EnableX room.

    • (void)sendVideoBuffer:(CVPixelBufferRef _Nonnull)sampleBuffer withTimeStamp:(int64_t)timeStampNs;

    where SampleBuffer is the frame of the screen and TimeStampNsc is in nanoseconds.

  2. If the user receives "CMSampleBufferRef" from the broadcast convert it using **"CVPixelBufferRef".

    • CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(bufferImage);
  3. Create a time stamp in the "int64_t" format

    • int64_t timeStampNs = CMTimeGetSeconds(CMSampleBufferGetPresentationTimeStamp(bufferImage)) *1000000000;
[enxRoom sendVideoBuffer: pixelBuffer withTimeStamp
:timeStampNs];

Compress the Sample Buffer Frame

The user receives the buffer image once the broadcast extension has successfully started through the broadcast callback method.

Note: The broadcast extension can use a maximum of 50m memory at runtime. If this limit is exceeded, the broadcast extension is terminated, and a warning with an appropriate message is displayed.

The user must compress the sample buffer frame (received through the broadcast extension) using vImage crop or any other crop methodology.

(void)processSampleBuffer:(CMSampleBufferRef)sampleBuffer withType:(RPSampleBufferType)sampleBufferType;

Stop Screen Sharing

The EnxRoom.stopScreenShare() method stops the ongoing screen sharing.

Once the screen share is unpublished, the broadcast extension class receives a callback method, and the application receives an acknowledgment method for starting the screen sharing.

Class: EnxRoom

MethodsDescription
[enxRoom stopScreenShare];Not Applicable
-(void)didStoppedBroadCast:(NSArray *)dataReceived by the broadcast extension class after the shared screen stream is unpublished.
-(void)room:(EnxRoom *)room didStartScreenShareACK:(NSArray *)DataReceived by the application for stopping the screen sharing.

Disconnect the Room

After the screen sharing is stopped, the user needs to disconnect the room that is connected through the broadcast extension for the screen sharing.

Class: EnxRoom

MethodsDescription
[enxRoom disconnect];Not Applicable
-(void)broadCastDisconnected;Received by the broadcast extension class after the broadcast room is disconnected.
-(void)disconnectedByOwner;Received by the broadcast extension class from the EnableX iOS SDK if a parent user is disconnected from an ongoing screen sharing.
EventsDescription
[self finishBroadcastWithError:nil];The user must stop the broadcast after receiving this event.

Exit Screen Sharing

The EnxRoom.exitScreenShare() method is used by the parent users for stopping an ongoing screen sharing.

Class: EnxRoom Method: -(void)exitScreenShare; Delegate Methods:

Delegate MethodsDescription
(void)room:(EnxRoom *_Nullable)room didExitScreenShareACK:(NSArray *_Nullable)Data;Acknowledgment callback for parent clients.
(void)didRequestedExitRoom:(NSArray *_Nullable)Data;Received by the child client (screen sharing client) to initiate stopping of the broadcast to disconnect from the room.

Error Codes and Exceptions

CodeDescription
5137Screen sharing is not running in conference.