【问题标题】:init() is unavailable in AVCaptureDeviceInput in Swift 4init() 在 Swift 4 的 AVCaptureDeviceInput 中不可用
【发布时间】:2017-10-01 19:50:28
【问题描述】:

我的应用程序中有一个视图控制器,它显示像 Snapchat 这样的后置摄像头,它在 Swift 3 中运行良好,但是当我更新到 Swift 4 时,由于以下错误,编译器不会让我运行它:

init() 不适用于AVCaptureDeviceInput

这个视图控制器应该在没有任何按钮或额外内容的情况下显示相机,就像 Snapchat 一样。所以,这里是完整的视图控制器代码:

import UIKit
import AVFoundation

class cameraViewController: UIViewController , UIImagePickerControllerDelegate , UINavigationControllerDelegate {

var captureSession : AVCaptureSession?

var stillImageOutput : AVCaptureStillImageOutput?

var previewLayer : AVCaptureVideoPreviewLayer?

var imagePicker: UIImagePickerController!

@IBOutlet weak var cameraView: UIView!

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

    previewLayer?.frame = cameraView.bounds
}

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


    captureSession = AVCaptureSession()

    captureSession?.sessionPreset = AVCaptureSessionPreset1280x720

    let backCamera = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo)

    let error : NSError?

    var input = AVCaptureDeviceInput()

    do {
        input = try AVCaptureDeviceInput(device: backCamera)
    }
    catch {
        //  error
    }

    if error == nil && (captureSession?.canAddInput(input))! {

        captureSession?.addInput(input)

        stillImageOutput = AVCaptureStillImageOutput()

        stillImageOutput?.outputSettings = [AVVideoCodecKey : AVVideoCodecJPEG]


        if (captureSession?.canAddOutput(stillImageOutput))! {

            captureSession?.addOutput(stillImageOutput)

            previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)

            previewLayer?.videoGravity = AVLayerVideoGravityResizeAspectFill

            previewLayer?.connection.videoOrientation = AVCaptureVideoOrientation.portrait

            cameraView.layer.addSublayer(previewLayer!)

            captureSession?.startRunning() 

        }
    }

}

}

因为这条线,我无法运行应用程序:

var input = AVCaptureDeviceInput()

【问题讨论】:

  • 请记住,用户可以随时撤销相机使用授权(SessionSetupResult)。在尝试访问它之前,您应该始终检查它。除此之外,您应该确保在主队列中执行此操作。 Apple 已发布其 AVCam 示例版本 7。您应该将其用作参考 developer.apple.com/library/content/samplecode/AVCam/…
  • 如果在构建时遇到问题,您需要将photoSettings.availablePreviewPhotoPixelFormatTypes 更改为photoSettings.__availablePreviewPhotoPixelFormatTypesphotoSettings.availablePreviewPhotoPixelFormatTypes 更改为photoSettings.__availablePreviewPhotoPixelFormatTypes

标签: ios swift4 xcode9 avcapturedevice


【解决方案1】:

在 Swift 4 中,您必须指定一个设备才能初始化 AVCaptureDeviceInput - 事实上,您已经在初始化它,在引发错误的代码后面只有两行。 p>

此外,在此之后,您将在 if 语句中隐式地解开原本安全解开的 AVCaptureSession

这是您的代码,经过完善:

do {
    guard let input = try AVCaptureDeviceInput(device: backCamera),
        captureSession = captureSession else {
        print("Error in initializing a device input")
    }

    if error == nil && (captureSession.canAddInput(input)) {

    [...]
}
catch let error {
    print(error.localizedDescription)
}

【讨论】:

    【解决方案2】:

    所以我使用了 do catch 中的所有左侧代码,我得到了结果,并且应用程序在 swift 4 中运行良好 - 所以我的问题代码中会出现视图而不是使用下面的代码

     override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
    
    
        captureSession = AVCaptureSession()
    
        captureSession?.sessionPreset = AVCaptureSessionPreset1280x720
    
    
        do {
            let input = try AVCaptureDeviceInput(device: .defaultDevice(withMediaType: AVMediaTypeVideo))
    
            captureSession?.addInput(input)
    
            stillImageOutput = AVCaptureStillImageOutput()
    
            stillImageOutput?.outputSettings = [AVVideoCodecKey : AVVideoCodecJPEG]
    
    
            if (captureSession?.canAddOutput(stillImageOutput))! {
    
                captureSession?.addOutput(stillImageOutput)
    
                previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
    
                previewLayer?.videoGravity = AVLayerVideoGravityResizeAspectFill
    
                previewLayer?.connection.videoOrientation = AVCaptureVideoOrientation.portrait
    
                cameraView.layer.addSublayer(previewLayer!)
    
                captureSession?.startRunning()
    
            }
    
    
    
        } catch {
    
            print(error)
    
        }
    
    }
    

    我已经回答了我的问题以帮助其他人

    【讨论】:

      【解决方案3】:

      你必须像下面这样使用:

      if let backCamera = AVCaptureDevice.default(for: .video) {
          do {
              var input = try AVCaptureDeviceInput(device: backCamera)
          } catch {
              //  error
          }
      }
      

      如何在你的代码中使用:

      override func viewWillAppear(_ animated: Bool) {
          super.viewWillAppear(animated)
      
          captureSession = AVCaptureSession()
          captureSession?.sessionPreset = AVCaptureSession.Preset.hd1280x720
      
          guard let backCamera = AVCaptureDevice.default(for: .video) else {
              print("AVCaptureDevice backCamera is nil")
              return
          }
      
          let error : NSError?
      
          do {
              let input = try AVCaptureDeviceInput(device: backCamera)
      
              if (captureSession?.canAddInput(input))! {
                  captureSession?.addInput(input)
                  stillImageOutput = AVCaptureStillImageOutput()
                  stillImageOutput?.outputSettings = [AVVideoCodecKey : AVVideoCodecJPEG]
      
                  if (captureSession?.canAddOutput(stillImageOutput!))! {
                      captureSession?.addOutput(stillImageOutput!)
                      previewLayer = AVCaptureVideoPreviewLayer(session: captureSession!)
                      previewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill
                      previewLayer?.connection?.videoOrientation = AVCaptureVideoOrientation.portrait
                      cameraView.layer.addSublayer(previewLayer!)
                      captureSession?.startRunning()
                  }
              }
          }
          catch {
              //  error
          }
      }
      

      【讨论】:

      • 它对我不起作用 :( 它说字符串类型没有成员视频
      • 你能发布一下你的使用方法吗?
      • 我使用了您在此处编写的代码,而不是在我的代码中执行 catch 是否正确?
      • 你在调用“.video”时做错了
      • 你能用课程的完整代码编辑你的答案吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-12-15
      • 1970-01-01
      • 2018-01-03
      • 2023-03-27
      • 1970-01-01
      • 2014-12-21
      • 2014-09-16
      相关资源
      最近更新 更多