我试图在视图控制器中集成一个画中画(画中画)控制器和相机预览。但是,相机预览仅在其首次指定的视图中可见(另一个视图变为黑色)。是否可以为两个视图使用相同的AVCaptureVideoPreviewLayer
示例?或者这里需要改变什么?
class ViewController: UIViewController {
let captureSession = AVCaptureSession()
let captureSessionQueue = DispatchQueue(label: "Capture Session Queue")
var pipVideoCallViewController: AVPictureInPictureVideoCallViewController!
var pipController: AVPictureInPictureController!
override func viewDidLoad() {
super.viewDidLoad()
let previewView = PreviewView(captureSession)
let previewLayer = previewView.previewLayer
previewLayer.frame = view.layer.bounds
previewLayer.videoGravity = .resizeAspectFill
previewLayer.connection?.videoOrientation = .landscapeLeft
view.layer.addSublayer(previewLayer)
pipVideoCallViewController = .init(previewView,
preferredContentSize: CGSize(width: 1080, height: 1920))
let pipContentSource = AVPictureInPictureController.ContentSource(
activeVideoCallSourceView: view,
contentViewController: pipVideoCallViewController)
pipController = AVPictureInPictureController(contentSource: pipContentSource)
pipController.delegate = self
pipController.canStartPictureInPictureAutomaticallyFromInline = true
startSession()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if !pipController.isPictureInPictureActive {
pipController.startPictureInPicture()
}
}
private func startSession() {
captureSessionQueue.async { [unowned self] in
let device = AVCaptureDevice.default(for: .video)!
captureSession.addInput(try! AVCaptureDeviceInput(device: device))
captureSession.sessionPreset = .hd1920x1080
captureSession.isMultitaskingCameraAccessEnabled = captureSession.isMultitaskingCameraAccessSupported
captureSession.startRunning()
}
}
}
extension ViewController: AVPictureInPictureControllerDelegate {
func pictureInPictureController(_ pictureInPictureController: AVPictureInPictureController, failedToStartPictureInPictureWithError error: Error) {
print(error.localizedDescription)
}
}
class PreviewView: UIView {
override class var layerClass: AnyClass {
AVCaptureVideoPreviewLayer.self
}
var previewLayer: AVCaptureVideoPreviewLayer {
layer as! AVCaptureVideoPreviewLayer
}
init(_ session: AVCaptureSession) {
super.init(frame: .zero)
previewLayer.session = session
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
extension AVPictureInPictureVideoCallViewController {
convenience init(_ previewView: PreviewView, preferredContentSize: CGSize) {
// Initialize.
self.init()
// Set the preferredContentSize.
self.preferredContentSize = preferredContentSize
// Configure the PreviewView.
previewView.translatesAutoresizingMaskIntoConstraints = false
previewView.frame = self.view.frame
self.view.addSubview(previewView)
NSLayoutConstraint.activate([
previewView.topAnchor.constraint(equalTo: self.view.topAnchor),
previewView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),
previewView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor),
previewView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor)
])
}
}
1条答案
按热度按时间dwthyt8l1#
AVCaptureVideoPreviewLayer只能添加到单个视图,创建单个AVCaptureVideoPreviewLayer将其作为子图层添加到两个视图
viewDidLoad将AV添加到
更新控制器