ios - Swift 4 捕获照片,photoOutput 返回 nil

标签 ios swift avcapturesession avcapturedevice

目前我有两个不同的 View Controller 和一个在它们之间切换的按钮。 我希望能够在每个设备上拍摄设备输入的照片。

我目前能够拍摄后置摄像头的照片进行处理,并且效果完美,但是当我尝试在另一个 Controller 中为第二个 View 编写相同的代码时,照片输出返回零,但是当我记录每个设备,它仍然显示前置和后置摄像头。

我对 swift 还很陌生,不确定为什么会发生这种情况。

ViewController 类、viewDidLoad 和变量:

class AddUserController: UIViewController , AVCaptureVideoDataOutputSampleBufferDelegate , UITextFieldDelegate{

   //variable for captureing video feed
   var captureSessionFront = AVCaptureSession()
   //variable for rendering camera to the view
   var videoPreviewLayer: AVCaptureVideoPreviewLayer?

   var frontCamera: AVCaptureDevice?
   var backCamera: AVCaptureDevice?
   var currentCamera2: AVCaptureDevice?
   var PhotoOutputFront: AVCapturePhotoOutput?
   var cameraPreviewLayer2: AVCaptureVideoPreviewLayer?

   var tempImage: UIImage?

   var tempstring: String?

   private var maskLayer = [CAShapeLayer]()



   @IBOutlet weak var textField: UITextField!

   //button action to save the user to the collection
   @IBAction func saveFaceBtn(_ sender: Any) {
       let settings = AVCapturePhotoSettings()
       PhotoOutputFront?.capturePhoto(with: settings, delegate: self)
       //print(PhotoOutputFront!)
   }

   override func viewDidLoad() {
       super.viewDidLoad()
       // Do any additional setup after loading the view, typically from a nib.

       //hide keyboard
       self.textField.delegate = self

       //video capture functions
       setupCaptureSession()
       setupDevice()
       setupInputOutput()
       setupPreview()
       startRunningCaptureSession()

功能:

func setupCaptureSession() {
       captureSessionFront.sessionPreset = AVCaptureSession.Preset.photo
   }
func setupDevice() {

       //discover devices
       let deviceDiscoverySession = AVCaptureDevice.DiscoverySession(
           deviceTypes: [AVCaptureDevice.DeviceType.builtInWideAngleCamera],
           mediaType: AVMediaType.video,
           position: AVCaptureDevice.Position.unspecified)

       //find devices and check if frint or back cameras discovered
       let devices = deviceDiscoverySession.devices

       for device in devices{
           print(device)
           if device.position == AVCaptureDevice.Position.front{
               frontCamera = device

           } else if device.position == AVCaptureDevice.Position.back{
               backCamera = device
           }
       }

       currentCamera2 = frontCamera

   }

   func setupInputOutput() {

       do
       {

           let captureDeviceInput2 = try AVCaptureDeviceInput(device: currentCamera2!)

           captureSessionFront.addInput(captureDeviceInput2)
           PhotoOutputFront?.setPreparedPhotoSettingsArray([AVCapturePhotoSettings(format: [AVVideoCodecKey: AVVideoCodecType.jpeg])], completionHandler: nil)
           print(PhotoOutputFront)
       }
       catch
       {
           print(error)
       }
   }

   func setupPreview() {
       cameraPreviewLayer2 = AVCaptureVideoPreviewLayer(session: captureSessionFront)
       cameraPreviewLayer2?.videoGravity = AVLayerVideoGravity.resizeAspectFill
       cameraPreviewLayer2?.connection?.videoOrientation = AVCaptureVideoOrientation.portrait
       cameraPreviewLayer2?.frame = self.view.frame
       self.view.layer.insertSublayer(cameraPreviewLayer2!, at: 0)
   }

   func startRunningCaptureSession() {
       captureSessionFront.startRunning()
   }

保存捕获的照片的扩展:

extension AddUserController: AVCapturePhotoCaptureDelegate {

   func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
       print("before if let")
       if let imageData = photo.fileDataRepresentation(){
           tempImage = UIImage(data: imageData)
           print(tempImage!)

           //check to see if name is empty
           let tempstring = self.textField.text
           if(tempstring != nil || tempstring != ""){

               print(tempstring!)
               //addPhotoToCollection()
           }


       }
   }

}

它一定是设置输入输出的东西,但我不确定我哪里出错了,因为这段代码适用于我的主视图 Controller 中的后置摄像头。我认为这与此功能有关,因为我的其他 Controller “PhotoOutput”不返回零。在这里,“PhotoOutputFront”返回 nil。

view    func setupInputOutput() {

       do
       {

           let captureDeviceInput2 = try AVCaptureDeviceInput(device: currentCamera2!)

           captureSessionFront.addInput(captureDeviceInput2)
           PhotoOutputFront?.setPreparedPhotoSettingsArray([AVCapturePhotoSettings(format: [AVVideoCodecKey: AVVideoCodecType.jpeg])], completionHandler: nil)
           print(PhotoOutputFront)
       }
       catch
       {
           print(error)
       }
   }

任何帮助将不胜感激。提前致谢!

最佳答案

问题是我没有将捕获设备添加为捕获 session 的输入,也没有添加捕获 session 的输出。

希望这可以帮助其他遇到 avcapture 设备问题的人。 :)

func setupInputOutput() {

       do
       {

           let captureDeviceInput2 = try AVCaptureDeviceInput(device: currentCamera2!)

           captureSessionFront.addInput(captureDeviceInput2)
           PhotoOutputFront = AVCapturePhotoOutput()
           PhotoOutputFront?.setPreparedPhotoSettingsArray([AVCapturePhotoSettings(format: [AVVideoCodecKey: AVVideoCodecType.jpeg])], completionHandler: nil)
           captureSessionFront.addOutput(PhotoOutputFront!)
       }
       catch
       {
           print(error)
       }
   }

关于ios - Swift 4 捕获照片,photoOutput 返回 nil,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49199395/

相关文章:

ios - 禁用 UI 旋转时 AVCaptureVideoPreviewLayer 方向错误

ios - UITableViewCell 高度在选择时不会更新。使用 UITableViewAutomaticDimension

android - Active Directory B2C 可以使用 Native Facebook App 而不是 webview 吗?

ios - 使用 Interface Builder 时查看 Controller 包含

ios - 无法使用 'taskCreated' 类型的参数列表调用 '([String : String?])'

swift - 使用 MQTT 实现离线聊天

ios - 从同一个 AVCaptureSession 创建多个 AVCaptureVideoPreviewLayer (IOS Camera) 并将它们添加到同一层

iPhone 设置 : create dependent settings?

swift - Swift 3 中的 Firebase 持久性

macos - macOS 上的多个 AVCaptureSession。正确的做法是什么?