Screen Sharing
iOS SDK provides support for sharing the entire screen of the device in the room or you can share just your App's Screen.
Share The Entire Device Screen
To share entire device screen the SDK uses Replaykit framework from Apple. To understand the documentation better consider familiarising yourself with live screen broadcast in iOS: https://developer.apple.com/videos/play/wwdc2018/601
Please note that for a peer to share their screen, their role must have screenshare enabled in the dashboard. Also, select the appropriate resolution that you desire the screenshare track should be of.
To share entire device screen the SDK uses Replaykit framework from Apple. To understand the documentation better consider familiarising yourself with live screen broadcast in iOS: https://developer.apple.com/videos/play/wwdc2018/601
Please note that for a peer to share their screen, their role must have screenshare enabled in the dashboard. Also, select the appropriate resolution that you desire the screenshare track should be of.
How to start screenshare from the app
You create an iOS broadcast upload extension. It uses Apple's ReplayKit framework to record the device screen and delivers frame samples to your broadcast extension. You can share not only your own app but also the entire device screen including other apps on the device.
HMSBroadcastExtensionSDK is made specifically to be used in the iOS broadcast upload extension target. After importing the SDK, you use HMSScreenRenderer class to process the sample buffer coming from RPBroadcastSampleHandler. These samples are then presented in your main meeting app as a screen recording track.
Video walk-through of implementation
Example project shown in the walkthrough is available here.
How to import
Using Swift Package Manager
You can use Swift Package Manager (use https://github.com/100mslive/100ms-ios-broadcast-sdk.git as the package source)
Add HMSBroadcastExtensionSDK to your main app target from Swift Package Manager. Then add HMSBroadcastExtensionSDK to your iOS broadcast upload extension target.
Using CocoaPods
Get the HMSBroadcastExtensionSDK via CocoaPods. Add the pod 'HMSBroadcastExtensionSDK'
to your broadcast upload extension target in Podfile as follows:
# Podfile platform :ios, '12.0' target 'MainApp' do pod 'HMSSDK' end target 'HMSScreenShare' do pod 'HMSBroadcastExtensionSDK' end
How to use HMSBroadcastExtensionSDK to share iOS screen with other participants in the room?
You need to follow following steps to be able to share screen from iOS app:
- Make a new Broadcast Upload Extension target from Xcode. This target will be embedded into your application. Xcode automatically sets everything up if you use Xcode template named Broadcast Upload Extension to create the target.
- Add App Group capability in your main app target as well as in this new Broadcast Upload Extension target. Use the same App Group ID in both the targets.
- Add HMSBroadcastExtensionSDK to your main app target from Swift Package Manager. You can use Swift Package Manager (use https://github.com/100mslive/100ms-ios-broadcast-sdk.git as the package source) to add this SDK to your app. Then add HMSBroadcastExtensionSDK to your iOS Broadcast Upload Extension target using plus button in target's framework and libraries section.
- In your main app set the app group string to the hmssdk instance like below:
hmsSDK = HMSSDK.build { sdk in sdk.appGroup = "group.live.100ms.videoapp" ... }
- Xcode creates a SampleHandler.swift file in a new folder for your Broadcast Upload Extension target. Modify this SampleHandler.swift file to contain the following code (delete all the code in SampleHandler.swift file and paste the following code):
import HMSBroadcastExtensionSDK class SampleHandler: HMSBroadcastSampleHandler { override var appGroupId: String { "group.live.100ms.videoapp" } }
HMSScreenRenderer uses this app group string to talk to your main app.
Where "group.live.100ms.videoapp" is the app group ID of your app group that created in step 2. Make sure to replace it with your App Group ID string.
And that's all. Now you can start broadcasting with help of RPSystemBroadcastPickerView
. Make sure to assign the bundle id of your broadcast upload extension to the preferred extension
property of RPSystemBroadcastPickerView
instance.
Share Just Your App's Screen
You can use the hmsSDK instance to start sharing your app screen like below:
hmsSDK.startAppScreenCapture() { error in // handle any errors }
You can stop stop sharing your screen like below:
hmsSDK.stopAppScreenCapture() { error in // handle any errors }
How to check if user is sharing their screen
There are 2 approaches that we suggest for checking if user is sharing screen:
- Check if the screen is added as a local track for the user like shown below
if localPeer?.auxiliaryTracks?.first(where: { $0.source == HMSCommonTrackSource.screen }) != nil { // Screen is getting shared }
- Maintain a state variable when screen track is added or removed like shown below
var isSharingScreen = false func on(track: HMSTrack, update: HMSTrackUpdate, for peer: HMSPeer) { if update == .trackAdded { if peer.isLocal && track.source == HMSCommonTrackSource.screen { isSharingScreen = true } } if update == .trackRemoved { if peer.isLocal && track.source == HMSCommonTrackSource.screen { isSharingScreen = false } } }
How to check if user is sharing their screen
There are 3 approaches that we suggest for checking if user is sharing screen:
- Check if the screen is added as a local track for the user like shown below
if localPeer?.auxiliaryTracks?.first(where: { $0.source == HMSCommonTrackSource.screen }) != nil { // Screen is getting shared }
- Maintain a state variable when screen track is added or removed like shown below
var isSharingScreen = false func on(track: HMSTrack, update: HMSTrackUpdate, for peer: HMSPeer) { if update == .trackAdded { if peer.isLocal && track.source == HMSCommonTrackSource.screen { isSharingScreen = true } } if update == .trackRemoved { if peer.isLocal && track.source == HMSCommonTrackSource.screen { isSharingScreen = false } } }
- Use the app group user-defaults to store the state of screen sharing from broadcast extension (using broadcastStarted and broadcastFinished functions)
Debugging issues in your screen-share implementation
-
If you use CocoaPods with M1 mac and compile for simulator then you might run into an error like this: "error framework not found Pods_hmsscreenshare". This issue is specific to CocoaPods method of integrating the 100ms SDK. If you use swift package manager, you wouldn't run into this error. As a workaround please use a snippet similar to at the end of this example Podfile to exclude arm64 arch for simulator from your pod screen share target: Workaround for M1 simulator issue https://github.com/100mslive/100ms-ios-sdk/blob/main/Example/Podfile Note: Pods-HMSScreenShare in the snippet is your CocoaPods framework target for broadcast extension (it's generally Pods-[Your Broadcast Extension target name])
-
If you are getting a crash while running with screen share feature, please make sure that the app group identifier is not misspelled in both the main app and the broadcast extension. Also make sure your entitlement file has the correct app group name.
Frequently asked questions
- How can I show only my screen share extension to the user when they want to share the screen using RPSystemBroadcastPickerView?
You can configure your RPSystemBroadcastPickerView instance to display only your extension by assigning a preferredExtension value to it:
let systemBroadcastPicker = RPSystemBroadcastPickerView(frame: CGRect(x: 0, y:0, width: 44, height: 44)) systemBroadcastPicker.preferredExtension = "live.100ms.videoapp.screenshare"
Replace "live.100ms.videoapp.screenshare" with the bundle ID of your own broadcast extension. This ensures that only your screen share extension is displayed to the user when selecting the option to share their screen.
Example implementation
👀 To see an Example iOS broadcast upload extension implementation for screen sharing using 100ms Broadcast extension SDK, checkout our Example project.
📲 Download the 100ms fully featured Sample iOS app here: https://testflight.apple.com/join/dhUSE7N8