Как получить переднюю камеру в Swift?

Я пытаюсь получить переднюю камеру с живым видом. Я могу получить заднюю камеру, используя:

var backCamera = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)

Но я не могу найти, как получить переднюю камеру. Как изменить код выше, чтобы использовать переднюю камеру?

Ответы

Ответ 1

Вот рабочий пример из одного из моих проектов, чтобы получить переднюю камеру. Это находится в objective-c, но доказано, что оно работает и достаточно легко конвертируется в быстрый.

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

for (AVCaptureDevice *device in videoDevices){

    if (device.position == AVCaptureDevicePositionFront){

        captureDevice = device;
        break;
    }
}

И в 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
            }
        }
    }
}

Ответ 2

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

Если вы ищете более короткое решение, хотя .filter, за которым следует .first, не является наиболее эффективным

Ответ 3

В iOS 10.0 и более поздних версиях вам не нужно выполнять итерацию через AVCaptureDevice. devices (или devicesWithMediaType), чтобы найти камеру по положению. (Фактически, оба этих API устарели в iOS 10 и не возвращают полный набор доступных устройств на iPhone 7 Plus, iPhone 8 Plus или iPhone X.)

Если вам просто нужно найти одно устройство на основе простых характеристик (например, переднюю камеру, которая может снимать видео), просто используйте AVCaptureDevice. defaultDevice(withDeviceType:mediaType:position:). Например:

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

Действительно, все это для большинства случаев использования.


Там также AVCaptureDeviceDiscoverySession в качестве замены старого метода итерации через массив devices. Тем не менее, большинство вещей, которые вы обычно повторяете в массиве devices, можно найти, используя новый метод defaultDevice(withDeviceType:mediaType:position:), поэтому вы можете также использовать это и писать меньше кода.

Случаи, когда AVCaptureDeviceDiscoverySession заслуживают внимания, являются менее распространенными, более сложными случаями: скажем, вы хотите найти все устройства, которые поддерживать определенную частоту кадров или использовать наблюдение за ключевым значением, чтобы увидеть, когда изменяется набор доступных устройств.


Кстати, у Apple также есть руководство к системе захвата фотографий iOS 10/Swift 3, а некоторые пример кода, который показывает лучшие рекомендации для этих API.

Ответ 4

Swift 4, iOS 10+ и Xcode 9 beta 5 заменяет

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

с реализацией AVCaptureDevice.DiscoverySession

if #available(iOS 10,*){
    if let cameraID = AVCaptureDevice.DiscoverySession(deviceTypes: [AVCaptureDeviceType.builtInWideAngleCamera], mediaType: AVMediaTypeVideo, position: AVCaptureDevicePosition.front).devices.first?.localizedName{
           //cameraID = "Front Camera"
    } 
}

Ответ 5

Задержки:

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

}

Ответ 6

На основе решения, представленного mbuff24. Методы массива включают. First (где:) кроме .filter()

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

Ответ 7

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)
    }