Screen Sharing
Enhance the collaborative experience of a session by using the screen sharing feature provided by the Video SDK. This feature gives users the ability to share their screen's content on a macOS device.
Screen sharing options
There are two different approaches for screen sharing with the Video SDK:
- Share the entire display
- Share a specific window
To utilize either method, you must retrieve an ZMVideoSDKShareHelper instance through the SDK:
let helper = ZMVideoSDK.shared()?.getShareHelper()
ZMVideoSDKShareHelper *helper = [[ZMVideoSDK sharedZMVideoSDK] getShareHelper];
After determining the type of share you are going to use, you must obtain the ID of the display or window you would like to share.
- For sharing a display, use the CGDirectDisplayID.
- For sharing a window, use the CGWindowID.
Start sharing
After obtaining the ID of the window/display you intend to share with your session, pass it into the corresponding startShare method.
Share a display
helper?.startShareScreen(displayId, shareOption: ZMVideoSDKShareOption())
[helper startShareScreen:displayId shareOption:shareOptions];
Share a window
helper?.startShareView(windowId, shareOption: ZMVideoSDKShareOption())
[helper startShareView:windowId shareOption:shareOptions];
Verify screen share
After successfully completing the above steps to share your screen, verify that your screen share has started by responding to the following callback to get notified when a user starts or stops screen sharing within your ZMVideoSDKDelegate:
func onUserShareStatusChanged(shareHelper: ZMVideoSDKShareHelper, user: ZMVideoSDKUser, shareAction: ZMVideoSDKShareAction) {
switch shareAction.shareStatus {
case .none:
break
// User has begun sharing.
case .start:
shareAction.getShareCanvas().subscribe(with: yourView, aspectMode: .original, resolution: .auto)
case .pause:
break
case .resume:
break
// User has stopped sharing.
case .stop:
// Retrieve the share canvas and unsubscribe it from your view
shareAction.getShareCanvas().unSubscribe(with: yourView)
default:
break
}
}
- (void)onUserShareStatusChanged:(ZMVideoSDKShareHelper*)shareHelper user:(ZMVideoSDKUser*)user shareAction:(ZMVideoSDKShareAction*)shareAction {
switch (shareAction.shareStatus) {
case ZMVideoSDKShareStatus_None:
break;
// User has begun sharing.
case ZMVideoSDKShareStatus_Start:
[[shareAction getShareCanvas] subscribeWithView:yourView aspectMode:ZMVideoSDKVideoAspect_Original resolution:ZMVideoSDKResolution_Auto];
case ZMVideoSDKShareStatus_Pause:
break;
case ZMVideoSDKShareStatus_Resume:
break;
// User has stopped sharing.
case ZMVideoSDKShareStatus_Stop:
// Retrieve the share canvas and unsubscribe it from your view
[[shareAction getShareCanvas] unSubscribeWithView:yourView];
default:
break;
}
}
To verify that the screen share data of a user is accessible on another device, subscribe to the user's share pipe:
let sharePipe = user.getSharePipe()
sharePipe?.subscribe(ZMVideoSDKResolution_720P, listener: self)
ZMVideoSDKRawDataPipe *sharePipe = [user getSharePipe];
[sharePipe subscribe:ZMVideoSDKResolution_720P listener:self];
Share multiple screens
If the local user would like to subscribe to a specific view instead of the latest view shared from the delegate callback onUserShareStatusChanged, identify the user to subscribe to, retrieve the user's share action list, and subscribe to the selected share action.
let user: ZMVideoSDKUser // Get the specific user you want to subscribe to their share screen
let shareActionList = user.getShareActionList()
// The shareActionList can contain 0 to multiple shares coming from the selected user
if let shareActionList = shareActionList, shareActionList.count > 0 {
// Get the share you want to subscribe to - Example the first share
let shareAction = shareActionList[0]
shareAction.getShareCanvas()?.subscribe(with: yourView, aspectMode: .original, resolution: .auto)
}
ZMVideoSDKUser* user; // Get the specific user you want to subscribe to their share screen
NSArray* shareActionList = [user getShareActionList];
// The shareActionList can contain 0 to multiple share coming from the selected user
if (shareActionList.count > 0) {
// Get the share you want to subscribe to - Example the first share
ZMVideoSDKShareAction* shareAction = [shareActionList objectAtIndex:0];
[[shareAction getShareCanvas] subscribeWithView:yourView aspectMode:ZMVideoSDKVideoAspect_Original resolution:ZMVideoSDKResolution_Auto];
}
Share device audio
There are two aspects to this:
- Starting a share with audio enabled.
- Starting audio share.
Start share with audio enabled
let shareOptions = ZMVideoSDKShareOption()
shareOptions.isOptimizeForSharedVideo = true
shareOptions.isWithDeviceAudio = true
ZMVideoSDKShareOption *shareOption = [[ZMVideoSDKShareOption alloc] init];
shareOption.isOptimizeForSharedVideo = true;
shareOption.isWithDeviceAudio = true;
Start sharing audio
helper?.enableShareDeviceAudio(true)
helper?.enableOptimize(forSharedVideo: true)
[helper enableShareDeviceAudio:true];
[helper enableOptimizeForSharedVideo:true];
Troubleshooting: No app windows
If you get an error during full-screen screen sharing where the display shows only your desktop but no app windows, this could be the result of a signing error. Follow these steps to sign your app and resolve this issue.
- Sign the Video SDK files. Be sure that all are signed recursively, including the
*.appfiles such asaomhost.app. - Archive the app in Xcode using Product > Archive.
- Select the archive under Window > Organizers and select Distribute App.
- Select Custom as the method for distribution.
- Select Copy App for the specific method of distribution.
- Go to the directory of the exported app in Terminal, then run
codesign --deep --force --verify --verbose --sign "your certificate" ./yourapp.app - In System Settings under Privacy & Security > Screen & System Audio Recording, add the signed app to the list of allowed applications and enable it.
With the screen recording permission added and both the SDK and app correctly signed, you should be able to share any app's windows after you start screen sharing with your app.