我是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:]无法将输出添加到捕获会话<AVCaptureSession:<AVCapturePhotoOutput: 0x283584560>0x2837fc560 [AVCaptureSessionPresetPhoto]>\n\t <AVCaptureDeviceInput:0x2835aa460 [Back Camera]>[vide]->\n\t <AVCaptureDeviceInput:0x2835aa460 [Back Camera]>[vide]->因为不支持同一类型的多个输出"<AVCapturePhotoOutput: 0x283592a60><AVCaptureVideoPreviewLayer: 0x283594bc0>
我上网查了一下,发现了这篇文章: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:对于任何人谁是以下,问题是,我打电话给他们的看法确实出现了使输出显示几次感谢马特的帮助(在评论中)。我通过使用视图加载修复了它
3条答案
按热度按时间9udxz4iz1#
在调用
addOutput:
之前,你应该检查canAddOutput:
。因为,调用addOutput:
太多次会导致崩溃。lmyy7pcs2#
在Swift 5.7,iOS 16.0中工作
jogvjijk3#
如果上述解决方案不起作用,请在每次会话之前或视图中从捕获会话中删除 * 输入 * 和 * 输出 * 将消失。
当新会话启动时,输入和输出将再次添加。