如何切换IOS相机

时间:2019-07-19 08:14:24

标签: ios swift

我已经迅速实现了一个摄像头应用程序,但是从前置摄像头切换到后置摄像头无法正常工作

这是我实现的代码

import UIKit
import AVFoundation

class ViewController: UIViewController {

    @IBOutlet weak var ImageView: UIView!

    var captureSession: AVCaptureSession?
    var videoPreviewLayer: AVCaptureVideoPreviewLayer?
    var backCamera = AVCaptureDevice.default(.builtInDualCamera, for: .video, position: .back)
    var frontCamera = AVCaptureDevice.default(.builtInDualCamera, for: .video, position: .front)
    var capturePhotoOut : AVCapturePhotoOutput?

    override func viewDidLoad() {
        super.viewDidLoad()

        if #available(iOS 10.2, *){
            let captureDevice = AVCaptureDevice.default(.builtInDualCamera, for: .video, position: .back)
            do{
                let input = try  AVCaptureDeviceInput(device: captureDevice!)
                captureSession = AVCaptureSession()
                captureSession?.addInput(input)
                videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession!)
                videoPreviewLayer?.frame = view.layer.bounds
                ImageView.layer.addSublayer(videoPreviewLayer!)
                captureSession?.startRunning()
            }catch{
                print("error")
            }
        }

        capturePhotoOut = AVCapturePhotoOutput()
        capturePhotoOut?.isHighResolutionCaptureEnabled = true
        captureSession?.sessionPreset = .photo
        captureSession?.addOutput(capturePhotoOut!)
        capturePhotoOut!.isDepthDataDeliveryEnabled = capturePhotoOut!.isDepthDataDeliverySupported
        capturePhotoOut!.isPortraitEffectsMatteDeliveryEnabled = capturePhotoOut!.isPortraitEffectsMatteDeliverySupported
    }

    func switchToFrontCamera(){
        if frontCamera?.isConnected == true {
            captureSession?.stopRunning()
            let captureDevice = AVCaptureDevice.default(.builtInDualCamera, for: .video, position: .front)
            do{

                let input = try AVCaptureDeviceInput(device: captureDevice!)
                captureSession = AVCaptureSession()
                captureSession?.addInput(input)
                videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession!)
                videoPreviewLayer?.frame = view.layer.bounds
                ImageView.layer.addSublayer(videoPreviewLayer!)
                captureSession?.startRunning()

            }catch{
                print("Error")
            }
        }else{
            print("noFrontCamera")
        }

    }

    func switchToBackCamera(){
        if backCamera?.isConnected == true {
            captureSession?.stopRunning()
            let captureDevice = AVCaptureDevice.default(.builtInDualCamera, for: .video, position: .back)
            do{
                let input = try AVCaptureDeviceInput(device: captureDevice!)
                captureSession = AVCaptureSession()
                captureSession?.addInput(input)
                videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession!)
                videoPreviewLayer?.frame = view.layer.bounds
                ImageView.layer.addSublayer(videoPreviewLayer!)
                captureSession?.startRunning()

            }catch{
                print("Error")
            }
        }else{
            print("noFrontCamera")
        }

    }


    @IBAction func rotateCamera(_ sender: Any) {
        guard let currentCameraInput: AVCaptureInput = captureSession?.inputs.first else {
            return
        }

        if let input = currentCameraInput as? AVCaptureDeviceInput{

            if input.device.position == .back {
                switchToFrontCamera()
            }

            if input.device.position == .front{
                switchToBackCamera()
            }

        }

    }


}

该应用启动时的前置摄像头可以找到,但是按下旋转按钮后它不会切换到后置摄像头

1 个答案:

答案 0 :(得分:0)

You can use the following code as i edited your code:

class MyView: UIView {
    //MARK: overriding the layerClass to return `AVCaptureVideoPreviewLayer`.
    override class var layerClass: AnyClass  {
        return AVCaptureVideoPreviewLayer.self
    }
    override var layer: AVCaptureVideoPreviewLayer {
        return super.layer as! AVCaptureVideoPreviewLayer
    }
}

class ViewController: UIViewController {

    @IBOutlet weak var ImageView: MyView!
    var captureSession: AVCaptureSession?
    var capturePhotoOut : AVCapturePhotoOutput?
    var captureDevice : AVCaptureDevice?

    var videoPreviewLayer: AVCaptureVideoPreviewLayer {
        return ImageView.layer
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        captureDevice = AVCaptureDevice.default(for: .video)
        doInitialSetup(with: captureDevice!)
    }

    func doInitialSetup(with videoCaptureDevice : AVCaptureDevice) {
        if #available(iOS 10.2, *){
            do{
                let input = try  AVCaptureDeviceInput(device: videoCaptureDevice)
                captureSession = AVCaptureSession()
                captureSession?.addInput(input)
                videoPreviewLayer.frame = ImageView.bounds
                videoPreviewLayer.session = captureSession
                captureSession?.startRunning()
            }catch{
                print("error")
            }
        }

        capturePhotoOut = AVCapturePhotoOutput()
        capturePhotoOut?.isHighResolutionCaptureEnabled = true
        captureSession?.sessionPreset = .photo
        captureSession?.addOutput(capturePhotoOut!)
        capturePhotoOut!.isDepthDataDeliveryEnabled = capturePhotoOut!.isDepthDataDeliverySupported
        if #available(iOS 12.0, *) {
            capturePhotoOut!.isPortraitEffectsMatteDeliveryEnabled = capturePhotoOut!.isPortraitEffectsMatteDeliverySupported
        } else {
            // Fallback on earlier versions
        }
    }

    @IBAction func rotateCamera(_ sender: Any) {
        captureSession?.stopRunning()
        if self.captureDevice?.position == .back  {
            self.captureDevice = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .front)
        }else if self.captureDevice?.position == .front{
            self.captureDevice = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .back)
        }
        doInitialSetup(with: self.captureDevice!)
    }  
}