设置AVCaptureDevice为1FPS时的摄像头异常问题咨询
嘿,我之前在做一个macOS监控类应用的时候,刚好碰到过和你一模一样的问题——FaceTime HD摄像头设1FPS后过会儿LED开始每秒闪,sample buffer回调直接断了,2FPS就完全正常。折腾了好一阵,总结了几个可行的方向,你可以试试:
别硬写1FPS,先匹配摄像头支持的帧率范围
有些摄像头(尤其是FaceTime HD)对硬设的极端低帧率兼容性不好,建议先获取它原生支持的帧率范围,再从中锁定最接近1FPS的设置。比如用AVCaptureDeviceFormat的videoSupportedFrameRateRanges遍历查找,然后同时设置activeVideoMinFrameDuration和activeVideoMaxFrameDuration来固定帧率。给你一段Swift示例代码:guard let frontCam = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .front) else { print("找不到前置摄像头") return } do { try frontCam.lockForConfiguration() let targetFPS = 1.0 var bestFormat: AVCaptureDeviceFormat? var matchingRange: AVFrameRateRange? // 遍历所有格式,找到支持目标帧率的选项 for format in frontCam.formats { for range in format.videoSupportedFrameRateRanges { if range.minFrameRate <= targetFPS && range.maxFrameRate >= targetFPS { bestFormat = format matchingRange = range break } } } if let format = bestFormat, let range = matchingRange { frontCam.activeFormat = format // 固定帧率,最小最大时长设为相同值 let frameDuration = CMTimeMake(value: 1, timescale: Int32(targetFPS)) frontCam.activeVideoMinFrameDuration = frameDuration frontCam.activeVideoMaxFrameDuration = frameDuration } frontCam.unlockForConfiguration() } catch { print("配置摄像头失败:\(error.localizedDescription)") }加个“唤醒”操作防止摄像头休眠
1FPS的采样间隔太长,摄像头可能触发了低功耗休眠机制,直接停掉了回调。你可以每隔个几百毫秒(比如500ms)主动查一下摄像头的状态,或者短暂把帧率调到2FPS再切回1FPS——虽然有点hack,但我当时用这个方法临时解决了问题,撑到后来苹果更新系统修复了部分类似bug。检查权限和后台状态
确保你的应用始终持有摄像头权限,要是有后台运行需求,别忘了在Info.plist里配置NSCameraUsageDescription和对应的后台模式。有时候权限意外失效也会导致摄像头驱动罢工。
如果上面的方法都不管用,那大概率是AVFoundation或者FaceTime HD摄像头驱动的bug了。你可以直接给苹果提交Bug报告,记得附上设备型号、系统版本、完整的复现代码和步骤,他们的工程师还是会跟进的。我当时提交后,在后续的macOS Ventura更新里,这个问题的出现频率降低了不少。
内容的提问来源于stack exchange,提问作者Kukiwon

