2016-12-21 7 views
0

По существу, я пытаюсь добиться того, чтобы передняя камера AVCaptureDevice была первой и единственной опцией приложения во время AVCaptureSession.Используйте переднюю камеру для автоматического просмотра AVCaptureDevice как Snapchat или Houseparty (Swift 3)

Я посмотрел вокруг StackOverflow и все методы и ответы, являются устаревшими, как ИО 10, Swift 3 и Xcode 8.

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

Может ли кто-нибудь помочь? Было бы удивительно, если бы так!

Вот мой код:

override func viewDidAppear(_ animated: Bool) { 
    super.viewDidAppear(animated) 

    previewLayer.frame = singleViewCameraSlot.bounds 
    self.singleViewCameraSlot.layer.addSublayer(previewLayer) 
    captureSession.startRunning() 

} 



lazy var captureSession: AVCaptureSession = { 
    let capture = AVCaptureSession() 
    capture.sessionPreset = AVCaptureSessionPreset1920x1080 
    return capture 
}() 

lazy var previewLayer: AVCaptureVideoPreviewLayer = { 
    let preview = AVCaptureVideoPreviewLayer(session: self.captureSession) 

    preview?.videoGravity = AVLayerVideoGravityResizeAspect 
    preview?.connection.videoOrientation = AVCaptureVideoOrientation.portrait 
    preview?.bounds = CGRect(x: 0, y: 0, width: self.view.bounds.width, height: self.view.bounds.height) 
    preview?.position = CGPoint(x: self.view.bounds.midX, y: self.view.bounds.midY) 

    return preview! 
}() 


func setupCameraSession() { 


    let frontCamera = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo) as AVCaptureDevice 

    do { 
     let deviceInput = try AVCaptureDeviceInput(device: frontCamera) 

     captureSession.beginConfiguration() 

     if (captureSession.canAddInput(deviceInput) == true) { 
      captureSession.addInput(deviceInput) 
     } 

     let dataOutput = AVCaptureVideoDataOutput() 

     dataOutput.videoSettings = [(kCVPixelBufferPixelFormatTypeKey as NSString) : NSNumber(value: kCVPixelFormatType_420YpCbCr8BiPlanarFullRange as UInt32)] 
     dataOutput.alwaysDiscardsLateVideoFrames = true 

     if (captureSession.canAddOutput(dataOutput) == true) { 
      captureSession.addOutput(dataOutput) 
     } 

     captureSession.commitConfiguration() 

     let queue = DispatchQueue(label: "io.goodnight.videoQueue") 
     dataOutput.setSampleBufferDelegate(self, queue: queue) 

    } 
    catch let error as NSError { 
     NSLog("\(error), \(error.localizedDescription)") 
    } 

} 

ответ

0

Если вы явно нужна фронтальная камера, вы можете использовать AVCaptureDeviceDiscoverySession, как указано здесь.

https://developer.apple.com/reference/avfoundation/avcapturedevicediscoverysession/2361539-init

Это позволяет определить типы устройств, которые вы хотите найти. Следующий (непроверенный) должен дать вам переднюю камеру.

let deviceSessions = AVCaptureDeviceDiscoverySession(deviceTypes: [AVCaptureDeviceType.builtInWideAngleCamera], mediaType: AVMediaTypeVideo, position: AVCaptureDevicePosition.front) 

Этот deviceSessions имеет свойство устройства, которое является массивом типов AVCaptureDevice, содержащих только устройства, соответствующие что критерии поиска.

deviceSessions?.devices 

Это должно быть либо 0 или 1 в зависимости от того, если устройство имеет переднюю камеру, обращенную или нет (некоторые плеерах не будет, например).

2

Если вам просто нужно найти единственное устройство на основе простых характеристик (например, переднюю камеру, которая может снимать видео), просто используйте 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 стоит использовать, являются менее распространенными, более сложными случаями: скажем, вы хотите найти все устройства, поддерживающие определенную частоту кадров, или использовать наблюдение за ключевыми значениями, чтобы увидеть, когда изменяется набор доступных устройств ,


Кстати ...

Я посмотрел вокруг StackOverflow и все методы и ответы, являются устаревшими, как ИО 10, Swift 3 и Xcode 8.

Если вы читали документы от Apple для этих методов (по крайней мере, this one, this one и this one), вы увидите наряду с этими предупреждениями Deprecation некоторые рекомендации для того, что можно использовать вместо. Также есть a guide для системы захвата фотографий iOS 10/Swift 3 и некоторые sample code, которые демонстрируют современные передовые методы для этих API.