Screen share in a group call
This page provides a code example for screen share in a group call (conference).
Sender - Start sending screen share
The code implementation for starting screen share is as follows.
Collect the devices for screen capture and select one from them.
func collectCaptureDevices() -> [PlanetKitScreenCaptureDevice] {
var captureDevices = [PlanetKitScreenCaptureDevice]()
autoreleasepool {
for display in PlanetKitScreen.shared.displays {
let name: String
if let screen = NSScreen.screens.first(where: { $0.displayID == display.displayID }) {
name = screen.localizedName
}
...
captureDevices.append(PlanetKitScreenCaptureDevice(display: display))
}
let windows = PlanetKitScreen.shared.windows.filter {
$0.sharingType != .none &&
$0.alpha > 0 &&
$0.level == kCGNormalWindowLevel
}
let myAppId = Bundle.main.bundleIdentifier
for window in windows {
guard let image = window.image, window.sharingType != .none, window.bundleId != nil else {
continue
}
if myAppId == window.bundleId {
continue
}
...
captureDevices.append(PlanetKitScreenCaptureDevice(window: window))
}
}
return captureDevices
}
To start sending screen share, call startMyScreenShare()
.
- The
subgroupName
parameter determines the destination of screen share. - If the
subgroupName
parameter isnil
, screen share is sent to the main room.
func startMyScreenShare(_ device: PlanetKitScreenCaptureDevice) {
...
conference.startMyScreenShare(device: device, subgroupName: nil) { success in
guard success else { return }
// UI code here if success
}
}
Sender - Change the destination of screen share
Depending on the type of destination, you can change the destination of screen share as follows:
- To change the destination to a subgroup other than the main room, call
changeMyScreenShareDestination()
with the subgroup name. - To change the destination to the main room, call
changeMyScreenShareDestinationToMainRoom()
.
// Change the destination to a subgroup other than the main room
conference.changeMyScreenShareDestination(subgroupName: subgroupName) { success in
guard success else { return }
// UI code here if success
}
// Change the destination to the main room
conference.changeMyScreenShareDestinationToMainRoom() { success in
guard success else { return }
// UI code here if success
}
Sender - Stop sending screen share
The code implementation for stopping screen share is as follows.
To stop screen share, call stopMyScreenShare().
conference.stopMyScreenShare() { success in
self.delegate?.screenShare(self, willDismiss: dismiss)
}
Receiver - Receive screen share update events
Check whether a peer's screen share has started or stopped through the screenShareDidUpdate
event of PlanetKitConferenceDelegate
.
If you have already created peer control, skip the next step and use it for the Receiver - Start or stop a peer's screen share video step. Otherwise, create peer control as in the next step.
extension VideoConferenceViewController: PlanetKitConferenceDelegate {
...
func screenShareDidUpdate(_ conference: PlanetKitConference, updated: PlanetKitConferenceScreenShareUpdateParam) {
if updated.state == .enabled {
NSLog("start screen share - \(updated.peerId) \(updated.subgroupName ?? "main")")
}
else {
NSLog("stop screen share - \(updated.peerId) \(updated.subgroupName ?? "main")")
}
// UI code here
DispatchQueue.main.async {
self.loadPage(self.currentPage)
}
}
}
Receiver - Create and register peer control
When a peer is connected to the call, create and register peer control for the peer.
extension VideoConferenceViewController {
...
var peers: [PlanetKitConferencePeer]
var peerViews: [ScreenPeerVideoView]
func loadPage(_ page: Int) {
...
peerViews[index].setupPeerControl(conference: conference, peer: peers[index])
}
}
#if os(macOS)
typealias UIView = NSView
#endif
class ScreenPeerVideoView: UIView {
...
var peerControl: PlanetKitPeerControl!
func setupPeerControl(conference: PlanetKitConference, peer: PlanetKitConferencePeer) {
guard let peerControl = conference.createPeerControl(peer: peer) else {
// Error code here
return
}
peerControl.register(self) { success in
// UI code here
self.setScreenShareEnabled(peer.screenShareState == .enabled)
}
self.peerControl = peerControl
}
func finalPeerControl() {
peerControl.unregister() { success in
// UI code here
}
}
}
Receiver - Start or stop a peer's screen share video
Check whether a peer's screen share has started or stopped through the didUpdateScreenShare
event of PlanetKitPeerControlDelegate
.
- When the peer's screen share started, add a peer screen share view and call
startScreenShare()
ofPlanetKitPeerControl
. - When the peer's screen share stopped, remove the peer screen share view and call
stopScreenShare()
ofPlanetKitPeerControl
.
#if os(macOS)
typealias UIView = NSView
#endif
class ScreenPeerVideoView: UIView {
...
var peerControl: PlanetKitPeerControl!
var peerScreenShareView: PlanetKitMTKView!
func setScreenShareEnabled(_ enabled: Bool) {
if enabled {
peerScreenShareView = PlanetKitMTKView(frame: view.bounds, device: nil)
view.addSubview(peerScreenShareView)
let subgroupName = peerControl.peer.currentScreenShareSubgroupName
peerControl.startScreenShare(delegate: peerScreenShareView, subgroupName: subgroupName) { success in
// UI code here
}
}
else {
peerScreenShareView.removeFromSuperview()
peerControl.stopScreenShare() { success in
// UI code here
}
}
}
}
extension ScreenPeerVideoView: PlanetKitPeerControlDelegate {
...
func didUpdateScreenShare(_ peerControl: PlanetKitPeerControl, subgroup: PlanetKitSubgroup, status: PlanetKitScreenShareStatus) {
DispatchQueue.main.async {
self.setScreenShareEnabled((status.state == .enabled))
}
}
}