I was creating my custom camera view using swift 3 and xcode.
I have got it to work, but i am facing a small issue. To switch camera device from front/back i stop the session, remove the video preview layer from the view and then create a new session and add a new video preview layer from the front camera. This makes the new camera come on with a jerk. I want smooth transition between the camera devices. How can i do that?
Here my code for loading the camera:
func loadCamera()
{
session?.stopRunning()
videoPreviewLayer?.removeFromSuperlayer()
session = AVCaptureSession()
session!.sessionPreset = AVCaptureSessionPresetPhoto
var backCamera = AVCaptureDevice.defaultDevice(withDeviceType: .builtInWideAngleCamera, mediaType: AVMediaTypeVideo, position: .front)
if cameraPos == "back"
{
backCamera = AVCaptureDevice.defaultDevice(withDeviceType: .builtInWideAngleCamera, mediaType: AVMediaTypeVideo, position: .back)
}
var error: NSError?
var input: AVCaptureDeviceInput!
do {
input = try AVCaptureDeviceInput(device: backCamera)
} catch let error1 as NSError {
error = error1
input = nil
print(error!.localizedDescription)
}
if error == nil && session!.canAddInput(input) {
session!.addInput(input)
stillImageOutput = AVCapturePhotoOutput()
if session!.canAddOutput(stillImageOutput) {
session!.addOutput(stillImageOutput)
videoPreviewLayer = AVCaptureVideoPreviewLayer(session: session)
videoPreviewLayer?.frame = cameraView.bounds
videoPreviewLayer?.videoGravity = AVLayerVideoGravityResizeAspectFill
videoPreviewLayer?.connection.videoOrientation = AVCaptureVideoOrientation.portrait
cameraView.layer.addSublayer(videoPreviewLayer!)
session!.startRunning()
}
}
}
I call this from viewWillAppear
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
loadCamera()
}
and i call load camera when user clicks on change camera
@IBAction func changeCamera(_ sender: UIButton) {
if cameraPos == "back"
{cameraPos = "front"}
else
{cameraPos = "back"}
loadCamera()
}
In loadCamera() you'll need to create an AVCaptureInput from the front capture device. It's good practice to hold both the back input and the front input on some camera singleton. The smooth transition between front and back can be done by removing all inputs then assigning another input.
func show(back: Bool) {
session.beginConfiguration()
if let inputs = session.inputs as? [AVCaptureDeviceInput] {
for input in inputs {
session.removeInput(input)
}
}
if back {
if session.canAddInput(backInput) {
session.addInput(backInput)
}
} else {
if session.canAddInput(frontInput) {
session.addInput(frontInput)
}
}
session.commitConfiguration()
}
Call the loadCamera()
function inside viewDidAppear
instead of viewWillAppear
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(true)
loadCamera()
}
Background thread:
DispatchQueue.global(qos: .background).async {
// perform ui updation and web related code
// background thread
DispatchQueue.main.async {
// main thread
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.