Swift应用添加AVCaptureVideoPreviewLayer实现相机预览时显示黑屏如何解决
AVCaptureVideoPreviewLayer 黑屏问题排查方案
常见触发原因及修复方式
- 相机权限未配置:iOS 要求访问相机前必须在 Info.plist 中添加
NSCameraUsageDescription字段,配置权限申请的说明文案,未配置的情况下系统会拒绝相机访问,直接出现黑屏。 - 预览图层尺寸未设置:你当前代码未给
previewLayer设置大小,默认尺寸为0,无法正常渲染画面。需要将previewLayer的frame设置为和父容器的bounds一致,同时可设置videoGravity控制画面适配规则。 - 捕获会话启动阻塞主线程:
AVCaptureSession的startRunning()是耗时操作,直接在主线程调用会阻塞UI渲染,需要放到后台串行队列执行。 - 运行环境问题:模拟器不支持相机预览能力,必须使用真机调试。
- 重复添加会话输入:
viewWillAppear会在页面每次展示时触发,多次调用会重复添加输入源导致会话异常,建议将会话配置逻辑移到viewDidLoad仅执行一次。
修正后的参考代码
var cameraInput : AVCaptureDeviceInput! // 单独创建相机操作的串行队列,避免阻塞主线程 let cameraQueue = DispatchQueue(label: "com.yourapp.cameraQueue") var videoSession : AVCaptureSession = AVCaptureSession() var previewLayer : AVCaptureVideoPreviewLayer! override func viewDidLoad() { super.viewDidLoad() setupCamera() } override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() // 每次页面布局变更时更新预览层尺寸,适配横竖屏切换 previewLayer.frame = view.bounds } func setupCamera() { // 先判断相机权限状态,未授权先申请权限 switch AVCaptureDevice.authorizationStatus(for: .video) { case .notDetermined: AVCaptureDevice.requestAccess(for: .video) { [weak self] granted in if granted { self?.configureSession() } } case .authorized: configureSession() default: print("相机权限未开启") return } } func configureSession() { cameraQueue.async { [weak self] in guard let self = self else { return } // 配置会话前先判断是否已经在运行,避免重复配置 guard !self.videoSession.isRunning else { return } guard let videoCamera = AVCaptureDevice.default(for: .video) else{ print("Camera Device doesnt work") return } guard let cameraInput = try? AVCaptureDeviceInput(device: videoCamera), self.videoSession.canAddInput(cameraInput) else { return } self.videoSession.addInput(cameraInput) DispatchQueue.main.async { self.previewLayer = AVCaptureVideoPreviewLayer(session: self.videoSession) // 设置画面适配模式 self.previewLayer.videoGravity = .resizeAspectFill self.previewLayer.frame = self.view.bounds self.view.layer.addSublayer(self.previewLayer) self.cameraQueue.async { self.videoSession.startRunning() } } } }
内容的提问来源于stack exchange,提问作者Mr Astronaut
相关产品推荐
相关产品推荐

