Как ускорить загрузку камеры в ячейке collectionView? - PullRequest
0 голосов
/ 27 августа 2018

Я пытаюсь поместить сеанс камеры внутри ячейки collectionView согласно документации Apple. Я поместил сеанс захвата вместе с любой дополнительной камерой, установленной на фоновом ядре. Я не уверен, правильно ли я это делаю, так как при перелистывании между ячейками производительность все еще остается низкой. Как правильно реализовать сеанс камеры в collectionView.

enter image description here

Важно

Метод startRunning () является блокирующим вызовом, который может занять некоторое время, поэтому вам следует выполнить настройку сеанса в последовательной очереди, чтобы основная очередь не была заблокирована (что обеспечивает отзывчивость пользовательского интерфейса). Посмотрите AVCam-iOS: Использование AVFoundation для захвата изображений и фильмов для примера реализации. Документация AVCapture Session

Код, помещенный в фоновый поток

//attempt to speed things up
let backgroundWorker2 = DispatchQueue(label:"BackgroundWorker2",qos: .userInteractive)

override func awakeFromNib() {
    super.awakeFromNib()

self.backgroundWorker2.async {
    self.setupCaptureSession()
   self.setupDevice()
    self.setupInput()
    self.setupPreviewLayer()
    self.startRunningCaptureSession()
}

}

Код полностью

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

    //attempt to speed things up
    let backgroundWorker2 = DispatchQueue(label:"BackgroundWorker2",qos: .userInteractive)

    override func awakeFromNib() {
        super.awakeFromNib()

        self.backgroundWorker2.async {
            self.setupCaptureSession()
           self.setupDevice()
            self.setupInput()
            self.setupPreviewLayer()
            self.startRunningCaptureSession()
        }

        }


    func setupCaptureSession(){
        captureSession.sessionPreset = AVCaptureSession.Preset.photo
    }

    func setupDevice(usingFrontCamera:Bool = false){
            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() {
            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])
        //
        settings.isAutoStillImageStabilizationEnabled = true
        if let photoOutputConnection = self.photoOutPut?.connection(with: .video){
            photoOutputConnection.videoOrientation = (cameraPreviewLayer?.connection?.videoOrientation)!
        }

}


}
...