分段控件切换至视频时相机预览层无法显示问题求助
相机App录像模式无法显示预览画面排查方案
我开发的相机App通过分段控件切换拍照和录像模式,拍照ViewController能正常显示视频流,但切换到VideoViewController时,只能看到设置了背景色的PreviewLayer,无法呈现相机预览画面。
相关代码
class VideoViewController: UIViewController { var isRecording: Bool = false private var permissionGranted = false var videoSession = AVCaptureSession() var captureSession = AVCaptureSession() var movieOutput = AVCaptureMovieFileOutput() let captureSessionQueue = DispatchQueue(label: "captureSessionQueue") let previewLayer = AVCaptureVideoPreviewLayer() override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .blue view.layer.addSublayer(previewLayer) previewLayer.backgroundColor = UIColor.systemPink.cgColor view.addSubview(startVideoButton) view.addSubview(stopVideoButton) stopVideoButton.isHidden = true startVideoButton.addTarget(self, action: #selector(startRecording), for: .touchUpInside) stopVideoButton.addTarget(self, action: #selector(stopRecording), for: .touchUpInside) checkCameraPermissions() } override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() previewLayer.frame = view.bounds startVideoButton.center = CGPoint(x: view.frame.size.width / 2, y: view.frame.size.height - 80) stopVideoButton.center = CGPoint(x: view.frame.size.width / 2, y: view.frame.size.height - 80) } private func setUpVideoCamera() { guard permissionGranted else { return } videoSession.beginConfiguration() videoSession.sessionPreset = .high let camera = AVCaptureDevice.default(for: .video) let cameraInput: AVCaptureDeviceInput do { cameraInput = try AVCaptureDeviceInput(device: camera!) } catch { print("Error setting device video input: \(error)") return } if videoSession.canAddInput(cameraInput) { videoSession.addInput(cameraInput) } if videoSession.canAddOutput(movieOutput) { videoSession.addOutput(movieOutput) } previewLayer.videoGravity = .resizeAspectFill previewLayer.session = videoSession videoSession.startRunning() // Add audio device do { let audioDevice = AVCaptureDevice.default(for: .audio) let audioDeviceInput = try AVCaptureDeviceInput(device: audioDevice!) if videoSession.canAddInput(audioDeviceInput) { videoSession.addInput(audioDeviceInput) } else { print("Could not add audio device input to the session") } } catch { print("Could not create audio device input: \(error)") } }
模拟器截图


问题排查与修复建议
缺失配置提交:
setUpVideoCamera中调用了videoSession.beginConfiguration()但未执行videoSession.commitConfiguration(),导致所有Session配置无法生效。需在添加完所有输入输出后补充这行代码:videoSession.commitConfiguration()Session操作未在专用队列执行:AVCaptureSession的配置、启动属于耗时操作,必须放在专用串行队列
captureSessionQueue中执行,避免主线程阻塞和线程安全问题。修改权限检查后的调用逻辑:// 示例权限检查逻辑,需确保授权成功后在队列中启动配置 private func checkCameraPermissions() { AVCaptureDevice.requestAccess(for: .video) { [weak self] granted in DispatchQueue.main.async { self?.permissionGranted = granted if granted { self?.captureSessionQueue.async { self?.setUpVideoCamera() } } } } }同时调整
setUpVideoCamera中Session启动的顺序,确保先提交配置再启动Session。冗余Session变量:代码中同时定义了
videoSession和captureSession,但实际仅使用videoSession,建议删除无用的captureSession变量,避免逻辑混淆。确认权限触发逻辑:检查
checkCameraPermissions方法,确保用户授权相机权限后,正确调用了setUpVideoCamera,否则相机配置逻辑不会被触发。
内容的提问来源于stack exchange,提问作者aliufemi
相关产品推荐
相关产品推荐

