Мне было интересно, есть ли способ взять 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
}
}
}
}
}
Прямо сейчас здесь отображаются два превью камеры, расположенные вертикально, я хочу расположить их рядом, чтобы при повороте устройства вбок они заполняли экран (один предпросмотр наслева, другой справа).