为什么我的相机翻转按钮只能在主队列上工作?

时间:2018-02-18 05:06:17

标签: ios swift avfoundation grand-central-dispatch

我一直在努力让我的翻页按钮继续工作并且一直收到错误

  

[AVCapturePhotoOutput capturePhotoWithSettings:delegate:]没有有效和启用的视频连接'

我能够通过添加一行代码来修复错误,以便在触摸翻页按钮时移除现有的captureSession.outputs,并将所有AVcaptureDevice设置移至DispatchQueue.main.async而不是单独的DispatchQueuesessionQueue = DispatchQueue(label: "session queue")

下面是翻转按钮的代码

@IBAction func FlipThe_camera(_ sender: UIButton) {
print("Flip Touched")

    self.captureSession.beginConfiguration()
    if let inputs = self.captureSession.inputs as? [AVCaptureDeviceInput] {
        for input in inputs {
            self.captureSession.removeInput(input)
            print("input removed")
        }
        //This seemed to have fixed it 
        for output in self.captureSession.outputs{
            captureSession.removeOutput(output)
            print("out put removed")
        }
    }


        self.usingFrontCamera = !self.usingFrontCamera
        self.setupCaptureSession()
        self.setupDevice(usingFrontCamera: self.usingFrontCamera)
        self.setupInput()
        self.captureSession.commitConfiguration()
        self.startRunningCaptureSession()
    }

setUpCatureSession()setupInput()中涉及的所有代码放到Dispatch.Queue.main上是否有任何损害?

我已将这两个函数中包含的代码从自己的线程转移到主线程上,这是一种不好的做法吗?谢谢你的建议?

func setupDevice(usingFrontCamera:Bool = false){
    DispatchQueue.main.async {
    //sessionQueue.async {
    let deviceDiscoverySession = AVCaptureDevice.DiscoverySession(deviceTypes: [AVCaptureDevice.DeviceType.builtInWideAngleCamera], mediaType: AVMediaType.video, position: AVCaptureDevice.Position.unspecified)
    let devices = deviceDiscoverySession.devices

    for device in devices{
        if usingFrontCamera && device.position == AVCaptureDevice.Position.front {
            self.currentCamera = device
        } else if device.position == AVCaptureDevice.Position.back {
            self.currentCamera = device
        }
    }
    }
}

func setupInput() {
    DispatchQueue.main.async {
    // sessionQueue.async {
        do {
            let captureDeviceInput = try AVCaptureDeviceInput(device: self.currentCamera!)
            if self.captureSession.canAddInput(captureDeviceInput) {
                self.captureSession.addInput(captureDeviceInput)
                print("input added")
            }
            self.photoOutPut = AVCapturePhotoOutput()
            self.photoOutPut?.setPreparedPhotoSettingsArray([AVCapturePhotoSettings(format:[AVVideoCodecKey: AVVideoCodecType.jpeg])], completionHandler: nil)
            if self.captureSession.canAddOutput(self.photoOutPut!) {
                self.captureSession.addOutput(self.photoOutPut!)
                print("output added")
            }
        } catch {
            print(error)
        }
    }
}

以下是完整的代码:

 import UIKit
 import AVFoundation

 protocol previewSegueDelegate {
func previewSegueDelegate(image:UIImage,device:AVCaptureDevice)
 }

class MainCameraCollectionViewCell: UICollectionViewCell {

var gdelegate: gestureDelegate?
var pdelegate: previewSegueDelegate?


@IBOutlet weak var myView: UIView!

var captureSession = AVCaptureSession()
private var sessionQueue: DispatchQueue!
var captureConnection = AVCaptureConnection()

var backCamera: AVCaptureDevice?
var frontCamera: AVCaptureDevice?
var currentCamera: AVCaptureDevice?

var photoOutPut: AVCapturePhotoOutput?

var cameraPreviewLayer: AVCaptureVideoPreviewLayer?

var image: UIImage?

 var usingFrontCamera = false

override func awakeFromNib() {
    super.awakeFromNib()
    setupCaptureSession()
    setupDevice()
    setupInput()
    setupPreviewLayer()
    startRunningCaptureSession()
}

func setupCaptureSession(){
    captureSession.sessionPreset = AVCaptureSession.Preset.photo
    sessionQueue = DispatchQueue(label: "session queue")
}

func setupDevice(usingFrontCamera:Bool = false){
    DispatchQueue.main.async {
    //sessionQueue.async {
    let deviceDiscoverySession = AVCaptureDevice.DiscoverySession(deviceTypes: [AVCaptureDevice.DeviceType.builtInWideAngleCamera], mediaType: AVMediaType.video, position: AVCaptureDevice.Position.unspecified)
    let devices = deviceDiscoverySession.devices

    for device in devices{
        if usingFrontCamera && device.position == AVCaptureDevice.Position.front {
            self.currentCamera = device
        } else if device.position == AVCaptureDevice.Position.back {
            self.currentCamera = device
        }
    }
    }
}

func setupInput() {
    DispatchQueue.main.async {
    // sessionQueue.async {
        do {
            let captureDeviceInput = try AVCaptureDeviceInput(device: self.currentCamera!)
            if self.captureSession.canAddInput(captureDeviceInput) {
                self.captureSession.addInput(captureDeviceInput)
                print("input added")
            }
            self.photoOutPut = AVCapturePhotoOutput()
            self.photoOutPut?.setPreparedPhotoSettingsArray([AVCapturePhotoSettings(format:[AVVideoCodecKey: AVVideoCodecType.jpeg])], completionHandler: nil)
            if self.captureSession.canAddOutput(self.photoOutPut!) {
                self.captureSession.addOutput(self.photoOutPut!)
                print("output added")
            }
        } catch {
            print(error)
        }
    }
}
func setupPreviewLayer(){
    cameraPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
    cameraPreviewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill
    cameraPreviewLayer?.connection?.videoOrientation = AVCaptureVideoOrientation.portrait
    cameraPreviewLayer?.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
    self.layer.insertSublayer(cameraPreviewLayer!, at: 0)
}

func startRunningCaptureSession(){
    captureSession.startRunning()
}


@IBAction func cameraButton_TouchUpInside(_ sender: Any) {
    print("Camera button tapped")
    let settings = AVCapturePhotoSettings(format: [AVVideoCodecKey: AVVideoCodecType.jpeg])
    if let photoOutputConnection = self.photoOutPut?.connection(with: .video){
        photoOutputConnection.videoOrientation = (cameraPreviewLayer?.connection?.videoOrientation)!
    }
    photoOutPut?.capturePhoto(with: settings, delegate: self as AVCapturePhotoCaptureDelegate)
}



@IBAction func FlipThe_camera(_ sender: UIButton) {
print("Flip Touched")

    self.captureSession.beginConfiguration()
    if let inputs = self.captureSession.inputs as? [AVCaptureDeviceInput] {
        for input in inputs {
            self.captureSession.removeInput(input)
            print("input removed")
        }
        //This seemed to have fixed it 
        for output in self.captureSession.outputs{
            captureSession.removeOutput(output)
            print("out put removed")
        }
    }


        self.usingFrontCamera = !self.usingFrontCamera
        self.setupCaptureSession()
        self.setupDevice(usingFrontCamera: self.usingFrontCamera)
        self.setupInput()
        self.captureSession.commitConfiguration()
        self.startRunningCaptureSession()
    }



  }


 extension MainCameraCollectionViewCell: AVCapturePhotoCaptureDelegate{
func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
    print("Im in the photo out put delgate")
    if let imageData = photo.fileDataRepresentation(){
        print(imageData)
        image = UIImage(data: imageData)
        if(self.image == nil){
            print("The image is empty")
        }
        print("The capture session is running photoOutput: \(captureSession.isRunning)")
        print("The capture session has been interupted photoOutput: \(captureSession.isInterrupted)")
        pdelegate?.previewSegueDelegate(image: self.image!, device: currentCamera!)
    }
    else{
        print("The photoOutput delegate error is \(String(describing: error))")
    }
  }

   }

0 个答案:

没有答案