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?
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
}
}
}
}
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.
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
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"
}
Ce dernier est:
guard let device = AVCaptureDevice.default(AVCaptureDevice.DeviceType.builtInWideAngleCamera, for: .video, position: .front) else {
return
}
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")
}
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)
}
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()