【问题标题】:How to switch IOS cameras如何切换IOS摄像头
【发布时间】:2019-12-14 13:04:00
【问题描述】:

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

这是我实现的代码

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()
            }

        }

    }


}

应用开始工作时找到前置摄像头,但按下旋转按钮时不会切换到后置摄像头

【问题讨论】:

  • 你不需要 backCamera 和 frontCamera 作为变量。切换相机时重新加载AVCaptureVideoPreviewLayer
  • 这个已经回答了:to the post

标签: ios swift


【解决方案1】:
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!)
    }  
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-12-31
    • 2020-11-14
    • 2018-09-04
    • 1970-01-01
    • 1970-01-01
    • 2020-10-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多