我目前在我的应用程序中有一个工作相机应用程序,并希望按钮调用前置或后置摄像头设备。我认为我已经获得了大部分就地代码,我唯一想知道的是如何编写按钮来调用这两个设备。
我已经尝试了一些if语句,但Xcode没有接受,这仍然是这个代码游戏的新手,通过实践来学习,但有时我遇到了冲击,所以任何帮助都会非常感激。
这是我使用的完整相机代码:
import Foundation
import UIKit
import AVFoundation
class CameraViewController: UIViewController{
var captureSession = AVCaptureSession()
var backCamera: AVCaptureDevice?
var frontCamera: AVCaptureDevice?
var currentCamera: AVCaptureDevice?
var photoOutput: AVCapturePhotoOutput?
var cameraPreviewLayer: AVCaptureVideoPreviewLayer?
var image: UIImage?
override func viewDidLoad() {
super.viewDidLoad()
setupCaptureSession()
setupDevice()
setupInputOutput()
setupPreviewLayer()
startRunningCaptureSession()
}
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
}
}
currentCamera = frontCamera
}
func setupInputOutput() {
do {
let captureDeviceInput = try AVCaptureDeviceInput(device: currentCamera!)
captureSession.addInput(captureDeviceInput)
photoOutput = AVCapturePhotoOutput()
photoOutput?.setPreparedPhotoSettingsArray([AVCapturePhotoSettings(format:[AVVideoCodecKey: AVVideoCodecType.jpeg])], completionHandler: nil)
captureSession.addOutput(photoOutput!)
} catch {
print(error)
}
}
func setupPreviewLayer() {
cameraPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
cameraPreviewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill
cameraPreviewLayer?.connection?.videoOrientation = AVCaptureVideoOrientation.portrait
cameraPreviewLayer?.frame = self.view.frame
self.view.layer.insertSublayer(cameraPreviewLayer!, at: 0)
}
func startRunningCaptureSession() {
captureSession.startRunning()
}
@IBAction func cameraButton(_ sender: Any) {
let settings = AVCapturePhotoSettings()
photoOutput?.capturePhoto(with: settings, delegate: self)
// performSegue(withIdentifier: "previewCameraPhoto", sender: nil)
}
@IBAction func switchCamera(_ sender: Any) {
// The button which should switch the Cameras back an forth.
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "previewCameraPhoto" {
let previewVC = segue.destination as! PreviewViewController
previewVC.image = self.image
}
}
}
extension CameraViewController: AVCapturePhotoCaptureDelegate {
func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
if let imageData = photo.fileDataRepresentation() {
image = UIImage(data: imageData)
performSegue(withIdentifier: "previewCameraPhoto", sender: nil)
}
}
override var prefersStatusBarHidden: Bool
{
return true
}
}
答案 0 :(得分:1)
你不需要为backCamera,frontCamera,currentCamera声明变量,你只需要为AVCaptureDeviceInput保存变量。
试着评论:
// var backCamera: AVCaptureDevice?
// var frontCamera: AVCaptureDevice?
// var currentCamera: AVCaptureDevice?
并添加:
var frontCameraDeviceInput: AVCaptureDeviceInput?
var backCameraDeviceInput: AVCaptureDeviceInput?
你的setupDevice函数看起来像这个
func setupDevice() {
let frontCamera = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .front)
let backCamera = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .back)
frontCameraDeviceInput = try? AVCaptureDeviceInput(device: frontCamera!)
backCameraDeviceInput = try? AVCaptureDeviceInput(device: backCamera!)
}
将setupInputOutput函数更改为:
func setupInputOutput() {
captureSession.addInput(backCameraDeviceInput!)
photoOutput = AVCapturePhotoOutput()
photoOutput?.setPreparedPhotoSettingsArray([AVCapturePhotoSettings(format:[AVVideoCodecKey: AVVideoCodecType.jpeg])], completionHandler: nil)
captureSession.addOutput(photoOutput!)
}
最后你的switchCamera
@IBAction func switchCamera(_ sender: Any) {
// The button which should switch the Cameras back an forth.
captureSession.beginConfiguration()
//Change camera device inputs from back to front or opposite
if captureSession.inputs.contains(frontCameraDeviceInput!) == true {
captureSession.removeInput(frontCameraDeviceInput!)
captureSession.addInput(backCameraDeviceInput!)
} else if captureSession.inputs.contains(backCameraDeviceInput!) == true {
captureSession.removeInput(backCameraDeviceInput!)
captureSession.addInput(frontCameraDeviceInput!)
}
//Commit all the configuration changes at once
captureSession.commitConfiguration();
}