What is the programmatic way to capture screen from a connected iOS device to the Mac?

What framework to use to capture screen of a device connected to the Mac in the way OBS or QuickTime Player does when an iOS device is connected to Mac via USB. I tried to list devices with AVFoundation and ScreenCaptureKit but only Mac camera, mic and displays are listed.

When you select New Movie Recording in the QuickTime Player you can choose an Connected iPad or iPhone to record it's screan. Same with OBS.

What is the way to do it in my own MacOS app?

Answered by GeroTheCoder in 795416022

This is a pretty broad question and I only dimly remember ever encountering this, but here I go:

I knew there was something specific about that and after a bit of digging I found it again. For connected devices to become visible you have to explicitly opt-in to them being considered sources for your app using CoreMediaIO. Basically somewhere in your app you have to include this snippet of code:

        var prop = CMIOObjectPropertyAddress(
            mSelector: CMIOObjectPropertySelector(kCMIOHardwarePropertyAllowScreenCaptureDevices),
            mScope: CMIOObjectPropertyScope(kCMIOObjectPropertyScopeGlobal),
            mElement: CMIOObjectPropertyElement(kCMIOObjectPropertyElementMain))
        var allow: UInt32 = 1;
        CMIOObjectSetPropertyData(CMIOObjectID(kCMIOObjectSystemObject), &prop, 0, nil,
                                  UInt32(MemoryLayout.size(ofValue: allow)), &allow)

You can then get a capture device using AVCaptureDevice.default(for: .muxed) (from the AVFoundation module) and use that to create an input for an AVCaptureSession using AVCaptureDeviceInput(device:).

I have only ever played around with this and never bothered with properly taking care about multiple connected devices and such, so I have no advice on how to best handle this.

Be aware that it takes a moment for the devices to show up after you execute the snippet above, so you might want to listen for AVCaptureSessionDidStartRunningNotification to wait before you create the device variable.

While jostling my memory I also stumbled upon this repo which seems to have a bare-bones (hopefully) running example, but it's not mine: https://github.com/mortenjust/Device-Recording-Bug-Demo (plus it seems to exist to illustrate some bug, but I don't know what that would be).

Hello,

I tried to do the same thing a while ago and succeed but can't find the code right now.

I did find a SO answer which look like what I used : https://stackoverflow.com/questions/59350500/how-to-get-iphone-as-avcapturedevice-on-macos

Hope that help :)

Accepted Answer

This is a pretty broad question and I only dimly remember ever encountering this, but here I go:

I knew there was something specific about that and after a bit of digging I found it again. For connected devices to become visible you have to explicitly opt-in to them being considered sources for your app using CoreMediaIO. Basically somewhere in your app you have to include this snippet of code:

        var prop = CMIOObjectPropertyAddress(
            mSelector: CMIOObjectPropertySelector(kCMIOHardwarePropertyAllowScreenCaptureDevices),
            mScope: CMIOObjectPropertyScope(kCMIOObjectPropertyScopeGlobal),
            mElement: CMIOObjectPropertyElement(kCMIOObjectPropertyElementMain))
        var allow: UInt32 = 1;
        CMIOObjectSetPropertyData(CMIOObjectID(kCMIOObjectSystemObject), &prop, 0, nil,
                                  UInt32(MemoryLayout.size(ofValue: allow)), &allow)

You can then get a capture device using AVCaptureDevice.default(for: .muxed) (from the AVFoundation module) and use that to create an input for an AVCaptureSession using AVCaptureDeviceInput(device:).

I have only ever played around with this and never bothered with properly taking care about multiple connected devices and such, so I have no advice on how to best handle this.

Be aware that it takes a moment for the devices to show up after you execute the snippet above, so you might want to listen for AVCaptureSessionDidStartRunningNotification to wait before you create the device variable.

While jostling my memory I also stumbled upon this repo which seems to have a bare-bones (hopefully) running example, but it's not mine: https://github.com/mortenjust/Device-Recording-Bug-Demo (plus it seems to exist to illustrate some bug, but I don't know what that would be).

What is the programmatic way to capture screen from a connected iOS device to the Mac?
 
 
Q