I would like to know how I could change the camera view when I press a button. At the moment, I am using a boolean var camera = false
and when I press a button, I want to change the value to true and get the other camera. But that is not working.
I now have this:
@IBAction func changeCamera(sender: AnyObject) {
camera = true
}
override func viewWillAppear(animated: Bool) {
captureSession = AVCaptureSession()
captureSession!.sessionPreset = AVCaptureSessionPresetPhoto
var captureDevice:AVCaptureDevice! = nil
//var backCamera = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
if (camera == false){
let videoDevices = AVCaptureDevice.devicesWithMediaType(AVMediaTypeVideo)
for device in videoDevices{
let device = device as AVCaptureDevice
if device.position == AVCaptureDevicePosition.Front {
captureDevice = device
break
}
}
} else {
var captureDevice = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
}
var error: NSError?
var input = AVCaptureDeviceInput(device: captureDevice, error: &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 = AVLayerVideoGravityResizeAspect
previewLayer!.connection?.videoOrientation = AVCaptureVideoOrientation.Portrait
previewView.layer.addSublayer(previewLayer)
captureSession!.startRunning()
}
}
}
The problem lies where you are setting the camera source.
You are setting it in viewDidAppear which will only be called when the view appears on the device. This is whenever you navigate to that view controller from another or close a presented view controller that is being presented by this one.
My suggestion would be to move the camera selection code into its own function that is called by both viewDidLoad and also whenever the changeCamera action is called.
@IBAction func changeCamera(sender: AnObject?) {
camera = !camera
reloadCamera()
}
func viewDidAppear(animated: Bool) {
// normal code
reloadCamera()
}
func reloadCamera() {
// camera loading code
captureSession = AVCaptureSession()
captureSession!.sessionPreset = AVCaptureSessionPresetPhoto
var captureDevice:AVCaptureDevice! = nil
// var backCamera = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
if (camera == false) {
let videoDevices = AVCaptureDevice.devicesWithMediaType(AVMediaTypeVideo)
for device in videoDevices{
let device = device as AVCaptureDevice
if device.position == AVCaptureDevicePosition.Front {
captureDevice = device
break
}
}
} else {
var captureDevice = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
}
var error: NSError?
var input = AVCaptureDeviceInput(device: captureDevice, error: &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 = AVLayerVideoGravityResizeAspect
previewLayer!.connection?.videoOrientation = AVCaptureVideoOrientation.Portrait
previewView.layer.addSublayer(previewLayer)
captureSession!.startRunning()
}
}
Also, an additional improvement would be to use a custom enum to store which camera is currently in use rather than a Boolean. This means you can add to it later say if there was ever a third camera. This would look like:
enum CameraType {
case front
case back
}
var camera = CameraType.back
I hope this helps, apologies for omitting the full code examples, currently on an iPad but I'll update when I get to a computer.
Make sure you remove the previous preview layer from the view before you change the camera.
func reloadCamera() {
captureSession?.stopRunning()
previewLayer?.removeFromSuperlayer()
// The rest of the camera loading code...
This should fix your camera freezing issue.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With