问题描述
我是Swift的初学者,使用Swift 5和XCode 11.5。这是我创建相机的代码。我希望足够了!
override func viewDidAppear(_ animated: Bool) {
setupCaptureSession()
setupDevice()
setupInputOutput()
setupPreviewLayer()
captureSession.startRunning()
}
func setupCaptureSession() {
captureSession.sessionPreset = AVCaptureSession.Preset.photo
}
func setupDevice() {
let devicediscoverySession = AVCaptureDevice.discoverySession(deviceTypes: [AVCaptureDevice.DeviceType.builtInWideAngleCamera],mediaType: AVMediaType.video,position: AVCaptureDevice.Position.unspecified)
let devices = devicediscoverySession.devices
for device in devices {
if device.position == AVCaptureDevice.Position.back {
backCamera = device
} else if device.position == AVCaptureDevice.Position.front {
frontCamera = device
}
}
currentDevice = backCamera
}
func setupInputOutput() {
do {
let captureDeviceInput = try AVCaptureDeviceInput(device: currentDevice!)
if let inputs = captureSession.inputs as? [AVCaptureDeviceInput] {
for input in inputs {
captureSession.removeInput(input)
}
}
captureSession.addInput(captureDeviceInput)
photoOutput = AVCapturePhotoOutput()
photoOutput!.setPreparedPhotoSettingsArray([AVCapturePhotoSettings(format: [AVVideoCodecKey : AVVideoCodecType.jpeg])],completionHandler: nil)
captureSession.addOutput(photoOutput!)
} catch {
print(error)
}
}
func setupPreviewLayer() {
self.cameraPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
self.cameraPreviewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill
self.cameraPreviewLayer?.connection?.videoOrientation = AVCaptureVideoOrientation.portrait
self.cameraPreviewLayer?.frame = view.frame
self.view.layer.insertSublayer(self.cameraPreviewLayer!,at: 0)
}
@IBAction func rotateCamera(_ sender: Any) {
captureSession.beginConfiguration()
// Change the device based on the current camera
let newDevice = (currentDevice?.position == AVCaptureDevice.Position.back) ? frontCamera : backCamera
// Remove all inputs from the session
for input in captureSession.inputs {
captureSession.removeInput(input as! AVCaptureDeviceInput)
}
// Change to the new input
let cameraInput:AVCaptureDeviceInput
do {
cameraInput = try AVCaptureDeviceInput(device: newDevice!)
} catch {
print(error)
return
}
if captureSession.canAddInput(cameraInput) {
captureSession.addInput(cameraInput)
}
currentDevice = newDevice
captureSession.commitConfiguration()
}
我正在尝试使用AVFoundation创建摄像机,但出现一条错误消息:
线程1:异常:“ ***-[AVCaptureSession addOutput:]无法添加输出
所以我看了网上,发现这篇文章:AVCapture Session To Capture Image SWIFT提到了类似的错误,但是因为它使用的是旧版本,所以我尝试重新创建它。但是,我能得到的最远的是:
dispatchQueue.global(qos: .userInteractive).async { // 1
self.captureSession.addOutput(self.photoOutput!)
try self.captureSession.addInput( AVCaptureDeviceInput(device: self.currentDevice!))
//supposed to add error here but Couldn't do it
self.captureSession.sessionPreset = AVCaptureSession.Preset.photo
var previewLayer = AVCaptureVideoPreviewLayer(session: self.captureSession)
previewLayer.frame = self.cameraview.layer.bounds
//In my project it said there was no member cameraview of UIViewController.
previewLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
dispatchQueue.main.async { // 2
// 3
self.cameraview.layer.addSublayer(previewLayer)
self.captureSession.startRunning()
}
}
由于从那时起不赞成使用许多方法,因此我很难找到新的方法,而且我什至无法将错误添加为参数,因为它是调用中的额外参数。如果有人可以帮助我解决如何解决多个输入问题,我将非常感激。我尽了最大的努力,但老实说我找不到任何解决方案。
谢谢!
编辑2:对于所有关注的人,问题在于我在视野中给他们打电话的确是在Matt的帮助下(在评论中)确实使输出多次显示。我通过使用视图加载来修复了它
解决方法
在调用 addOutput:
之前,您应该检查 canAddOutput:
。因为调用 addOutput:
次数过多会导致崩溃。