swiftiphonemacosavcapturedevicecore-media

How to get iPhone as AVCaptureDevice on macOS?


I have implemented the code from the post linked below. However it is not updated to account for AVCaptureDevice.devices() being now deprecated.

iOS Device not listed by AVCaptureDevice.devices() unless Quicktime is opened

Does anyone have a latest implementation of this?

Thank you!


Solution

  • Okay, so after doing a combination of some of the other Stack Overflow answers I was able to get it to work with the latest implementation of AVCaptureDevice.DiscoverySession.

    The trick was to call to DiscoverSession to get the devices after enabling Screen Capture Devices. Then adding the observer to look for newly connected devices and it will show.

    The previous answers all used the old AVCaptureDevice.devices() method. My example below uses the updated method.

    import Cocoa
    import Foundation
    import AVKit
    import CoreMediaIO
    
    class PlayerNSView: NSView{
        private let playerLayer = AVPlayerLayer()
        private let nc = NotificationCenter.default
    
        override init(frame:CGRect){
            super.init(frame: frame)
    
    
            let urlVideo = URL(string: "https://www.radiantmediaplayer.com/media/bbb-360p.mp4")!
            let player = AVPlayer(url: urlVideo)
            //player.play()
            playerLayer.player = player
            if layer == nil{
                layer = CALayer()
            }
            layer?.addSublayer(playerLayer)
    
            self.enableDalDevices()
    
            let discoverySession = AVCaptureDevice.DiscoverySession(deviceTypes: [.externalUnknown], mediaType: nil, position: .unspecified)
    
    
    
            nc.addObserver(self, selector: #selector(newDevice), name: NSNotification.Name.AVCaptureDeviceWasConnected, object: nil)
    
        }
    
        @objc func newDevice() {
            let discoverySession = AVCaptureDevice.DiscoverySession(deviceTypes: [.externalUnknown], mediaType: nil, position: .unspecified)
            print("Devices: \(discoverySession.devices)")
        }
    
    
    
        public func enableDalDevices() {
    
    
            var property = CMIOObjectPropertyAddress(mSelector: CMIOObjectPropertySelector(kCMIOHardwarePropertyAllowScreenCaptureDevices), mScope: CMIOObjectPropertyScope(kCMIOObjectPropertyScopeGlobal), mElement: CMIOObjectPropertyElement(kCMIOObjectPropertyElementMaster))
            var allow : UInt32 = 1
            let sizeOfAllow = MemoryLayout.size(ofValue: allow)
            CMIOObjectSetPropertyData(CMIOObjectID(kCMIOObjectSystemObject), &property, 0, nil, UInt32(sizeOfAllow), &allow)
    
        }
    
    
        required init?(coder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
        override func layout() {
            super.layout()
    
            playerLayer.backgroundColor = .black
            playerLayer.frame = bounds
        }
    }