web-dev-qa-db-fra.com

Comment obtenir la caméra frontale dans Swift?

J'essaie d'obtenir la caméra frontale avec vue en direct. Je peux obtenir la caméra de recul en utilisant:

var backCamera = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)

Mais je n'arrive pas à trouver comment obtenir la caméra frontale. Comment puis-je changer le code ci-dessus pour utiliser la caméra frontale? 

20
mindfreek

Voici un exemple de travail d'un de mes projets pour obtenir la caméra frontale. Ceci est en Objective-C mais s’avère efficace et assez facile à convertir en Swift.

NSArray *videoDevices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
AVCaptureDevice *captureDevice = nil;

for (AVCaptureDevice *device in videoDevices){

    if (device.position == AVCaptureDevicePositionFront){

        captureDevice = device;
        break;
    }
}

Et dans Swift 3.2+:

if let videoDevices = AVCaptureDevice.devices(withMediaType: AVMediaTypeVideo) {
    var captureDevice: AVCaptureDevice
    for device in videoDevices {
        if let device = device as? AVCaptureDevice {
            if device.position == AVCaptureDevicePosition.front {
                captureDevice = device
                break
            }
        }
    }
}
19
chrissukhram

Dans iOS 10.0 et versions ultérieures, il n'est pas nécessaire de parcourir la AVCaptureDevice. devices (ou devicesWithMediaType ) pour rechercher une caméra par position. (En fait, ces deux API sont obsolètes dans iOS 10 et ne renvoient pas l'ensemble complet des périphériques disponibles sur iPhone 7 Plus, iPhone 8 Plus ou iPhone X.)

Si vous avez juste besoin de trouver un seul appareil basé sur des caractéristiques simples (comme une caméra frontale pouvant filmer une vidéo), utilisez simplement AVCaptureDevice. defaultDevice(withDeviceType:mediaType:position:) . Par exemple:

guard let device = AVCaptureDevice.defaultDevice(
    withDeviceType: .builtInWideAngleCamera,
    mediaType: AVMediaTypeVideo,
    position: .front)
    else { fatalError("no front camera. but don't all iOS 10 devices have them?")

// then use the device: captureSession.addInput(device) or whatever

C'est tout ce qu'il y a à faire pour la plupart des cas d'utilisation.


Il existe également AVCaptureDeviceDiscoverySession en remplacement de l'ancienne méthode d'itération dans le tableau devices. Cependant, la plupart des choses pour lesquelles vous parcourez le tableau devices peuvent être trouvées à l'aide de la nouvelle méthode defaultDevice(withDeviceType:mediaType:position:) . Vous pouvez donc aussi bien l'utiliser et écrire moins de code.

Les cas où AVCaptureDeviceDiscoverySession vaut la peine d'être utilisé sont les cas les moins fréquents et les plus compliqués: supposons que vous souhaitiez rechercher tous les périphériques prenant en charge une certaine fréquence d'images ou que vous utilisiez l'observation clé-valeur pour savoir quand l'ensemble des périphériques disponibles change .


À propos, Apple a également un guide sur le système de capture de photos iOS 10/Swift 3 ainsi que des exemples de code qui illustrent les meilleures pratiques actuelles pour ces API.

9
rickster
guard let device = AVCaptureDevice.devices().filter({ $0.position == .Front })
    .first as? AVCaptureDevice else {
        fatalError("No front facing camera found")
}

Si vous cherchez une solution plus courte bien que .filter suivi de .first ne soit pas le plus efficace

8
mbuff24

Swift 4.1, iOS 10+ et Xcode 9.3 remplace

if let cameraID = AVCaptureDevice.defaultDevice(withDeviceType: AVCaptureDeviceType.builtInWideAngleCamera, mediaType: AVMediaTypeVideo, position: AVCaptureDevicePosition.front)?.localizedName {
       //cameraID = "Front Camera"
}

avec AVCaptureDevice.DiscoverySession implementation

if let cameraID = AVCaptureDevice.DiscoverySession(deviceTypes: [AVCaptureDevice.DeviceType.builtInWideAngleCamera], mediaType: AVMediaType.video, position: AVCaptureDevice.Position.front).devices.first?.localizedName{
        //cameraID = "Front Camera"
} 
4

Ce dernier est:

guard let device = AVCaptureDevice.default(AVCaptureDevice.DeviceType.builtInWideAngleCamera, for: .video, position: .front) else {
            return

}

2
zumzum

Basé sur la solution présentée par mbuff24 . Les méthodes de tableau incluent .first (où :) en plus de .filter ()

guard let frontCamera = AVCaptureDevice.devices().first(where: { ($0 as AnyObject).position == .front }) as? AVCaptureDevice else {
            fatalError("No front facing camera found")
            }
1
Paulo
import AVFoundation
import Foundation


@IBOutlet weak var imageView: UIImageView!
    let captureSession = AVCaptureSession()
    let stillImageOutput = AVCaptureStillImageOutput()
    var previewLayer : AVCaptureVideoPreviewLayer?
    var captureDevice : AVCaptureDevice?
    var Arrdata:[Studentdata] = []
 override func viewDidLoad() {
        super.viewDidLoad()
        captureSession.sessionPreset = AVCaptureSessionPresetHigh
            if let devices = AVCaptureDevice.devices() as? [AVCaptureDevice]
            {
                for device in devices
                {
                    if (device.hasMediaType(AVMediaTypeVideo))
                    {
                        if(device.position == AVCaptureDevicePosition.front)
                        {
                            captureDevice = device
                            if captureDevice != nil
                            {
                                print("Capture device found")
                                beginSession()
                            }
                        }
                    }
                }
            }


    }

func beginSession()
    {
        do
        {
            try captureSession.addInput(AVCaptureDeviceInput(device: captureDevice))
            stillImageOutput.outputSettings = [AVVideoCodecKey:AVVideoCodecJPEG]
            if captureSession.canAddOutput(stillImageOutput)
            {
                captureSession.addOutput(stillImageOutput)
            }
        }
        catch
        {
            print("error: \(error.localizedDescription)")
        }
        guard let previewLayer = AVCaptureVideoPreviewLayer(session: captureSession) else
        {
            print("no preview layer")
            return
        }
        self.view.layer.addSublayer(previewLayer)
        previewLayer.frame = self.view.layer.frame
        captureSession.startRunning()
        self.view.addSubview(imageView)
    }
0
Rob-4608
var captureSession: AVCaptureSession?
var frontDevice: AVCaptureDevice?
var frontInput: AVCaptureInput?

if let frontDevice = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInWideAngleCamera], mediaType: AVMediaType.video, position: .front).devices.first {
  frontInput = try AVCaptureDeviceInput(device: frontDevice)
}

captureSession?.beginConfiguration()
if let front = frontInput, captureSession?.canAddInput(front) == true {
  captureSession?.addInput(front)
}
captureSession?.commitConfiguration()
0
jnblanchard