根据我之前的问题,我对我的代码进行了很多更改,这些更改已经购买了一组新的问题,这就是为什么我决定创建一个新问题而不是遵循之前的问题。
我正在玩Swift开发,我正在尝试创建一个基本应用程序,在UIImageview
内显示相机。
我正在使用AVFoundation
框架。
到目前为止,我已经能够在负载下设置前置摄像头了。我的问题是,如何实现按钮点击时切换相机的功能?
我首先初始化实例:
var captureSession = AVCaptureSession()
var sessionOutput = AVCapturePhotoOutput()
var sessionOutputSetting = AVCapturePhotoSettings(format: [AVVideoCodecKey:AVVideoCodecJPEG])
var previewLayer = AVCaptureVideoPreviewLayer()
我还创建了一个切换bool:
// Bool to manage camera toggle. False = front-face (default)
var toggle = false
在viewWillApear
我调用pickCamera
函数,该函数检查切换值并创建设备恢复会话:
func pickCamera(which: Bool) {
if (which == true) {
let deviceDescovery = AVCaptureDeviceDiscoverySession(deviceTypes: [AVCaptureDeviceType.builtInDualCamera, AVCaptureDeviceType.builtInTelephotoCamera, AVCaptureDeviceType.builtInWideAngleCamera], mediaType: AVMediaTypeVideo, position: AVCaptureDevicePosition.back)
startCamera(deviceDesc: deviceDescovery!)
toggle = true;
} else if (which == false) {
let deviceDescovery = AVCaptureDeviceDiscoverySession(deviceTypes: [AVCaptureDeviceType.builtInDualCamera, AVCaptureDeviceType.builtInTelephotoCamera, AVCaptureDeviceType.builtInWideAngleCamera], mediaType: AVMediaTypeVideo, position: AVCaptureDevicePosition.front)
startCamera(deviceDesc: deviceDescovery!)
toggle = false;
}
}
startCamera
函数然后创建并设置captureSession并添加到父图层以显示:
func startCamera(deviceDesc: AVCaptureDeviceDiscoverySession) {
for device in (deviceDesc.devices)! {
if (device.position == AVCaptureDevicePosition.back) {
do {
let input = try AVCaptureDeviceInput(device: device)
if (captureSession.canAddInput(input)) {
captureSession.addInput(input)
if (captureSession.canAddOutput(sessionOutput)) {
captureSession.addOutput(sessionOutput)
previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
previewLayer.connection.videoOrientation = AVCaptureVideoOrientation.portrait
captureSession.startRunning()
cameraView.layer.addSublayer(previewLayer)
}
}
}
catch {
print("Exception")
}
} else if (device.position == AVCaptureDevicePosition.front) {
do {
let input = try AVCaptureDeviceInput(device: device)
if (captureSession.canAddInput(input)) {
captureSession.addInput(input)
if (captureSession.canAddOutput(sessionOutput)) {
captureSession.addOutput(sessionOutput)
previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
previewLayer.connection.videoOrientation = AVCaptureVideoOrientation.portrait
captureSession.startRunning()
cameraView.layer.addSublayer(previewLayer)
}
}
}
catch {
print("Exception")
}
}
}
}
我还添加了一个带动作的按钮:
@IBAction func toggleCamera(_ sender: Any) {
if (toggle == false) {
print("Changing to back camera")
previewLayer.removeFromSuperlayer()
toggle = true;
pickCamera(which: true)
} else if (toggle == true) {
print("Changing to front camera")
previewLayer.removeFromSuperlayer()
toggle = false;
pickCamera(which: false)
}
}
toggle方法应该清除当前视图并调用pickCamera
方法,该方法应创建备用相机的新实例。
虽然由于某种原因,这不起作用。我猜这与未正确清除前一个视图/正确添加新视图有关,但我又不确定。
感谢您抽出宝贵时间查看我的问题,请询问我是否遗漏了信息或者没有正确解释自己。
更新
终于修好了。问题在于在创建新captureSession
之前未停止当前captureSession
。
要解决此问题,我更新了toggleCamera
功能以包含:
let currentCameraInput: AVCaptureInput = captureSession.inputs[0] as! AVCaptureInput
对于对代码感兴趣的任何人,请查看here