[SWIFT] Obtenez l'écran en temps réel de l'iPhone connecté au Mac avec un câble

J'ai fait une implémentation minimale qui acquiert l'écran d'un iPhone câblé à un mac en temps réel.

Jusqu'à présent, il était nécessaire de démarrer QuickTime Player et de sélectionner l'iPhone dans "Nouvel enregistrement de film", etc., mais il est désormais possible de le faire avec votre propre programme.

output.gif

Il est téléchargé sur GitHub. https://github.com/satoshi0212/DeviceCameraMonitorSample

Les mises à jour d'informations telles que la caméra virtuelle / AR / expression vidéo, y compris cette implémentation, sont publiées sur Twitter. https://twitter.com/shmdevelop

Point de mise en œuvre

Paramètres du projet

«Matériel» et «Caméra» doivent être sélectionnés.

スクリーンショット 2020-10-11 23.41.04.png

plist

Ajoutez Privacy --Camera Usage Description à votre plist.

スクリーンショット 2020-10-12 2.26.56.png

Paramètres de recherche d'appareils

ʻAVCaptureDevice.DiscoverySession` En spécifiant ce qui suit avant l'exécution, le périphérique externe sera affiché par opt-in.


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

Et si vous recherchez avec les paramètres suivants, l'iPhone est inclus dans les appareils. Vous pouvez identifier les appareils iPhone en filtrant les appareils trouvés de manière appropriée par «modelID» et «fabricant».


        let devices = AVCaptureDevice.DiscoverySession(deviceTypes: [.externalUnknown], mediaType: nil, position: .unspecified).devices
        if let device = devices.filter({ $0.modelID == "iOS Device" && $0.manufacturer == "Apple Inc." }).first {
            ...
        }

Cependant, il était également nécessaire d'observer la notification de ʻAVCaptureDeviceWasConnectedNotification` car l'iPhone peut ne pas être trouvé immédiatement après le démarrage ou la recherche.


        let nc = NotificationCenter.default
        nc.addObserver(forName: NSNotification.Name(rawValue: "AVCaptureDeviceWasConnectedNotification"), object: nil, queue: .main) { (notification) in
            print(notification)
            guard let device = notification.object as? AVCaptureDevice else { return }
            ...
        }

À part: redimensionner pour l'affichage

Dans l'implémentation téléchargée, il a été redimensionné pour l'affichage à l'écran.

Calculez le rapport avec la hauteur comme valeur fixe, calculez la largeur et spécifiez la taille de l'imageView. L'image est redimensionnée avec CGAffineTransform.


    private func resizeIfNeeded(w: CGFloat, h: CGFloat) {
        guard targetRect == nil else { return }
        let aspect = h / fixedHeight
        let rect = CGRect(x: 0, y: 0, width: floor(w / aspect), height: fixedHeight)
        imageView.frame = rect
        targetRect = rect
    }

    ...

    func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
        connection.videoOrientation = .portrait

        DispatchQueue.main.async(execute: {
            let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)!
            let ciImage = CIImage(cvPixelBuffer: pixelBuffer)
            let w = CGFloat(CVPixelBufferGetWidth(pixelBuffer))
            let h = CGFloat(CVPixelBufferGetHeight(pixelBuffer))
            self.resizeIfNeeded(w: w, h: h)

            guard let targetRect = self.targetRect else { return }
            let m = CGAffineTransform(scaleX: targetRect.width / w, y: targetRect.height / h)
            let resizedImage = ciImage.transformed(by: m)
            let cgimage = self.context.createCGImage(resizedImage, from: targetRect)!
            let image = NSImage(cgImage: cgimage, size: targetRect.size)
            self.imageView.image = image
        })
    }

Recommended Posts

Obtenez l'écran en temps réel de l'iPhone connecté au Mac avec un câble
À partir d'avril 2018 Comment installer Java 8 sur Mac