Заставить CAReplicator отображать горизонтально - PullRequest
0 голосов
/ 20 октября 2019

Мне было интересно, есть ли способ взять CAReplicator, который в моем случае использования создает два превью камеры, накладываемых друг на друга, и вместо этого визуализирует эти два по горизонтали. Мой ViewController:

import UIKit
import AVFoundation

class ViewController: UIViewController {

    let captureSession = AVCaptureSession()
    var previewLayer:AVCaptureVideoPreviewLayer!

    var replicatorLayer = CAReplicatorLayer()

    var captureDevice:AVCaptureDevice!

    override func viewDidLoad() {
        super.viewDidLoad()
        prepareCamera()
    }

    func prepareCamera(){
        captureSession.sessionPreset = AVCaptureSession.Preset.photo

        let availableDevices = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInWideAngleCamera], mediaType: AVMediaType.video, position: .back).devices
        captureDevice = availableDevices.first
        beginSession()

    }

    func beginSession(){
        do {
            let captureDeviceInput = try AVCaptureDeviceInput(device: captureDevice)
            captureSession.addInput(captureDeviceInput)
        } catch {
            print(error.localizedDescription)
        }

        let previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
        self.previewLayer = previewLayer
        self.previewLayer.videoGravity = .resizeAspectFill
        self.previewLayer.frame = self.view.bounds//CGRect(x: 0.0, y: 0.0, width: view.bounds.size.width, height: view.bounds.size.height / 2)

        let replicatorInstances = 2

        replicatorLayer.frame = CGRect(x: 0, y: 0, width: view.bounds.size.width, height: CGFloat(view.bounds.size.height / CGFloat(replicatorInstances)))
        replicatorLayer.instanceCount = replicatorInstances
        replicatorLayer.instanceTransform = CATransform3DMakeTranslation(0.0, view.bounds.size.height / CGFloat(replicatorInstances), 0.0)
        replicatorLayer.addSublayer(previewLayer)
        self.view.layer.addSublayer(replicatorLayer)
        captureSession.startRunning()

        let dataOutput =  AVCaptureVideoDataOutput()
        dataOutput.videoSettings = [(kCVPixelBufferPixelFormatTypeKey as NSString):NSNumber(value:kCVPixelFormatType_32BGRA)] as [String : Any]
        dataOutput.alwaysDiscardsLateVideoFrames = true

        if captureSession.canAddOutput(dataOutput) {
            captureSession.addOutput(dataOutput)
        }

        captureSession.commitConfiguration()

        let queue = DispatchQueue(label: "clockworksciencce")
        dataOutput.setSampleBufferDelegate(self as? AVCaptureVideoDataOutputSampleBufferDelegate, queue: queue)

    }

    private func updatePreviewLayer(layer: AVCaptureConnection, orientation: AVCaptureVideoOrientation) {

        layer.videoOrientation = orientation

        previewLayer.frame = self.view.bounds


    }
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()

        if let connection =  self.previewLayer?.connection  {

            let currentDevice: UIDevice = UIDevice.current

            let orientation: UIDeviceOrientation = currentDevice.orientation

            let previewLayerConnection : AVCaptureConnection = connection

            if previewLayerConnection.isVideoOrientationSupported {

                switch (orientation) {
                case .portrait: updatePreviewLayer(layer: previewLayerConnection, orientation: .portrait)

                    break

                case .landscapeRight: updatePreviewLayer(layer: previewLayerConnection, orientation: .landscapeLeft)

                    break

                case .landscapeLeft: updatePreviewLayer(layer: previewLayerConnection, orientation: .landscapeRight)

                    break

                case .portraitUpsideDown: updatePreviewLayer(layer: previewLayerConnection, orientation: .portraitUpsideDown)

                    break

                default: updatePreviewLayer(layer: previewLayerConnection, orientation: .portrait)

                    break
                }
            }
        }
    }

}

Прямо сейчас здесь отображаются два превью камеры, расположенные вертикально, я хочу расположить их рядом, чтобы при повороте устройства вбок они заполняли экран (один предпросмотр наслева, другой справа).

1 Ответ

0 голосов
/ 24 октября 2019

Это так же просто, как изменить строку

replicatorLayer.instanceTransform = CATransform3DMakeTranslation(0.0, view.bounds.size.height / CGFloat(replicatorInstances), 0.0)

на

replicatorLayer.instanceTransform = CATransform3DMakeTranslation(view.bounds.size.height / CGFloat(replicatorInstances), 0.0, 0.0)
...