Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 如何停止collectionView单元格中的相机延迟?_Ios_Swift_Avfoundation_Grand Central Dispatch_Avcapturesession - Fatal编程技术网

Ios 如何停止collectionView单元格中的相机延迟?

Ios 如何停止collectionView单元格中的相机延迟?,ios,swift,avfoundation,grand-central-dispatch,avcapturesession,Ios,Swift,Avfoundation,Grand Central Dispatch,Avcapturesession,我有一个collectionView,它的单元格充当屏幕。当我在打开应用程序后滑动到相机单元时,会有一秒钟的延迟,然后在之后,来回滑动是平滑的,下面是这个延迟的视频。是否有任何方法可以防止这种情况,或者在到达单元格之前在后台启动捕获会话?谢谢你的帮助 摄像机单元代码 import UIKit import AVFoundation class MainCameraCollectionViewCell: UICollectionViewCell { var captureSessi

我有一个collectionView,它的单元格充当屏幕。当我在打开应用程序后滑动到相机单元时,会有一秒钟的延迟,然后在之后,来回滑动是平滑的,下面是这个延迟的视频。是否有任何方法可以防止这种情况,或者在到达单元格之前在后台启动捕获会话?谢谢你的帮助

摄像机单元代码

import UIKit
import AVFoundation


class MainCameraCollectionViewCell: UICollectionViewCell {

    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()
        self.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 {
                    //backCamera = device
                    self.currentCamera = device
                } else if device.position == AVCaptureDevice.Position.back {
                    //frontCamera = device
                    self.currentCamera = device
                }
            }
        }
    }
    func setupInput() {
        DispatchQueue.main.async {
            do {
                let captureDeviceInput = try AVCaptureDeviceInput(device: self.currentCamera!)
                if self.captureSession.canAddInput(captureDeviceInput) {
                    self.captureSession.addInput(captureDeviceInput)
                }
                self.photoOutPut = AVCapturePhotoOutput()
                self.photoOutPut?.setPreparedPhotoSettingsArray([AVCapturePhotoSettings(format:[AVVideoCodecKey: AVVideoCodecType.jpeg])], completionHandler: nil)
                if self.captureSession.canAddOutput(self.photoOutPut!) {
                    self.captureSession.addOutput(self.photoOutPut!)
                }
            } 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_Touched(_ sender: Any) {
        let settings = AVCapturePhotoSettings(format: [AVVideoCodecKey: AVVideoCodecType.jpeg])
        //
        settings.isAutoStillImageStabilizationEnabled = true
        if let photoOutputConnection = self.photoOutPut?.connection(with: .video){
            photoOutputConnection.videoOrientation = (cameraPreviewLayer?.connection?.videoOrientation)!
        }
    }



    @IBAction func Flip_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()
    }

}

初始化相机需要时间。一旦你的应用程序请求使用摄像头,支持软件就必须在后台初始化,这实际上是不可能加速的


我建议将与AVFoundation相关的任何内容放在后台线程中,并在应用程序加载后初始化它。这样,一旦用户准备好刷卡到相机单元,相机就可以为用户准备好了。如果你不想预加载,你至少可以把背景放在后台,并利用某种活动指示器来显示用户正在加载东西,而不是让你的主线程在摄像机启动时被阻挡。< / P>如果我的答案是有用的,你能考虑接受吗?